diff --git a/core/modules/migrate/src/Plugin/migrate/destination/EntityConfigBase.php b/core/modules/migrate/src/Plugin/migrate/destination/EntityConfigBase.php index 0cc00d6..5633022 100644 --- a/core/modules/migrate/src/Plugin/migrate/destination/EntityConfigBase.php +++ b/core/modules/migrate/src/Plugin/migrate/destination/EntityConfigBase.php @@ -4,9 +4,14 @@ use Drupal\Component\Utility\NestedArray; use Drupal\Core\Entity\EntityInterface; +use Drupal\Core\Entity\EntityStorageInterface; +use Drupal\Core\Language\LanguageManagerInterface; +use Drupal\language\ConfigurableLanguageManagerInterface; +use Drupal\migrate\Plugin\MigrationInterface; use Drupal\migrate\MigrateException; use Drupal\migrate\Plugin\MigrateIdMapInterface; use Drupal\migrate\Row; +use Symfony\Component\DependencyInjection\ContainerInterface; /** * Class for importing configuration entities. @@ -21,6 +26,52 @@ class EntityConfigBase extends Entity { /** + * The language manager. + * + * @var \Drupal\Core\Language\LanguageManagerInterface + */ + protected $languageManager; + + /** + * Construct a new entity. + * + * @param array $configuration + * A configuration array containing information about the plugin instance. + * @param string $plugin_id + * The plugin_id for the plugin instance. + * @param mixed $plugin_definition + * The plugin implementation definition. + * @param MigrationInterface $migration + * The migration. + * @param EntityStorageInterface $storage + * The storage for this entity type. + * @param array $bundles + * The list of bundles this entity type has. + * @param LanguageManagerInterface $language_manager + * The language manager. + */ + public function __construct(array $configuration, $plugin_id, $plugin_definition, MigrationInterface $migration, EntityStorageInterface $storage, array $bundles, LanguageManagerInterface $language_manager) { + parent::__construct($configuration, $plugin_id, $plugin_definition, $migration, $storage, $bundles); + $this->languageManager = $language_manager; + } + + /** + * {@inheritdoc} + */ + public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition, MigrationInterface $migration = NULL) { + $entity_type_id = static::getEntityTypeId($plugin_id); + return new static( + $configuration, + $plugin_id, + $plugin_definition, + $migration, + $container->get('entity.manager')->getStorage($entity_type_id), + array_keys($container->get('entity.manager')->getBundleInfo($entity_type_id)), + $container->get('language_manager') + ); + } + + /** * {@inheritdoc} */ public function import(Row $row, array $old_destination_id_values = array()) { @@ -70,10 +121,27 @@ public function getIds() { * The row object to update from. */ protected function updateEntity(EntityInterface $entity, Row $row) { - foreach ($row->getRawDestination() as $property => $value) { - $this->updateEntityProperty($entity, explode(Row::PROPERTY_SEPARATOR, $property), $value); + // This is a translation if the language in the active config matches the + // language of this row. + $translation = FALSE; + if ($row->hasDestinationProperty('langcode') && $this->languageManager instanceof ConfigurableLanguageManagerInterface) { + $config = $entity->getConfigDependencyName(); + $langcode = \Drupal::config($config)->get('langcode'); + if ($langcode != $row->getDestinationProperty('langcode')) { + $translation = TRUE; + } } + if ($translation) { + $config_override = $this->languageManager->getLanguageConfigOverride($row->getDestinationProperty('langcode'), $config); + $config_override->set(str_replace(Row::PROPERTY_SEPARATOR, '.', $row->getDestinationProperty('property')), $row->getDestinationProperty('translation')); + $config_override->save(); + } + else { + foreach ($row->getRawDestination() as $property => $value) { + $this->updateEntityProperty($entity, explode(Row::PROPERTY_SEPARATOR, $property), $value); + } + } $this->setRollbackAction($row->getIdMap()); } diff --git a/core/modules/migrate_drupal/src/Plugin/migrate/destination/EntityFieldStorageConfig.php b/core/modules/migrate_drupal/src/Plugin/migrate/destination/EntityFieldStorageConfig.php index cc8431d..c230f61 100644 --- a/core/modules/migrate_drupal/src/Plugin/migrate/destination/EntityFieldStorageConfig.php +++ b/core/modules/migrate_drupal/src/Plugin/migrate/destination/EntityFieldStorageConfig.php @@ -4,6 +4,7 @@ use Drupal\Core\Entity\EntityStorageInterface; use Drupal\Core\Field\FieldTypePluginManagerInterface; +use Drupal\Core\Language\LanguageManagerInterface; use Symfony\Component\DependencyInjection\ContainerInterface; use Drupal\migrate\Plugin\MigrationInterface; use Drupal\migrate\Plugin\migrate\destination\EntityFieldStorageConfig as BaseEntityFieldStorageConfig; @@ -39,11 +40,14 @@ class EntityFieldStorageConfig extends BaseEntityFieldStorageConfig { * The storage for this entity type. * @param array $bundles * The list of bundles this entity type has. + * @param LanguageManagerInterface $language_manager + * The language manager. * @param \Drupal\Core\Field\FieldTypePluginManagerInterface $field_type_plugin_manager * The field type plugin manager. */ - public function __construct(array $configuration, $plugin_id, $plugin_definition, MigrationInterface $migration, EntityStorageInterface $storage, array $bundles, FieldTypePluginManagerInterface $field_type_plugin_manager) { - parent::__construct($configuration, $plugin_id, $plugin_definition, $migration, $storage, $bundles); + public function __construct(array $configuration, $plugin_id, $plugin_definition, MigrationInterface $migration, EntityStorageInterface $storage, array $bundles, LanguageManagerInterface $language_manager, FieldTypePluginManagerInterface $field_type_plugin_manager) { + parent::__construct($configuration, $plugin_id, $plugin_definition, $migration, $storage, $bundles, $language_manager, $field_type_plugin_manager); + $this->languageManager = $language_manager; $this->fieldTypePluginManager = $field_type_plugin_manager; } @@ -59,6 +63,7 @@ public static function create(ContainerInterface $container, array $configuratio $migration, $container->get('entity.manager')->getStorage($entity_type_id), array_keys($container->get('entity.manager')->getBundleInfo($entity_type_id)), + $container->get('language_manager'), $container->get('plugin.manager.field.field_type') ); } diff --git a/core/modules/migrate_drupal_ui/src/Form/MigrateUpgradeForm.php b/core/modules/migrate_drupal_ui/src/Form/MigrateUpgradeForm.php index 2d60c46..00f0138 100644 --- a/core/modules/migrate_drupal_ui/src/Form/MigrateUpgradeForm.php +++ b/core/modules/migrate_drupal_ui/src/Form/MigrateUpgradeForm.php @@ -498,6 +498,10 @@ class MigrateUpgradeForm extends ConfirmFormBase { 'source_module' => 'taxonomy', 'destination_module' => 'taxonomy', ], + 'd6_i18n_taxonomy_vocabulary' => [ + 'source_module' => 'taxonomy', + 'destination_module' => 'taxonomy', + ], 'd6_term_node' => [ 'source_module' => 'taxonomy', 'destination_module' => 'taxonomy', diff --git a/core/modules/taxonomy/migration_templates/d6_i18n_taxonomy_vocabulary.yml b/core/modules/taxonomy/migration_templates/d6_i18n_taxonomy_vocabulary.yml new file mode 100644 index 0000000..43fdf75 --- /dev/null +++ b/core/modules/taxonomy/migration_templates/d6_i18n_taxonomy_vocabulary.yml @@ -0,0 +1,24 @@ +id: d6_i18n_taxonomy_vocabulary +label: Taxonomy vocabularies +migration_tags: + - Drupal 6 +source: + plugin: d6_i18n_taxonomy_vocabulary +process: + vid: + - + plugin: machine_name + source: name + - + plugin: substr + length: 32 + langcode: language + property: + plugin: static_map + source: property + map: + name: name + description: description + translation: translation +destination: + plugin: entity:taxonomy_vocabulary diff --git a/core/modules/taxonomy/src/Plugin/migrate/source/d6/I18nTaxonomyVocabulary.php b/core/modules/taxonomy/src/Plugin/migrate/source/d6/I18nTaxonomyVocabulary.php new file mode 100644 index 0000000..45a96fd --- /dev/null +++ b/core/modules/taxonomy/src/Plugin/migrate/source/d6/I18nTaxonomyVocabulary.php @@ -0,0 +1,66 @@ +select('vocabulary', 'v') + ->fields('v', array('vid', 'name', 'description')) + ->fields('i18n', array('lid', 'type', 'property', 'objectid')) + ->fields('lt', array('lid', 'translation')) + ->condition('i18n.type', 'vocabulary'); + $query->addField('lt', 'language', 'language'); + $query->join('i18n_strings', 'i18n', 'i18n.objectid = v.vid'); + $query->leftJoin('locales_target', 'lt', 'lt.lid = i18n.lid'); + + return $query; + } + /** + * {@inheritdoc} + */ + public function fields() { + return array( + 'vid' => $this->t('The vocabulary ID.'), + 'language' => $this->t('Language for this field.'), + 'property' => $this->t('Name of property being translated.'), + 'translation' => $this->t('Translation of either the title or explanation.')); + } + + /** + * {@inheritdoc} + */ + public function getIds() { + $ids['vid']['type'] = 'integer'; + return $ids; + } + +} diff --git a/core/modules/taxonomy/tests/src/Kernel/Migrate/d6/MigrateTaxonomyVocabularyTest.php b/core/modules/taxonomy/tests/src/Kernel/Migrate/d6/MigrateTaxonomyVocabularyTest.php index c2d4ab6..5bb5b46 100644 --- a/core/modules/taxonomy/tests/src/Kernel/Migrate/d6/MigrateTaxonomyVocabularyTest.php +++ b/core/modules/taxonomy/tests/src/Kernel/Migrate/d6/MigrateTaxonomyVocabularyTest.php @@ -15,14 +15,14 @@ class MigrateTaxonomyVocabularyTest extends MigrateDrupal6TestBase { /** * {@inheritdoc} */ - public static $modules = array('taxonomy'); + public static $modules = ['config_translation', 'locale', 'language', 'taxonomy']; /** * {@inheritdoc} */ protected function setUp() { parent::setUp(); - $this->executeMigration('d6_taxonomy_vocabulary'); + $this->executeMigrations(['d6_taxonomy_vocabulary', 'd6_i18n_taxonomy_vocabulary']); } /** @@ -43,6 +43,18 @@ public function testTaxonomyVocabulary() { $this->assertIdentical('description of vocabulary name much longer than thirty two characters', $vocabulary->getDescription()); $this->assertIdentical(3, $vocabulary->getHierarchy()); $this->assertIdentical(7, $vocabulary->get('weight')); + + $language_manager = \Drupal::service('language_manager'); + $config = $language_manager->getLanguageConfigOverride('fr', 'taxonomy.vocabulary.vocabulary_1_i_0_'); + $this->assertSame('fr - vocabulary 1 (i=0)', $config->get('name')); + $config = $language_manager->getLanguageConfigOverride('fr', 'taxonomy.vocabulary.vocabulary_2_i_1_'); + $this->assertSame('fr - vocabulary 2 (i=1)', $config->get('name')); + $config = $language_manager->getLanguageConfigOverride('fr', 'taxonomy.vocabulary.vocabulary_3_i_2_'); + $this->assertSame('fr - vocabulary 3 (i=2)', $config->get('name')); + $config = $language_manager->getLanguageConfigOverride('fr', 'taxonomy.vocabulary.vocabulary_name_much_longer_than'); + $this->assertSame('Nom de vocabulaire beaucoup plus long que trente-deux caractères', $config->get('name')); + $config = $language_manager->getLanguageConfigOverride('fr', 'taxonomy.vocabulary.tags'); + $this->assertSame('fr - Tags', $config->get('name')); } } diff --git a/core/modules/taxonomy/tests/src/Kernel/Plugin/migrate/source/d6/I18nVocabularyTest.php b/core/modules/taxonomy/tests/src/Kernel/Plugin/migrate/source/d6/I18nVocabularyTest.php new file mode 100644 index 0000000..3255a48 --- /dev/null +++ b/core/modules/taxonomy/tests/src/Kernel/Plugin/migrate/source/d6/I18nVocabularyTest.php @@ -0,0 +1,131 @@ + 1, + 'objectid' => 1, + 'type' => 'vocabulary', + 'property' => 'name', + 'objectindex' => 1, + 'format' => 0, + ], + [ + 'lid' => 2, + 'objectid' => 2, + 'type' => 'vocabulary', + 'property' => 'name', + 'objectindex' => 2, + 'format' => 0, + ], + ]; + + protected $locales_target = [ + [ + 'lid' => 1, + 'language' => 'fr', + 'translation' => 'fr - vocabulary 1', + 'plid' => 0, + 'plural' => 0, + 'i18n_status' => 0, + ], + [ + 'lid' => 2, + 'language' => 'fr', + 'translation' => 'fr - vocabulary 2', + 'plid' => 0, + 'plural' => 0, + 'i18n_status' => 0, + ], + ]; + + protected $vocabulary = [ + [ + 'vid' => 1, + 'name' => 'vocabulary 1', + 'description' => 'description of vocabulary 1', + 'help' => 1, + 'relations' => 1, + 'hierarchy' => 1, + 'multiple' => 0, + 'required' => 0, + 'tags' => 0, + 'module' => 'taxonomy', + 'weight' => 4, + 'language' => '' + ], + [ + 'vid' => 2, + 'name' => 'vocabulary 2', + 'description' => 'description of vocabulary 2', + 'help' => 1, + 'relations' => 1, + 'hierarchy' => 1, + 'multiple' => 0, + 'required' => 0, + 'tags' => 0, + 'module' => 'taxonomy', + 'weight' => 5, + 'language' => '' + ], + ]; + + protected $expectedResults = [ + [ + 'vid' => 1, + 'name' => 'vocabulary 1', + 'description' => 'description of vocabulary 1', + 'lid' => '1', + 'type' => 'vocabulary', + 'property' => 'name', + 'objectid'=> '1', + 'lt_lid' => '1', + 'translation' => 'fr - vocabulary 1', + 'language' => 'fr', + ], + [ + 'vid' => 2, + 'name' => 'vocabulary 2', + 'description' => 'description of vocabulary 2', + 'lid' => '2', + 'type' => 'vocabulary', + 'property' => 'name', + 'objectid'=> '2', + 'lt_lid' => '2', + 'translation' => 'fr - vocabulary 2', + 'language' => 'fr', + ], + ]; + + /** + * {@inheritdoc} + */ + public function providerSource() { + $tests = []; + + $tests[0][0]['i18n_strings'] = $this->i18n_strings; + $tests[0][0]['locales_target'] = $this->locales_target; + $tests[0][0]['vocabulary'] = $this->vocabulary; + + $tests[0][1] = $this->expectedResults; + + return $tests; + } + +}