diff --git a/core/modules/migrate_drupal/migrate_drupal.module b/core/modules/migrate_drupal/migrate_drupal.module index bbb0622184..ef52b571e5 100644 --- a/core/modules/migrate_drupal/migrate_drupal.module +++ b/core/modules/migrate_drupal/migrate_drupal.module @@ -107,15 +107,55 @@ function migrate_drupal_migration_plugins_alter(&$definitions) { return $value; }; // Alter references to the classic node migration to the master node - // migration in all relevant core migrations. The classic node migrations - // are not altered.. + // migration in all relevant core migrations. The references altered are + // those in migration_dependencies and in the process pipeline. In the + // process pipeline we are concerned with references to classic mode + // migrations in a migration_lookup process. + // + // The process pipeline is altered so that the migration_lookup returns + // the correct ids. For example, the classic d6_node_revision migration + // has a single ID, the revision ID, but the d6_node_master has three IDs, + // the node ID, the revision ID and the language. To ensure the pipeline + // works for both migrations we need to insert a process to return only + // the revision ID if the master node migration was used. + // + // Example: d6_term_node_revision + // + // Before + // vid: + // - + // plugin: migration_lookup + // migration: d6_node_revision + // source: vid + // - + // plugin: skip_on_empty + // method: row + //After + // vid: + // - + // plugin: migration_lookup + // migration: + // - d6_node_revision + // - d6_node_master + // source: vid + // - + // plugin: skip_on_empty + // method: row + // - + // plugin: node_master_node_lookup + // + // The classic node migrations are not altered. + // + // See \Drupal\migrate_drupal\Plugin\migrate\process\NodeMasterNodeLookup + // See \Drupal\migrate_drupal\Plugin\migrate\process\NodeMasterNodeRevisionLookup + // See core/modules/migrate_drupal/src/Plugin/migrate/process/NodeMasterNodeTranslationLookup.php foreach ($definitions as &$definition) { $is_node_classic_migration = preg_match('/d([67])_(node|node_translation|node_revision)($|:.*)/', $definition['id']); if (!$is_node_classic_migration && isset($definition['migration_dependencies'])) { array_walk_recursive($definition['migration_dependencies'], $replace_with_master_migration); } - // Pipeline does not extract the migration_lookup return value. + // Alter the migration_lookup process so the node ID is returned. if (preg_match('/d6_term_node($|:.*)/', $definition['id'])) { $tmp = $definition['process']['nid'][0]['migration']; $definition['process']['nid'][0]['migration'] = _insert_migration($tmp); @@ -123,7 +163,7 @@ function migrate_drupal_migration_plugins_alter(&$definitions) { 'plugin' => 'node_master_node_lookup', ]; } - // Pipeline does not extract the migration_lookup return value. + // Alter the migration_lookup process so the revision ID is returned. if (preg_match('/d6_term_node_revision($|:.*)/', $definition['id'])) { $tmp = $definition['process']['vid'][0]['migration']; $definition['process']['vid'][0]['migration'] = _insert_migration($tmp); @@ -131,7 +171,8 @@ function migrate_drupal_migration_plugins_alter(&$definitions) { 'plugin' => 'node_master_node_revision_lookup', ]; } - // Pipeline does not extract the migration_lookup return value. + // Alter the migration_lookup process so the node ID and langcode are + // returned. if (preg_match('/d6_term_node_translation($|:.*)/', $definition['id'])) { $tmp = $definition['process']['dest_nid'][0]['migration']; $definition['process']['dest_nid'][0]['migration'] = _insert_migration($tmp); @@ -141,7 +182,7 @@ function migrate_drupal_migration_plugins_alter(&$definitions) { } } - // Pipeline does not extract the migration_lookup return value. + // Alter the migration_lookup process so the node ID is returned. if (isset($definitions['d6_comment'])) { $tmp = $definitions['d6_comment']['process']['entity_id'][0]['migration']; $definitions['d6_comment']['process']['entity_id'][0]['migration'] = _insert_migration($tmp); @@ -149,7 +190,8 @@ function migrate_drupal_migration_plugins_alter(&$definitions) { 'plugin' => 'node_master_node_lookup', ]; } - // Pipeline does not extract the migration_lookup return value. + // Alter the migration_lookup process so the node ID and langcode are + // returned. if (isset($definitions['d6_url_alias'])) { $tmp = $definitions['d6_url_alias']['process']['node_translation'][2]['migration']; $definitions['d6_url_alias']['process']['node_translation'][2]['migration'] = _insert_migration($tmp); @@ -157,7 +199,7 @@ function migrate_drupal_migration_plugins_alter(&$definitions) { 'plugin' => 'node_master_node_translation_lookup', ]; } - // Pipeline does not extract the migration_lookup return value. + // Alter the migration_lookup process so the node ID is returned. if (isset($definitions['d7_comment'])) { $tmp = $definitions['d7_comment']['process']['entity_id'][0]['migration']; $definitions['d7_comment']['process']['entity_id'][0]['migration'] = _insert_migration($tmp); @@ -165,7 +207,8 @@ function migrate_drupal_migration_plugins_alter(&$definitions) { 'plugin' => 'node_master_node_lookup', ]; } - // Pipeline does not extract the migration_lookup return value. + // Alter the migration_lookup process so the node ID and langcode are + // returned. if (isset($definitions['d7_url_alias'])) { $tmp = $definitions['d7_url_alias']['process']['node_translation'][2]['migration']; $definitions['d7_url_alias']['process']['node_translation'][2]['migration'] = _insert_migration($tmp); @@ -173,7 +216,7 @@ function migrate_drupal_migration_plugins_alter(&$definitions) { 'plugin' => 'node_master_node_translation_lookup', ]; } - // Pipeline does not extract the migration_lookup return value. + // Alter the migration_lookup process so the node ID is returned. if (isset($definitions['statistics_node_counter'])) { $tmp = $definitions['statistics_node_counter']['process']['nid'][0]['migration']; $definitions['statistics_node_counter']['process']['nid'][0]['migration'] = _insert_migration($tmp); @@ -181,7 +224,10 @@ function migrate_drupal_migration_plugins_alter(&$definitions) { 'plugin' => 'node_master_node_lookup', ]; } - // Pipeline extracts the first item of the migration_lookup return value. + // Alter the migration_lookup process to include the master node migration. + // A node_master_node*_lookup process is not needed because the + // migration_lookup is followed by an extract process which will get the + // node ID. if (isset($definitions['node_translation_menu_links'])) { $tmp = $definitions['node_translation_menu_links']['process']['new_nid'][4]['migration']; $definitions['node_translation_menu_links']['process']['new_nid'][4]['migration'] = _insert_migration($tmp); diff --git a/core/modules/migrate_drupal/src/MigrationConfigurationTrait.php b/core/modules/migrate_drupal/src/MigrationConfigurationTrait.php index 52fefdf2ca..71b116fe04 100644 --- a/core/modules/migrate_drupal/src/MigrationConfigurationTrait.php +++ b/core/modules/migrate_drupal/src/MigrationConfigurationTrait.php @@ -121,7 +121,7 @@ protected function createDatabaseStateSettings(array $database, $drupal_version) */ protected function getMigrations($database_state_key, $drupal_version) { $version_tag = 'Drupal ' . $drupal_version; - /** @var \Drupal\migrate\Plugin\Migration[] $all_migrations */ + /** @var \Drupal\migrate\Plugin\MigrationInterface[] $all_migrations */ $all_migrations = $this->getMigrationPluginManager()->createInstancesByTag($version_tag); // If this source database is multilingual then we must run only the @@ -130,16 +130,19 @@ protected function getMigrations($database_state_key, $drupal_version) { // multilingual then we want to run all dN_node* migrations except // dN_node_master. Here we unset the migrations we don't want to run. $type = $this->getNodeMigrateType($all_migrations, $drupal_version); - if ($type === NodeMigrateType::NODE_MIGRATE_TYPE_MASTER) { - $patterns = '/(d' . $drupal_version . '_node:)|(d' . $drupal_version . '_node_translation:)|(d' . $drupal_version . '_node_revision:)|(entity_translation)/'; - } - if ($type === NodeMigrateType::NODE_MIGRATE_TYPE_CLASSIC) { - $patterns = '/(d' . $drupal_version . '_node_master:)/'; - } - if ($type === NodeMigrateType::NODE_MIGRATE_TYPE_BOTH) { - $patterns = '//'; - } + switch ($type) { + case NodeMigrateType::NODE_MIGRATE_TYPE_MASTER: + $patterns = '/(d' . $drupal_version . '_node:)|(d' . $drupal_version . '_node_translation:)|(d' . $drupal_version . '_node_revision:)|(entity_translation)/'; + break; + case NodeMigrateType::NODE_MIGRATE_TYPE_CLASSIC: + $patterns = '/(d' . $drupal_version . '_node_master:)/'; + break; + + case NodeMigrateType::NODE_MIGRATE_TYPE_BOTH: + $patterns = '//'; + break; + } foreach ($all_migrations as $key => $migrations) { if (preg_match($patterns, $key)) { unset($all_migrations[$key]); @@ -302,13 +305,15 @@ protected function getState() { * The node master migration is the default. It is not used when there * are existing tables for dN_node. * - * @param array $migrations + * @param \Drupal\migrate\Plugin\MigrationInterface[] $migrations * An array of migrations keyed by migration ID. * @param string $version - * The legacy Drupal version. + * The Drupal version of the source database. * * @return string - * Indicator of the node migration map tables in use. + * One of NodeMigrateType::NODE_MIGRATE_TYPE_CLASSIC, + * NodeMigrateType::NODE_MIGRATE_TYPE_MASTER, or + * NodeMigrateType::NODE_MIGRATE_TYPE_BOTH */ protected function getNodeMigrateType(array $migrations, $version) { $migrate_type = NodeMigrateType::NODE_MIGRATE_TYPE_MASTER; @@ -318,13 +323,13 @@ protected function getNodeMigrateType(array $migrations, $version) { $ids = ['node_master', 'node']; foreach ($ids as $id) { // Create the variable name, 'node_exists' or 'node_master_exists' and - // set it the default value, FALSE. + // set it to the default value, FALSE. $exists = $id . '_exists'; $$exists = FALSE; $patterns = '/d' . $version . '_' . $id . ':/'; $matches = preg_grep($patterns, array_keys($migrations)); - // Set the existence flag True when the migration exists and has a map - // table with entries. + // When the migration has a map table set 'node_exists' or + // 'node_master_exists' to TRUE. foreach ($matches as $match) { if ($migrations[$match]->getIdMap()->processedCount()) { $$exists = TRUE; diff --git a/core/modules/migrate_drupal/src/NodeMigrateType.php b/core/modules/migrate_drupal/src/NodeMigrateType.php index e4600bd00d..71cb88c62a 100644 --- a/core/modules/migrate_drupal/src/NodeMigrateType.php +++ b/core/modules/migrate_drupal/src/NodeMigrateType.php @@ -8,17 +8,17 @@ final class NodeMigrateType { /** - * Indicates of the node migration map tables in use. + * Only the master node migration map tables are in use. */ const NODE_MIGRATE_TYPE_MASTER = 'MASTER'; /** - * Indicates of the node migration map tables in use. + * Only the classic node migration map tables are in use. */ const NODE_MIGRATE_TYPE_CLASSIC = 'CLASSIC'; /** - * Indicates of the node migration map tables in use. + * Both the classic and master node migration map tables are in use. */ const NODE_MIGRATE_TYPE_BOTH = 'BOTH'; @@ -29,7 +29,7 @@ final class NodeMigrateType { * are existing tables for dN_node. * * @param array[] $definitions - * An associative array of migration. The array is normally keyed by + * An associative array of migrations. The array is normally keyed by * migration ID. However, the followup migrations are keyed by * 'entity_type__bundle'. Each value is the migration array, obtained by * decoding the migration YAML file and enriched with some meta information @@ -67,6 +67,9 @@ public function getNodeMigrateType(array $definitions) { $version_string = FALSE; if ($connection) { + // Determine the source database version. This is an excerpt from + // getLegacyDrupalVersion for Drupal 5, 6 or 7 source databases. + // See \Drupal\migrate_drupal\MigrationConfigurationTrait::getLegacyDrupalVersion if ($connection->schema()->tableExists('system')) { try { $version_string = $connection @@ -118,10 +121,8 @@ public function getNodeMigrateType(array $definitions) { // migration. foreach ($base_tables as $base_table) { if ($connection->schema()->tableExists($base_table)) { - if ($connection->select($base_table) - ->countQuery() - ->execute() - ->fetchField()) { + if ($connection->select($base_table)->countQuery() + ->execute()->fetchField()) { $$exists = TRUE; break; } diff --git a/core/modules/migrate_drupal/src/Plugin/migrate/EntityReferenceTranslationDeriver.php b/core/modules/migrate_drupal/src/Plugin/migrate/EntityReferenceTranslationDeriver.php index 52c04dd195..e0ea95b7d5 100644 --- a/core/modules/migrate_drupal/src/Plugin/migrate/EntityReferenceTranslationDeriver.php +++ b/core/modules/migrate_drupal/src/Plugin/migrate/EntityReferenceTranslationDeriver.php @@ -186,6 +186,9 @@ public function getDerivativeDefinitions($base_plugin_definition) { } } } + // Ensure these migrations are also altered. This is done here because This + // deriver is only used for the follow up migrations which are created after + // the migrations_plugin_alter is run. if ($this->derivatives) { migrate_drupal_migration_plugins_alter($this->derivatives); } diff --git a/core/modules/migrate_drupal/tests/modules/node_migrate_classic/node_migrate_classic.info.yml b/core/modules/migrate_drupal/tests/modules/node_migrate_classic/node_migrate_classic.info.yml index 1c3c334eee..1cfac5fbcf 100644 --- a/core/modules/migrate_drupal/tests/modules/node_migrate_classic/node_migrate_classic.info.yml +++ b/core/modules/migrate_drupal/tests/modules/node_migrate_classic/node_migrate_classic.info.yml @@ -1,4 +1,4 @@ -name: Node migrate calssic +name: Node migrate classic type: module description: Use the classic node migrations. package: Testing diff --git a/core/modules/migrate_drupal/tests/src/Kernel/MigrationPluginAlterTest.php b/core/modules/migrate_drupal/tests/src/Kernel/MigrationPluginAlterTest.php index d366fa97de..681ca572e7 100644 --- a/core/modules/migrate_drupal/tests/src/Kernel/MigrationPluginAlterTest.php +++ b/core/modules/migrate_drupal/tests/src/Kernel/MigrationPluginAlterTest.php @@ -32,7 +32,7 @@ protected function setUp() { * @param array $migrations * An array of migrations. * @param array $expected - * The expected results.. + * The expected results. * * @dataProvider providerMigrationPluginAlter * @@ -58,7 +58,7 @@ public function providerMigrationPluginAlter() { $tests = []; // Tests migrations that should never be altered, once without an extra - // modules installed, then with content_translation installed and finally + // module installed, then with content_translation installed and finally // with 'node_migrate_master' installed. $migrations = [ 'test' => [