diff --git a/core/lib/Drupal/Core/Entity/ContentEntityBase.php b/core/lib/Drupal/Core/Entity/ContentEntityBase.php index 586da85..b1b2684 100644 --- a/core/lib/Drupal/Core/Entity/ContentEntityBase.php +++ b/core/lib/Drupal/Core/Entity/ContentEntityBase.php @@ -10,6 +10,7 @@ use Drupal\Component\Utility\String; use Drupal\Core\Entity\Plugin\DataType\EntityReference; use Drupal\Core\Entity\TypedData\EntityDataDefinition; +use Drupal\Core\Field\FieldItemListInterface; use Drupal\Core\Language\LanguageInterface; use Drupal\Core\Session\AccountInterface; use Drupal\Core\TypedData\TypedDataInterface; @@ -290,6 +291,13 @@ public function setValue($value, $notify = TRUE) { } /** + * TODO Find a better solution. + */ + public function setItems($name, FieldItemListInterface $items) { + $this->fields[$name][$this->activeLangcode] = $items; + } + + /** * {@inheritdoc} */ public function getString() { diff --git a/core/modules/content_translation/content_translation.admin.inc b/core/modules/content_translation/content_translation.admin.inc index 7fc13b2..c0ed51f 100644 --- a/core/modules/content_translation/content_translation.admin.inc +++ b/core/modules/content_translation/content_translation.admin.inc @@ -98,6 +98,8 @@ function _content_translation_form_language_content_settings_form_alter(array &$ // entity might have fields and if there are fields to translate. if ($entity_type->isFieldable()) { $fields = $entity_manager->getFieldDefinitions($entity_type_id, $bundle); + $translation_metadata = content_translation_entity_base_field_info($entity_type); + if ($fields) { $form['settings'][$entity_type_id][$bundle]['translatable'] = array( '#type' => 'checkbox', @@ -106,7 +108,8 @@ function _content_translation_form_language_content_settings_form_alter(array &$ foreach ($fields as $field_name => $definition) { // Allow to configure only fields supporting multilingual storage. - if (!empty($storage_definitions[$field_name]) && $storage_definitions[$field_name]->isTranslatable()) { + // We skip our own fields as they are always translatable. + if (!isset($translation_metadata[$field_name]) && !empty($storage_definitions[$field_name]) && $storage_definitions[$field_name]->isTranslatable()) { $form['settings'][$entity_type_id][$bundle]['fields'][$field_name] = array( '#label' => $definition->getLabel(), '#type' => 'checkbox', diff --git a/core/modules/content_translation/content_translation.module b/core/modules/content_translation/content_translation.module index dddad7c..0958ada 100644 --- a/core/modules/content_translation/content_translation.module +++ b/core/modules/content_translation/content_translation.module @@ -8,10 +8,10 @@ use Drupal\Core\Entity\ContentEntityInterface; use Drupal\Core\Entity\EntityFormInterface; use Drupal\Core\Entity\EntityInterface; +use Drupal\Core\Entity\EntityTypeInterface; use Drupal\Core\Form\FormStateInterface; use Drupal\Core\Language\LanguageInterface; use Drupal\Core\Routing\RouteMatchInterface; -use Drupal\field\Entity\FieldInstanceConfig; use Drupal\node\NodeInterface; /** @@ -129,6 +129,14 @@ function content_translation_entity_type_alter(array &$entity_types) { } /** + * Implements hook_entity_base_field_info(). + */ +function content_translation_entity_base_field_info(EntityTypeInterface $entity_type) { + $entity_type_id = $entity_type->id(); + return content_translation_enabled($entity_type_id) ? content_translation_controller($entity_type_id)->getTranslationMetadataFieldDefinitions() : array(); +} + +/** * Implements hook_entity_bundle_info_alter(). */ function content_translation_entity_bundle_info_alter(&$bundles) { @@ -456,7 +464,8 @@ function content_translation_language_fallback_candidates_entity_view_alter(&$ca $current_user = \Drupal::currentuser(); if (!$current_user->hasPermission('translate any entity') && !$current_user->hasPermission($permission)) { foreach ($entity->getTranslationLanguages() as $langcode => $language) { - if (empty($entity->translation[$langcode]['status'])) { + $translation = $entity->getTranslation($langcode); + if (empty($translation->translation_status->value)) { unset($candidates[$langcode]); } } @@ -494,15 +503,19 @@ function content_translation_load_translation_metadata(array $entities, $entity_ $query = 'SELECT * FROM {content_translation} te WHERE te.entity_type = :entity_type AND te.entity_id IN (:entity_id)'; $result = db_query($query, array(':entity_type' => $entity_type, ':entity_id' => array_keys($entities))); $exclude = array('entity_type', 'entity_id', 'langcode'); + foreach ($result as $record) { $entity = $entities[$record->entity_id]; - // @todo Declare these as entity (translation?) properties. - foreach ($record as $field_name => $value) { - if (!in_array($field_name, $exclude)) { - $langcode = $record->langcode; - $entity->translation[$langcode][$field_name] = $value; - if (!$entity->hasTranslation($langcode)) { - $entity->initTranslation($langcode); + if ($entity instanceof ContentEntityInterface) { + foreach ($record as $key => $value) { + if (!in_array($key, $exclude)) { + $langcode = $record->langcode; + if (!$entity->hasTranslation($langcode)) { + $entity->initTranslation($langcode); + } + $name = 'translation_' . $key; + $item = $entity->getTranslation($langcode)->get($name); + $item->{$item[0]->getFieldDefinition()->getMainPropertyName()} = $value; } } } @@ -518,14 +531,27 @@ function content_translation_entity_insert(EntityInterface $entity) { return; } + $definitions = $entity->getFieldDefinitions(); $fields = array('entity_type', 'entity_id', 'langcode', 'source', 'outdated', 'uid', 'status', 'created', 'changed'); $query = db_insert('content_translation')->fields($fields); foreach ($entity->getTranslationLanguages() as $langcode => $language) { - $translation = isset($entity->translation[$langcode]) ? $entity->translation[$langcode] : array(); + $translation = $entity->getTranslation($langcode); + + $record = array(); + foreach ($fields as $key) { + $name = 'translation_' . $key; + if (isset($definitions[$name])) { + $items = $translation->get($name); + $property_name = $items[0]->mainPropertyName(); + if ($property_name && isset($items->{$property_name})) { + $record[$key] = $items->{$property_name}; + } + } + } - $translation += array( - 'source' => '', + $record += array( + 'source' => LanguageInterface::LANGCODE_NOT_SPECIFIED, 'uid' => \Drupal::currentUser()->id(), 'outdated' => FALSE, 'status' => TRUE, @@ -533,15 +559,14 @@ function content_translation_entity_insert(EntityInterface $entity) { 'changed' => REQUEST_TIME, ); - $translation['entity_type'] = $entity->getEntityTypeId(); - $translation['entity_id'] = $entity->id(); - $translation['langcode'] = $langcode; + $record['entity_type'] = $entity->getEntityTypeId(); + $record['entity_id'] = $entity->id(); + $record['langcode'] = $langcode; // Reorder values to match the schema. $values = array(); - foreach ($fields as $field_name) { - $value = is_bool($translation[$field_name]) ? intval($translation[$field_name]) : $translation[$field_name]; - $values[$field_name] = $value; + foreach ($fields as $key) { + $values[$key] = is_bool($record[$key]) ? intval($record[$key]) : $record[$key]; } $query->values($values); } @@ -636,14 +661,35 @@ function content_translation_form_field_ui_field_instance_edit_form_alter(array } /** + * Implements hook_entity_load(). + */ +function content_translation_entity_load(array $entities, $entity_type_id) { + if (content_translation_enabled($entity_type_id)) { + foreach ($entities as $entity) { + if ($entity instanceof ContentEntityInterface && $entity->isTranslatable()) { + if (!isset($handler)) { + $handler = content_translation_controller($entity_type_id); + } + $handler->entityLoad($entity); + } + } + } +} + +/** * Implements hook_entity_presave(). */ function content_translation_entity_presave(EntityInterface $entity) { - if ($entity instanceof ContentEntityInterface && $entity->isTranslatable()) { - // @todo Avoid using request attributes once translation metadata become - // regular fields. - $attributes = \Drupal::request()->attributes; - \Drupal::service('content_translation.synchronizer')->synchronizeFields($entity, $entity->language()->id, $attributes->get('source_langcode')); + if ($entity instanceof ContentEntityInterface && $entity->isTranslatable() && !$entity->isNew()) { + // If we are creating a new translation we need to use the source language + // as original language, since source values are the only ones available to + // compare against. + if (!isset($entity->original)) { + $entity->original = entity_load_unchanged($entity->entityType(), $entity->id()); + } + $langcode = $entity->language()->id; + $source_langcode = !$entity->original->hasTranslation($langcode) ? $entity->translation_source->id : NULL; + \Drupal::service('content_translation.synchronizer')->synchronizeFields($entity, $langcode, $source_langcode); } } diff --git a/core/modules/content_translation/src/ContentTranslationHandler.php b/core/modules/content_translation/src/ContentTranslationHandler.php index 60eb6f3..bd5451a 100644 --- a/core/modules/content_translation/src/ContentTranslationHandler.php +++ b/core/modules/content_translation/src/ContentTranslationHandler.php @@ -9,6 +9,7 @@ use Drupal\Core\Entity\EntityInterface; use Drupal\Core\Entity\EntityTypeInterface; +use Drupal\Core\Field\BaseFieldDefinition; use Drupal\Core\Form\FormStateInterface; use Drupal\Core\Language\LanguageInterface; use Drupal\Core\Render\Element; @@ -48,11 +49,73 @@ public function __construct(EntityTypeInterface $entity_type) { /** * {@inheritdoc} */ + public function getTranslationMetadataFieldDefinitions() { + $definitions = array(); + + $definitions['translation_source'] = BaseFieldDefinition::create('language') + ->setLabel(t('Translation source')) + ->setDescription(t('The source language from which this translation was created.')) + ->setCustomStorage(TRUE) + ->setTranslatable(TRUE); + + $definitions['translation_outdated'] = BaseFieldDefinition::create('boolean') + ->setLabel(t('Translation outdated')) + ->setDescription(t('A boolean indicating whether this translation needs to be updated.')) + ->setSettings(array( + 'default_value' => FALSE, + )) + ->setCustomStorage(TRUE) + ->setTranslatable(TRUE); + + $definitions['translation_uid'] = BaseFieldDefinition::create('entity_reference') + ->setLabel(t('Translation author')) + ->setDescription(t('The author of this translation.')) + ->setSettings(array( + 'target_type' => 'user', + 'default_value' => 0, + )) + ->setCustomStorage(TRUE) + ->setTranslatable(TRUE); + + $definitions['translation_status'] = BaseFieldDefinition::create('boolean') + ->setLabel(t('Translation status')) + ->setDescription(t('A boolean indicating whether the translation is visible to non-translators.')) + ->setSettings(array( + 'default_value' => TRUE, + )) + ->setCustomStorage(TRUE) + ->setTranslatable(TRUE); + + $definitions['translation_created'] = BaseFieldDefinition::create('created') + ->setLabel(t('Translation created time')) + ->setDescription(t('The Unix timestamp when the translation was created.')) + ->setCustomStorage(TRUE) + ->setTranslatable(TRUE); + + $definitions['translation_changed'] = BaseFieldDefinition::create('changed') + ->setLabel(t('Translation changed time')) + ->setDescription(t('The Unix timestamp when the translation was most recently saved.')) + ->setPropertyConstraints('value', array('EntityChanged' => array())) + ->setCustomStorage(TRUE) + ->setTranslatable(TRUE); + + return $definitions; + } + + /** + * {@inheritdoc} + */ + public function entityLoad(EntityInterface $entity) { + } + + /** + * {@inheritdoc} + */ public function retranslate(EntityInterface $entity, $langcode = NULL) { $updated_langcode = !empty($langcode) ? $langcode : $entity->language()->id; $translations = $entity->getTranslationLanguages(); foreach ($translations as $langcode => $language) { - $entity->translation[$langcode]['outdated'] = $langcode != $updated_langcode; + $entity->getTranslation($langcode)->translation_outdated->value = $langcode != $updated_langcode; } } @@ -193,7 +256,7 @@ public function entityFormAlter(array &$form, FormStateInterface $form_state, En ); // A new translation is enabled by default. - $status = $new_translation || $entity->translation[$form_langcode]['status']; + $status = $new_translation || $entity->translation_status->value; // If there is only one published translation we cannot unpublish it, // since there would be nothing left to display. $enabled = TRUE; @@ -204,8 +267,8 @@ public function entityFormAlter(array &$form, FormStateInterface $form_state, En // When creating a brand new translation, $entity->translation is not // set. if (!$new_translation) { - foreach ($entity->translation as $translation) { - $published += $translation['status']; + foreach ($entity->getTranslationLanguages() as $langcode => $language) { + $published += $entity->getTranslation($langcode)->translation_status->value; } } $enabled = $published > 1; @@ -222,7 +285,7 @@ public function entityFormAlter(array &$form, FormStateInterface $form_state, En '#disabled' => !$enabled, ); - $translate = !$new_translation && $entity->translation[$form_langcode]['outdated']; + $translate = !$new_translation && $entity->translation_outdated->value; if (!$translate) { $form['content_translation']['retranslate'] = array( '#type' => 'checkbox', @@ -245,8 +308,8 @@ public function entityFormAlter(array &$form, FormStateInterface $form_state, En if ($new_translation) { $name = \Drupal::currentUser()->getUsername(); } - elseif ($entity->translation[$form_langcode]['uid']) { - $name = user_load($entity->translation[$form_langcode]['uid'])->getUsername(); + elseif ($entity->translation_uid->target_id) { + $name = $entity->translation_uid->entity->getUsername(); } $form['content_translation']['name'] = array( '#type' => 'textfield', @@ -257,7 +320,7 @@ public function entityFormAlter(array &$form, FormStateInterface $form_state, En '#description' => t('Leave blank for %anonymous.', array('%anonymous' => \Drupal::config('user.settings')->get('anonymous'))), ); - $date = $new_translation ? REQUEST_TIME : $entity->translation[$form_langcode]['created']; + $date = $new_translation ? REQUEST_TIME : $entity->translation_created->value; $form['content_translation']['created'] = array( '#type' => 'textfield', '#title' => t('Authored on'), @@ -379,35 +442,22 @@ protected function addTranslatabilityClue(&$element) { public function entityFormEntityBuild($entity_type, EntityInterface $entity, array $form, FormStateInterface $form_state) { $form_object = $form_state->getFormObject(); $form_langcode = $form_object->getFormLangcode($form_state); - - if (!isset($entity->translation[$form_langcode])) { - $entity->translation[$form_langcode] = array(); - } $values = $form_state->getValue('content_translation', array()); - $translation = &$entity->translation[$form_langcode]; - // @todo Use the entity setter when all entities support multilingual - // properties. - $translation['uid'] = !empty($values['name']) && ($account = user_load_by_name($values['name'])) ? $account->id() : 0; - $translation['status'] = !empty($values['status']); - $translation['created'] = !empty($values['created']) ? strtotime($values['created']) : REQUEST_TIME; - $translation['changed'] = REQUEST_TIME; + $entity->translation_uid->target_id = !empty($values['name']) && ($account = user_load_by_name($values['name'])) ? $account->id() : 0; + $entity->translation_status->value = !empty($values['status']); + $entity->translation_created->value = !empty($values['created']) ? strtotime($values['created']) : REQUEST_TIME; + $entity->translation_changed->value = REQUEST_TIME; $source_langcode = $this->getSourceLangcode($form_state); if ($source_langcode) { - $translation['source'] = $source_langcode; + $entity->translation_source->value = $source_langcode; } - $translation['outdated'] = !empty($values['outdated']); + $entity->translation_outdated->value = !empty($values['outdated']); if (!empty($values['retranslate'])) { $this->retranslate($entity, $form_langcode); } - - // Set contextual information that can be reused during the storage phase. - // @todo Remove this once translation metadata are converted to regular - // fields. - $attributes = \Drupal::request()->attributes; - $attributes->set('source_langcode', $source_langcode); } /** diff --git a/core/modules/content_translation/src/ContentTranslationHandlerInterface.php b/core/modules/content_translation/src/ContentTranslationHandlerInterface.php index 8d3d725..e5c96ef 100644 --- a/core/modules/content_translation/src/ContentTranslationHandlerInterface.php +++ b/core/modules/content_translation/src/ContentTranslationHandlerInterface.php @@ -19,6 +19,20 @@ interface ContentTranslationHandlerInterface { /** + * TODO + * + * @return \Drupal\Core\Field\BaseFieldDefinition[] + */ + public function getTranslationMetadataFieldDefinitions(); + + /** + * TODO + * + * @param EntityInterface $entity + */ + public function entityLoad(EntityInterface $entity); + + /** * Checks if the user can perform the given operation on translations of the * wrapped entity. * diff --git a/core/modules/content_translation/src/Controller/ContentTranslationController.php b/core/modules/content_translation/src/Controller/ContentTranslationController.php index 5f2c460..f780b73 100644 --- a/core/modules/content_translation/src/Controller/ContentTranslationController.php +++ b/core/modules/content_translation/src/Controller/ContentTranslationController.php @@ -46,6 +46,7 @@ public function prepareTranslation(ContentEntityInterface $entity, LanguageInter * Array of page elements to render. */ public function overview(Request $request, $entity_type_id = NULL) { + /** @var \Drupal\Core\Entity\ContentEntityInterface $entity */ $entity = $request->attributes->get($entity_type_id); $account = $this->currentUser(); $handler = $this->entityManager()->getHandler($entity_type_id, 'translation'); @@ -69,8 +70,9 @@ public function overview(Request $request, $entity_type_id = NULL) { } // Show source-language column if there are non-original source langcodes. - $additional_source_langcodes = array_filter($entity->translation, function ($translation) use ($original) { - return !empty($translation['source']) && $translation['source'] != $original; + $additional_source_langcodes = array_filter(array_keys($translations), function ($langcode) use ($entity, $original) { + $translation = $entity->getTranslation($langcode); + return $translation->translation_source->value != $original; }); $show_source_column = !empty($additional_source_langcodes); @@ -119,7 +121,8 @@ public function overview(Request $request, $entity_type_id = NULL) { $links = &$operations['data']['#links']; if (array_key_exists($langcode, $translations)) { // Existing translation in the translation set: display status. - $source = isset($entity->translation[$langcode]['source']) ? $entity->translation[$langcode]['source'] : ''; + $translation = $entity->getTranslation($langcode); + $source = isset($translation->translation_source) ? $translation->translation_source->value : LanguageInterface::LANGCODE_NOT_SPECIFIED; $is_original = $langcode == $original; $label = $entity->getTranslation($langcode)->label(); $link = isset($links->links[$langcode]['href']) ? $links->links[$langcode] : array('href' => $entity->getSystemPath()); @@ -146,13 +149,12 @@ public function overview(Request $request, $entity_type_id = NULL) { if (isset($links['edit'])) { $links['edit']['title'] = $this->t('Edit'); } - $translation = $entity->translation[$langcode]; $status = array('data' => array( '#type' => 'inline_template', '#template' => '{% if status %}{{ "Published"|t }}{% else %}{{ "Not published"|t }}{% endif %}{% if outdated %} {{ "outdated"|t }}{% endif %}', '#context' => array( - 'status' => $translation['status'], - 'outdated' => $translation['outdated'], + 'status' => $translation->translation_status->value, + 'outdated' => $translation->translation_outdated->value, ), )); diff --git a/core/modules/content_translation/src/Tests/ContentTranslationSyncImageTest.php b/core/modules/content_translation/src/Tests/ContentTranslationSyncImageTest.php index 5783ed8..301ac26 100644 --- a/core/modules/content_translation/src/Tests/ContentTranslationSyncImageTest.php +++ b/core/modules/content_translation/src/Tests/ContentTranslationSyncImageTest.php @@ -117,10 +117,6 @@ function testImageFieldSync() { $default_langcode = $this->langcodes[0]; $langcode = $this->langcodes[1]; - // Populate the required contextual values. - $attributes = \Drupal::request()->attributes; - $attributes->set('source_langcode', $default_langcode); - // Populate the test entity with some random initial values. $values = array( 'name' => $this->randomMachineName(), @@ -188,6 +184,7 @@ function testImageFieldSync() { // Perform synchronization: the translation language is used as source, // while the default language is used as target. + $translation->translation_source->id = $default_langcode; $entity = $this->saveEntity($translation); $translation = $entity->getTranslation($langcode); @@ -217,8 +214,6 @@ function testImageFieldSync() { 'title' => $langcode . '_' . $removed_fid . '_' . $this->randomMachineName(), ); $translation->{$this->fieldName}->setValue(array_values($values[$langcode])); - // When updating an entity we do not have a source language defined. - $attributes->remove('source_langcode'); $entity = $this->saveEntity($translation); $translation = $entity->getTranslation($langcode); diff --git a/core/modules/content_translation/src/Tests/ContentTranslationUITest.php b/core/modules/content_translation/src/Tests/ContentTranslationUITest.php index 58d0c59..7c91943 100644 --- a/core/modules/content_translation/src/Tests/ContentTranslationUITest.php +++ b/core/modules/content_translation/src/Tests/ContentTranslationUITest.php @@ -160,7 +160,7 @@ protected function doTestOutdatedStatus() { $this->drupalGet($path); $this->assertFieldByXPath('//input[@name="content_translation[retranslate]"]', FALSE, 'The retranslate flag is now shown.'); $entity = entity_load($this->entityTypeId, $this->entityId, TRUE); - $this->assertFalse($entity->translation[$added_langcode]['outdated'], 'The "outdated" status has been correctly stored.'); + $this->assertFalse($entity->getTranslation($added_langcode)->translation_outdated->value, 'The "outdated" status has been correctly stored.'); } } } @@ -178,7 +178,7 @@ protected function doTestPublishedStatus() { $edit = array('content_translation[status]' => FALSE); $this->drupalPostForm($langcode . '/' . $path, $edit, $this->getFormSubmitAction($entity, $langcode)); $entity = entity_load($this->entityTypeId, $this->entityId, TRUE); - $this->assertFalse($entity->translation[$langcode]['status'], 'The translation has been correctly unpublished.'); + $this->assertFalse($entity->getTranslation($langcode)->translation_status->value, 'The translation has been correctly unpublished.'); } } @@ -212,8 +212,9 @@ protected function doTestAuthoringInfo() { $entity = entity_load($this->entityTypeId, $this->entityId, TRUE); foreach ($this->langcodes as $langcode) { - $this->assertEqual($entity->translation[$langcode]['uid'], $values[$langcode]['uid'], 'Translation author correctly stored.'); - $this->assertEqual($entity->translation[$langcode]['created'], $values[$langcode]['created'], 'Translation date correctly stored.'); + $translation = $entity->getTranslation($langcode); + $this->assertEqual($translation->translation_uid->target_id == $values[$langcode]['uid'], 'Translation author correctly stored.'); + $this->assertEqual($translation->translation_created->value == $values[$langcode]['created'], 'Translation date correctly stored.'); } // Try to post non valid values and check that they are rejected. @@ -225,8 +226,9 @@ protected function doTestAuthoringInfo() { ); $this->drupalPostForm($path, $edit, $this->getFormSubmitAction($entity, $langcode)); $this->assertTrue($this->xpath('//div[contains(@class, "error")]//ul'), 'Invalid values generate a list of form errors.'); - $this->assertEqual($entity->translation[$langcode]['uid'], $values[$langcode]['uid'], 'Translation author correctly kept.'); - $this->assertEqual($entity->translation[$langcode]['created'], $values[$langcode]['created'], 'Translation date correctly kept.'); + $translation = $entity->getTranslation($langcode); + $this->assertEqual($translation->translation_uid->target_id == $values[$langcode]['uid'], 'Translation author correctly kept.'); + $this->assertEqual($translation->translation_created->value == $values[$langcode]['created'], 'Translation date correctly kept.'); } /** diff --git a/core/modules/node/src/NodeTranslationHandler.php b/core/modules/node/src/NodeTranslationHandler.php index 1b27e84..4b702b8 100644 --- a/core/modules/node/src/NodeTranslationHandler.php +++ b/core/modules/node/src/NodeTranslationHandler.php @@ -19,6 +19,35 @@ class NodeTranslationHandler extends ContentTranslationHandler { /** * {@inheritdoc} */ + public function getTranslationMetadataFieldDefinitions() { + $definitions = parent::getTranslationMetadataFieldDefinitions(); + + // TODO + $computed_keys = array('uid', 'status', 'created', 'changed'); + foreach ($computed_keys as $key) { + $computed_key = 'translation_' . $key; + $definitions[$computed_key]->setComputed(TRUE); + $definitions[$computed_key]->setCustomStorage(TRUE); + $definitions[$computed_key]->setQueryable(FALSE); + } + + return $definitions; + } + + /** + * {@inheritdoc} + */ + public function entityLoad(EntityInterface $node) { + $computed_fields = array('uid', 'status', 'created', 'changed'); + foreach ($computed_fields as $field_name) { + $computed_field_name = 'translation_' . $field_name; + $node->setItems($computed_field_name, $node->{$field_name}); + } + } + + /** + * {@inheritdoc} + */ public function entityFormAlter(array &$form, FormStateInterface $form_state, EntityInterface $entity) { parent::entityFormAlter($form, $form_state, $entity); diff --git a/core/modules/node/src/Tests/NodeTranslationUITest.php b/core/modules/node/src/Tests/NodeTranslationUITest.php index 59416a3..75ff7bf 100644 --- a/core/modules/node/src/Tests/NodeTranslationUITest.php +++ b/core/modules/node/src/Tests/NodeTranslationUITest.php @@ -126,7 +126,7 @@ protected function doTestPublishedStatus() { // The node is created as unpublished thus we switch to the published // status first. $status = !$index; - $this->assertEqual($status, $entity->translation[$langcode]['status'], 'The translation has been correctly unpublished.'); + $this->assertEqual($status, $entity->getTranslation($langcode)->translation_status->value, 'The translation has been correctly unpublished.'); $translation = $entity->getTranslation($langcode); $this->assertEqual($status, $translation->isPublished(), 'The status of the translation has been correctly saved.'); } @@ -163,9 +163,9 @@ protected function doTestAuthoringInfo() { $entity = entity_load($this->entityTypeId, $this->entityId, TRUE); foreach ($this->langcodes as $langcode) { - $this->assertEqual($entity->translation[$langcode]['uid'], $values[$langcode]['uid'], 'Translation author correctly stored.'); - $this->assertEqual($entity->translation[$langcode]['created'], $values[$langcode]['created'], 'Translation date correctly stored.'); $translation = $entity->getTranslation($langcode); + $this->assertEqual($translation->translation_uid->target_id, $values[$langcode]['uid'], 'Translation author correctly stored.'); + $this->assertEqual($translation->translation_created->value, $values[$langcode]['created'], 'Translation date correctly stored.'); $this->assertEqual($translation->getOwnerId(), $values[$langcode]['uid'], 'Author of translation correctly stored.'); $this->assertEqual($translation->getCreatedTime(), $values[$langcode]['created'], 'Date of Translation correctly stored.'); $this->assertEqual($translation->isSticky(), $values[$langcode]['sticky'], 'Sticky of Translation correctly stored.');