diff --git a/core/modules/migrate/src/Plugin/migrate/destination/EntityContentBase.php b/core/modules/migrate/src/Plugin/migrate/destination/EntityContentBase.php index 9430628..9ed7841 100644 --- a/core/modules/migrate/src/Plugin/migrate/destination/EntityContentBase.php +++ b/core/modules/migrate/src/Plugin/migrate/destination/EntityContentBase.php @@ -88,41 +88,13 @@ public function import(Row $row, array $old_destination_id_values = array()) { } $ids = $this->save($entity, $old_destination_id_values); - if (!empty($this->configuration['source_language_keys'])) { + if (!empty($this->configuration['translations'])) { $ids[] = $entity->language()->getId(); } return $ids; } /** - * Get the destination ID values of a translation of this entity. - * - * @param \Drupal\migrate\Row $row - * The row object. - * @param array &$destination_ids - * The old destination IDs, to be modified by this method. - */ - protected function getTranslatedDestinationIds(Row $row, array &$destination_ids) { - if (empty($destination_ids) && isset($this->configuration['source_language_keys'])) { - // Get source IDs, without language keys. - $source_language_keys = (array) $this->configuration['source_language_keys']; - $source_ids = array_diff_key($row->getSourceIdValues(), array_flip($source_language_keys)); - - // Try to lookup another translation of the same entity. - $dest_ids = $this->migration->getIdMap()->lookupDestinationIds($source_ids); - $destination_ids = reset($dest_ids) ?: []; - } - } - - /** - * {@inheritdoc} - */ - protected function getEntity(Row $row, array $old_destination_id_values) { - $this->getTranslatedDestinationIds($row, $old_destination_id_values); - return parent::getEntity($row, $old_destination_id_values); - } - - /** * Saves the entity. * * @param \Drupal\Core\Entity\ContentEntityInterface $entity @@ -157,7 +129,7 @@ protected function baseIds() { public function getIds() { $ids = $this->baseIds(); - if (!empty($this->configuration['source_language_keys'])) { + if (!empty($this->configuration['translations'])) { if ($key = $this->getKey('langcode')) { $ids[$key]['type'] = 'string'; } diff --git a/core/modules/migrate_drupal/tests/src/Kernel/d6/MigrateDrupal6TestBase.php b/core/modules/migrate_drupal/tests/src/Kernel/d6/MigrateDrupal6TestBase.php index 476ea38..f52164e 100644 --- a/core/modules/migrate_drupal/tests/src/Kernel/d6/MigrateDrupal6TestBase.php +++ b/core/modules/migrate_drupal/tests/src/Kernel/d6/MigrateDrupal6TestBase.php @@ -91,7 +91,7 @@ protected function migrateContent($include_revisions = FALSE) { $this->migrateFields(); $this->installEntitySchema('node'); - $this->executeMigrations(['d6_node_settings', 'd6_node']); + $this->executeMigrations(['d6_node_settings', 'd6_node', 'd6_node_translation']); if ($include_revisions) { $this->executeMigrations(['d6_node_revision']); diff --git a/core/modules/node/migration_templates/d6_node.yml b/core/modules/node/migration_templates/d6_node.yml index 0b61a6b..82571b8 100644 --- a/core/modules/node/migration_templates/d6_node.yml +++ b/core/modules/node/migration_templates/d6_node.yml @@ -38,7 +38,6 @@ process: destination: plugin: entity:node - source_language_keys: language migration_dependencies: required: - d6_user diff --git a/core/modules/node/migration_templates/d6_node_translation.yml b/core/modules/node/migration_templates/d6_node_translation.yml new file mode 100644 index 0000000..9a33acd --- /dev/null +++ b/core/modules/node/migration_templates/d6_node_translation.yml @@ -0,0 +1,57 @@ +id: d6_node_translation +label: Nodes translations +migration_tags: + - Drupal 6 +deriver: Drupal\node\Plugin\migrate\D6NodeDeriver +source: + plugin: d6_node +process: + nid: + - + plugin: migration + migration: d6_node + source: nid + - + plugin: skip_on_empty + method: row + type: type + langcode: + plugin: default_value + source: language + default_value: "und" + title: title + uid: node_uid + status: status + created: created + changed: changed + promote: promote + sticky: sticky + 'body/format': + plugin: migration + migration: d6_filter_format + source: format + 'body/value': body + 'body/summary': teaser + revision_uid: revision_uid + revision_log: log + revision_timestamp: timestamp + +# unmapped d6 fields. +# tnid +# translate +# moderate +# comment + +destination: + plugin: entity:node + translations: true +migration_dependencies: + required: + - d6_user + - d6_node_type + - d6_node_settings + - d6_filter_format + optional: + - d6_field_instance_widget_settings + - d6_field_formatter_settings + - d6_upload_field_instance diff --git a/core/modules/node/src/Plugin/migrate/D6NodeDeriver.php b/core/modules/node/src/Plugin/migrate/D6NodeDeriver.php index d586efd..d83eb17 100644 --- a/core/modules/node/src/Plugin/migrate/D6NodeDeriver.php +++ b/core/modules/node/src/Plugin/migrate/D6NodeDeriver.php @@ -99,9 +99,10 @@ public function getDerivativeDefinitions($base_plugin_definition) { ]); $values['source']['node_type'] = $node_type; - // If this migration is based on the d6_node_revision migration, it - // should explicitly depend on the corresponding d6_node variant. - if ($base_plugin_definition['id'] == 'd6_node_revision') { + // If this migration is based on the d6_node_revision migration, or + // is for translations of nodes, it should explicitly depend on the + // corresponding d6_node variant. + if (in_array($base_plugin_definition['id'], ['d6_node_revision', 'd6_node_translation'])) { $values['migration_dependencies']['required'][] = 'd6_node:' . $node_type; } diff --git a/core/modules/node/src/Plugin/migrate/source/d6/Node.php b/core/modules/node/src/Plugin/migrate/source/d6/Node.php index d39c486..5379843 100644 --- a/core/modules/node/src/Plugin/migrate/source/d6/Node.php +++ b/core/modules/node/src/Plugin/migrate/source/d6/Node.php @@ -260,8 +260,6 @@ protected function getCckData(array $field, Row $node) { public function getIds() { $ids['nid']['type'] = 'integer'; $ids['nid']['alias'] = 'n'; - $ids['language']['type'] = 'string'; - $ids['language']['alias'] = 'n'; return $ids; } @@ -298,6 +296,14 @@ protected function translationQuery() { 'max_vid.translation_set IN (n.nid, n.tnid)'); $query->fields('max_vid', ['vid']); + // Are we yielding original nodes, or translations? + if (empty($this->configuration['translations'])) { + $query->where('n.tnid = 0 OR n.tnid = n.nid'); + } + else { + $query->where('n.tnid <> 0 AND n.tnid <> n.nid'); + } + return $query; } } diff --git a/core/modules/node/tests/src/Kernel/Migrate/d6/MigrateNodeTest.php b/core/modules/node/tests/src/Kernel/Migrate/d6/MigrateNodeTest.php index 1f78d3a..e7896cf 100644 --- a/core/modules/node/tests/src/Kernel/Migrate/d6/MigrateNodeTest.php +++ b/core/modules/node/tests/src/Kernel/Migrate/d6/MigrateNodeTest.php @@ -24,7 +24,7 @@ protected function setUp() { parent::setUp(); $this->setUpMigratedFiles(); $this->installSchema('file', ['file_usage']); - $this->executeMigrations(['language', 'd6_node']); + $this->executeMigrations(['language', 'd6_node', 'd6_node_translation']); } /** @@ -85,6 +85,7 @@ public function testNode() { $this->assertTrue($node instanceof NodeInterface); $this->assertIdentical('en', $node->langcode->value); $this->assertIdentical('The Real McCoy', $node->title->value); + $this->assertTrue($node->hasTranslation('fr')); // Node 10 is a translation of node 9, and should not be imported separately. $this->assertNull(Node::load(10)); @@ -119,9 +120,7 @@ public function testNode() { // Now insert a row indicating a failure and set to update later. $title = $this->rerunMigration(array( 'sourceid1' => 2, - 'sourceid2' => 'en', 'destid1' => NULL, - 'destid2' => NULL, 'source_row_status' => MigrateIdMapInterface::STATUS_NEEDS_UPDATE, )); $node = Node::load(2); @@ -152,10 +151,7 @@ protected function rerunMigration($new_row = []) { $default_connection = \Drupal::database(); $default_connection->truncate($table_name)->execute(); if ($new_row) { - $hash = $migration->getIdMap()->getSourceIDsHash([ - 'nid' => $new_row['sourceid1'], - 'language' => $new_row['sourceid2'] - ]); + $hash = $migration->getIdMap()->getSourceIDsHash(['nid' => $new_row['sourceid1']]); $new_row['source_ids_hash'] = $hash; $default_connection->insert($table_name) ->fields($new_row) diff --git a/core/modules/node/tests/src/Unit/Plugin/migrate/source/d6/NodeTest.php b/core/modules/node/tests/src/Unit/Plugin/migrate/source/d6/NodeTest.php index 80f75b0..456e2be 100644 --- a/core/modules/node/tests/src/Unit/Plugin/migrate/source/d6/NodeTest.php +++ b/core/modules/node/tests/src/Unit/Plugin/migrate/source/d6/NodeTest.php @@ -2,16 +2,12 @@ namespace Drupal\Tests\node\Unit\Plugin\migrate\source\d6; -use Drupal\Tests\migrate\Unit\MigrateSqlSourceTestCase; - /** * Tests D6 node source plugin. * * @group node */ -class NodeTest extends MigrateSqlSourceTestCase { - - const PLUGIN_CLASS = 'Drupal\node\Plugin\migrate\source\d6\Node'; +class NodeTest extends NodeTestBase { protected $migrationConfiguration = array( 'id' => 'test', @@ -118,194 +114,6 @@ class NodeTest extends MigrateSqlSourceTestCase { 'timestamp' => 1279308994, 'format' => 1, ), - array( - 'nid' => 6, - 'vid' => 7, - 'type' => 'story', - 'language' => 'fr', - 'title' => 'node title 7', - 'uid' => 1, - 'status' => 1, - 'created' => 1279290910, - 'changed' => 1279308995, - 'comment' => 0, - 'promote' => 1, - 'moderate' => 0, - 'sticky' => 0, - 'tnid' => 6, - 'translate' => 0, - // Node revision fields. - 'body' => 'body for node 7', - 'teaser' => 'body for node 7', - 'log' => '', - 'timestamp' => 1279308995, - 'format' => 1, - ), ); - /** - * {@inheritdoc} - */ - protected function setUp() { - $this->databaseContents['content_node_field'] = array( - array( - 'field_name' => 'field_test_four', - 'type' => 'number_float', - 'global_settings' => 'a:0:{}', - 'required' => '0', - 'multiple' => '0', - 'db_storage' => '1', - 'module' => 'number', - 'db_columns' => 'a:1:{s:5:"value";a:3:{s:4:"type";s:5:"float";s:8:"not null";b:0;s:8:"sortable";b:1;}}', - 'active' => '1', - 'locked' => '0', - ), - ); - $this->databaseContents['content_node_field_instance'] = array( - array( - 'field_name' => 'field_test_four', - 'type_name' => 'story', - 'weight' => '3', - 'label' => 'Float Field', - 'widget_type' => 'number', - 'widget_settings' => 'a:0:{}', - 'display_settings' => 'a:0:{}', - 'description' => 'An example float field.', - 'widget_module' => 'number', - 'widget_active' => '1', - ), - ); - $this->databaseContents['content_type_story'] = array( - array( - 'nid' => 5, - 'vid' => 5, - 'uid' => 5, - 'field_test_four_value' => '3.14159', - ), - ); - $this->databaseContents['system'] = array( - array( - 'type' => 'module', - 'name' => 'content', - 'schema_version' => 6001, - 'status' => TRUE, - ), - ); - $this->databaseContents['node'] = [ - [ - 'nid' => 1, - 'vid' => 1, - 'type' => 'page', - 'language' => 'en', - 'title' => 'node title 1', - 'uid' => 1, - 'status' => 1, - 'created' => 1279051598, - 'changed' => 1279051598, - 'comment' => 2, - 'promote' => 1, - 'moderate' => 0, - 'sticky' => 0, - 'translate' => 0, - 'tnid' => 0, - ], - [ - 'nid' => 2, - 'vid' => 2, - 'type' => 'page', - 'language' => 'en', - 'title' => 'node title 2', - 'uid' => 1, - 'status' => 1, - 'created' => 1279290908, - 'changed' => 1279308993, - 'comment' => 0, - 'promote' => 1, - 'moderate' => 0, - 'sticky' => 0, - 'translate' => 0, - 'tnid' => 0, - ], - [ - 'nid' => 5, - 'vid' => 5, - 'type' => 'story', - 'language' => 'en', - 'title' => 'node title 5', - 'uid' => 1, - 'status' => 1, - 'created' => 1279290908, - 'changed' => 1279308993, - 'comment' => 0, - 'promote' => 1, - 'moderate' => 0, - 'sticky' => 0, - 'translate' => 0, - 'tnid' => 0, - ], - [ - 'nid' => 6, - 'vid' => 6, - 'type' => 'story', - 'language' => 'en', - 'title' => 'node title 6', - 'uid' => 1, - 'status' => 1, - 'created' => 1279290909, - 'changed' => 1279308994, - 'comment' => 0, - 'promote' => 1, - 'moderate' => 0, - 'sticky' => 0, - 'translate' => 0, - 'tnid' => 6, - ], - [ - 'nid' => 7, - 'vid' => 7, - 'type' => 'story', - 'language' => 'fr', - 'title' => 'node title 7', - 'uid' => 1, - 'status' => 1, - 'created' => 1279290910, - 'changed' => 1279308995, - 'comment' => 0, - 'promote' => 1, - 'moderate' => 0, - 'sticky' => 0, - 'translate' => 0, - 'tnid' => 6, - ], - ]; - - foreach ($this->databaseContents['node'] as $k => $row) { - // Find the equivalent row from expected results. - $result_row = NULL; - foreach ($this->expectedResults as $result) { - if (in_array($result['nid'], [$row['nid'], $row['tnid']]) && $result['language'] == $row['language']) { - $result_row = $result; - break; - } - } - - // Populate node_revisions. - foreach (array('nid', 'vid', 'title', 'uid', 'body', 'teaser', 'format', 'timestamp', 'log') as $field) { - $value = isset($row[$field]) ? $row[$field] : $result_row[$field]; - $this->databaseContents['node_revisions'][$k][$field] = $value; - if ($field == 'uid') { - $this->databaseContents['node_revisions'][$k]['uid']++; - } - } - } - - array_walk($this->expectedResults, function (&$row) { - $row['node_uid'] = $row['uid']; - $row['revision_uid'] = $row['uid'] + 1; - unset($row['uid']); - }); - - parent::setUp(); - } - } diff --git a/core/modules/node/tests/src/Unit/Plugin/migrate/source/d6/NodeTestBase.php b/core/modules/node/tests/src/Unit/Plugin/migrate/source/d6/NodeTestBase.php new file mode 100644 index 0000000..8850fc4 --- /dev/null +++ b/core/modules/node/tests/src/Unit/Plugin/migrate/source/d6/NodeTestBase.php @@ -0,0 +1,179 @@ +databaseContents['content_node_field'] = array( + array( + 'field_name' => 'field_test_four', + 'type' => 'number_float', + 'global_settings' => 'a:0:{}', + 'required' => '0', + 'multiple' => '0', + 'db_storage' => '1', + 'module' => 'number', + 'db_columns' => 'a:1:{s:5:"value";a:3:{s:4:"type";s:5:"float";s:8:"not null";b:0;s:8:"sortable";b:1;}}', + 'active' => '1', + 'locked' => '0', + ), + ); + $this->databaseContents['content_node_field_instance'] = array( + array( + 'field_name' => 'field_test_four', + 'type_name' => 'story', + 'weight' => '3', + 'label' => 'Float Field', + 'widget_type' => 'number', + 'widget_settings' => 'a:0:{}', + 'display_settings' => 'a:0:{}', + 'description' => 'An example float field.', + 'widget_module' => 'number', + 'widget_active' => '1', + ), + ); + $this->databaseContents['content_type_story'] = array( + array( + 'nid' => 5, + 'vid' => 5, + 'uid' => 5, + 'field_test_four_value' => '3.14159', + ), + ); + $this->databaseContents['system'] = array( + array( + 'type' => 'module', + 'name' => 'content', + 'schema_version' => 6001, + 'status' => TRUE, + ), + ); + $this->databaseContents['node'] = [ + [ + 'nid' => 1, + 'vid' => 1, + 'type' => 'page', + 'language' => 'en', + 'title' => 'node title 1', + 'uid' => 1, + 'status' => 1, + 'created' => 1279051598, + 'changed' => 1279051598, + 'comment' => 2, + 'promote' => 1, + 'moderate' => 0, + 'sticky' => 0, + 'translate' => 0, + 'tnid' => 0, + ], + [ + 'nid' => 2, + 'vid' => 2, + 'type' => 'page', + 'language' => 'en', + 'title' => 'node title 2', + 'uid' => 1, + 'status' => 1, + 'created' => 1279290908, + 'changed' => 1279308993, + 'comment' => 0, + 'promote' => 1, + 'moderate' => 0, + 'sticky' => 0, + 'translate' => 0, + 'tnid' => 0, + ], + [ + 'nid' => 5, + 'vid' => 5, + 'type' => 'story', + 'language' => 'en', + 'title' => 'node title 5', + 'uid' => 1, + 'status' => 1, + 'created' => 1279290908, + 'changed' => 1279308993, + 'comment' => 0, + 'promote' => 1, + 'moderate' => 0, + 'sticky' => 0, + 'translate' => 0, + 'tnid' => 0, + ], + [ + 'nid' => 6, + 'vid' => 6, + 'type' => 'story', + 'language' => 'en', + 'title' => 'node title 6', + 'uid' => 1, + 'status' => 1, + 'created' => 1279290909, + 'changed' => 1279308994, + 'comment' => 0, + 'promote' => 1, + 'moderate' => 0, + 'sticky' => 0, + 'translate' => 0, + 'tnid' => 6, + ], + [ + 'nid' => 7, + 'vid' => 7, + 'type' => 'story', + 'language' => 'fr', + 'title' => 'node title 7', + 'uid' => 1, + 'status' => 1, + 'created' => 1279290910, + 'changed' => 1279308995, + 'comment' => 0, + 'promote' => 1, + 'moderate' => 0, + 'sticky' => 0, + 'translate' => 0, + 'tnid' => 6, + ], + ]; + + foreach ($this->databaseContents['node'] as $k => $row) { + // Find the equivalent row from expected results. + $result_row = NULL; + foreach ($this->expectedResults as $result) { + if (in_array($result['nid'], [$row['nid'], $row['tnid']]) && $result['language'] == $row['language']) { + $result_row = $result; + break; + } + } + + // Populate node_revisions. + foreach (array('nid', 'vid', 'title', 'uid', 'body', 'teaser', 'format', 'timestamp', 'log') as $field) { + $value = isset($row[$field]) ? $row[$field] : $result_row[$field]; + $this->databaseContents['node_revisions'][$k][$field] = $value; + if ($field == 'uid') { + $this->databaseContents['node_revisions'][$k]['uid']++; + } + } + } + + array_walk($this->expectedResults, function (&$row) { + $row['node_uid'] = $row['uid']; + $row['revision_uid'] = $row['uid'] + 1; + unset($row['uid']); + }); + + parent::setUp(); + } + +} diff --git a/core/modules/node/tests/src/Unit/Plugin/migrate/source/d6/NodeTranslationTest.php b/core/modules/node/tests/src/Unit/Plugin/migrate/source/d6/NodeTranslationTest.php new file mode 100644 index 0000000..6dfca19 --- /dev/null +++ b/core/modules/node/tests/src/Unit/Plugin/migrate/source/d6/NodeTranslationTest.php @@ -0,0 +1,46 @@ + 'test', + 'source' => array( + 'plugin' => 'd6_node', + 'translations' => TRUE, + ), + ); + + protected $expectedResults = array( + array( + 'nid' => 6, + 'vid' => 7, + 'type' => 'story', + 'language' => 'fr', + 'title' => 'node title 7', + 'uid' => 1, + 'status' => 1, + 'created' => 1279290910, + 'changed' => 1279308995, + 'comment' => 0, + 'promote' => 1, + 'moderate' => 0, + 'sticky' => 0, + 'tnid' => 6, + 'translate' => 0, + // Node revision fields. + 'body' => 'body for node 7', + 'teaser' => 'body for node 7', + 'log' => '', + 'timestamp' => 1279308995, + 'format' => 1, + ), + ); + +} diff --git a/core/modules/taxonomy/migration_templates/d6_term_node.yml b/core/modules/taxonomy/migration_templates/d6_term_node.yml index 7c08570..63aec85 100644 --- a/core/modules/taxonomy/migration_templates/d6_term_node.yml +++ b/core/modules/taxonomy/migration_templates/d6_term_node.yml @@ -10,15 +10,10 @@ 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: