/** * {@inheritdoc} */ public function convert(TargetInterface $target) { // If the hook implementation contains logic, we cannot convert it and // that's that. So we'll leave a FIXME and bail out. /** @var \Pharborist\Functions\FunctionDeclarationNode $hook */ $hook = $target->getIndexer('function')->get('hook_menu'); if ($hook->is(new ContainsLogicFilter())) { $hook->setDocComment(DocCommentNode::create($this->pluginDefinition['fixme'])); $target->save($hook); return; } $hook_menu = new HookMenu($target, $this->routeConverters); foreach ($hook_menu->getSourceRoutes() as $path => $route) { /** @var \Drupal\drupalmoduleupgrader\Routing\Drupal7\RouteWrapper $route */ if ($route->containsKey('page callback')) { $plugin_id = $this->routeConverters->hasDefinition($route['page callback']) ? $route['page callback'] : 'default'; /** @var \Drupal\drupalmoduleupgrader\Routing\RouteConverterInterface $converter */ $this->routeConverters->createInstance($plugin_id)->buildRoute($target, $route); } } $routing = []; foreach ($hook_menu->getDestinationRoutes() as $name => $route) { $routing[$name] = ['path' => $route->getPath()->__toString(), 'defaults' => $route->getDefaults(), 'requirements' => $route->getRequirements()]; } $this->writeInfo($target, 'routing', $routing); }
/** * Builds the Drupal 8 router by running the Drupal 7 router items through * the appropriate route converters. * * @return RouterInterface */ private function buildDestinationRoutes() { // @todo These are currently hardcoded on the D7 -> D8 conversion. Make this // configurable. $router = new Drupal8Router(); $this->routeMap = []; foreach ($this->getSourceRoutes() as $path => $route) { /** @var Drupal7\RouteWrapper $route */ // If the route hasn't got a page callback...don't even try. if (!$route->containsKey('page callback')) { continue; } // Get the appropriate route converter, which will build the route // definition. $plugin_id = $route['page callback']; if (!$this->routeConverters->hasDefinition($plugin_id)) { $plugin_id = 'default'; } /** @var Drupal8\RouteWrapper $d8_route */ $d8_route = $this->routeConverters->createInstance($plugin_id)->buildRouteDefinition($this->target, $route); $router->addRoute($d8_route); $this->routeMap[$path] = $d8_route->getIdentifier(); } $router->finalize(); foreach ($this->getSourceRoutes()->getDefaultLocalTasks() as $path => $route) { /** @var Drupal7\RouteWrapper $route */ if ($route->hasParent()) { $parent = (string) $route->getParent()->getPath(); $this->routeMap[$path] = $this->routeMap[$parent]; } } return $router; }
/** * {@inheritdoc} */ public function getDerivativeDefinitions($base_plugin_definition) { $fields = []; try { $source_plugin = static::getSourcePlugin('d7_field_instance'); $source_plugin->checkRequirements(); // Read all field instance definitions in the source database. foreach ($source_plugin as $row) { if ($row->getSourceProperty('entity_type') == 'node') { $fields[$row->getSourceProperty('bundle')][$row->getSourceProperty('field_name')] = $row->getSource(); } } } catch (RequirementsException $e) { // If checkRequirements() failed then the field module did not exist and // we do not have any fields. Therefore, $fields will be empty and below // we'll create a migration just for the node properties. } try { foreach (static::getSourcePlugin('d7_node_type') as $row) { $node_type = $row->getSourceProperty('type'); $values = $base_plugin_definition; $values['label'] = t('@label (@type)', ['@label' => $values['label'], '@type' => $row->getSourceProperty('name')]); $values['source']['node_type'] = $node_type; $migration = \Drupal::service('plugin.manager.migration')->createStubMigration($values); if (isset($fields[$node_type])) { foreach ($fields[$node_type] as $field_name => $info) { $field_type = $info['type']; if ($this->cckPluginManager->hasDefinition($field_type)) { if (!isset($this->cckPluginCache[$field_type])) { $this->cckPluginCache[$field_type] = $this->cckPluginManager->createInstance($field_type, [], $migration); } $this->cckPluginCache[$field_type]->processCckFieldValues($migration, $field_name, $info); } else { $migration->setProcessOfProperty($field_name, $field_name); } } } $this->derivatives[$node_type] = $migration->getPluginDefinition(); } } catch (DatabaseExceptionWrapper $e) { // Once we begin iterating the source plugin it is possible that the // source tables will not exist. This can happen when the // MigrationPluginManager gathers up the migration definitions but we do // not actually have a Drupal 7 source database. } return $this->derivatives; }
/** * {@inheritdoc} */ public function buildRoute(TargetInterface $target, Drupal7Route $route) { $definition = $this->buildRouteDefinition($target, $route); $map = $this->buildParameterMap($target, $route); $map->applyRoute($definition->unwrap()); $indexer = $target->getIndexer('function'); foreach ($map->toArray() as $function_name => $parameters) { if ($parameters && $indexer->has($function_name)) { /** @var \Pharborist\Functions\FunctionDeclarationNode $function */ $function = $indexer->get($function_name); foreach ($parameters as $parameter_name => $info) { $parameter = $function->getParameterByName($parameter_name)->setName($info['name'], TRUE); if (isset($info['type'])) { $plugin_id = '_rewriter:' . $info['type']; if ($this->rewriters->hasDefinition($plugin_id)) { $this->rewriters->createInstance($plugin_id)->rewrite($parameter); } } } } } $class_indexer = $target->getIndexer('class'); if ($class_indexer->has('DefaultController')) { $controller = $class_indexer->get('DefaultController'); } else { $controller = $this->getController($target, $route); $class_indexer->addFile($this->writeClass($target, $controller)); } if ($indexer->has($route['title callback'])) { if (!$controller->hasMethod($route['title callback'])) { $indexer->get($route['title callback'])->cloneAsMethodOf($controller); } } if ($indexer->has($route['access callback'])) { $func = $indexer->get($route['access callback']); $returns = $func->find(Filter::isInstanceOf('\\Pharborist\\ReturnStatementNode')); foreach ($returns as $ret) { $call = ClassMethodCallNode::create('\\Drupal\\Core\\Access\\AccessResult', 'allowedIf')->appendArgument($ret->getExpression()); $ret->replaceWith(ReturnStatementNode::create($call)); } // The access callback always receives an $account parameter. if ($func->hasParameter('account')) { $func->getParameter('account')->setTypeHint('Drupal\\Core\\Session\\AccountInterface'); } else { $account = ParameterNode::create('account')->setTypeHint('Drupal\\Core\\Session\\AccountInterface'); $func->appendParameter($account); } if (!$controller->hasMethod($route['access callback'])) { $func->cloneAsMethodOf($controller); } } if ($indexer->has($route['page callback'])) { if (!$controller->hasMethod($route['page callback'])) { $indexer->get($route['page callback'])->cloneAsMethodOf($controller); } } $this->writeClass($target, $controller); }
/** * {@inheritdoc} */ public function transform($value, MigrateExecutableInterface $migrate_executable, Row $row, $destination_property) { $plugin_id = parent::transform($value, $migrate_executable, $row, $destination_property); // If the static map is bypassed on failure, the returned plugin ID will be // an array if $value was. Plugin IDs cannot be arrays, so flatten it before // passing it into the filter manager. if (is_array($plugin_id)) { $plugin_id = implode(':', $plugin_id); } if ($this->filterManager->hasDefinition($plugin_id)) { return $plugin_id; } else { $fallback = $this->filterManager->getFallbackPluginId($plugin_id); $message = $this->t('Filter @plugin_id could not be mapped to an existing filter plugin; defaulting to @fallback.', ['@plugin_id' => $plugin_id, '@fallback' => $fallback]); $migrate_executable->saveMessage((string) $message, MigrationInterface::MESSAGE_WARNING); return $fallback; } }
/** * Gets the definition of all derivatives of a base plugin. * * @param array $base_plugin_definition * The definition array of the base plugin. * * @return array * An array of full derivative definitions keyed on derivative id. * * @see \Drupal\Component\Plugin\Derivative\DeriverBase::getDerivativeDefinition() */ public function getDerivativeDefinitions($base_plugin_definition) { if ($base_plugin_definition['id'] == 'd6_node_translation' && !$this->includeTranslations) { // Refuse to generate anything. return $this->derivatives; } // Read all CCK field instance definitions in the source database. $fields = array(); try { $source_plugin = static::getSourcePlugin('d6_field_instance'); $source_plugin->checkRequirements(); foreach ($source_plugin as $row) { $fields[$row->getSourceProperty('type_name')][$row->getSourceProperty('field_name')] = $row->getSource(); } } catch (RequirementsException $e) { // If checkRequirements() failed then the content module did not exist and // we do not have any CCK fields. Therefore, $fields will be empty and // below we'll create a migration just for the node properties. } try { foreach (static::getSourcePlugin('d6_node_type') as $row) { $node_type = $row->getSourceProperty('type'); $values = $base_plugin_definition; $values['label'] = t("@label (@type)", ['@label' => $values['label'], '@type' => $node_type]); $values['source']['node_type'] = $node_type; $values['destination']['default_bundle'] = $node_type; // If this migration is based on the d6_node_revision migration or // is for translations of nodes, it should explicitly depend on the // corresponding d6_node variant. if (in_array($base_plugin_definition['id'], ['d6_node_revision', 'd6_node_translation'])) { $values['migration_dependencies']['required'][] = 'd6_node:' . $node_type; } $migration = \Drupal::service('plugin.manager.migration')->createStubMigration($values); if (isset($fields[$node_type])) { foreach ($fields[$node_type] as $field_name => $info) { $field_type = $info['type']; if ($this->cckPluginManager->hasDefinition($info['type'])) { if (!isset($this->cckPluginCache[$field_type])) { $this->cckPluginCache[$field_type] = $this->cckPluginManager->createInstance($field_type, ['core' => 6], $migration); } $this->cckPluginCache[$field_type]->processCckFieldValues($migration, $field_name, $info); } else { $migration->setProcessOfProperty($field_name, $field_name); } } } $this->derivatives[$node_type] = $migration->getPluginDefinition(); } } catch (DatabaseExceptionWrapper $e) { // Once we begin iterating the source plugin it is possible that the // source tables will not exist. This can happen when the // MigrationPluginManager gathers up the migration definitions but we do // not actually have a Drupal 6 source database. } return $this->derivatives; }
/** * {@inheritdoc} */ public function form(array $form, FormStateInterface $form_state) { $form = parent::form($form, $form_state); $form['#attached']['library'][] = 'core/drupal.dialog.ajax'; $key_providers = []; foreach ($this->manager->getDefinitions() as $plugin_id => $definition) { $key_providers[$plugin_id] = (string) $definition['title']; } /** @var $key \Drupal\key\KeyInterface */ $key = $this->entity; $form['#tree'] = TRUE; $form['label'] = array('#type' => 'textfield', '#title' => $this->t('Key name'), '#maxlength' => 255, '#default_value' => $key->label(), '#required' => TRUE); $form['id'] = array('#type' => 'machine_name', '#default_value' => $key->id(), '#machine_name' => array('exists' => '\\Drupal\\key\\Entity\\Key::load'), '#disabled' => !$key->isNew()); $form['description'] = array('#type' => 'textfield', '#title' => $this->t('Description'), '#default_value' => $key->getDescription(), '#description' => $this->t('A short description of the key.')); $form['key_provider'] = array('#type' => 'select', '#title' => $this->t('Key Provider'), '#options' => $key_providers, '#empty_option' => t('- Select key provider -'), '#empty_value' => '', '#ajax' => ['callback' => [$this, 'getKeyProviderForm'], 'event' => 'change', 'wrapper' => 'key-provider-form'], '#required' => TRUE, '#default_value' => $key->getKeyProvider()); $form['key_provider_settings'] = ['#prefix' => '<div id="key-provider-form">', '#suffix' => '</div>']; if ($this->manager->hasDefinition($key->getKeyProvider())) { // @todo compare ids to ensure appropriate plugin values. $plugin = $this->manager->createInstance($key->getKeyProvider(), $key->getKeyProviderSettings()); $form['key_provider_settings'] += $plugin->buildConfigurationForm([], $form_state); } return $form; }
/** * {@inheritdoc} */ public function buildConfigurationForm(array $form, FormStateInterface $form_state) { $form = parent::buildConfigurationForm($form, $form_state); $form['threshold'] = array('#type' => 'textfield', '#title' => $this->t('Threshold'), '#description' => $this->t('Defines the score at which a contact is considered a match.'), '#maxlength' => 28, '#size' => 28, '#required' => TRUE, '#default_value' => $this->getConfigurationItem('threshold')); $return_description = $this->t(<<<EOF If two or more contact records result in matches with identical scores, CRM Core will give preference to one over the other base on selected option. EOF ); $form['return_order'] = array('#type' => 'select', '#title' => $this->t('Return Order'), '#description' => $return_description, '#default_value' => $this->getConfigurationItem('return_order'), '#options' => array('created' => $this->t('Most recently created'), 'updated' => $this->t('Most recently updated'), 'associated' => $this->t('Associated with user'))); $strict_description = $this->t(<<<EOF Check this box to return a match for this contact type the first time one is identified that meets the threshold. Stops redundant processing. EOF ); $form['strict'] = array('#type' => 'checkbox', '#title' => $this->t('Strict matching'), '#description' => $strict_description, '#default_value' => $this->getConfigurationItem('strict')); $form['rules'] = array('#title' => $this->t('Field Matching'), '#type' => 'table', '#tree' => TRUE, '#header' => $this->buildHeader(), '#empty' => $this->t('There are no fields available.'), '#tabledrag' => array(array('action' => 'order', 'relationship' => 'sibling', 'group' => 'weight')), '#theme_wrappers' => array('form_element')); // @todo: Display fields per bundle. $contact_types = $this->entityManager->getStorage('crm_core_contact_type')->loadMultiple(); $fields = []; foreach ($contact_types as $contact_type_id => $value) { $fields += $this->entityManager->getFieldDefinitions('crm_core_contact', $contact_type_id); } foreach ($fields as $field) { $rules = $this->getConfigurationItem('rules'); $config = empty($rules[$field->getName()]) ? array() : $rules[$field->getName()]; $config['field'] = $field; $match_field_id = 'unsupported'; if ($this->pluginManager->hasDefinition($field->getType())) { $match_field_id = $field->getType(); } /* @var \Drupal\crm_core_match\Plugin\crm_core_match\field\FieldHandlerInterface $match_field */ $match_field = $this->pluginManager->createInstance($match_field_id, $config); $disabled = $match_field_id == 'unsupported'; foreach ($match_field->getPropertyNames($field) as $name) { $row = $this->buildRow($match_field, $name, $disabled); $form['rules'][$field->getName() . ':' . $name] = $row; } } return $form; }