diff --git a/core/lib/Drupal/Core/Entity/DatabaseStorageController.php b/core/lib/Drupal/Core/Entity/DatabaseStorageController.php index 3e1dd4b..7e9bc5a 100644 --- a/core/lib/Drupal/Core/Entity/DatabaseStorageController.php +++ b/core/lib/Drupal/Core/Entity/DatabaseStorageController.php @@ -533,6 +533,14 @@ public function save(EntityInterface $entity) { $this->preSave($entity); $this->invokeHook('presave', $entity); + // Ensure the default langcode is stored in the base table. + // @todo clarify if it wouldn't be better to rename the column in the base + // table default_langcode as well. + if ($this->dataTable) { + $langcode = $entity->langcode; + $entity->langcode = $entity->default_langcode; + } + if (!$entity->isNew()) { if ($entity->isDefaultRevision()) { $return = drupal_write_record($this->entityInfo['base table'], $entity, $this->idKey); @@ -542,16 +550,35 @@ public function save(EntityInterface $entity) { // with $isDefaultRevision = FALSE? $return = FALSE; } + if ($this->dataTable) { + // Ensure the appropriate langcodes are stored in the property data. + $entity->default_langcode = $entity->langcode; + $entity->langcode = $langcode; + } if ($this->revisionKey) { $this->saveRevision($entity); } if ($this->dataTable) { - $primary_keys = array( - $this->idKey, - $this->revisionKey, - 'langcode', - ); - drupal_write_record($this->entityInfo['data table'], $entity, $primary_keys); + // @todo find a nicer way to do this. + $query = db_select($this->entityInfo['data table']) + ->condition($this->idKey, $entity->id()) + ->condition('langcode', $entity->langcode); + $query->addExpression('1'); + if ($query->execute()->fetchField()) { + $primary_keys = array( + $this->idKey, + $this->revisionKey, + 'langcode', + ); + $primary_keys = array($this->idKey); + $primary_keys[] = 'langcode'; + // Update existing property row. + drupal_write_record($this->entityInfo['data table'], $entity, $primary_keys); + } + else { + // Insert new property row. + drupal_write_record($this->entityInfo['data table'], $entity); + } } $this->resetCache(array($entity->id())); $this->postSave($entity, TRUE); @@ -559,6 +586,11 @@ public function save(EntityInterface $entity) { } else { $return = drupal_write_record($this->entityInfo['base table'], $entity); + if ($this->dataTable) { + // Ensure the appropriate langcodes are stored in the property data. + $entity->default_langcode = $entity->langcode; + $entity->langcode = $langcode; + } if ($this->revisionKey) { $this->saveRevision($entity); } @@ -593,6 +625,18 @@ public function save(EntityInterface $entity) { * The entity object. */ protected function saveRevision(EntityInterface $entity) { + // When saving properties in a new language create a new revision. + // @todo find a nicer way to do this. + if ($this->dataTable) { + $query = db_select($this->revisionTable) + ->condition($this->idKey, $entity->id()) + ->condition('langcode', $entity->langcode); + $query->addExpression('1'); + if (!$query->execute()->fetchField() && !$entity->isNewRevision()) { + $entity->setNewRevision(); + } + } + // Convert the entity into an array as it might not have the same properties // as the entity, it is just a raw structure. $record = (array) $entity; diff --git a/core/modules/node/lib/Drupal/node/Tests/NodeFieldMultilingualTestCase.php b/core/modules/node/lib/Drupal/node/Tests/NodeFieldMultilingualTestCase.php index 9c3dd06..c80b339 100644 --- a/core/modules/node/lib/Drupal/node/Tests/NodeFieldMultilingualTestCase.php +++ b/core/modules/node/lib/Drupal/node/Tests/NodeFieldMultilingualTestCase.php @@ -141,4 +141,66 @@ function testMultilingualDisplaySettings() { )); $this->assertEqual(current($body), $node->body['en'][0]['value'], 'Node body found.'); } + + /** + * Test property translation. + */ + public function testMultilingualProperties() { + $title_values = array( + 'en' => $this->randomName(8), + 'it' => $this->randomName(8), + ); + $node = $this->drupalCreateNode(array( + 'title' => $title_values['en'], + 'body' => array('en' => array(array($this->randomString(30)))), + 'langcode' => 'en', + )); + + // Save properties in a different language. + $node->title = $title_values['it']; + $node->langcode = 'it'; + $node->save(); + + $node_property_data = db_select('node_property_data') + ->fields('node_property_data') + ->condition('nid', $node->id()) + ->execute() + ->fetchAll(); + $this->assertEqual(2, count($node_property_data), 'Two property items found.'); + $property_languages = array(); + $property_default_languages = array(); + foreach ($node_property_data as $node_property_data_raw) { + $property_languages[$node_property_data_raw->langcode] = $node_property_data_raw->langcode; + $property_default_languages[$node_property_data_raw->default_langcode] = $node_property_data_raw->default_langcode; + + $this->assertEqual($title_values[$node_property_data_raw->langcode], $node_property_data_raw->title, $node_property_data_raw->langcode . ': Language specific title found.'); + } + $this->assertEqual(array('en' => 'en', 'it' => 'it'), $property_languages, 'Expected property languages found.'); + $this->assertEqual(array('en' => 'en'), $property_default_languages, 'Default language of properties is consistent.'); + + $node_property_revision = db_select('node_property_revision') + ->fields('node_property_revision') + ->condition('nid', $node->id()) + ->orderBy('vid') + ->execute() + ->fetchAll(); + $this->assertEqual(2, count($node_property_revision), 'Two property revision rows found.'); + $revision_languages = array(); + $revision_default_languages = array(); + foreach ($node_property_revision as $node_property_revision_raw) { + $revision_languages[$node_property_revision_raw->langcode] = $node_property_revision_raw->langcode; + $revision_default_languages[$node_property_revision_raw->default_langcode] = $node_property_revision_raw->default_langcode; + + $this->assertEqual($title_values[$node_property_revision_raw->langcode], $node_property_revision_raw->title, $node_property_revision_raw->langcode . ': Language specific title found.'); + } + $this->assertEqual(array('en' => 'en', 'it' => 'it'), $revision_languages, 'Expected property revision languages found.'); + $this->assertEqual(array('en' => 'en'), $revision_default_languages, 'Default language of revisions is consistent.'); + + $node_raw_data = db_select('node') + ->fields('node') + ->condition('nid', $node->id()) + ->execute() + ->fetchAll(); + $this->assertEqual('en', $node_raw_data[0]->langcode, 'Default language unchanged.'); + } } diff --git a/core/modules/node/node.install b/core/modules/node/node.install index c308ed6..c2df993 100644 --- a/core/modules/node/node.install +++ b/core/modules/node/node.install @@ -738,11 +738,25 @@ function node_update_8006(&$sandbox) { $sandbox['#finished'] = empty($sandbox['max']) ? 1 : ($sandbox['progress'] / $sandbox['max']); } +/** + * Move the language default values to config. + */ +function node_update_8007() { + $types = db_query('SELECT type FROM {node_type}')->fetchCol(); + foreach ($types as $type) { + $language_default = update_variable_get('node_type_language_default_' . $type, NULL); + $language_hidden = update_variable_get('node_type_language_hidden_' . $type, NULL); + if (isset($language_default) || isset($language_hidden)) { + $values = array('langcode' => $language_default, 'language_hidden' => $language_hidden); + config('language.settings')->set('node.' . $type . '.language.default_configuration', $values)->save(); + } + } +} /** * Add dedicated tables for node properties. */ -function node_update_8007() { +function node_update_8008() { $schema = node_schema(); // Create property table if necessary. if (!db_table_exists('node_property_data')) { @@ -758,7 +772,7 @@ function node_update_8007() { /** * Move property data to dedicated table. */ -function node_update_8008(&$sandbox) { +function node_update_8009(&$sandbox) { if (!isset($sandbox['progress'])) { $sandbox['progress'] = 0; $sandbox['last'] = (int) db_query('SELECT npd.nid FROM {node_property_data npd} ORDER BY nid DESC')->fetchField(); @@ -796,7 +810,7 @@ function node_update_8008(&$sandbox) { /** * Move property revisions to dedicated table. */ -function node_update_8009(&$sandbox) { +function node_update_8010(&$sandbox) { if (!isset($sandbox['progress'])) { $sandbox['progress'] = 0; $sandbox['last'] = (int) db_query('SELECT npr.vid FROM {node_property_revision} npr ORDER BY vid DESC')->fetchField(); @@ -836,7 +850,7 @@ function node_update_8009(&$sandbox) { /** * Cleanup old tables after finishing switch to dedicated property tables. */ -function node_update_8010() { +function node_update_8011() { $old_base_table_fields = array( 'title', 'uid', @@ -894,21 +908,6 @@ function node_update_8010() { } /** - * Move the language default values to config. - */ -function node_update_8007() { - $types = db_query('SELECT type FROM {node_type}')->fetchCol(); - foreach ($types as $type) { - $language_default = update_variable_get('node_type_language_default_' . $type, NULL); - $language_hidden = update_variable_get('node_type_language_hidden_' . $type, NULL); - if (isset($language_default) || isset($language_hidden)) { - $values = array('langcode' => $language_default, 'language_hidden' => $language_hidden); - config('language.settings')->set('node.' . $type . '.language.default_configuration', $values)->save(); - } - } -} - -/** * @} End of "addtogroup updates-7.x-to-8.x" * The next series of updates should start at 9000. */