migrations/d7_metatag_field_instance.yml | 7 +--- .../migrate/source/d7/MetatagFieldDeriver.php | 19 +++------ .../migrate/source/d7/MetatagFieldInstance.php | 45 +++++++++++++++++++++- .../source/d7/MetatagFieldInstanceDeriver.php | 21 +++++----- 4 files changed, 63 insertions(+), 29 deletions(-) diff --git a/migrations/d7_metatag_field_instance.yml b/migrations/d7_metatag_field_instance.yml index 35a500d..70d1d78 100644 --- a/migrations/d7_metatag_field_instance.yml +++ b/migrations/d7_metatag_field_instance.yml @@ -26,9 +26,4 @@ migration_dependencies: required: # The base field migration is required before this migration can run. - d7_metatag_field - - # @todo Is this accurate? Does it really need the vocabulary migration, or - # is it more precautionary, that it *might* be needed so it might as well be - # executed first? - - d7_node_type - - d7_taxonomy_vocabulary + # Relevant required dependencies are added in \Drupal\metatag\Migrate\MigrationPluginAlterer. diff --git a/src/Plugin/migrate/source/d7/MetatagFieldDeriver.php b/src/Plugin/migrate/source/d7/MetatagFieldDeriver.php index 0d8fa5a..294dc2b 100644 --- a/src/Plugin/migrate/source/d7/MetatagFieldDeriver.php +++ b/src/Plugin/migrate/source/d7/MetatagFieldDeriver.php @@ -23,17 +23,6 @@ class MetatagFieldDeriver extends DeriverBase implements ContainerDeriverInterfa use MigrationConfigurationTrait; use StringTranslationTrait; - /** - * Required entity type DB tables, keyed by the entity type ID. - * - * @var string[][] - */ - protected $supportedEntityTypesTables = [ - 'node' => ['node', 'node_type'], - 'taxonomy_term' => ['taxonomy_term_data', 'taxonomy_vocabulary'], - 'user' => [], - ]; - /** * The entity type manager. * @@ -42,7 +31,7 @@ class MetatagFieldDeriver extends DeriverBase implements ContainerDeriverInterfa protected $entityTypeManager; /** - * Constructs a PathRedirectDeriver instance. + * Constructs a MetatagFieldDeriver instance. * * @param \Drupal\Core\Entity\EntityTypeManagerInterface $entity_type_manager * The entity type manager. @@ -82,6 +71,11 @@ class MetatagFieldDeriver extends DeriverBase implements ContainerDeriverInterfa ->execute() ->fetchAllKeyed(0, 0); foreach ($entity_type_ids as $entity_type_id) { + // Skip if the entity type is missing. + if (!($entity_type_definition = $this->entityTypeManager->getDefinition($entity_type_id, FALSE))) { + continue; + } + $this->derivatives[$entity_type_id] = $base_plugin_definition; $this->derivatives[$entity_type_id]['source']['entity_type'] = $entity_type_id; $this->derivatives[$entity_type_id]['source']['entity_type_id'] = $entity_type_id; @@ -90,7 +84,6 @@ class MetatagFieldDeriver extends DeriverBase implements ContainerDeriverInterfa '@type' => $this->entityTypeManager->getDefinition($entity_type_id)->getPluralLabel(), ]); } - $this->derivatives['other'] = $base_plugin_definition; return $this->derivatives; } diff --git a/src/Plugin/migrate/source/d7/MetatagFieldInstance.php b/src/Plugin/migrate/source/d7/MetatagFieldInstance.php index 217f49c..000f6b5 100644 --- a/src/Plugin/migrate/source/d7/MetatagFieldInstance.php +++ b/src/Plugin/migrate/source/d7/MetatagFieldInstance.php @@ -48,9 +48,44 @@ class MetatagFieldInstance extends DrupalSqlBase { * {@inheritdoc} */ public function query() { - return $this->select('metatag', 'm') + $base_query = $this->select('metatag', 'm') ->fields('m', ['entity_type']) ->groupBy('entity_type'); + + if (isset($this->configuration['entity_type_id'])) { + $entity_type_id = $this->configuration['entity_type_id']; + $base_query->condition('m.entity_type', $entity_type_id); + + if (isset($this->configuration['bundle'])) { + $bundle = $this->configuration['bundle']; + switch ($entity_type_id) { + case 'node': + // We want to get a per-node-type metatag migration. So we inner join + // the base query on node table based on the parsed node ID. + $base_query->join('node', 'n', "n.nid = m.entity_id"); + $base_query->condition('n.type', $bundle); + $base_query->addField('n', 'type', 'bundle'); + $base_query->groupBy('bundle'); + break; + + case 'taxonomy_term': + // Join the taxonomy term data table to the base query; based on + // the parsed taxonomy term ID. + $base_query->join('taxonomy_term_data', 'ttd', "ttd.tid = m.entity_id"); + $base_query->fields('ttd', ['vid']); + // Since the "taxonomy_term_data" table contains only the taxonomy + // vocabulary ID, but not the vocabulary name, we have to inner + // join the "taxonomy_vocabulary" table as well. + $base_query->join('taxonomy_vocabulary', 'tv', 'ttd.vid = tv.vid'); + $base_query->condition('tv.machine_name', $bundle); + $base_query->addField('tv', 'machine_name', 'bundle'); + $base_query->groupBy('bundle'); + break; + } + } + } + + return $base_query; } /** @@ -69,6 +104,14 @@ class MetatagFieldInstance extends DrupalSqlBase { public function initializeIterator() { $bundles = []; foreach (parent::initializeIterator() as $instance) { + // For entity types for which we support creating derivatives, do not + // retrieve the bundles using the D8|9 entity type bundle info service, + // because then we will end up creating meta tag fields even for bundles + // that do not use meta tags. + if (isset($instance['bundle'])) { + $bundles[] = $instance; + continue; + } $bundle_info = $this->entityTypeBundleInfo ->getBundleInfo($instance['entity_type']); foreach (array_keys($bundle_info) as $bundle) { diff --git a/src/Plugin/migrate/source/d7/MetatagFieldInstanceDeriver.php b/src/Plugin/migrate/source/d7/MetatagFieldInstanceDeriver.php index 2015ca1..0b73988 100644 --- a/src/Plugin/migrate/source/d7/MetatagFieldInstanceDeriver.php +++ b/src/Plugin/migrate/source/d7/MetatagFieldInstanceDeriver.php @@ -89,12 +89,17 @@ class MetatagFieldInstanceDeriver extends DeriverBase implements ContainerDerive $base_query = $source->getDatabase()->select('metatag', 'm'); $base_query->condition('m.entity_type', $entity_type_id); + // If there are no metatags for this entity type, no derivatives needed. + $metatag_count = (int) (clone $base_query)->countQuery()->execute()->fetchField(); + if ($metatag_count === 0) { + continue; + } + $metatags_grouped_by_bundle = []; switch ($entity_type_id) { case 'node': - // We want to get a per-node-type path redirect migration. So we - // inner join the base query on node table based on the parsed - // node ID. + // We want to get a per-node-type metatag migration. So we inner join + // the base query on node table based on the parsed node ID. $base_query->join('node', 'n', "n.nid = m.entity_id"); $base_query->fields('n', ['type']); // We'll need the "human" name of the node type. @@ -103,7 +108,7 @@ class MetatagFieldInstanceDeriver extends DeriverBase implements ContainerDerive $base_query->groupBy('n.type'); $base_query->groupBy('nt.name'); - // Get every node-related path redirect ID, grouped by node type. + // Get every node-related metatag, grouped by node type. $rows = $base_query->execute()->fetchAllAssoc('type'); $metatags_grouped_by_bundle = array_reduce($rows, function (array $carry, $row) { $carry[$row->type] = $row->name; @@ -116,7 +121,6 @@ class MetatagFieldInstanceDeriver extends DeriverBase implements ContainerDerive // Join the taxonomy term data table to the base query; based on // the parsed taxonomy term ID. $base_query->join('taxonomy_term_data', 'ttd', "ttd.tid = m.entity_id"); - $foo = ''; $base_query->fields('ttd', ['vid']); // Since the "taxonomy_term_data" table contains only the taxonomy // vocabulary ID, but not the vocabulary name, we have to inner @@ -127,7 +131,7 @@ class MetatagFieldInstanceDeriver extends DeriverBase implements ContainerDerive $base_query->groupBy('tv.machine_name'); $base_query->groupBy('tv.name'); - // Get all of the path redirects whose destination is a taxonomy + // Get all of the metatags whose destination is a taxonomy // term URL. $rows = $base_query->execute()->fetchAllAssoc('machine_name'); $metatags_grouped_by_bundle = array_reduce($rows, function (array $carry, $row) { @@ -140,7 +144,7 @@ class MetatagFieldInstanceDeriver extends DeriverBase implements ContainerDerive // If we have per-bundle results for a content entity type, we are // able to derive migrations per entity type and bundle. - // Dependency metadata is added im redirect_migration_plugins_alter(). + // Dependency metadata is added im \Drupal\metatag\Migrate\MigrationPluginAlterer::alterMigrationPlugins(). if (!empty($metatags_grouped_by_bundle)) { foreach ($metatags_grouped_by_bundle as $bundle_id => $bundle_label) { $derivative_id = "$entity_type_id:$bundle_id"; @@ -156,7 +160,7 @@ class MetatagFieldInstanceDeriver extends DeriverBase implements ContainerDerive } } // If we don't have per-bundle results, we will derive only a - // per-entity-type path redirect migration. + // per-entity-type metatag migration. else { $this->derivatives[$entity_type_id] = $base_plugin_definition; $this->derivatives[$entity_type_id]['source']['entity_type_id'] = $entity_type_id; @@ -166,7 +170,6 @@ class MetatagFieldInstanceDeriver extends DeriverBase implements ContainerDerive ]); } } - $this->derivatives['other'] = $base_plugin_definition; return $this->derivatives; }