diff --git a/core/modules/action/action.info.yml b/core/modules/action/action.info.yml
index 7559efbcb2..bc9caaf385 100644
--- a/core/modules/action/action.info.yml
+++ b/core/modules/action/action.info.yml
@@ -5,3 +5,10 @@ package: Core
version: VERSION
core: 8.x
configure: entity.action.collection
+migrations_finished:
+ 6:
+ system: action
+ action: action
+ 7:
+ system: action
+ action: action
diff --git a/core/modules/aggregator/aggregator.info.yml b/core/modules/aggregator/aggregator.info.yml
index d6ffbaa85b..61e217fb8d 100644
--- a/core/modules/aggregator/aggregator.info.yml
+++ b/core/modules/aggregator/aggregator.info.yml
@@ -8,3 +8,8 @@ configure: aggregator.admin_settings
dependencies:
- drupal:file
- drupal:options
+migrations_finished:
+ 6:
+ aggregator: aggregator
+ 7:
+ aggregator: aggregator
diff --git a/core/modules/ban/ban.info.yml b/core/modules/ban/ban.info.yml
index ba6300de1c..86b42a898e 100644
--- a/core/modules/ban/ban.info.yml
+++ b/core/modules/ban/ban.info.yml
@@ -5,3 +5,6 @@ package: Core
version: VERSION
core: 8.x
configure: ban.admin_page
+migrations_finished:
+ 7:
+ system: ban
diff --git a/core/modules/block/block.info.yml b/core/modules/block/block.info.yml
index 47501efb17..a26f3afd49 100644
--- a/core/modules/block/block.info.yml
+++ b/core/modules/block/block.info.yml
@@ -5,3 +5,8 @@ package: Core
version: VERSION
core: 8.x
configure: block.admin_display
+migrations_finished:
+ 6:
+ block: block
+ 7:
+ block: block
diff --git a/core/modules/block_content/block_content.info.yml b/core/modules/block_content/block_content.info.yml
index 3315a2738e..78a5e26ebb 100644
--- a/core/modules/block_content/block_content.info.yml
+++ b/core/modules/block_content/block_content.info.yml
@@ -9,3 +9,8 @@ dependencies:
- drupal:text
- drupal:user
configure: entity.block_content.collection
+migrations_finished:
+ 6:
+ block: block_content
+ 7:
+ block: block_content
diff --git a/core/modules/book/book.info.yml b/core/modules/book/book.info.yml
index d883cc6ead..d2d52fbf58 100644
--- a/core/modules/book/book.info.yml
+++ b/core/modules/book/book.info.yml
@@ -7,3 +7,8 @@ core: 8.x
dependencies:
- drupal:node
configure: book.settings
+migrations_finished:
+ 6:
+ book: book
+ 7:
+ book: book
diff --git a/core/modules/color/color.info.yml b/core/modules/color/color.info.yml
index 9ea6daf6b5..6d35f59c27 100644
--- a/core/modules/color/color.info.yml
+++ b/core/modules/color/color.info.yml
@@ -4,3 +4,6 @@ description: 'Allows administrators to change the color scheme of compatible the
package: Core
version: VERSION
core: 8.x
+migrations_finished:
+ 7:
+ color: color
diff --git a/core/modules/comment/comment.info.yml b/core/modules/comment/comment.info.yml
index b552cf17bf..5eaac4a36a 100644
--- a/core/modules/comment/comment.info.yml
+++ b/core/modules/comment/comment.info.yml
@@ -7,3 +7,10 @@ core: 8.x
dependencies:
- drupal:text
configure: comment.admin
+migrations_finished:
+ 6:
+ comment: comment
+ node: comment
+ 7:
+ comment: comment
+ node: comment
diff --git a/core/modules/config_translation/config_translation.info.yml b/core/modules/config_translation/config_translation.info.yml
index 904f57783e..c461c34cc4 100644
--- a/core/modules/config_translation/config_translation.info.yml
+++ b/core/modules/config_translation/config_translation.info.yml
@@ -7,3 +7,25 @@ core: 8.x
configure: config_translation.mapper_list
dependencies:
- drupal:locale
+migrations_finished:
+ 6:
+ i18nprofile: config_translation
+ 7:
+ i18n_variable: config_translation
+migrations_not_finished:
+ 6:
+ # language content comment settings.
+ locale: language
+ i18n: config_translation
+ # field labels and descriptions, synchronized fields.
+ i18ncck: config_translation
+ #
+ i18ntaxonomy: config_translation
+ 7:
+ # language content comment settings.
+ locale: language
+ i18n: config_translation
+ # field labels and descriptions, field options.
+ i18n_field: config_translation
+ # localized. vocabulary language settings, taxonomy term language.
+ i18n_taxonomy: config_translation
diff --git a/core/modules/contact/contact.info.yml b/core/modules/contact/contact.info.yml
index 2507fbd167..92029a8ab2 100644
--- a/core/modules/contact/contact.info.yml
+++ b/core/modules/contact/contact.info.yml
@@ -5,3 +5,8 @@ package: Core
version: VERSION
core: 8.x
configure: entity.contact_form.collection
+migrations_finished:
+ 6:
+ contact: contact
+ 7:
+ contact: contact
diff --git a/core/modules/content_translation/content_translation.info.yml b/core/modules/content_translation/content_translation.info.yml
index 68d1ec0cb3..f5a551d3d4 100644
--- a/core/modules/content_translation/content_translation.info.yml
+++ b/core/modules/content_translation/content_translation.info.yml
@@ -7,3 +7,26 @@ package: Multilingual
version: VERSION
core: 8.x
configure: language.content_settings_page
+migrations_finished:
+ 6:
+ i18nblocks: content_translation
+ i18nmenu: content_translation
+ menu: content_translation
+ statistics: statistics
+ taxonomy: content_translation
+ 7:
+ block: content_translation
+ entity_translation: content_translation
+ i18n_block: content_translation
+ menu: content_translation
+ statistics: statistics
+migrations_not_finished:
+ # Also D6 an D7 node revision translations.
+ 6:
+ # Taxonomy term references.
+ i18ntaxonomy: content_translation
+ 7:
+ # menu links.
+ i18n_menu: content_translation
+ # localized.
+ i18n_taxonomy: content_translation
diff --git a/core/modules/datetime/datetime.info.yml b/core/modules/datetime/datetime.info.yml
index 884cafcd78..91b0040891 100644
--- a/core/modules/datetime/datetime.info.yml
+++ b/core/modules/datetime/datetime.info.yml
@@ -6,3 +6,8 @@ version: VERSION
core: 8.x
dependencies:
- drupal:field
+migrations_finished:
+ 6:
+ date: datetime
+ 7:
+ date: datetime
diff --git a/core/modules/dblog/dblog.info.yml b/core/modules/dblog/dblog.info.yml
index b214fb76c7..21fc7aaf73 100644
--- a/core/modules/dblog/dblog.info.yml
+++ b/core/modules/dblog/dblog.info.yml
@@ -5,3 +5,8 @@ package: Core
version: VERSION
core: 8.x
configure: system.logging_settings
+migrations_finished:
+ 6:
+ dblog: dblog
+ 7:
+ dblog: dblog
diff --git a/core/modules/field/field.info.yml b/core/modules/field/field.info.yml
index 13b5da0054..71175aa8bc 100644
--- a/core/modules/field/field.info.yml
+++ b/core/modules/field/field.info.yml
@@ -4,3 +4,13 @@ description: 'Field API to add fields to entities like nodes and users.'
package: Core
version: VERSION
core: 8.x
+migrations_finished:
+ 6:
+ content: field
+ email: core
+ 7:
+ email: core
+ entityreference: core
+ field: field
+ field_sql_storage: field
+ number: core
diff --git a/core/modules/file/file.info.yml b/core/modules/file/file.info.yml
index f9f78a703d..9d12c08c83 100644
--- a/core/modules/file/file.info.yml
+++ b/core/modules/file/file.info.yml
@@ -6,3 +6,11 @@ version: VERSION
core: 8.x
dependencies:
- drupal:field
+migrations_finished:
+ 6:
+ filefield: file
+ system: file
+ upload: file
+ 7:
+ file: file
+ system: file
diff --git a/core/modules/filter/filter.info.yml b/core/modules/filter/filter.info.yml
index 0f3c94ce66..9475728992 100644
--- a/core/modules/filter/filter.info.yml
+++ b/core/modules/filter/filter.info.yml
@@ -7,3 +7,8 @@ core: 8.x
configure: filter.admin_overview
dependencies:
- drupal:user
+migrations_finished:
+ 6:
+ filter: filter
+ 7:
+ filter: filter
diff --git a/core/modules/forum/forum.info.yml b/core/modules/forum/forum.info.yml
index d275dfccb1..1cb31d1a93 100644
--- a/core/modules/forum/forum.info.yml
+++ b/core/modules/forum/forum.info.yml
@@ -11,3 +11,8 @@ package: Core
version: VERSION
core: 8.x
configure: forum.overview
+migrations_finished:
+ 6:
+ forum: forum
+ 7:
+ forum: forum
diff --git a/core/modules/image/image.info.yml b/core/modules/image/image.info.yml
index c17c7e09a1..4dd58b74bc 100644
--- a/core/modules/image/image.info.yml
+++ b/core/modules/image/image.info.yml
@@ -7,3 +7,9 @@ core: 8.x
dependencies:
- drupal:file
configure: entity.image_style.collection
+migrations_finished:
+ 6:
+ imagecache: image
+ imagefield: image
+ 7:
+ image: image
diff --git a/core/modules/language/language.info.yml b/core/modules/language/language.info.yml
index 30770401ad..9e9fb06396 100644
--- a/core/modules/language/language.info.yml
+++ b/core/modules/language/language.info.yml
@@ -5,3 +5,10 @@ package: Multilingual
version: VERSION
core: 8.x
configure: entity.configurable_language.collection
+migrations_finished:
+ 6:
+ locale: language, system
+ system: language
+ taxonomy: language
+ 7:
+ locale: language, system
diff --git a/core/modules/language/migrations/d6_language_negotiation_settings.yml b/core/modules/language/migrations/d6_language_negotiation_settings.yml
index a4ae19b87d..e6bf27424b 100644
--- a/core/modules/language/migrations/d6_language_negotiation_settings.yml
+++ b/core/modules/language/migrations/d6_language_negotiation_settings.yml
@@ -7,7 +7,7 @@ source:
plugin: variable
variables:
- language_negotiation
- source_module: language
+ source_module: locale
process:
session/parameter:
plugin: default_value
diff --git a/core/modules/language/migrations/d6_language_types.yml b/core/modules/language/migrations/d6_language_types.yml
index 5c54fc6fb9..47d62caf6b 100644
--- a/core/modules/language/migrations/d6_language_types.yml
+++ b/core/modules/language/migrations/d6_language_types.yml
@@ -7,7 +7,7 @@ source:
plugin: variable
variables:
- language_negotiation
- source_module: language
+ source_module: locale
process:
all:
plugin: default_value
diff --git a/core/modules/language/migrations/d7_language_types.yml b/core/modules/language/migrations/d7_language_types.yml
index 017f2e2d6f..33df3cf0dc 100644
--- a/core/modules/language/migrations/d7_language_types.yml
+++ b/core/modules/language/migrations/d7_language_types.yml
@@ -13,7 +13,7 @@ source:
- locale_language_providers_weight_language
- locale_language_providers_weight_language_content
- locale_language_providers_weight_language_url
- source_module: language
+ source_module: locale
process:
all:
plugin: language_types
diff --git a/core/modules/link/link.info.yml b/core/modules/link/link.info.yml
index c3f8f9c94a..78009c6033 100644
--- a/core/modules/link/link.info.yml
+++ b/core/modules/link/link.info.yml
@@ -6,3 +6,8 @@ package: Field types
version: VERSION
dependencies:
- drupal:field
+migrations_finished:
+ 6:
+ link: link
+ 7:
+ link: link
diff --git a/core/modules/locale/locale.info.yml b/core/modules/locale/locale.info.yml
index 1db8704e71..d84afd8b9b 100644
--- a/core/modules/locale/locale.info.yml
+++ b/core/modules/locale/locale.info.yml
@@ -8,3 +8,8 @@ core: 8.x
dependencies:
- drupal:language
- drupal:file
+migrations_finished:
+ 6:
+ locale: locale
+ 7:
+ locale: locale
diff --git a/core/modules/menu_link_content/menu_link_content.info.yml b/core/modules/menu_link_content/menu_link_content.info.yml
index c001f5eb53..b835c88b95 100644
--- a/core/modules/menu_link_content/menu_link_content.info.yml
+++ b/core/modules/menu_link_content/menu_link_content.info.yml
@@ -6,3 +6,9 @@ version: VERSION
core: 8.x
dependencies:
- drupal:link
+migrations_finished:
+ 6:
+ menu: menu_link_content
+ 7:
+ menu: menu_link_content
+
diff --git a/core/modules/menu_ui/menu_ui.info.yml b/core/modules/menu_ui/menu_ui.info.yml
index 0623320585..9489e46a48 100644
--- a/core/modules/menu_ui/menu_ui.info.yml
+++ b/core/modules/menu_ui/menu_ui.info.yml
@@ -7,3 +7,8 @@ core: 8.x
configure: entity.menu.collection
dependencies:
- drupal:menu_link_content
+migrations_finished:
+ 6:
+ menu: menu_ui
+ 7:
+ menu: menu_ui
diff --git a/core/modules/migrate/tests/src/Kernel/MigrateStatusTest.php b/core/modules/migrate/tests/src/Kernel/MigrateStatusTest.php
index 7dc0b5b9b6..df9e770305 100644
--- a/core/modules/migrate/tests/src/Kernel/MigrateStatusTest.php
+++ b/core/modules/migrate/tests/src/Kernel/MigrateStatusTest.php
@@ -17,7 +17,7 @@ class MigrateStatusTest extends MigrateTestBase {
public function testStatus() {
// Create a minimally valid migration.
$definition = [
- 'id' => 'migration_status_test',
+ 'id' => 'migrate_status_test',
'migration_tags' => ['Testing'],
'source' => ['plugin' => 'empty'],
'destination' => [
diff --git a/core/modules/migrate_drupal/migrate_drupal.info.yml b/core/modules/migrate_drupal/migrate_drupal.info.yml
index 638bc382fd..8a195b98bc 100644
--- a/core/modules/migrate_drupal/migrate_drupal.info.yml
+++ b/core/modules/migrate_drupal/migrate_drupal.info.yml
@@ -6,3 +6,7 @@ version: VERSION
core: 8.x
dependencies:
- drupal:migrate
+migrations_finished:
+ 6:
+ nodereference: core
+ userreference: core
diff --git a/core/modules/migrate_drupal_multilingual/migrate_drupal_multilingual.info.yml b/core/modules/migrate_drupal_multilingual/migrate_drupal_multilingual.info.yml
index 75a79dc285..ea27adb14d 100644
--- a/core/modules/migrate_drupal_multilingual/migrate_drupal_multilingual.info.yml
+++ b/core/modules/migrate_drupal_multilingual/migrate_drupal_multilingual.info.yml
@@ -5,3 +5,9 @@ package: 'Core (Experimental)'
core: 8.x
dependencies:
- migrate_drupal
+# Multilingual is not finished until this module is removed.
+migrations_not_finished:
+ 6:
+ i18n: i18n
+ 7:
+ i18n: i18n
diff --git a/core/modules/migrate_drupal_ui/src/Form/ReviewForm.php b/core/modules/migrate_drupal_ui/src/Form/ReviewForm.php
index f78109e41f..7ffa14e63c 100644
--- a/core/modules/migrate_drupal_ui/src/Form/ReviewForm.php
+++ b/core/modules/migrate_drupal_ui/src/Form/ReviewForm.php
@@ -13,16 +13,69 @@
/**
* Migrate Upgrade review form.
*
- * This confirmation form uses the source_module and destination_module
- * properties on the source, destination and field plugins as well as the
- * system data from the source to determine if there is a migration path for
- * each module in the source.
+ * This confirmation form provides the user with a summary of all the modules
+ * enabled on the source site and whether they will be upgraded or not. Data
+ * from all the migration plugins (source, destination and field) and the
+ * .info.yml file for each enabled Drupal 8 module to decide the migration
+ * status for each enabled source module.
+ *
+ * Modules inform the upgrade process of their migrations by adding data to
+ * their .info.yml file. This data is only added when a source module should
+ * provide migrations, whether they are written or not. If a module will not be
+ * providing migrations no changes need to be made to the .info.yml file.
+ *
+ * Information stored in .info.yml files for migrate.
+ * - migrations_finished: A list of information about migrations supplied by
+ * this module that are complete.
+ * - version: A Drupal legacy version number.
+ * - source_module/destination_module: A list of key value pairs identifying
+ * the source_module and destination_module for all the migrations in this
+ * module.
+ * - migrations_not_finished: A list of information about migrations that this
+ * module should provide but are not yet written.
+ * - version: A Drupal legacy version number.
+ * - source_module/destination_module: A list of key value pairs identifying
+ * the source_module and destination_module for the migrations still to be
+ * written.
+ * @code
+ * migrations_finished:
+ * 6:
+ * node: node
+ * 7:
+ * node: node
+ * entity_translation: node
+ * migrations_not_finished:
+ * 7:
+ * commerce_product: commerce_product
+ * @endcode
+ *
+ * In this example the module has completed migrations for data from the Drupal
+ * 6 and Drupal 7 Node Modules to the Drupal 8 Node Modules and for data from
+ * the Drupal 7 Entity Translation Module to the Drupal 8 Node Module.
+ *
+ * This module also plans on providing a migration for some data from the
+ * Drupal 7 Commerce Product Module to the Drupal 8 Commerce Product Module
+ * but no migrations are provided.
*
* @internal
*/
class ReviewForm extends MigrateUpgradeFormBase {
/**
+ * Source modules status for will be upgraded.
+ *
+ * @var string
+ */
+ const CHECKED = 'checked';
+
+ /**
+ * Source modules status for will not be upgraded.
+ *
+ * @var string
+ */
+ const ERROR = 'error';
+
+ /**
* The state service.
*
* @var \Drupal\Core\State\StateInterface
@@ -51,11 +104,28 @@ class ReviewForm extends MigrateUpgradeFormBase {
protected $migrations;
/**
+ * Display data.
+ *
+ * @var array
+ */
+ protected $display;
+
+ /**
+ * The destination site migrate information from info.yml.
+ *
+ * @var array
+ */
+ protected $destinationSystemMigrateInfo;
+
+ /**
* List of extensions that do not need an upgrade path.
*
* This property is an array where the keys are the major Drupal core version
* from which we are upgrading, and the values are arrays of extension names
- * that do not need an upgrade path.
+ * that do not need an upgrade path and are not names in the 'source_module'
+ * annotation for a migration. In other words, the functionality of these
+ * extensions has moved into core, or been dropped from core, and there isn't
+ * a Drupal 8 module of the same name.
*
* @var array[]
*/
@@ -191,7 +261,7 @@ public function buildForm(array $form, FormStateInterface $form_state) {
// Get all the data needed for this form.
$version = $this->store->get('version');
$this->migrations = $this->store->get('migrations');
- // Fetch the system data at the first opportunity.
+ // Fetch the source system data at the first opportunity.
$system_data = $this->store->get('system_data');
// If data is missing or this is the wrong step, start over.
@@ -203,7 +273,9 @@ public function buildForm(array $form, FormStateInterface $form_state) {
$form = parent::buildForm($form, $form_state);
$form['#title'] = $this->t('What will be upgraded?');
- // Get the source_module and destination_module for each migration.
+ // Build an array of migrations, table_data, keyed by source_module and
+ // destination_module. Only migrations that have both a source_module and
+ // a destination_module definition are added to the array.
$migrations = $this->pluginManager->createInstances(array_keys($this->store->get('migrations')));
$table_data = [];
foreach ($migrations as $migration) {
@@ -218,11 +290,11 @@ public function buildForm(array $form, FormStateInterface $form_state) {
}
if ($source_module && $destination_module) {
- $table_data[$source_module][$destination_module][$migration_id] = $migration->label();
+ $table_data[$source_module][] = $destination_module;
}
}
- // Get the source_module and destination_module from the field plugins.
+ // Add entries for the field plugins to table_data.
$definitions = $this->fieldPluginManager->getDefinitions();
foreach ($definitions as $definition) {
// This is not strict so that we find field plugins with an annotation
@@ -230,23 +302,35 @@ public function buildForm(array $form, FormStateInterface $form_state) {
if (in_array($version, $definition['core'])) {
$source_module = $definition['source_module'];
$destination_module = $definition['destination_module'];
- $table_data[$source_module][$destination_module][$definition['id']] = $definition['id'];
+ $table_data[$source_module][] = $destination_module;
}
}
- // Add source_module and destination_module for modules that do not need an
- // upgrade path and are enabled on the source site.
- foreach ($this->noUpgradePaths[$version] as $extension) {
- if (isset($system_data['module'][$extension]) && $system_data['module'][$extension]['status']) {
- $table_data[$extension]['core'][$extension] = $extension;
- }
+ // Remove duplicate destination_modules.
+ foreach ($table_data as $key => $destination_modules) {
+ $table_data[$key] = array_unique($destination_modules);
}
- // Sort the table by source module names and within that destination
- // module names.
- ksort($table_data);
- foreach ($table_data as $source_module => $destination_module_info) {
- ksort($table_data[$source_module]);
+ // Get the migrate information from .info.yml and build an array of source
+ // modules and there migration status. The destination is not used yet but
+ // can be later for validating the source/destination pairs with the
+ // actual source/destination pairs in the migrate plugins.
+ $system_info = system_get_info('module');
+
+ $this->destinationSystemMigrateInfo = [];
+ $properties = ['migrations_finished', 'migrations_not_finished'];
+ foreach ($system_info as $module => $info) {
+ foreach ($properties as $property) {
+ if (isset($info[$property])) {
+ foreach ($info[$property] as $info_version => $migrate_info) {
+ if ($info_version == $version) {
+ foreach ($migrate_info as $source => $destination) {
+ $this->destinationSystemMigrateInfo[$source][] = $property;
+ }
+ }
+ }
+ }
+ }
}
// Remove core profiles from the system data.
@@ -254,7 +338,8 @@ public function buildForm(array $form, FormStateInterface $form_state) {
unset($system_data['module'][$profile]);
}
- $unmigrated_source_modules = array_diff_key($system_data['module'], $table_data);
+ // Prepare an array with the data to display.
+ $display = $this->buildDisplay($version, $system_data, $table_data);
// Missing migrations.
$missing_module_list = [
@@ -262,7 +347,7 @@ public function buildForm(array $form, FormStateInterface $form_state) {
'#open' => TRUE,
'#title' => $this->t('Modules that will not be upgraded'),
'#summary_attributes' => ['id' => ['error']],
- '#description' => $this->t('There are no modules installed on your new site to replace these modules. If you proceed with the upgrade now, configuration and/or content needed by these modules will not be available on your new site. For more information, see Review the pre-upgrade analysis in the Upgrading to Drupal 8 handbook.', [':review' => 'https://www.drupal.org/docs/8/upgrade/upgrade-using-web-browser#pre-upgrade-analysis', ':migrate' => 'https://www.drupal.org/docs/8/upgrade']),
+ '#description' => $this->t('The new site is missing modules corresponding to the old site\'s modules. Unless they are installed prior to the upgrade, configuration and/or content needed by them will not be available on your new site. Read the checklist to help decide what to do.', [':review' => 'https://www.drupal.org/docs/8/upgrade/upgrade-using-web-browser#pre-upgrade-analysis']),
'#weight' => 2,
];
$missing_module_list['module_list'] = [
@@ -272,12 +357,14 @@ public function buildForm(array $form, FormStateInterface $form_state) {
$this->t('Drupal 8'),
],
];
+
$missing_count = 0;
- ksort($unmigrated_source_modules);
- foreach ($unmigrated_source_modules as $source_module => $module_data) {
- if ($module_data['status']) {
+ if (isset($display[static::ERROR])) {
+ foreach ($display[static::ERROR] as $source_module => $data) {
$missing_count++;
- $missing_module_list['module_list'][$source_module] = [
+ // Get the migration status for this $source_module, if a module of the
+ // same name exists on the destination site.
+ $missing_module_list['module_list'][] = [
'source_module' => [
'#type' => 'html_tag',
'#tag' => 'span',
@@ -289,7 +376,9 @@ public function buildForm(array $form, FormStateInterface $form_state) {
],
],
],
- 'destination_module' => ['#plain_text' => 'Not upgraded'],
+ 'destination_module' => [
+ '#plain_text' => $data['destination_modules'],
+ ],
];
}
}
@@ -299,7 +388,7 @@ public function buildForm(array $form, FormStateInterface $form_state) {
'#type' => 'details',
'#title' => $this->t('Modules that will be upgraded'),
'#summary_attributes' => ['id' => ['checked']],
- '#weight' => 3,
+ '#weight' => 4,
];
$available_module_list['module_list'] = [
@@ -311,29 +400,26 @@ public function buildForm(array $form, FormStateInterface $form_state) {
];
$available_count = 0;
- foreach ($table_data as $source_module => $destination_module_info) {
- $available_count++;
- $destination_details = [];
- foreach ($destination_module_info as $destination_module => $migration_ids) {
- $destination_details[$destination_module] = [
- '#type' => 'item',
- '#plain_text' => $destination_module,
- ];
- }
- $available_module_list['module_list'][$source_module] = [
- 'source_module' => [
- '#type' => 'html_tag',
- '#tag' => 'span',
- '#value' => $source_module,
- '#attributes' => [
- 'class' => [
- 'upgrade-analysis-report__status-icon',
- 'upgrade-analysis-report__status-icon--checked',
+ if (isset($display[static::CHECKED])) {
+ foreach ($display[static::CHECKED] as $source_module => $data) {
+ $available_count++;
+ $available_module_list['module_list'][] = [
+ 'source_module' => [
+ '#type' => 'html_tag',
+ '#tag' => 'span',
+ '#value' => $source_module,
+ '#attributes' => [
+ 'class' => [
+ 'upgrade-analysis-report__status-icon',
+ 'upgrade-analysis-report__status-icon--checked',
+ ],
],
],
- ],
- 'destination_module' => $destination_details,
- ];
+ 'destination_module' => [
+ '#plain_text' => $data['destination_modules'],
+ ],
+ ];
+ }
}
$counters = [];
@@ -353,9 +439,8 @@ public function buildForm(array $form, FormStateInterface $form_state) {
$counters[] = [
'#theme' => 'status_report_counter',
'#amount' => $available_count,
- '#text' => $this->formatPlural($available_count, 'Module will be upgraded', 'Modules will be upgraded'),
- '#severity' => 'checked',
- '#weight' => 1,
+ '#text' => $this->formatPlural($missing_count, 'Module will be upgraded', 'Modules will be upgraded'),
+ '#weight' => 2,
];
$general_info[] = $available_module_list;
}
@@ -402,4 +487,101 @@ public function getConfirmText() {
return $this->t('Perform upgrade');
}
+ /**
+ * Determines migration status for each source module enabled on the source.
+ *
+ * If there are no migrations for this module and the module is listed in the
+ * NoUpgradePath list then the status is set to CHECKED. If it is not listed
+ * in NoUpgradePath list the status is to ERROR.
+ *
+ * When there are migrations for this module the following happens.
+ * If the destination module is 'core' the status is set to CHECKED.
+ * If there are any occurrences of 'migrations_not_finished' in the .info.yml
+ * information for this source module/destination module pair then the status
+ * is set to ERROR otherwise the status is set to CHECKED.
+ *
+ * @param string $version
+ * The legacy drupal version.
+ * @param array $source_system_data
+ * The data from the source site system table.
+ * @param array $table_data
+ * The source modules that have at least one migration.
+ *
+ * @return array
+ * An associative array of data keyed by the display categories, 'error'
+ * and 'checked'.
+ */
+ public function buildDisplay($version, array $source_system_data, array $table_data) {
+ // Loop through every source module that is enabled on the source site.
+ foreach ($source_system_data['module'] as $module) {
+ $source_module = $module['name'];
+ if ($module['status']) {
+ // Set the defaults to display.
+ $destination_modules = [];
+ $migration_status = static::ERROR;
+
+ // If there are migrations using this source_module, determine the
+ // migration status.
+ if (isset($table_data[$source_module])) {
+ $destination_modules = $table_data[$source_module];
+ foreach ($table_data[$source_module] as $destination_module) {
+ // Some field plugins use a destination_module of 'core'.
+ if ($destination_module === 'core') {
+ $migration_status = static::CHECKED;
+ }
+ else {
+ // Check the destination site system info for the status
+ // of the migrations for this source_module.
+ if (isset($this->destinationSystemMigrateInfo[$source_module])) {
+ // If migrations and no declaration then it is not finished.
+ if (empty($this->destinationSystemMigrateInfo[$source_module])) {
+ $migration_status = static::ERROR;
+ }
+ // If 'migrations_not_finished' declared then it is not
+ // finished.
+ elseif (in_array('migrations_not_finished', $this->destinationSystemMigrateInfo[$source_module])) {
+ $migration_status = static::ERROR;
+ }
+ // The it must be finished.
+ else {
+ $migration_status = static::CHECKED;
+ }
+ }
+ }
+ }
+ }
+ else {
+ // This may be a no upgrade path.
+ if (in_array($source_module, $this->noUpgradePaths[$version])) {
+ $migration_status = static::CHECKED;
+ $destination_modules = ['core'];
+ }
+ }
+ $destination_modules = array_unique($destination_modules);
+ sort($destination_modules);
+ $this->addToDisplay($source_module, $migration_status, $destination_modules);
+ }
+ }
+ foreach ($this->display as $key => $value) {
+ ksort($this->display[$key]);
+ }
+ return $this->display;
+ }
+
+ /**
+ * Helper to setup display array.
+ *
+ * @param string $source_module
+ * The source module name.
+ * @param string $migration_status
+ * The computed migration status of the source module.
+ * @param array $destination_modules
+ * The destination modules names.
+ */
+ public function addToDisplay($source_module, $migration_status, array $destination_modules) {
+ $category = $migration_status;
+ $this->display[$category][$source_module]['display_status'] = $migration_status;
+ $this->display[$category][$source_module]['destination_modules'] = implode(', ', $destination_modules);
+ }
+
}
diff --git a/core/modules/migrate_drupal_ui/tests/modules/migrate_status_active_test/migrate_status_active_test.info.yml b/core/modules/migrate_drupal_ui/tests/modules/migrate_status_active_test/migrate_status_active_test.info.yml
new file mode 100644
index 0000000000..c71b30f2c0
--- /dev/null
+++ b/core/modules/migrate_drupal_ui/tests/modules/migrate_status_active_test/migrate_status_active_test.info.yml
@@ -0,0 +1,6 @@
+name: 'Migrate status active test'
+type: module
+description: "Tests the 'active' migrate status"
+package: Testing
+version: VERSION
+core: 8.x
diff --git a/core/modules/migrate_drupal_ui/tests/modules/migrate_status_incomplete_test/migrate_status_incomplete_test.info.yml b/core/modules/migrate_drupal_ui/tests/modules/migrate_status_incomplete_test/migrate_status_incomplete_test.info.yml
new file mode 100644
index 0000000000..665ea3d1a3
--- /dev/null
+++ b/core/modules/migrate_drupal_ui/tests/modules/migrate_status_incomplete_test/migrate_status_incomplete_test.info.yml
@@ -0,0 +1,9 @@
+name: 'Migrate status incomplete test'
+type: module
+description: "Tests the 'incomplete' migrate status"
+package: Testing
+version: VERSION
+core: 8.x
+migrations_not_finished:
+ 6:
+ block: block
diff --git a/core/modules/migrate_drupal_ui/tests/modules/migrate_status_incomplete_test/migrations/migrate_status_incomplete_test.yml b/core/modules/migrate_drupal_ui/tests/modules/migrate_status_incomplete_test/migrations/migrate_status_incomplete_test.yml
new file mode 100644
index 0000000000..b1c5f7f0c4
--- /dev/null
+++ b/core/modules/migrate_drupal_ui/tests/modules/migrate_status_incomplete_test/migrations/migrate_status_incomplete_test.yml
@@ -0,0 +1,20 @@
+id: migrate_status_incomplete_test
+label: Migrate status incomplete test
+migration_tags:
+ - Drupal 6
+ - Drupal 7
+ - Configuration
+source:
+ plugin: embedded_data
+ data_rows:
+ -
+ entity_type: block_content
+ ids:
+ entity_type:
+ type: string
+ source_module: block
+process:
+ entity_type: entity_type
+destination:
+ plugin: entity:field_config
+ destination_module: migrate_status_incomplete_test
diff --git a/core/modules/migrate_drupal_ui/tests/src/Functional/MigrateUpgradeExecuteTestBase.php b/core/modules/migrate_drupal_ui/tests/src/Functional/MigrateUpgradeExecuteTestBase.php
index f165bb7c8e..ed901febec 100644
--- a/core/modules/migrate_drupal_ui/tests/src/Functional/MigrateUpgradeExecuteTestBase.php
+++ b/core/modules/migrate_drupal_ui/tests/src/Functional/MigrateUpgradeExecuteTestBase.php
@@ -117,7 +117,7 @@ public function testMigrateUpgradeExecute() {
// Ensure there are no errors about any other missing migration providers.
$session->pageTextNotContains(t('module not found'));
- // Test the upgrade paths.
+ // Test the review page.
$available_paths = $this->getAvailablePaths();
$missing_paths = $this->getMissingPaths();
$this->assertReviewPage($session, $available_paths, $missing_paths);
@@ -146,12 +146,7 @@ public function testMigrateUpgradeExecute() {
$this->drupalPostForm(NULL, [], t('I acknowledge I may lose data. Continue anyway.'));
$session->statusCodeEquals(200);
- // Need to update available and missing path lists.
- $all_available = $this->getAvailablePaths();
- $all_available[] = 'aggregator';
- $all_missing = $this->getMissingPaths();
- $all_missing = array_diff($all_missing, ['aggregator']);
- $this->assertReviewPage($session, $all_available, $all_missing);
+ // Run the incremental migration and check the results.
$this->drupalPostForm(NULL, [], t('Perform upgrade'));
$session->pageTextContains(t('Congratulations, you upgraded Drupal!'));
$this->assertMigrationResults($this->getEntityCountsIncremental(), $version);
diff --git a/core/modules/migrate_drupal_ui/tests/src/Functional/MigrateUpgradeReviewPageTestBase.php b/core/modules/migrate_drupal_ui/tests/src/Functional/MigrateUpgradeReviewPageTestBase.php
index 5c97a69070..a587d4406f 100644
--- a/core/modules/migrate_drupal_ui/tests/src/Functional/MigrateUpgradeReviewPageTestBase.php
+++ b/core/modules/migrate_drupal_ui/tests/src/Functional/MigrateUpgradeReviewPageTestBase.php
@@ -82,7 +82,8 @@ public function testMigrateUpgradeReviewPage() {
$this->drupalPostForm(NULL, $this->edits, t('Review upgrade'));
$this->drupalPostForm(NULL, [], t('I acknowledge I may lose data. Continue anyway.'));
- // Test the upgrade paths.
+ // Test the upgrade paths. First remove the module from the available paths
+ // list.
$available_paths = $this->getAvailablePaths();
$available_paths = array_diff($available_paths, [$module]);
$missing_paths = $this->getMissingPaths();
@@ -136,6 +137,16 @@ public function prepare() {
$conditions->condition('name', 'simpletest');
$update->condition($conditions);
$update->execute();
+
+ // Create entries for D8 test modules.
+ $insert = $this->sourceDatabase->insert('system')
+ ->fields([
+ 'filename' => 'migrate_status_active_test',
+ 'name' => 'migrate_status_active_test',
+ 'type' => 'module',
+ 'status' => 1,
+ ]);
+ $insert->execute();
}
/**
diff --git a/core/modules/migrate_drupal_ui/tests/src/Functional/MigrateUpgradeTestBase.php b/core/modules/migrate_drupal_ui/tests/src/Functional/MigrateUpgradeTestBase.php
index bc73aba4c4..14274bc572 100644
--- a/core/modules/migrate_drupal_ui/tests/src/Functional/MigrateUpgradeTestBase.php
+++ b/core/modules/migrate_drupal_ui/tests/src/Functional/MigrateUpgradeTestBase.php
@@ -169,13 +169,13 @@ protected function assertUpgradePaths(WebAssert $session, array $available_paths
* Helper method to assert the text on the 'Upgrade analysis report' page.
*
* @param \Drupal\Tests\WebAssert $session
- * The current session.
- * @param array $all_available
- * Array of modules that will be upgraded.
- * @param array $all_missing
- * Array of modules that will not be upgraded.
+ * The web-assert session.
+ * @param array $available_paths
+ * An array of modules that will be upgraded.
+ * @param array $missing_paths
+ * An array of modules that will not be upgraded.
*/
- protected function assertReviewPage(WebAssert $session, array $all_available, array $all_missing) {
+ protected function assertReviewPage(WebAssert $session, array $available_paths, array $missing_paths) {
$this->assertText('What will be upgraded?');
// Ensure there are no errors about the missing modules from the test module.
@@ -185,17 +185,7 @@ protected function assertReviewPage(WebAssert $session, array $all_available, ar
// Ensure there are no errors about any other missing migration providers.
$session->pageTextNotContains(t('module not found'));
- // Test the available migration paths.
- foreach ($all_available as $available) {
- $session->elementExists('xpath', "//span[contains(@class, 'checked') and text() = '$available']");
- $session->elementNotExists('xpath', "//span[contains(@class, 'error') and text() = '$available']");
- }
-
- // Test the missing migration paths.
- foreach ($all_missing as $missing) {
- $session->elementExists('xpath', "//span[contains(@class, 'error') and text() = '$missing']");
- $session->elementNotExists('xpath', "//span[contains(@class, 'checked') and text() = '$missing']");
- }
+ $this->assertUpgradePaths($session, $available_paths, $missing_paths);
}
/**
diff --git a/core/modules/migrate_drupal_ui/tests/src/Functional/d6/MigrateUpgrade6I18nReviewPageTest.php b/core/modules/migrate_drupal_ui/tests/src/Functional/d6/MigrateUpgrade6I18nReviewPageTest.php
index a4deaa25cf..d63c5fd1e8 100644
--- a/core/modules/migrate_drupal_ui/tests/src/Functional/d6/MigrateUpgrade6I18nReviewPageTest.php
+++ b/core/modules/migrate_drupal_ui/tests/src/Functional/d6/MigrateUpgrade6I18nReviewPageTest.php
@@ -61,7 +61,6 @@ protected function getAvailablePaths() {
'forum',
'imagecache',
'imagefield',
- 'language',
'link',
'locale',
'menu',
@@ -128,6 +127,13 @@ protected function getAvailablePaths() {
/**
* {@inheritdoc}
*/
+ protected function getIncompletePaths() {
+ return [];
+ }
+
+ /**
+ * {@inheritdoc}
+ */
protected function getMissingPaths() {
return [
'devel',
@@ -143,6 +149,7 @@ protected function getMissingPaths() {
'i18nsync',
'i18ntaxonomy',
'i18nviews',
+ 'migrate_status_active_test',
'phone',
'views',
];
diff --git a/core/modules/migrate_drupal_ui/tests/src/Functional/d6/MigrateUpgrade6NoMultilingualTest.php b/core/modules/migrate_drupal_ui/tests/src/Functional/d6/MigrateUpgrade6NoMultilingualTest.php
index e07e8bf211..1923478318 100644
--- a/core/modules/migrate_drupal_ui/tests/src/Functional/d6/MigrateUpgrade6NoMultilingualTest.php
+++ b/core/modules/migrate_drupal_ui/tests/src/Functional/d6/MigrateUpgrade6NoMultilingualTest.php
@@ -128,7 +128,6 @@ protected function getAvailablePaths() {
'forum',
'imagecache',
'imagefield',
- 'language',
'link',
'locale',
'menu',
diff --git a/core/modules/migrate_drupal_ui/tests/src/Functional/d6/MigrateUpgrade6ReviewPageTest.php b/core/modules/migrate_drupal_ui/tests/src/Functional/d6/MigrateUpgrade6ReviewPageTest.php
index 91657f742a..0b7de20b61 100644
--- a/core/modules/migrate_drupal_ui/tests/src/Functional/d6/MigrateUpgrade6ReviewPageTest.php
+++ b/core/modules/migrate_drupal_ui/tests/src/Functional/d6/MigrateUpgrade6ReviewPageTest.php
@@ -29,6 +29,9 @@ class MigrateUpgrade6ReviewPageTest extends MigrateUpgradeReviewPageTestBase {
'update',
// Required for translation migrations.
'migrate_drupal_multilingual',
+ // Test migrations statuses.
+ 'migrate_status_incomplete_test',
+ 'migrate_status_active_test',
];
/**
@@ -52,7 +55,6 @@ protected function getSourceBasePath() {
protected function getAvailablePaths() {
return [
'aggregator',
- 'block',
'book',
'comment',
'contact',
@@ -63,18 +65,13 @@ protected function getAvailablePaths() {
'filefield',
'filter',
'forum',
- 'i18n',
'i18nblocks',
- 'i18ncck',
'i18nmenu',
'i18nprofile',
'i18nstrings',
- 'i18ntaxonomy',
'imagecache',
'imagefield',
- 'language',
'link',
- 'locale',
'menu',
'node',
'nodereference',
@@ -143,10 +140,16 @@ protected function getMissingPaths() {
'devel',
'devel_generate',
'devel_node_access',
+ 'block',
+ 'i18n',
+ 'i18ncck',
'i18ncontent',
'i18npoll',
'i18nsync',
+ 'i18ntaxonomy',
'i18nviews',
+ 'locale',
+ 'migrate_status_active_test',
'phone',
'views',
];
diff --git a/core/modules/migrate_drupal_ui/tests/src/Functional/d6/MigrateUpgrade6Test.php b/core/modules/migrate_drupal_ui/tests/src/Functional/d6/MigrateUpgrade6Test.php
index 215a06e3d6..66c2423b2f 100644
--- a/core/modules/migrate_drupal_ui/tests/src/Functional/d6/MigrateUpgrade6Test.php
+++ b/core/modules/migrate_drupal_ui/tests/src/Functional/d6/MigrateUpgrade6Test.php
@@ -130,39 +130,33 @@ protected function getAvailablePaths() {
'contact',
'content',
'date',
- 'dblog',
'email',
'filefield',
'filter',
'forum',
- 'i18n',
'i18nblocks',
- 'i18ncck',
'i18nmenu',
- 'i18nprofile',
'i18nstrings',
- 'i18ntaxonomy',
'imagecache',
'imagefield',
- 'language',
- 'link',
+ 'i18nprofile',
'locale',
'menu',
'node',
'nodereference',
'optionwidgets',
'path',
- 'profile',
'search',
'statistics',
'system',
'taxonomy',
'text',
+ 'translation',
'upload',
'user',
'userreference',
// Include modules that do not have an upgrade path and are enabled in the
- // source database, defined in the $noUpgradePath property
+ // source database', defined in the $noUpgradePath property
// in MigrateUpgradeForm.
'date_api',
'date_timezone',
@@ -180,7 +174,10 @@ protected function getAvailablePaths() {
*/
protected function getMissingPaths() {
return [
+ 'i18n',
+ 'i18ncck',
'i18ncontent',
+ 'i18ntaxonomy',
];
}
diff --git a/core/modules/migrate_drupal_ui/tests/src/Functional/d7/MigrateUpgrade7NoMultilingualTest.php b/core/modules/migrate_drupal_ui/tests/src/Functional/d7/MigrateUpgrade7NoMultilingualTest.php
index a8f51e7718..2b5bd447b4 100644
--- a/core/modules/migrate_drupal_ui/tests/src/Functional/d7/MigrateUpgrade7NoMultilingualTest.php
+++ b/core/modules/migrate_drupal_ui/tests/src/Functional/d7/MigrateUpgrade7NoMultilingualTest.php
@@ -167,6 +167,13 @@ protected function getAvailablePaths() {
/**
* {@inheritdoc}
*/
+ protected function getIncompletePaths() {
+ return [];
+ }
+
+ /**
+ * {@inheritdoc}
+ */
protected function getMissingPaths() {
return [
// These modules are in the missing path list because they are installed
diff --git a/core/modules/migrate_drupal_ui/tests/src/Functional/d7/MigrateUpgrade7ReviewPageTest.php b/core/modules/migrate_drupal_ui/tests/src/Functional/d7/MigrateUpgrade7ReviewPageTest.php
index 9e68d9dba1..656f14eb3a 100644
--- a/core/modules/migrate_drupal_ui/tests/src/Functional/d7/MigrateUpgrade7ReviewPageTest.php
+++ b/core/modules/migrate_drupal_ui/tests/src/Functional/d7/MigrateUpgrade7ReviewPageTest.php
@@ -59,14 +59,13 @@ protected function getAvailablePaths() {
'date',
'dblog',
'email',
- 'field',
+ 'entity_translation',
'field_sql_storage',
'file',
'filter',
'forum',
'image',
'i18n_block',
- 'language',
'link',
'list',
'locale',
@@ -111,7 +110,7 @@ protected function getAvailablePaths() {
'entity_feature',
'entity_token',
'entityreference',
- 'entity_translation',
+ 'field',
'field_ui',
'help',
'openid',
@@ -161,6 +160,7 @@ protected function getMissingPaths() {
'variable_realm',
'variable_store',
'variable_views',
+ 'migrate_status_active_test',
'views',
];
}
diff --git a/core/modules/migrate_drupal_ui/tests/src/Functional/d7/MigrateUpgrade7Test.php b/core/modules/migrate_drupal_ui/tests/src/Functional/d7/MigrateUpgrade7Test.php
index 1579c830ba..eaa58b67af 100644
--- a/core/modules/migrate_drupal_ui/tests/src/Functional/d7/MigrateUpgrade7Test.php
+++ b/core/modules/migrate_drupal_ui/tests/src/Functional/d7/MigrateUpgrade7Test.php
@@ -128,18 +128,19 @@ protected function getAvailablePaths() {
'color',
'comment',
'contact',
+ 'ctools',
'date',
'dblog',
'email',
+ 'entity_translation',
'entityreference',
- 'field',
'field_sql_storage',
'file',
'filter',
'forum',
+ 'i18n_block',
'i18n_variable',
'image',
- 'language',
'link',
'list',
'locale',
@@ -148,7 +149,6 @@ protected function getAvailablePaths() {
'number',
'options',
'path',
- 'phone',
'rdf',
'search',
'shortcut',
@@ -156,6 +156,7 @@ protected function getAvailablePaths() {
'system',
'taxonomy',
'text',
+ 'title',
'user',
// Include modules that do not have an upgrade path and are enabled in the
// source database, defined in the $noUpgradePath property
@@ -183,6 +184,8 @@ protected function getMissingPaths() {
'variable',
'variable_realm',
'variable_store',
+ 'field',
+ 'phone',
// These modules are in the missing path list because they are installed
// on the source site but they are not installed on the destination site.
'syslog',
diff --git a/core/modules/migrate_drupal_ui/tests/src/Kernel/VSValidateMigrationStatus.php b/core/modules/migrate_drupal_ui/tests/src/Kernel/VSValidateMigrationStatus.php
new file mode 100644
index 0000000000..4778770a0a
--- /dev/null
+++ b/core/modules/migrate_drupal_ui/tests/src/Kernel/VSValidateMigrationStatus.php
@@ -0,0 +1,172 @@
+enableAllModules();
+
+ /** @var \Drupal\migrate\Plugin\MigrationPluginManager $plugin_manager */
+ $plugin_manager = $this->container->get('plugin.manager.migration');
+
+ // Build an array for each migration keyed by provider. The value is a
+ // string consisting of the version number, the provide, the source_module
+ // and the destination module.
+ // Todo: Is using the provide sufficient here?
+ $migration_data = [];
+ $migration_data_with_migration = [];
+ $versions = ['6', '7'];
+ foreach ($versions as $version) {
+ $migrations = $plugin_manager->createInstancesByTag('Drupal ' . $version);
+ /** @var \Drupal\migrate\Plugin\Migration $migration */
+ foreach ($migrations as $migration) {
+ $id = $migration->getBaseId();
+ $definition = $migration->getPluginDefinition();
+ if (is_array($definition['provider'])) {
+ $provider = reset($definition['provider']);
+ }
+ else {
+ $provider = $definition['provider'];
+ }
+
+ $source_module = $migration->getSourcePlugin()->getSourceModule();
+ $destination_module = $migration->getDestinationPlugin()
+ ->getDestinationModule();
+
+ $tmp = implode(static::SEPARATOR, [
+ $version,
+ $provider,
+ $source_module,
+ $destination_module,
+ ]);
+ $migration_data[] = $tmp;
+ $migration_data_with_migration[$tmp][] = $id;
+ }
+ }
+
+ /** @var \Drupal\migrate\Plugin\MigrationPluginManager $plugin_manager */
+ $definitions = $this->container->get('plugin.manager.migrate.field')
+ ->getDefinitions();
+ foreach ($definitions as $key => $definition) {
+ foreach ($definition['core'] as $version) {
+ $tmp = implode(static::SEPARATOR, [
+ $version,
+ $definition['provider'],
+ $definition['source_module'],
+ $definition['destination_module'],
+ ]);
+ $migration_data[] = $tmp;
+ $migration_data_with_migration[$tmp][] = $definition['id'];
+ }
+ }
+
+ // Get the migrate information from .info.yml and build an array of source
+ // modules and there migration status. The destination is not used yet but
+ // can be later for validating the source/destination pairs with the
+ // actual source/destination pairs in the migrate plugins.
+ $system_info = system_get_info('module');
+
+ $system_data = [];
+ $properties = ['migrations_finished', 'migrations_not_finished'];
+ foreach ($system_info as $module => $info) {
+ foreach ($properties as $property) {
+ if (isset($info[$property])) {
+ foreach ($info[$property] as $info_version => $migrate_info) {
+ foreach ($migrate_info as $source => $destination) {
+ // Destination is a CSV.
+ $tmp = str_getcsv($destination);
+ foreach ($tmp as $dest) {
+ $key = [$info_version, $module, $source, trim($dest)];
+ $system_data[$property][] = implode(static::SEPARATOR, $key);
+ }
+ }
+ }
+ }
+ }
+ }
+
+ sort($system_data['migrations_finished']);
+ sort($system_data['migrations_not_finished']);
+ $system_data_unique['migrations_finished'] = array_unique($system_data['migrations_finished']);
+ $system_data_unique['migrations_not_finished'] = array_unique($system_data['migrations_not_finished']);
+ sort($migration_data);
+ $migration_data_unique = array_unique($migration_data);
+
+ // Migration data is in info.yml but not found in the migration data.
+ $finished_only_in_system = array_diff($system_data_unique['migrations_finished'], $migration_data_unique);
+ print_r(' *** finished_only_in_system ***');
+ print_r($finished_only_in_system);
+
+ // Migration data is in info.yml but not found in the migration data.
+ $not_finished_only_in_system = array_diff($system_data_unique['migrations_not_finished'], $migration_data_unique);
+ print_r(' *** not finished_only_in_system ***');
+ print_r($not_finished_only_in_system);
+
+ // Migration data is in the migration data but not in info.yml.
+ $finished_only_in_migration = array_diff($migration_data_unique, $system_data_unique['migrations_finished']);
+ print_r(' *** finished_only_in_migration ***');
+ print_r($finished_only_in_migration);
+
+ // Migration data is in the migration data but not in info.yml.
+ $not_finished_only_in_migration = array_diff($migration_data_unique, $system_data_unique['migrations_finished']);
+ print_r(' *** not finished_only_in_migration ***');
+ print_r($not_finished_only_in_migration);
+ $not_finished = $system_data_unique['migrations_not_finished'];
+
+ if (!empty($finished_only_in_migration)) {
+ foreach ($finished_only_in_migration as $only) {
+ $data = explode('|', $only);
+ $msg = sprintf("\nAdd to info.yml for %s?\n", $data[1]);
+ print_r($msg);
+ $msg = sprintf("version: %s provider: %s source: %s destination: %s\n", $data[0], $data[1], $data[2], $data[3]);
+ $migration_ids = $migration_data_with_migration[$only];
+ var_dump($migration_ids);
+ print_r($msg);
+ }
+ }
+
+ // Assert that each migration status declared finished in info.yml is in the
+ // list of discovered migrations. The migrations not finished are not
+ // checked because the migration does not need to exist yet.
+ foreach ($system_data['migrations_finished'] as $datum) {
+ $data = explode('|', $datum);
+ $msg = sprintf("version: %s provider: %s source: %s destination: %s\n", $data[0], $data[1], $data[2], $data[3]);
+ $this->assertContains($datum, $migration_data, $msg);
+ }
+ }
+
+ /**
+ * Enable all available modules.
+ */
+ protected function enableAllModules() {
+ // Install all available modules.
+ $module_handler = $this->container->get('module_handler');
+ $modules = $this->coreModuleListDataProvider();
+ $modules_enabled = $module_handler->getModuleList();
+ $modules_to_enable = array_keys(array_diff_key($modules, $modules_enabled));
+ $this->enableModules($modules_to_enable);
+ }
+
+}
diff --git a/core/modules/migrate_drupal_ui/tests/src/Kernel/ValidateMigrationStatusTest.php b/core/modules/migrate_drupal_ui/tests/src/Kernel/ValidateMigrationStatusTest.php
new file mode 100644
index 0000000000..70612e2157
--- /dev/null
+++ b/core/modules/migrate_drupal_ui/tests/src/Kernel/ValidateMigrationStatusTest.php
@@ -0,0 +1,149 @@
+enableAllModules();
+
+ /** @var \Drupal\migrate\Plugin\MigrationPluginManager $plugin_manager */
+ $plugin_manager = $this->container->get('plugin.manager.migration');
+
+ // Build an array for each migration keyed by provider. The value is a
+ // string consisting of the version number, the provide, the source_module
+ // and the destination module.
+ $migration_data = [];
+ $migration_data_with_migration = [];
+ $versions = ['6', '7'];
+ foreach ($versions as $version) {
+ $migrations = $plugin_manager->createInstancesByTag('Drupal ' . $version);
+ /** @var \Drupal\migrate\Plugin\Migration $migration */
+ foreach ($migrations as $migration) {
+ $id = $migration->getBaseId();
+ $definition = $migration->getPluginDefinition();
+ if (is_array($definition['provider'])) {
+ $provider = reset($definition['provider']);
+ }
+ else {
+ $provider = $definition['provider'];
+ }
+
+ $source_module = $migration->getSourcePlugin()->getSourceModule();
+ $destination_module = $migration->getDestinationPlugin()
+ ->getDestinationModule();
+
+ $tmp = implode(static::SEPARATOR, [
+ $version,
+ $provider,
+ $source_module,
+ $destination_module,
+ ]);
+ $migration_data[] = $tmp;
+ $migration_data_with_migration[$tmp][] = $id;
+ }
+ }
+
+ /** @var \Drupal\migrate\Plugin\MigrationPluginManager $plugin_manager */
+ $definitions = $this->container->get('plugin.manager.migrate.field')
+ ->getDefinitions();
+ foreach ($definitions as $key => $definition) {
+ foreach ($definition['core'] as $version) {
+ $tmp = implode(static::SEPARATOR, [
+ $version,
+ $definition['provider'],
+ $definition['source_module'],
+ $definition['destination_module'],
+ ]);
+ $migration_data[] = $tmp;
+ $migration_data_with_migration[$tmp][] = $definition['id'];
+ }
+ }
+
+ // Get the migrate information from .info.yml and build an array of source
+ // modules and there migration status. The destination is not used yet but
+ // can be later for validating the source/destination pairs with the
+ // actual source/destination pairs in the migrate plugins.
+ $system_info = system_get_info('module');
+
+ $system_data = [];
+ $properties = ['migrations_finished', 'migrations_not_finished'];
+ foreach ($system_info as $module => $info) {
+ foreach ($properties as $property) {
+ if (isset($info[$property])) {
+ foreach ($info[$property] as $info_version => $migrate_info) {
+ foreach ($migrate_info as $source => $destination) {
+ // Destination is a CSV.
+ $tmp = str_getcsv($destination);
+ foreach ($tmp as $dest) {
+ $key = [$info_version, $module, $source, trim($dest)];
+ $system_data[$property][] = implode(static::SEPARATOR, $key);
+ }
+ }
+ }
+ }
+ }
+ }
+
+ sort($system_data['migrations_finished']);
+ sort($system_data['migrations_not_finished']);
+ $system_data_unique['migrations_finished'] = array_unique($system_data['migrations_finished']);
+ $system_data_unique['migrations_not_finished'] = array_unique($system_data['migrations_not_finished']);
+ sort($migration_data);
+ $migration_data_unique = array_unique($migration_data);
+
+ // Assert that each migration status declared finished in info.yml is in the
+ // list of discovered migrations. The migrations not finished are not
+ // checked because the migration does not need to exist yet.
+ foreach ($system_data_unique['migrations_finished'] as $datum) {
+ $data = str_getcsv($datum);
+ $msg = sprintf("No migration found for version '%s' with source_module '%s' and destination_module '%s' declared in module '%s'", $data[0], $data[2], $data[3], $data[1]);
+ $this->assertContains($datum, $migration_data_unique, $msg);
+ }
+
+ // Assert that each migration has a corresponding declaration in the system
+ // info.yml files.
+ foreach ($migration_data_unique as $datum) {
+ $data = str_getcsv($datum);
+ $msg = sprintf("No info.yml entry found for version '%s' with source_module '%s' and destination_module '%s' declared in module '%s'", $data[0], $data[2], $data[3], $data[1]);
+ $in_finished = in_array($datum, $system_data_unique['migrations_finished']);
+ $in_not_finished = in_array($datum, $system_data_unique['migrations_not_finished']);
+ $found = $in_finished || $in_not_finished;
+ $this->assertTrue($found, $msg);
+ }
+ }
+
+ /**
+ * Enable all available modules.
+ */
+ protected function enableAllModules() {
+ // Install all available modules.
+ $module_handler = $this->container->get('module_handler');
+ $modules = $this->coreModuleListDataProvider();
+ $modules_enabled = $module_handler->getModuleList();
+ $modules_to_enable = array_keys(array_diff_key($modules, $modules_enabled));
+ $this->enableModules($modules_to_enable);
+ }
+
+}
diff --git a/core/modules/node/node.info.yml b/core/modules/node/node.info.yml
index 88cba8572b..af364d07aa 100644
--- a/core/modules/node/node.info.yml
+++ b/core/modules/node/node.info.yml
@@ -7,3 +7,9 @@ core: 8.x
configure: entity.node_type.collection
dependencies:
- drupal:text
+migrations_finished:
+ 6:
+ content: node
+ node: node
+ 7:
+ node: node
diff --git a/core/modules/options/options.info.yml b/core/modules/options/options.info.yml
index 41c5374a40..324fe0bd8a 100644
--- a/core/modules/options/options.info.yml
+++ b/core/modules/options/options.info.yml
@@ -7,3 +7,9 @@ core: 8.x
dependencies:
- drupal:field
- drupal:text
+migrations_finished:
+ 6:
+ optionwidgets: options
+ 7:
+ options: options
+ list: options
\ No newline at end of file
diff --git a/core/modules/path/path.info.yml b/core/modules/path/path.info.yml
index ba2c759c99..eb4834e67d 100644
--- a/core/modules/path/path.info.yml
+++ b/core/modules/path/path.info.yml
@@ -5,3 +5,8 @@ package: Core
version: VERSION
core: 8.x
configure: path.admin_overview
+migrations_finished:
+ 6:
+ path: path
+ 7:
+ path: path
diff --git a/core/modules/rdf/rdf.info.yml b/core/modules/rdf/rdf.info.yml
index ec1b50905b..57a34d3f92 100644
--- a/core/modules/rdf/rdf.info.yml
+++ b/core/modules/rdf/rdf.info.yml
@@ -4,3 +4,6 @@ description: 'Enriches your content with metadata to let other applications (e.g
package: Core
version: VERSION
core: 8.x
+migrations_finished:
+ 7:
+ rdf: rdf
diff --git a/core/modules/search/search.info.yml b/core/modules/search/search.info.yml
index 97b7d3fe77..a6765b96ab 100644
--- a/core/modules/search/search.info.yml
+++ b/core/modules/search/search.info.yml
@@ -5,3 +5,8 @@ package: Core
version: VERSION
core: 8.x
configure: entity.search_page.collection
+migrations_finished:
+ 6:
+ search: search
+ 7:
+ search: search
diff --git a/core/modules/shortcut/shortcut.info.yml b/core/modules/shortcut/shortcut.info.yml
index 8546317e10..7a4cccb34f 100644
--- a/core/modules/shortcut/shortcut.info.yml
+++ b/core/modules/shortcut/shortcut.info.yml
@@ -7,3 +7,6 @@ core: 8.x
configure: entity.shortcut_set.collection
dependencies:
- drupal:link
+migrations_finished:
+ 7:
+ shortcut: shortcut
diff --git a/core/modules/simpletest/simpletest.info.yml b/core/modules/simpletest/simpletest.info.yml
index 232680e7cf..d13efd8996 100644
--- a/core/modules/simpletest/simpletest.info.yml
+++ b/core/modules/simpletest/simpletest.info.yml
@@ -5,3 +5,8 @@ package: Core
version: VERSION
core: 8.x
configure: simpletest.settings
+migrations_finished:
+ 6:
+ simpletest: simpletest
+ 7:
+ simpletest: simpletest
diff --git a/core/modules/statistics/statistics.info.yml b/core/modules/statistics/statistics.info.yml
index 84a50bec9a..0406562aa4 100644
--- a/core/modules/statistics/statistics.info.yml
+++ b/core/modules/statistics/statistics.info.yml
@@ -7,3 +7,8 @@ core: 8.x
configure: statistics.settings
dependencies:
- drupal:node
+migrations_finished:
+ 6:
+ statistics: statistics
+ 7:
+ statistics: statistics
diff --git a/core/modules/syslog/syslog.info.yml b/core/modules/syslog/syslog.info.yml
index 1d8dc8f1b6..89a74908ae 100644
--- a/core/modules/syslog/syslog.info.yml
+++ b/core/modules/syslog/syslog.info.yml
@@ -5,3 +5,8 @@ package: Core
version: VERSION
core: 8.x
configure: system.logging_settings
+migrations_finished:
+ 6:
+ syslog: syslog
+ 7:
+ syslog: syslog
diff --git a/core/modules/system/system.info.yml b/core/modules/system/system.info.yml
index 1f2a064484..0ff0b6d2a8 100644
--- a/core/modules/system/system.info.yml
+++ b/core/modules/system/system.info.yml
@@ -6,3 +6,10 @@ version: VERSION
core: 8.x
required: true
configure: system.admin_config_system
+migrations_finished:
+ 6:
+ menu: system
+ system: system
+ 7:
+ menu: system
+ system: system
diff --git a/core/modules/taxonomy/taxonomy.info.yml b/core/modules/taxonomy/taxonomy.info.yml
index 8eccaf52f1..a08da88539 100644
--- a/core/modules/taxonomy/taxonomy.info.yml
+++ b/core/modules/taxonomy/taxonomy.info.yml
@@ -8,3 +8,8 @@ dependencies:
- drupal:node
- drupal:text
configure: entity.taxonomy_vocabulary.collection
+migrations_finished:
+ 6:
+ taxonomy: core, taxonomy
+ 7:
+ taxonomy: core, taxonomy
diff --git a/core/modules/telephone/telephone.info.yml b/core/modules/telephone/telephone.info.yml
index ab44ec0263..39b6456840 100644
--- a/core/modules/telephone/telephone.info.yml
+++ b/core/modules/telephone/telephone.info.yml
@@ -6,3 +6,6 @@ version: VERSION
core: 8.x
dependencies:
- drupal:field
+migrations_finished:
+ 7:
+ phone: telephone
diff --git a/core/modules/text/text.info.yml b/core/modules/text/text.info.yml
index 5f09ace218..5c6c093a4e 100644
--- a/core/modules/text/text.info.yml
+++ b/core/modules/text/text.info.yml
@@ -7,3 +7,8 @@ core: 8.x
dependencies:
- drupal:field
- drupal:filter
+migrations_finished:
+ 6:
+ text: text
+ 7:
+ text: text
diff --git a/core/modules/tracker/tracker.info.yml b/core/modules/tracker/tracker.info.yml
index d855210676..e86d793762 100644
--- a/core/modules/tracker/tracker.info.yml
+++ b/core/modules/tracker/tracker.info.yml
@@ -7,3 +7,6 @@ dependencies:
package: Core
version: VERSION
core: 8.x
+migrations_finished:
+ 7:
+ tracker: tracker
diff --git a/core/modules/update/update.info.yml b/core/modules/update/update.info.yml
index b4536011d2..4ceb791f86 100644
--- a/core/modules/update/update.info.yml
+++ b/core/modules/update/update.info.yml
@@ -7,3 +7,8 @@ core: 8.x
configure: update.settings
dependencies:
- drupal:file
+migrations_finished:
+ 6:
+ update: update
+ 7:
+ update: update
diff --git a/core/modules/user/user.info.yml b/core/modules/user/user.info.yml
index 86faf68a68..900d07476e 100644
--- a/core/modules/user/user.info.yml
+++ b/core/modules/user/user.info.yml
@@ -8,3 +8,10 @@ required: true
configure: user.admin_index
dependencies:
- drupal:system
+migrations_finished:
+ 6:
+ profile: user
+ user: user
+ 7:
+ profile: user
+ user: user