Skip to content

Commit 1689c42

Browse files
committed
Issue #3008030 by quietone, masipila, maxocub: Migrate D7 i18n fields label and description
(cherry picked from commit dbf4fb8)
1 parent 5d400cc commit 1689c42

File tree

6 files changed

+1351
-10
lines changed

6 files changed

+1351
-10
lines changed
Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
id: d7_field_instance_label_description_translation
2+
label: Field label and description translation
3+
migration_tags:
4+
- Drupal 7
5+
- Configuration
6+
- Multilingual
7+
class: Drupal\migrate_drupal\Plugin\migrate\FieldMigration
8+
field_plugin_method: alterFieldInstanceMigration
9+
source:
10+
plugin: d7_field_instance_label_description_translation
11+
process:
12+
langcode:
13+
plugin: skip_on_empty
14+
source: language
15+
method: row
16+
translation:
17+
plugin: skip_on_empty
18+
source: translation
19+
method: row
20+
entity_type_exists:
21+
plugin: skip_on_empty
22+
source: entity_type
23+
method: row
24+
objectid_exists:
25+
plugin: skip_on_empty
26+
source: objectid
27+
method: row
28+
type_exists:
29+
plugin: skip_on_empty
30+
source: type
31+
method: row
32+
exists:
33+
-
34+
plugin: migration_lookup
35+
migration: d7_field_instance
36+
source:
37+
- entity_type
38+
- objectid
39+
- type
40+
-
41+
plugin: skip_on_empty
42+
method: row
43+
bundle: objectid
44+
property:
45+
plugin: static_map
46+
source: property
47+
bypass: true
48+
map:
49+
label: label
50+
description: description
51+
title_value: label
52+
entity_type: entity_type
53+
field_name: type
54+
destination:
55+
plugin: entity:field_config
56+
migration_dependencies:
57+
required:
58+
- d7_field_instance
59+
optional:
60+
- d7_node_type
61+
- d7_comment_type
62+
- d7_taxonomy_vocabulary
Lines changed: 93 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,93 @@
1+
<?php
2+
3+
namespace Drupal\field\Plugin\migrate\source\d7;
4+
5+
use Drupal\migrate_drupal\Plugin\migrate\source\DrupalSqlBase;
6+
7+
/**
8+
* Gets field label and description translations.
9+
*
10+
* @MigrateSource(
11+
* id = "d7_field_instance_label_description_translation",
12+
* source_module = "i18n_field"
13+
* )
14+
*/
15+
class FieldLabelDescriptionTranslation extends DrupalSqlBase {
16+
17+
/**
18+
* {@inheritdoc}
19+
*/
20+
public function query() {
21+
// Get translations for field labels and descriptions.
22+
$query = $this->select('i18n_string', 'i18n')
23+
->fields('i18n')
24+
->fields('lt', [
25+
'lid',
26+
'translation',
27+
'language',
28+
'plid',
29+
'plural',
30+
'i18n_status',
31+
])
32+
->fields('fci', [
33+
'id',
34+
'field_id',
35+
'field_name',
36+
'entity_type',
37+
'bundle',
38+
'data',
39+
'deleted',
40+
])
41+
->condition('i18n.textgroup', 'field')
42+
->isNotNull('language')
43+
->isNotNull('translation');
44+
$condition = $query->orConditionGroup()
45+
->condition('textgroup', 'field')
46+
->condition('objectid', '#allowed_values', '!=');
47+
$query->condition($condition);
48+
$query->leftJoin('locales_target', 'lt', 'lt.lid = i18n.lid');
49+
50+
$query->leftjoin('field_config_instance', 'fci', 'fci.bundle = i18n.objectid AND fci.field_name = i18n.type');
51+
return $query;
52+
}
53+
54+
/**
55+
* {@inheritdoc}
56+
*/
57+
public function fields() {
58+
return [
59+
'lid' => $this->t('Locales target language ID.'),
60+
'textgroup' => $this->t('A module defined group of translations'),
61+
'context' => $this->t('Full string ID for quick search: type:objectid:property.'),
62+
'objectid' => $this->t('Object ID'),
63+
'type' => $this->t('Object type for this string'),
64+
'property' => $this->t('Object property for this string'),
65+
'objectindex' => $this->t('Integer value of Object ID'),
66+
'format' => $this->t('The {filter_format}.format of the string'),
67+
'translation' => $this->t('Translation'),
68+
'language' => $this->t('Language code'),
69+
'plid' => $this->t('Parent lid'),
70+
'plural' => $this->t('Plural index number'),
71+
'i18n_status' => $this->t('Translation needs update'),
72+
'id' => $this->t('The field instance ID.'),
73+
'field_id' => $this->t('The field ID.'),
74+
'field_name' => $this->t('The field name.'),
75+
'entity_type' => $this->t('The entity type.'),
76+
'bundle' => $this->t('The entity bundle.'),
77+
'data' => $this->t('The field instance data.'),
78+
'deleted' => $this->t('Deleted'),
79+
];
80+
}
81+
82+
/**
83+
* {@inheritdoc}
84+
*/
85+
public function getIds() {
86+
$ids['property']['type'] = 'string';
87+
$ids['language']['type'] = 'string';
88+
$ids['lid']['type'] = 'integer';
89+
$ids['lid']['alias'] = 'lt';
90+
return $ids;
91+
}
92+
93+
}

modules/field/tests/src/Kernel/Migrate/d6/MigrateFieldInstanceLabelDescriptionTest.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
use Drupal\Tests\migrate_drupal\Kernel\d6\MigrateDrupal6TestBase;
99

1010
/**
11-
* Tests migration field label and description i18n translations.
11+
* Tests migration of field label and description translations.
1212
*
1313
* @group migrate_drupal_6
1414
* @group legacy
@@ -57,7 +57,7 @@ public static function migrateDumpAlter(KernelTestBase $test) {
5757
}
5858

5959
/**
60-
* Tests migration of file variables to file.settings.yml.
60+
* Tests migration of field label and description translations.
6161
*/
6262
public function testFieldInstanceLabelDescriptionTranslationMigration() {
6363
$language_manager = $this->container->get('language_manager');
Lines changed: 113 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,113 @@
1+
<?php
2+
3+
namespace Drupal\Tests\field\Kernel\Migrate\d7;
4+
5+
use Drupal\Core\Database\Database;
6+
use Drupal\KernelTests\KernelTestBase;
7+
use Drupal\Tests\migrate\Kernel\MigrateDumpAlterInterface;
8+
use Drupal\Tests\migrate_drupal\Kernel\d7\MigrateDrupal7TestBase;
9+
10+
/**
11+
* Tests migration field label and description i18n translations.
12+
*
13+
* @group migrate_drupal_7
14+
* @group legacy
15+
*/
16+
class MigrateFieldInstanceLabelDescriptionTest extends MigrateDrupal7TestBase implements MigrateDumpAlterInterface {
17+
18+
/**
19+
* {@inheritdoc}
20+
*/
21+
public static $modules = [
22+
'comment',
23+
'config_translation',
24+
'datetime',
25+
'field',
26+
'file',
27+
'image',
28+
'language',
29+
'link',
30+
'locale',
31+
'menu_ui',
32+
// Required for translation migrations.
33+
'migrate_drupal_multilingual',
34+
'node',
35+
'system',
36+
'taxonomy',
37+
'telephone',
38+
'text',
39+
];
40+
41+
/**
42+
* {@inheritdoc}
43+
*/
44+
public function setUp() {
45+
parent::setUp();
46+
47+
$this->installEntitySchema('node');
48+
$this->installEntitySchema('comment');
49+
$this->installEntitySchema('taxonomy_term');
50+
$this->installConfig(static::$modules);
51+
52+
$this->executeMigrations([
53+
'd7_node_type',
54+
'd7_comment_type',
55+
'd7_taxonomy_vocabulary',
56+
'd7_field',
57+
'd7_field_instance',
58+
'd7_field_instance_widget_settings',
59+
'language',
60+
'd7_field_instance_label_description_translation',
61+
]);
62+
}
63+
64+
/**
65+
* {@inheritdoc}
66+
*/
67+
public static function migrateDumpAlter(KernelTestBase $test) {
68+
$db = Database::getConnection('default', 'migrate');
69+
// Alter the database to test the migration is successful when a translated
70+
// field is deleted but the translation data for that field remains in both
71+
// the i18n_strings and locales_target tables.
72+
$db->delete('field_config_instance')
73+
->condition('field_name', 'field_image')
74+
->condition('bundle', 'article')
75+
->execute();
76+
}
77+
78+
/**
79+
* Tests migration of file variables to file.settings.yml.
80+
*/
81+
public function testFieldInstanceLabelDescriptionTranslationMigration() {
82+
$language_manager = $this->container->get('language_manager');
83+
84+
// Check that the deleted field with translations was skipped.
85+
$config_translation = $language_manager->getLanguageConfigOverride('fr', 'field.field.node.article.field_image');
86+
$this->assertNull($config_translation->get('label'));
87+
$this->assertNull($config_translation->get('description'));
88+
89+
// Tests fields on 'test_content_type' node type.
90+
$config_translation = $language_manager->getLanguageConfigOverride('fr', 'field.field.node.test_content_type.field_email');
91+
$this->assertNull($config_translation->get('label'));
92+
$this->assertSame("fr - The email help text.", $config_translation->get('description'));
93+
94+
$config_translation = $language_manager->getLanguageConfigOverride('is', 'field.field.node.test_content_type.field_email');
95+
$this->assertSame("is - Email", $config_translation->get('label'));
96+
$this->assertSame("is - The email help text.", $config_translation->get('description'));
97+
98+
$config_translation = $language_manager->getLanguageConfigOverride('is', 'field.field.node.test_content_type.field_boolean');
99+
$this->assertSame("is - Some helpful text.", $config_translation->get('description'));
100+
101+
// Tests fields on 'article' node type.
102+
$config_translation = $language_manager->getLanguageConfigOverride('fr', 'field.field.node.article.body');
103+
$this->assertSame("fr - Body", $config_translation->get('label'));
104+
105+
$config_translation = $language_manager->getLanguageConfigOverride('fr', 'field.field.node.article.field_link');
106+
$this->assertSame("fr - Link", $config_translation->get('label'));
107+
108+
// Tests fields on 'test_vocabulary' vocabulary type.
109+
$config_translation = $language_manager->getLanguageConfigOverride('is', 'field.field.taxonomy_term.test_vocabulary.field_term_reference');
110+
$this->assertSame("is - Term Reference", $config_translation->get('label'));
111+
}
112+
113+
}

0 commit comments

Comments
 (0)