diff --git a/core/modules/migrate_drupal/migrate_drupal.module b/core/modules/migrate_drupal/migrate_drupal.module index 17979b8753..2e4e3ae818 100644 --- a/core/modules/migrate_drupal/migrate_drupal.module +++ b/core/modules/migrate_drupal/migrate_drupal.module @@ -95,7 +95,7 @@ function migrate_drupal_migration_plugins_alter(&$definitions) { // If this source database is multilingual then we are only running the // dN_node_master migration and not any other dN_node* migration. Alter all // instances of migration_lookup in core migrations to use dN_node_master. - if (_isMultilingualSource($definitions)) { + if (_useMasterNodeMigration($definitions) === 'MASTER') { foreach ($definitions as &$definition) { if (!preg_match('/d([67])_(node|node_translation|node_revision)($|:.*)/', $definition['id'])) { $properties = ['destination', 'migration_dependencies']; @@ -110,6 +110,7 @@ function migrate_drupal_migration_plugins_alter(&$definitions) { } } } + // Pipeline does not extract the migration_lookup return value. if (preg_match('/d6_term_node($|:.*)/', $definition['id'])) { $tmp = $definition['process']['nid'][0]['migration']; @@ -200,14 +201,16 @@ function _insert_migration($migrations) { } /** - * Determines if i18n is installed in the source database. + * Determines is the node master migration is to be used. + * + * The node master migration is the default. It is not used when there + * are existing tables for dNnode. * - * @return bool - * True is i18n is enabled in the source database otherwise FALSE. + * @return string + * Indicator of the node migration map tables in use. */ -function _isMultilingualSource($definitions) { +function _useMasterNodeMigration($definitions) { /** @var \Drupal\migrate\Plugin\migrate\source\SqlBase $source_plugin */ - $status = FALSE; if (isset($definitions['system_site'])) { $source_plugin = \Drupal::service('plugin.manager.migration') ->createStubMigration($definitions['system_site']) @@ -219,13 +222,59 @@ function _isMultilingualSource($definitions) { catch (\Exception $e) { // @todo: do something useful. } - if ($connection && $connection->schema()->tableExists('system')) { - // Connect to source database. - $status = $connection->query("SELECT status FROM {system} WHERE name = :name and type = :type", [ - ':name' => 'i18n', - ':type' => 'module', - ])->fetchField(); + $version_string = FALSE; + if ($connection->schema()->tableExists('system')) { + try { + $version_string = $connection + ->query('SELECT schema_version FROM {system} WHERE name = :module', [':module' => 'system']) + ->fetchField(); + if ($version_string && $version_string[0] == '1') { + if ((int) $version_string >= 1000) { + $version_string = '5'; + } + else { + $version_string = FALSE; + } + } + } + catch (\PDOException $e) { + $version_string = FALSE; + } } + $version= $version_string ? substr($version_string, 0, 1) : FALSE; + + $useMasterNode = 'MASTER'; + $node_exists = FALSE; + $node_master_exists = FALSE; + $connection = \Drupal::database(); + + $ids = ['node_master', 'node']; + foreach ($ids as $id) { + $pattern = ' /d' . $version . '_' . $id . ':/'; + $exists = $id . '_exists'; + $$exists = FALSE; + $matches = preg_grep($pattern, array_keys($definitions)); + $tables = preg_replace('/:/', '__', $matches); + foreach ($tables as $table) { + $table_name = 'migrate_map_' . $table; + if ($connection->query("Select count(*) from $table_name")->fetchField()) { + $$exists = TRUE; + break; + } + } + } + + if ($node_exists && $node_master_exists) { + $useMasterNode = 'BOTH'; + } + if ($node_exists && !$node_master_exists) { + $useMasterNode = "NOT_MASTER'"; + } + + // Save the migration type in state. + $state = \Drupal::service('state'); + $state->set('migrate_drupal.master', $useMasterNode); + return $useMasterNode; } - return ($status === '1') ? TRUE : FALSE; + } diff --git a/core/modules/migrate_drupal/src/MigrationConfigurationTrait.php b/core/modules/migrate_drupal/src/MigrationConfigurationTrait.php index b487c18c8d..01c46cc988 100644 --- a/core/modules/migrate_drupal/src/MigrationConfigurationTrait.php +++ b/core/modules/migrate_drupal/src/MigrationConfigurationTrait.php @@ -6,6 +6,7 @@ use Drupal\Core\Database\Database; use Drupal\Core\Database\DatabaseExceptionWrapper; use Drupal\migrate\Exception\RequirementsException; +use Drupal\migrate\MigrateException; use Drupal\migrate\Plugin\RequirementsInterface; /** @@ -129,12 +130,16 @@ protected function getMigrations($database_state_key, $drupal_version) { // entity translation migrations. Conversely, if the source database is not // 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. - if ($this->isMultilingualSource($database_state_key, $drupal_version)) { + $type = $this->useMasterNodeMigration($all_migrations, $drupal_version); + if ($type === 'MASTER') { $patterns = '/(d' . $drupal_version . '_node:)|(d' . $drupal_version . '_node_translation:)|(d' . $drupal_version . '_node_revision:)|(entity_translation)/'; } - else { + if ($type === 'NOT_MASTER') { $patterns = '/(d' . $drupal_version . '_node_master:)/'; } + if ($type === 'BOTH') { + $patterns = '//'; + } foreach ($all_migrations as $key => $migrations) { if (preg_match($patterns, $key)) { @@ -293,23 +298,43 @@ protected function getState() { } /** - * Determines if the i18n module is installed in the source database. + * Determines is the node master migration is to be used. + * + * The node master migration is the default. It is not used when there + * are existing tables for dNnode. * - * @return bool - * The version if this is a source database with i18n, FALSE otherwise. + * @return string + * Indicator of the node migration map tables in use. */ - protected function isMultilingualSource($database_state_key, $version) { - $status = 0; - $database_state = \Drupal::state()->get($database_state_key); - // Connect to source database. - $connection = $this->getConnection($database_state['database']); - if ($connection) { - $status = $connection->query("SELECT status FROM {system} WHERE name = :name and type = :type", [ - ':name' => 'i18n', - ':type' => 'module', - ])->fetchField(); + protected function useMasterNodeMigration($migrations, $version) { + $useMasterNode = 'MASTER'; + $node_exists = FALSE; + $node_master_exists = FALSE; + + $ids = ['node_master', 'node']; + foreach ($ids as $id) { + $exists = $id . '_exists'; + $$exists = FALSE; + $patterns = '/d' . $version . '_' . $id . ':/'; + $matches = preg_grep($patterns, array_keys($migrations)); + foreach ($matches as $match) { + if ($migrations[$match]->getIdMap()->processedCount()) { + $$exists = TRUE; + break; + } + } + } + if ($node_exists && $node_master_exists) { + $useMasterNode = 'BOTH'; + } + if ($node_exists && !$node_master_exists) { + $useMasterNode = "NOT_MASTER'"; } - return ($status === '1') ? TRUE : FALSE; + + // Save the migration type in state. + $state = $this->getState(); + $state->set('migrate_drupal.master', $useMasterNode); + return $useMasterNode; } }