diff --git a/core/lib/Drupal/Core/Entity/DatabaseStorageController.php b/core/lib/Drupal/Core/Entity/DatabaseStorageController.php index 3e1dd4b..cd641fb 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,41 @@ 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 ($this->revisionKey) { + $query->condition($this->idKey, $entity->getRevisionId()); + } + if ($query->execute()->fetchField()) { + $primary_keys = array( + $this->idKey, + $this->revisionKey, + 'langcode', + ); + $primary_keys = array($this->idKey); + if (empty($this->revisionKey)) { + $primary_keys[] = $this->revisionKey; + } + $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 +592,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 +631,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.'); + } }