Commit 20f44c05 authored by Gábor Hojtsy's avatar Gábor Hojtsy

Issue #2953360 by quietone, heddn, yogeshmpawar, phenaproxima, Gábor Hojtsy,...

Issue #2953360 by quietone, heddn, yogeshmpawar, phenaproxima, Gábor Hojtsy, maxocub, catch, alexpott, masipila: Experimental migrate_drupal_multilingual module
parent 61ce7a7e
......@@ -138,6 +138,7 @@
"drupal/menu_ui": "self.version",
"drupal/migrate": "self.version",
"drupal/migrate_drupal": "self.version",
"drupal/migrate_drupal_multilingual": "self.version",
"drupal/migrate_drupal_ui": "self.version",
"drupal/node": "self.version",
"drupal/options": "self.version",
......
......@@ -26,6 +26,8 @@ class MigrateBlockContentTranslationTest extends MigrateDrupal6TestBase {
'language',
'statistics',
'taxonomy',
// Required for translation migrations.
'migrate_drupal_multilingual',
];
/**
......
......@@ -19,6 +19,8 @@ class MigrateCustomBlockContentTranslationTest extends MigrateDrupal6TestBase {
'block_content',
'content_translation',
'language',
// Required for translation migrations.
'migrate_drupal_multilingual',
];
/**
......
......@@ -3,6 +3,7 @@ label: Maintenance page configuration
migration_tags:
- Drupal 6
- Configuration
- Multilingual
source:
plugin: variable_translation
variables:
......
......@@ -3,6 +3,7 @@ label: Site configuration
migration_tags:
- Drupal 6
- Configuration
- Multilingual
source:
plugin: variable_translation
constants:
......
......@@ -3,6 +3,7 @@ label: Taxonomy vocabularies
migration_tags:
- Drupal 6
- Configuration
- Multilingual
source:
plugin: d6_taxonomy_vocabulary_translation
process:
......@@ -23,6 +24,7 @@ process:
translation: translation
destination:
plugin: entity:taxonomy_vocabulary
destination_module: config_translation
migration_dependencies:
required:
- d6_taxonomy_vocabulary
......@@ -3,6 +3,7 @@ label: User mail configuration
migration_tags:
- Drupal 6
- Configuration
- Multilingual
source:
plugin: variable_translation
variables:
......
......@@ -3,6 +3,7 @@ label: User profile field instance configuration
migration_tags:
- Drupal 6
- Configuration
- Multilingual
source:
plugin: d6_profile_field_translation
constants:
......
......@@ -3,6 +3,7 @@ label: User configuration
migration_tags:
- Drupal 6
- Configuration
- Multilingual
source:
plugin: variable_translation
variables:
......
......@@ -12,7 +12,12 @@
*/
class MigrateSystemMaintenanceTranslationTest extends MigrateDrupal6TestBase {
public static $modules = ['language', 'config_translation'];
public static $modules = [
'language',
'config_translation',
// Required for translation migrations.
'migrate_drupal_multilingual',
];
/**
* {@inheritdoc}
......
......@@ -12,7 +12,12 @@
*/
class MigrateSystemSiteTranslationTest extends MigrateDrupal6TestBase {
public static $modules = ['language', 'config_translation'];
public static $modules = [
'language',
'config_translation',
// Required for translation migrations.
'migrate_drupal_multilingual',
];
/**
* {@inheritdoc}
......
......@@ -15,7 +15,13 @@ class MigrateUserConfigsTranslationTest extends MigrateDrupal6TestBase {
use SchemaCheckTestTrait;
public static $modules = ['language', 'locale', 'config_translation'];
public static $modules = [
'language',
'locale',
'config_translation',
// Required for translation migrations.
'migrate_drupal_multilingual',
];
/**
* {@inheritdoc}
......
......@@ -15,7 +15,14 @@ class MigrateUserProfileFieldInstanceTranslationTest extends MigrateDrupal6TestB
/**
* {@inheritdoc}
*/
public static $modules = ['config_translation', 'locale', 'language', 'field'];
public static $modules = [
'config_translation',
'locale',
'language',
'field',
// Required for translation migrations.
'migrate_drupal_multilingual',
];
/**
* Tests migration of translated user profile fields.
......
......@@ -3,6 +3,7 @@ label: Block translations
migration_tags:
- Drupal 6
- Configuration
- Multilingual
source:
plugin: d6_block_translation
constants:
......
......@@ -3,6 +3,7 @@ label: Custom block translations
migration_tags:
- Drupal 6
- Content
- Multilingual
source:
plugin: d6_box_translation
process:
......
......@@ -2,6 +2,7 @@ id: d6_entity_reference_translation
label: Entity reference translations
migration_tags:
- Drupal 6
- Multilingual
- Follow-up migration
deriver: Drupal\migrate_drupal\Plugin\migrate\EntityReferenceTranslationDeriver
# Supported target types for entity reference translation migrations. The array
......
......@@ -3,6 +3,7 @@ label: Menu links
migration_tags:
- Drupal 6
- Content
- Multilingual
source:
plugin: d6_menu_link_translation
process:
......
......@@ -4,6 +4,7 @@ migration_tags:
- Drupal 6
- translation
- Content
- Multilingual
class: Drupal\node\Plugin\migrate\D6NodeTranslation
deriver: Drupal\node\Plugin\migrate\D6NodeDeriver
source:
......
......@@ -3,6 +3,7 @@ label: Taxonomy terms
migration_tags:
- Drupal 6
- Content
- Multilingual
source:
plugin: d6_taxonomy_term
translations: true
......@@ -34,6 +35,7 @@ process:
changed: timestamp
destination:
plugin: entity:taxonomy_term
destination_module: content_translation
migration_dependencies:
required:
- d6_taxonomy_vocabulary
......
......@@ -2,6 +2,7 @@ id: d7_entity_reference_translation
label: Entity reference translations
migration_tags:
- Drupal 7
- Multilingual
- Follow-up migration
deriver: Drupal\migrate_drupal\Plugin\migrate\EntityReferenceTranslationDeriver
# Supported target types for entity reference translation migrations. The array
......
......@@ -3,6 +3,7 @@ label: Drupal 7 Entity Translation settings
migration_tags:
- Drupal 7
- Configuration
- Multilingual
source:
plugin: d7_entity_translation_settings
process:
......
......@@ -4,6 +4,7 @@ migration_tags:
- Drupal 7
- translation
- Content
- Multilingual
class: Drupal\node\Plugin\migrate\D7NodeTranslation
deriver: Drupal\node\Plugin\migrate\D7NodeDeriver
source:
......
......@@ -5,6 +5,7 @@ migration_tags:
- Drupal 6
- Drupal 7
- Content
- Multilingual
source:
plugin: menu_link
constants:
......
......@@ -4,6 +4,7 @@ migration_tags:
- Drupal 6
- Drupal 7
- Content
- Multilingual
source:
plugin: node_counter
process:
......
......@@ -20,6 +20,8 @@ class MigrateTaxonomyTermTranslationTest extends MigrateDrupal6TestBase {
'content_translation',
'language',
'menu_ui',
// Required for translation migrations.
'migrate_drupal_multilingual',
'node',
'taxonomy',
];
......
......@@ -20,6 +20,8 @@ class MigrateEntityTranslationSettingsTest extends MigrateDrupal7TestBase {
'content_translation',
'language',
'menu_ui',
// Required for translation migrations.
'migrate_drupal_multilingual',
'node',
'taxonomy',
'text',
......
......@@ -20,6 +20,8 @@ class MigrateMenuLinkTest extends MigrateNodeTestBase {
'content_translation',
'language',
'menu_link_content',
// Required for translation migrations.
'migrate_drupal_multilingual',
'menu_ui',
];
......
......@@ -20,6 +20,8 @@ class MigrateMenuLinkTranslationTest extends MigrateDrupal6TestBase {
'menu_link_content',
'language',
'content_translation',
// Required for translation migrations.
'migrate_drupal_multilingual',
];
/**
......
......@@ -24,6 +24,8 @@ class MigrateMenuLinkTest extends MigrateDrupal7TestBase {
'link',
'menu_ui',
'menu_link_content',
// Required for translation migrations.
'migrate_drupal_multilingual',
'node',
'text',
];
......
......@@ -24,3 +24,10 @@ function migrate_drupal_update_8502() {
->set('follow_up_migration_tags', ['Follow-up migration'])
->save();
}
/**
* Install migrate_drupal_multilingual since migrate_drupal is installed.
*/
function migrate_drupal_update_8601() {
\Drupal::service('module_installer')->install(['migrate_drupal_multilingual']);
}
......@@ -110,6 +110,12 @@ protected function getMigrations($database_state_key, $drupal_version) {
if (!empty(array_intersect($migration->getMigrationTags(), $this->getFollowUpMigrationTags()))) {
continue;
}
// Multilingual migrations require migrate_drupal_multilingual.
$tags = $migration->getMigrationTags() ?: [];
if (in_array('Multilingual', $tags, TRUE) && (!\Drupal::service('module_handler')->moduleExists('migrate_drupal_multilingual'))) {
throw new RequirementsException(sprintf("Install migrate_drupal_multilingual to run migration '%s'.", $migration->getPluginId()));
}
try {
// @todo https://drupal.org/node/2681867 We should be able to validate
// the entire migration at this point.
......
......@@ -19,6 +19,8 @@ class FollowUpMigrationsTest extends MigrateNodeTestBase {
'content_translation',
'language',
'menu_ui',
// A requirement for d6_node_translation.
'migrate_drupal_multilingual',
];
/**
......
......@@ -26,6 +26,8 @@ class FollowUpMigrationsTest extends MigrateDrupal7TestBase {
'language',
'link',
'menu_ui',
// A requirement for translation migrations.
'migrate_drupal_multilingual',
'node',
'taxonomy',
'telephone',
......
name: 'Migrate Drupal Multilingual'
type: module
description: 'Provides a requirement for multilingual migrations.'
package: 'Core (Experimental)'
core: 8.x
dependencies:
- migrate_drupal
<?php
/**
* @file
* Provides a requirement for multilingual content and configuration migrations.
*/
use Drupal\Core\Routing\RouteMatchInterface;
/**
* Implements hook_help().
*/
function migrate_drupal_multilingual_help($route_name, RouteMatchInterface $route_match) {
switch ($route_name) {
case 'help.page.migrate_drupal_multilingual':
$output = '';
$output .= '<h3>' . t('About') . '</h3>';
$output .= '<p>' . t('The Migrate Drupal Multilingual module is a requirement for migrating translations. It does not provide a user interface. For more information, see the <a href=":migrate_drupal_multilingual">online documentation for the Migrate Drupal Multilingual module</a>.', [':migrate_drupal_multilingual' => 'https://www.drupal.org/node/2959712']) . '</p>';
return $output;
}
}
......@@ -59,7 +59,6 @@ protected function getAvailablePaths() {
'filefield',
'filter',
'forum',
'i18ntaxonomy',
'imagecache',
'imagefield',
'language',
......@@ -142,6 +141,7 @@ protected function getMissingPaths() {
'i18npoll',
'i18nprofile',
'i18nsync',
'i18ntaxonomy',
'i18nviews',
'phone',
'views',
......
<?php
namespace Drupal\Tests\migrate_drupal_ui\Functional\d6;
use Drupal\Tests\migrate_drupal_ui\Functional\MigrateUpgradeExecuteTestBase;
/**
* Tests Drupal 6 upgrade without translations.
*
* The test method is provided by the MigrateUpgradeTestBase class.
*
* @group migrate_drupal_ui
*/
class MigrateUpgrade6NoMultilingualTest extends MigrateUpgradeExecuteTestBase {
/**
* {@inheritdoc}
*/
public static $modules = [
'language',
'content_translation',
'config_translation',
'migrate_drupal_ui',
'telephone',
'aggregator',
'book',
'forum',
'statistics',
];
/**
* {@inheritdoc}
*/
protected function setUp() {
parent::setUp();
$this->loadFixture(drupal_get_path('module', 'migrate_drupal') . '/tests/fixtures/drupal6.php');
}
/**
* {@inheritdoc}
*/
protected function getSourceBasePath() {
return __DIR__ . '/files';
}
/**
* {@inheritdoc}
*/
protected function getEntityCounts() {
return [
'aggregator_item' => 1,
'aggregator_feed' => 2,
'block' => 35,
'block_content' => 2,
'block_content_type' => 1,
'comment' => 6,
// The 'standard' profile provides the 'comment' comment type, and the
// migration creates 12 comment types, one per node type.
'comment_type' => 13,
'contact_form' => 5,
'configurable_language' => 5,
'editor' => 2,
'field_config' => 89,
'field_storage_config' => 63,
'file' => 8,
'filter_format' => 7,
'image_style' => 5,
'language_content_settings' => 3,
'migration' => 105,
'node' => 17,
// The 'book' module provides the 'book' node type, and the migration
// creates 12 node types.
'node_type' => 13,
'rdf_mapping' => 7,
'search_page' => 2,
'shortcut' => 2,
'shortcut_set' => 1,
'action' => 23,
'menu' => 8,
'taxonomy_term' => 8,
'taxonomy_vocabulary' => 7,
'tour' => 4,
'user' => 7,
'user_role' => 6,
'menu_link_content' => 8,
'view' => 16,
'date_format' => 11,
'entity_form_display' => 29,
'entity_form_mode' => 1,
'entity_view_display' => 55,
'entity_view_mode' => 14,
'base_field_override' => 38,
];
}
/**
* {@inheritdoc}
*/
protected function getEntityCountsIncremental() {
$counts = $this->getEntityCounts();
$counts['block_content'] = 3;
$counts['comment'] = 7;
$counts['file'] = 9;
$counts['menu_link_content'] = 9;
$counts['node'] = 18;
$counts['taxonomy_term'] = 9;
$counts['user'] = 8;
$counts['view'] = 16;
return $counts;
}
/**
* {@inheritdoc}
*/
protected function getAvailablePaths() {
return [
'aggregator',
'block',
'book',
'comment',
'contact',
'content',
'date',
'dblog',
'email',
'filefield',
'filter',
'forum',
'imagecache',
'imagefield',
'language',
'link',
'locale',
'menu',
'node',
'nodereference',
'optionwidgets',
'path',
'profile',
'search',
'statistics',
'system',
'taxonomy',
'text',
'upload',
'user',
'userreference',
// Include modules that do not have an upgrade path and are enabled in the
// source database, defined in the $noUpgradePath property
// in MigrateUpgradeForm.
'date_api',
'date_timezone',
'event',
'i18n',
'i18nstrings',
'imageapi',
'number',
'php',
'profile',
'variable_admin',
];
}
/**
* {@inheritdoc}
*/
protected function getMissingPaths() {
return [
'i18nblocks',
'i18ncck',
'i18ncontent',
'i18nmenu',
'i18nprofile',
];
}
/**
* {@inheritdoc}
*/
public function testMigrateUpgradeExecute() {
$connection_options = $this->sourceDatabase->getConnectionOptions();
$this->drupalGet('/upgrade');
$session = $this->assertSession();
$session->responseContains('Upgrade a site by importing its files and the data from its database into a clean and empty new install of Drupal 8.');
$button = $session->buttonExists('Continue');
$button->click();
$session->pageTextContains('Provide credentials for the database of the Drupal site you want to upgrade.');
$driver = $connection_options['driver'];
$connection_options['prefix'] = $connection_options['prefix']['default'];
// Use the driver connection form to get the correct options out of the
// database settings. This supports all of the databases we test against.
$drivers = drupal_get_database_types();
$form = $drivers[$driver]->getFormOptions($connection_options);
$connection_options = array_intersect_key($connection_options, $form + $form['advanced_options']);
$version = $this->getLegacyDrupalVersion($this->sourceDatabase);
$edit = [
$driver => $connection_options,
'version' => $version,
];
if (count($drivers) !== 1) {
$edit['driver'] = $driver;
}
$edits = $this->translatePostValues($edit);
$this->drupalPostForm(NULL, $edits, t('Review upgrade'));
$session->pageTextContains("Install migrate_drupal_multilingual to run migration 'd6_system_maintenance_translation'.");
}
}
......@@ -18,6 +18,7 @@ class MigrateUpgrade6ReviewPageTest extends MigrateUpgradeReviewPageTestBase {
public static $modules = [
'language',
'content_translation',
'config_translation',
'telephone',
'aggregator',
'book',
......@@ -26,6 +27,8 @@ class MigrateUpgrade6ReviewPageTest extends MigrateUpgradeReviewPageTestBase {
'syslog',
'tracker',
'update',
// Required for translation migrations.
'migrate_drupal_multilingual',
];
/**
......@@ -60,7 +63,11 @@ protected function getAvailablePaths() {
'filefield',
'filter',
'forum',
'i18n',
'i18nblocks',
'i18nmenu',
'i18nprofile',
'i18nstrings',
'i18ntaxonomy',
'imagecache',
'imagefield',
......@@ -105,9 +112,6 @@ protected function getAvailablePaths() {
'fieldgroup',
'filefield_meta',
'help',
'i18n',
'i18nmenu',
'i18nstrings',
'imageapi',
'imageapi_gd',
'imageapi_imagemagick',
......@@ -141,7 +145,6 @@ protected function getMissingPaths() {
'i18ncck',
'i18ncontent',
'i18npoll',
'i18nprofile',
'i18nsync',
'i18nviews',
'phone',
......
......@@ -23,6 +23,7 @@ class MigrateUpgrade6Test extends MigrateUpgradeExecuteTestBase {
public static $modules = [
'language',
'content_translation',
'config_translation',
'migrate_drupal_ui',
'telephone',
'aggregator',
......@@ -30,6 +31,8 @@ class MigrateUpgrade6Test extends MigrateUpgradeExecuteTestBase {
'forum',
'statistics',
'migration_provider_test',
// Required for translation migrations.
'migrate_drupal_multilingual',
];
/**
......@@ -83,7 +86,7 @@ protected function getEntityCounts() {
'menu' => 8,
'taxonomy_term' => 8,
'taxonomy_vocabulary' => 7,
'tour' => 4,
'tour' => 5,
'user' => 7,
'user_role' => 6,
'menu_link_content' => 10,
......@@ -132,9 +135,11 @@ protected function getAvailablePaths() {
'filefield',