From 9ac85b0b07bf28de1dcde8f3e2a087e5f6226996 Mon Sep 17 00:00:00 2001 From: webchick Date: Mon, 22 Sep 2014 22:18:44 -0700 Subject: [PATCH] Issue #2279323 by benjy, oadaeh, ultimate, chx: Fixed Data for fields with multiple values do not import. --- .../migrate/source/d6/CckFieldValues.php | 20 ++-- .../src/Tests/Dump/Drupal6FieldInstance.php | 98 ++++++++++++++++++- .../src/Tests/Dump/Drupal6Node.php | 59 +++++++++++ .../src/Tests/Dump/Drupal6NodeType.php | 24 +++++ .../Tests/d6/MigrateCckFieldValuesTest.php | 18 ++++ .../d6/MigrateNodeBundleSettingsTest.php | 1 + .../src/Tests/d6/MigrateNodeTestBase.php | 9 ++ 7 files changed, 222 insertions(+), 7 deletions(-) diff --git a/core/modules/migrate_drupal/src/Plugin/migrate/source/d6/CckFieldValues.php b/core/modules/migrate_drupal/src/Plugin/migrate/source/d6/CckFieldValues.php index 4e3e2d00d3d..60b5fdacca3 100644 --- a/core/modules/migrate_drupal/src/Plugin/migrate/source/d6/CckFieldValues.php +++ b/core/modules/migrate_drupal/src/Plugin/migrate/source/d6/CckFieldValues.php @@ -105,12 +105,20 @@ class CckFieldValues extends DrupalSqlBase implements SourceEntityInterface { } } } - if ($results = $query->execute()->fetchAssoc()) { - $source = $row->getSource(); - // We diff the results because the extra will be all the field columns. - $new_fields = array_diff($results, $source); - foreach ($new_fields as $key => $value) { - $row->setSourceProperty($key, $value); + + // The $query only contains single value CCK fields and so when the only + // CCK field attached to a content type is a multi-valued CCK field then + // this query would be invalid. Checking the count tells us if any single + // fields have been added the query. + if (count($query->getFields())) { + if ($results = $query->execute()->fetchAssoc()) { + $source = $row->getSource(); + // We diff the results with the source to find any field columns + // in the content type's main table. + $new_fields = array_diff($results, $source); + foreach ($new_fields as $key => $value) { + $row->setSourceProperty($key, $value); + } } } } diff --git a/core/modules/migrate_drupal/src/Tests/Dump/Drupal6FieldInstance.php b/core/modules/migrate_drupal/src/Tests/Dump/Drupal6FieldInstance.php index 497704803db..65ae0ac22e9 100644 --- a/core/modules/migrate_drupal/src/Tests/Dump/Drupal6FieldInstance.php +++ b/core/modules/migrate_drupal/src/Tests/Dump/Drupal6FieldInstance.php @@ -754,6 +754,42 @@ class Drupal6FieldInstance extends Drupal6DumpBase { )), 'description' => 'An example text field using a single on/off checkbox.', )) + ->values(array( + 'field_name' => 'field_multivalue', + 'type_name' => 'test_planet', + 'weight' => 2, + 'label' => 'Decimal Field', + 'widget_type' => 'number', + 'widget_settings' => serialize(array( + 'default_value' => array( + 0 => array( + 'value' => '', + '_error_element' => 'default_value_widget][field_multivalue][0][value', + ), + ), + 'default_value_php' => NULL, + )), + 'display_settings' => serialize(array( + 'weight' => 2, + 'parent' => '', + 'label' => array( + 'format' => 'above', + ), + 'teaser' => array( + 'format' => 'default', + 'exclude' => 0, + ), + 'full' => array( + 'format' => 'default', + 'exclude' => 0, + ), + 4 => array( + 'format' => 'default', + 'exclude' => 0, + ), + )), + 'description' => 'An example multi-valued decimal field.', + )) ->execute(); // Create the field table. @@ -1036,6 +1072,16 @@ Goodbye";s:18:"allowed_values_php";s:0:"";}', 'db_columns' => 'a:0:{}', 'active' => 1, )) + ->values(array( + 'field_name' => 'field_multivalue', + 'module' => 'number', + 'type' => 'number_decimal', + 'global_settings' => 'a:9:{s:6:"prefix";s:0:"";s:6:"suffix";s:0:"";s:3:"min";s:0:"";s:3:"max";s:0:"";s:14:"allowed_values";s:0:"";s:18:"allowed_values_php";s:0:"";s:9:"precision";s:2:"10";s:5:"scale";s:1:"2";s:7:"decimal";s:1:".";}', + 'multiple' => 1, + 'db_storage' => 0, + 'db_columns' => 'a:1:{s:5:"value";a:5:{s:4:"type";s:7:"numeric";s:9:"precision";s:2:"10";s:5:"scale";s:1:"2";s:8:"not null";b:0;s:8:"sortable";b:1;}}', + 'active' => 1, + )) ->execute(); $this->createTable('content_field_test', array( @@ -1084,7 +1130,6 @@ Goodbye";s:18:"allowed_values_php";s:0:"";}', )) ->execute(); - $this->createTable('content_field_test_two', array( 'description' => 'Table for field_test_two', 'fields' => array( @@ -1145,6 +1190,57 @@ Goodbye";s:18:"allowed_values_php";s:0:"";}', 'field_test_two_format' => 1, )) ->execute(); + + $this->createTable('content_field_multivalue', array( + 'description' => 'Table for field_multivalue', + 'fields' => array( + 'vid' => array( + 'description' => 'The primary identifier for this version.', + 'type' => 'serial', + 'unsigned' => TRUE, + 'not null' => TRUE, + ), + 'nid' => array( + 'description' => 'The {node} this version belongs to.', + 'type' => 'int', + 'unsigned' => TRUE, + 'not null' => TRUE, + 'default' => 0, + ), + 'field_multivalue_value' => array( + 'type' => 'numeric', + 'precision' => '10', + 'scale' => '2', + 'not null' => false, + ), + 'delta' => array( + 'type' => 'int', + 'unsigned' => TRUE, + 'not null' => TRUE, + 'default' => 0, + ), + ), + 'primary key' => array('vid', 'delta'), + )); + $this->database->insert('content_field_multivalue')->fields(array( + 'vid', + 'nid', + 'field_multivalue_value', + 'delta', + )) + ->values(array( + 'vid' => 4, + 'nid' => 3, + 'field_multivalue_value' => 33, + 'delta' => 0, + )) + ->values(array( + 'vid' => 4, + 'nid' => 3, + 'field_multivalue_value' => 44, + 'delta' => 1, + )) + ->execute(); $this->setModuleVersion('content', '6001'); } diff --git a/core/modules/migrate_drupal/src/Tests/Dump/Drupal6Node.php b/core/modules/migrate_drupal/src/Tests/Dump/Drupal6Node.php index 4cd47e601b2..cc5374b4ed3 100644 --- a/core/modules/migrate_drupal/src/Tests/Dump/Drupal6Node.php +++ b/core/modules/migrate_drupal/src/Tests/Dump/Drupal6Node.php @@ -183,6 +183,23 @@ class Drupal6Node extends Drupal6DumpBase { 'tnid' => 0, 'translate' => 0, )) + ->values(array( + 'nid' => 3, + 'vid' => 4, + 'type' => 'test_planet', + 'language' => '', + 'title' => 'Test planet title 3', + 'uid' => 1, + 'status' => 1, + 'created' => 1388271527, + 'changed' => 1390096401, + 'comment' => 0, + 'promote' => 0, + 'moderate' => 0, + 'sticky' => 0, + 'tnid' => 0, + 'translate' => 0, + )) ->execute(); $this->createTable('node_revisions', array( 'description' => 'Stores information about each saved version of a {node}.', @@ -285,6 +302,17 @@ class Drupal6Node extends Drupal6DumpBase { 'timestamp' => 1390095701, 'format' => 1, )) + ->values(array( + 'nid' => 3, + 'vid' => 4, + 'uid' => 1, + 'title' => 'Test page title rev 4', + 'body' => 'test page body rev 4', + 'teaser' => 'test page teaser rev 4', + 'log' => '', + 'timestamp' => 1390095701, + 'format' => 1, + )) ->execute(); $this->createTable('content_type_story', array( @@ -343,5 +371,36 @@ class Drupal6Node extends Drupal6DumpBase { )) ->execute(); $this->setModuleVersion('content', 6001); + + $this->createTable('content_type_test_planet', array( + 'description' => 'The content type join table.', + 'fields' => array( + 'nid' => array( + 'description' => 'The {node} this version belongs to.', + 'type' => 'int', + 'unsigned' => TRUE, + 'not null' => TRUE, + 'default' => 0, + ), + 'vid' => array( + 'description' => 'The primary identifier for this version.', + 'type' => 'serial', + 'unsigned' => TRUE, + 'not null' => TRUE, + ), + ), + 'primary key' => array('vid'), + )); + + $this->database->insert('content_type_test_planet')->fields( + array( + 'nid', + 'vid', + )) + ->values(array( + 'nid' => 3, + 'vid' => 4, + )) + ->execute(); } } diff --git a/core/modules/migrate_drupal/src/Tests/Dump/Drupal6NodeType.php b/core/modules/migrate_drupal/src/Tests/Dump/Drupal6NodeType.php index c6e9baf74f9..f0eaaba2070 100644 --- a/core/modules/migrate_drupal/src/Tests/Dump/Drupal6NodeType.php +++ b/core/modules/migrate_drupal/src/Tests/Dump/Drupal6NodeType.php @@ -65,6 +65,22 @@ class Drupal6NodeType extends Drupal6DumpBase { 'locked' => 0, 'orig_type' => 'story', )) + ->values(array( + 'type' => 'test_planet', + 'name' => 'Migrate test planet', + 'module' => 'node', + 'description' => "A story, similar in form to a page, is ideal for creating and displaying content that informs or engages website visitors. Press releases, site announcements, and informal blog-like entries may all be created with a story entry. By default, a story entry is automatically featured on the site's initial home page, and provides the ability to post comments.", + 'help' => '', + 'has_title' => 1, + 'title_label' => 'Title', + 'has_body' => 0, + 'body_label' => 'Body', + 'min_word_count' => 0, + 'custom' => 1, + 'modified' => 1, + 'locked' => 0, + 'orig_type' => 'test_planet', + )) ->values(array( 'type' => 'test_event', 'name' => 'Migrate test event', @@ -129,6 +145,13 @@ class Drupal6NodeType extends Drupal6DumpBase { 1 => 'revision', )), )) + ->values(array( + 'name' => 'node_options_test_planet', + 'value' => serialize(array( + 0 => 'sticky', + 1 => 'revision', + )), + )) ->values(array( 'name' => 'theme_settings', 'value' => serialize(array( @@ -153,6 +176,7 @@ class Drupal6NodeType extends Drupal6DumpBase { 'toggle_node_info_test_page' => 1, 'toggle_node_info_test_story' => 1, 'toggle_node_info_test_event' => 1, + 'toggle_node_info_test_planet' => 1, )), )) ->execute(); diff --git a/core/modules/migrate_drupal/src/Tests/d6/MigrateCckFieldValuesTest.php b/core/modules/migrate_drupal/src/Tests/d6/MigrateCckFieldValuesTest.php index 159e7acdd2a..c97afe37f97 100644 --- a/core/modules/migrate_drupal/src/Tests/d6/MigrateCckFieldValuesTest.php +++ b/core/modules/migrate_drupal/src/Tests/d6/MigrateCckFieldValuesTest.php @@ -71,6 +71,18 @@ class MigrateCckFieldValuesTest extends MigrateNodeTestBase { 'bundle' => 'story', ))->save(); + entity_create('field_storage_config', array( + 'entity_type' => 'node', + 'name' => 'field_multivalue', + 'type' => 'integer', + 'cardinality' => -1, + ))->save(); + entity_create('field_config', array( + 'entity_type' => 'node', + 'field_name' => 'field_multivalue', + 'bundle' => 'test_planet', + ))->save(); + // Add some id mappings for the dependant migrations. $id_mappings = array( 'd6_field_formatter_settings' => array( @@ -82,6 +94,7 @@ class MigrateCckFieldValuesTest extends MigrateNodeTestBase { 'd6_node' => array( array(array(1), array(1)), array(array(2), array(2)), + array(array(3), array(3)), ), ); $this->prepareMigrations($id_mappings); @@ -105,6 +118,11 @@ class MigrateCckFieldValuesTest extends MigrateNodeTestBase { $this->assertEqual($node->field_test_two[1]->value, 20, 'Multi field second value is correct.'); $this->assertEqual($node->field_test_three->value, '42.42', 'Single field second value is correct.'); $this->assertEqual($node->field_test_integer_selectlist[0]->value, '3412', 'Integer select list value is correct'); + + $planet_node = Node::load(3); + $this->assertEqual($planet_node->field_multivalue->value, 33); + $this->assertEqual($planet_node->field_multivalue[1]->value, 44); + } } diff --git a/core/modules/migrate_drupal/src/Tests/d6/MigrateNodeBundleSettingsTest.php b/core/modules/migrate_drupal/src/Tests/d6/MigrateNodeBundleSettingsTest.php index 36eb89379f1..18e139fe3a8 100644 --- a/core/modules/migrate_drupal/src/Tests/d6/MigrateNodeBundleSettingsTest.php +++ b/core/modules/migrate_drupal/src/Tests/d6/MigrateNodeBundleSettingsTest.php @@ -32,6 +32,7 @@ class MigrateNodeBundleSettingsTest extends MigrateDrupalTestBase { // Setup the bundles. entity_create('node_type', array('type' => 'test_page'))->save(); + entity_create('node_type', array('type' => 'test_planet'))->save(); entity_create('node_type', array('type' => 'test_story'))->save(); entity_create('node_type', array('type' => 'test_event'))->save(); entity_create('node_type', array('type' => 'story'))->save(); diff --git a/core/modules/migrate_drupal/src/Tests/d6/MigrateNodeTestBase.php b/core/modules/migrate_drupal/src/Tests/d6/MigrateNodeTestBase.php index b45a6736b6c..72cef7ee5e9 100644 --- a/core/modules/migrate_drupal/src/Tests/d6/MigrateNodeTestBase.php +++ b/core/modules/migrate_drupal/src/Tests/d6/MigrateNodeTestBase.php @@ -22,6 +22,7 @@ abstract class MigrateNodeTestBase extends MigrateDrupalTestBase { */ protected function setUp() { parent::setUp(); + entity_create('node_type', array('type' => 'test_planet'))->save(); $node_type = entity_create('node_type', array('type' => 'story')); $node_type->save(); node_add_body_field($node_type); @@ -61,6 +62,14 @@ abstract class MigrateNodeTestBase extends MigrateDrupalTestBase { $node->enforceIsNew(); $node->save(); + $node = entity_create('node', array( + 'type' => 'test_planet', + 'nid' => 3, + 'vid' => 4, + )); + $node->enforceIsNew(); + $node->save(); + // Load dumps. $dumps = array( $this->getDumpDirectory() . '/Drupal6Node.php',