diff --git a/core/modules/taxonomy/migration_templates/d6_term_node.yml b/core/modules/taxonomy/migration_templates/d6_term_node.yml index 63aec85..7c08570 100644 --- a/core/modules/taxonomy/migration_templates/d6_term_node.yml +++ b/core/modules/taxonomy/migration_templates/d6_term_node.yml @@ -10,10 +10,15 @@ process: - plugin: migration migration: d6_node - source: nid + source: + - nid - plugin: skip_on_empty method: row + - + plugin: extract + index: + - 0 type: type # The actual field name is dynamic and will be added by the builder. destination: diff --git a/core/modules/taxonomy/tests/src/Kernel/Migrate/d6/MigrateTermNodeTest.php b/core/modules/taxonomy/tests/src/Kernel/Migrate/d6/MigrateTermNodeTest.php index 40be413..3e13a55 100644 --- a/core/modules/taxonomy/tests/src/Kernel/Migrate/d6/MigrateTermNodeTest.php +++ b/core/modules/taxonomy/tests/src/Kernel/Migrate/d6/MigrateTermNodeTest.php @@ -55,7 +55,7 @@ public function testTermNode() { public function testSkipNonExistentNode() { // Node 2 is migrated by d6_node__story, but we need to pretend that it // failed, so record that in the map table. - $this->mockFailure('d6_node:story', ['nid' => 2]); + $this->mockFailure('d6_node:story', ['nid' => 2, 'language' => 'en']); // d6_term_node__2 should skip over node 2 (a.k.a. revision 3) because, // according to the map table, it failed. diff --git a/core/modules/user/src/Plugin/migrate/User.php b/core/modules/user/src/Plugin/migrate/User.php index 986b58d..65d5c2f 100644 --- a/core/modules/user/src/Plugin/migrate/User.php +++ b/core/modules/user/src/Plugin/migrate/User.php @@ -2,13 +2,80 @@ namespace Drupal\user\Plugin\migrate; +use Drupal\Core\Extension\ModuleHandlerInterface; +use Drupal\Core\Language\LanguageManagerInterface; use Drupal\migrate\Exception\RequirementsException; +use Drupal\migrate\Plugin\MigrateDestinationPluginManager; +use Drupal\migrate\Plugin\MigratePluginManager; use Drupal\migrate\Plugin\Migration; +use Drupal\migrate\Plugin\MigrationPluginManagerInterface; +use Symfony\Component\DependencyInjection\ContainerInterface; /** * Plugin class for Drupal 7 user migrations dealing with fields and profiles. */ class User extends Migration { + /** + * The module handler. + * + * @var \Drupal\Core\Extension\ModuleHandlerInterface + */ + protected $moduleHandler; + + /** + * The language manager. + * + * @var \Drupal\Core\Language\LanguageManagerInterface + */ + protected $languageManager; + + /** + * Constructs a user migration. + * + * @param array $configuration + * Plugin configuration. + * @param string $plugin_id + * The plugin ID. + * @param mixed $plugin_definition + * The plugin definition. + * @param \Drupal\migrate\Plugin\MigrationPluginManagerInterface $migration_plugin_manager + * The migration plugin manager. + * @param \Drupal\migrate\Plugin\MigratePluginManager $source_plugin_manager + * The source migration plugin manager. + * @param \Drupal\migrate\Plugin\MigratePluginManager $process_plugin_manager + * The process migration plugin manager. + * @param \Drupal\migrate\Plugin\MigrateDestinationPluginManager $destination_plugin_manager + * The destination migration plugin manager. + * @param \Drupal\migrate\Plugin\MigratePluginManager $idmap_plugin_manager + * The ID map migration plugin manager. + * @param \Drupal\Core\Extension\ModuleHandlerInterface $module_handler + * The module handler. + * @param \Drupal\Core\Language\LanguageManagerInterface $language_manager + * The language manager. + */ + public function __construct(array $configuration, $plugin_id, $plugin_definition, MigrationPluginManagerInterface $migration_plugin_manager, MigratePluginManager $source_plugin_manager, MigratePluginManager $process_plugin_manager, MigrateDestinationPluginManager $destination_plugin_manager, MigratePluginManager $idmap_plugin_manager, ModuleHandlerInterface $module_handler, LanguageManagerInterface $language_manager) { + parent::__construct($configuration, $plugin_id, $plugin_definition, $migration_plugin_manager, $source_plugin_manager, $process_plugin_manager, $destination_plugin_manager, $idmap_plugin_manager); + $this->moduleHandler = $module_handler; + $this->languageManager = $language_manager; + } + + /** + * {@inheritdoc} + */ + public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition) { + return new static( + $configuration, + $plugin_id, + $plugin_definition, + $container->get('plugin.manager.migration'), + $container->get('plugin.manager.migrate.source'), + $container->get('plugin.manager.migrate.process'), + $container->get('plugin.manager.migrate.destination'), + $container->get('plugin.manager.migrate.id_map'), + $container->get('module_handler'), + $container->get('language_manager') + ); + } /** * Flag indicating whether the CCK data has been filled already. @@ -28,7 +95,7 @@ public function getProcess() { 'ignore_map' => TRUE, ] + $this->source; $definition['destination']['plugin'] = 'null'; - if (\Drupal::moduleHandler()->moduleExists('field')) { + if ($this->moduleHandler->moduleExists('field')) { $definition['source']['plugin'] = 'd7_field_instance'; $field_migration = $this->migrationPluginManager->createStubMigration($definition); foreach ($field_migration->getSourcePlugin() as $row) { @@ -50,6 +117,15 @@ public function getProcess() { // The checkRequirements() call will fail when the profile module does // not exist on the source site. } + + // Use the default language if none is provided. + $this->process['langcode'] = [ + 'source' => 'language', + 'plugin' => 'default_value', + 'strict' => FALSE, + 'default_value' => $this->languageManager->getDefaultLanguage()->getId(), + ]; + } return parent::getProcess(); } diff --git a/core/modules/user/tests/src/Kernel/Migrate/d7/MigrateUserTest.php b/core/modules/user/tests/src/Kernel/Migrate/d7/MigrateUserTest.php index 61ff800..3d300f4 100644 --- a/core/modules/user/tests/src/Kernel/Migrate/d7/MigrateUserTest.php +++ b/core/modules/user/tests/src/Kernel/Migrate/d7/MigrateUserTest.php @@ -59,7 +59,7 @@ protected function setUp() { * @param bool $has_picture * Whether the user is expected to have a picture attached. */ - protected function assertEntity($id, $label, $mail, $access, $login, $blocked, $langcode, $init, array $roles = [RoleInterface::AUTHENTICATED_ID], $has_picture = FALSE) { + protected function assertEntity($id, $label, $mail, $access, $login, $blocked, $langcode, $preferred_langcode, $init, array $roles = [RoleInterface::AUTHENTICATED_ID], $has_picture = FALSE) { /** @var \Drupal\user\UserInterface $user */ $user = User::load($id); $this->assertTrue($user instanceof UserInterface); @@ -72,8 +72,8 @@ protected function assertEntity($id, $label, $mail, $access, $login, $blocked, $ // user preferred language is not configured on the site. We just want to // test if the value was imported correctly. $this->assertIdentical($langcode, $user->langcode->value); - $this->assertIdentical($langcode, $user->preferred_langcode->value); - $this->assertIdentical($langcode, $user->preferred_admin_langcode->value); + $this->assertIdentical($preferred_langcode, $user->preferred_langcode->value); + $this->assertIdentical($preferred_langcode, $user->preferred_admin_langcode->value); $this->assertIdentical($init, $user->getInitialEmail()); $this->assertIdentical($roles, $user->getRoles()); $this->assertIdentical($has_picture, !$user->user_picture->isEmpty()); @@ -83,7 +83,8 @@ protected function assertEntity($id, $label, $mail, $access, $login, $blocked, $ * Tests the Drupal 7 user to Drupal 8 migration. */ public function testUser() { - $this->assertEntity(2, 'Odo', 'odo@local.host', '0', '0', FALSE, '', 'odo@local.host'); + $this->assertEquals('en', \Drupal::languageManager()->getDefaultLanguage()->getId()); + $this->assertEntity(2, 'Odo', 'odo@local.host', '0', '0', FALSE, 'en', '', 'odo@local.host'); } }