diff --git a/core/lib/Drupal/Core/Entity/ContentEntityBase.php b/core/lib/Drupal/Core/Entity/ContentEntityBase.php index f2c8436..5a91ef9 100644 --- a/core/lib/Drupal/Core/Entity/ContentEntityBase.php +++ b/core/lib/Drupal/Core/Entity/ContentEntityBase.php @@ -737,21 +737,18 @@ public function getTranslation($langcode) { if (isset($this->translations[$langcode]['entity'])) { $translation = $this->translations[$langcode]['entity']; } + // Otherwise if an existing language was specified instantiate it. + elseif (isset($this->translations[$langcode])) { + $translation = $this->initializeTranslation($langcode); + $this->translations[$langcode]['entity'] = $translation; + } + // If the entity or the requested language is not a configured language, we + // fall back to the original entity itself, since in this case we are not + // dealing with a translation. else { - if (isset($this->translations[$langcode])) { - $translation = $this->initializeTranslation($langcode); - $this->translations[$langcode]['entity'] = $translation; - } - else { - // If we were given a valid language and there is no translation for it, - // we return a new one. - $this->getLanguages(); - if (isset($this->languages[$langcode])) { - // If the entity or the requested language is not a configured - // language, we fall back to the entity itself, since in this case it - // cannot have translations. - $translation = !$this->languages[$this->defaultLangcode]->isLocked() && !$this->languages[$langcode]->isLocked() ? $this->addTranslation($langcode) : $this; - } + $this->getLanguages(); + if (isset($this->languages[$langcode]) && ($this->languages[$this->defaultLangcode]->isLocked() || $this->languages[$langcode]->isLocked())) { + $translation = $this->getUntranslated(); } } diff --git a/core/lib/Drupal/Core/Entity/ContentEntityForm.php b/core/lib/Drupal/Core/Entity/ContentEntityForm.php index eed3cac..d29ae3a 100644 --- a/core/lib/Drupal/Core/Entity/ContentEntityForm.php +++ b/core/lib/Drupal/Core/Entity/ContentEntityForm.php @@ -173,7 +173,7 @@ protected function init(FormStateInterface $form_state) { // language. $this->initFormLangcodes($form_state); $langcode = $this->getFormLangcode($form_state); - $this->entity = $this->entity->getTranslation($langcode); + $this->entity = $this->entity->hasTranslation($langcode) ? $this->entity->getTranslation($langcode) : $this->entity->addTranslation($langcode); $form_display = EntityFormDisplay::collectRenderDisplay($this->entity, $this->getOperation()); $this->setFormDisplay($form_display, $form_state); diff --git a/core/modules/content_translation/src/Tests/ContentTranslationSyncImageTest.php b/core/modules/content_translation/src/Tests/ContentTranslationSyncImageTest.php index 606b5b3..56b1ed5 100644 --- a/core/modules/content_translation/src/Tests/ContentTranslationSyncImageTest.php +++ b/core/modules/content_translation/src/Tests/ContentTranslationSyncImageTest.php @@ -160,7 +160,7 @@ function testImageFieldSync() { // items will be one less than the original values to check that only the // translated ones will be preserved. In fact we want the same fids and // items order for both languages. - $translation = $entity->getTranslation($langcode); + $translation = $entity->addTranslation($langcode); for ($delta = 0; $delta < $this->cardinality - 1; $delta++) { // Simulate a field reordering: items are shifted of one position ahead. // The modulo operator ensures we start from the beginning after reaching diff --git a/core/modules/field/src/Tests/TranslationTest.php b/core/modules/field/src/Tests/TranslationTest.php index d73beaf..8328951 100644 --- a/core/modules/field/src/Tests/TranslationTest.php +++ b/core/modules/field/src/Tests/TranslationTest.php @@ -124,7 +124,8 @@ function testTranslatableFieldSaveLoad() { $entity->langcode->value = reset($available_langcodes); foreach ($available_langcodes as $langcode) { $field_translations[$langcode] = $this->_generateTestFieldValues($this->fieldStorage->getCardinality()); - $entity->getTranslation($langcode)->{$this->fieldName}->setValue($field_translations[$langcode]); + $translation = $entity->hasTranslation($langcode) ? $entity->getTranslation($langcode) : $entity->addTranslation($langcode); + $translation->{$this->fieldName}->setValue($field_translations[$langcode]); } // Save and reload the field translations. @@ -160,7 +161,8 @@ function testTranslatableFieldSaveLoad() { $entity = entity_create($entity_type_id, $values); foreach ($translation_langcodes as $langcode) { $values[$this->fieldName][$langcode] = $this->_generateTestFieldValues($this->fieldStorage->getCardinality()); - $entity->getTranslation($langcode, FALSE)->{$this->fieldName}->setValue($values[$this->fieldName][$langcode]); + $translation = $entity->hasTranslation($langcode) ? $entity->getTranslation($langcode) : $entity->addTranslation($langcode); + $translation->{$this->fieldName}->setValue($values[$this->fieldName][$langcode]); } $field_langcodes = array_keys($entity->getTranslationLanguages()); @@ -178,8 +180,9 @@ function testTranslatableFieldSaveLoad() { $entity = entity_create($entity_type_id, $values); foreach ($translation_langcodes as $langcode) { $values[$this->fieldName][$langcode] = $this->_generateTestFieldValues($this->fieldStorage->getCardinality()); - $entity->getTranslation($langcode)->{$this->fieldName}->setValue($values[$this->fieldName][$langcode]); - $entity->getTranslation($langcode)->{$field_name_default}->setValue($empty_items); + $translation = $entity->hasTranslation($langcode) ? $entity->getTranslation($langcode) : $entity->addTranslation($langcode); + $translation->{$this->fieldName}->setValue($values[$this->fieldName][$langcode]); + $translation->{$field_name_default}->setValue($empty_items); $values[$field_name_default][$langcode] = $empty_items; } diff --git a/core/modules/field/src/Tests/TranslationWebTest.php b/core/modules/field/src/Tests/TranslationWebTest.php index 326692d..4aa8c48 100644 --- a/core/modules/field/src/Tests/TranslationWebTest.php +++ b/core/modules/field/src/Tests/TranslationWebTest.php @@ -104,7 +104,8 @@ function testFieldFormTranslationRevisions() { ksort($available_langcodes); $entity->langcode->value = key($available_langcodes); foreach ($available_langcodes as $langcode => $value) { - $entity->getTranslation($langcode)->{$field_name}->value = $value + 1; + $translation = $entity->hasTranslation($langcode) ? $entity->getTranslation($langcode) : $entity->addTranslation($langcode); + $translation->{$field_name}->value = $value + 1; } $entity->save(); diff --git a/core/modules/file/src/Plugin/Field/FieldType/FileFieldItemList.php b/core/modules/file/src/Plugin/Field/FieldType/FileFieldItemList.php index 90dcaa9..d28d26f 100644 --- a/core/modules/file/src/Plugin/Field/FieldType/FileFieldItemList.php +++ b/core/modules/file/src/Plugin/Field/FieldType/FileFieldItemList.php @@ -54,7 +54,9 @@ public function postSave($update) { // Get the file IDs attached to the field before this update. $field_name = $this->getFieldDefinition()->getName(); $original_ids = array(); - $original_items = $entity->original->getTranslation($this->getLangcode())->$field_name; + $langcode = $this->getLangcode(); + $original = $entity->original; + $original_items = $original->hasTranslation($langcode) ? $original->getTranslation($langcode)->{$field_name} : $original->{$field_name}; foreach ($original_items as $item) { $original_ids[] = $item->target_id; } diff --git a/core/modules/hal/src/Normalizer/FieldItemNormalizer.php b/core/modules/hal/src/Normalizer/FieldItemNormalizer.php index 53c544c..0f7ef6f 100644 --- a/core/modules/hal/src/Normalizer/FieldItemNormalizer.php +++ b/core/modules/hal/src/Normalizer/FieldItemNormalizer.php @@ -107,7 +107,8 @@ protected function createTranslatedInstance(FieldItemInterface $item, $langcode) unset($items[$delta]); // Instead, create a new item for the entity in the requested language. - $entity_translation = $item->getEntity()->getTranslation($langcode); + $entity = $item->getEntity(); + $entity_translation = $entity->hasTranslation($langcode) ? $entity->getTranslation($langcode) : $entity->addTranslation($langcode); $field_name = $item->getFieldDefinition()->getName(); return $entity_translation->get($field_name)->appendItem(); } diff --git a/core/modules/hal/src/Tests/NormalizeTest.php b/core/modules/hal/src/Tests/NormalizeTest.php index 44d7f24..0f24d73 100644 --- a/core/modules/hal/src/Tests/NormalizeTest.php +++ b/core/modules/hal/src/Tests/NormalizeTest.php @@ -58,7 +58,7 @@ public function testNormalize() { $entity = entity_create('entity_test', $values); $entity->save(); // Add an English value for name and entity reference properties. - $entity->getTranslation('en')->set('name', array(0 => array('value' => $translation_values['name']))); + $entity->addTranslation('en')->set('name', array(0 => array('value' => $translation_values['name']))); $entity->getTranslation('en')->set('field_test_entity_reference', array(0 => $translation_values['field_test_entity_reference'])); $entity->save(); diff --git a/core/modules/node/src/NodeAccessControlHandler.php b/core/modules/node/src/NodeAccessControlHandler.php index f655a5e..1d29b39 100644 --- a/core/modules/node/src/NodeAccessControlHandler.php +++ b/core/modules/node/src/NodeAccessControlHandler.php @@ -100,7 +100,8 @@ public function createAccess($entity_bundle = NULL, AccountInterface $account = protected function checkAccess(EntityInterface $node, $operation, $langcode, AccountInterface $account) { /** @var \Drupal\node\NodeInterface $node */ /** @var \Drupal\node\NodeInterface $translation */ - $translation = $node->getTranslation($langcode); + $translation = $node->hasTranslation($langcode) ? $node->getTranslation($langcode) : $node; + // Fetch information from the node object if possible. $status = $translation->isPublished(); $uid = $translation->getOwnerId(); diff --git a/core/modules/node/src/Tests/NodeAccessLanguageAwareCombinationTest.php b/core/modules/node/src/Tests/NodeAccessLanguageAwareCombinationTest.php index d60cf6f..afa5368 100644 --- a/core/modules/node/src/Tests/NodeAccessLanguageAwareCombinationTest.php +++ b/core/modules/node/src/Tests/NodeAccessLanguageAwareCombinationTest.php @@ -110,7 +110,7 @@ protected function setUp() { 'field_private' => array(array('value' => 0)), 'private' => FALSE, )); - $translation = $node->getTranslation('ca'); + $translation = $node->addTranslation('ca'); $translation->title->value = $this->randomString(); $translation->field_private->value = 0; $node->save(); @@ -121,7 +121,7 @@ protected function setUp() { 'field_private' => array(array('value' => 0)), 'private' => TRUE, )); - $translation = $node->getTranslation('ca'); + $translation = $node->addTranslation('ca'); $translation->title->value = $this->randomString(); $translation->field_private->value = 0; $node->save(); @@ -132,7 +132,7 @@ protected function setUp() { 'field_private' => array(array('value' => 1)), 'private' => FALSE, )); - $translation = $node->getTranslation('ca'); + $translation = $node->addTranslation('ca'); $translation->title->value = $this->randomString(); $translation->field_private->value = 0; $node->save(); @@ -143,7 +143,7 @@ protected function setUp() { 'field_private' => array(array('value' => 0)), 'private' => FALSE, )); - $translation = $node->getTranslation('ca'); + $translation = $node->addTranslation('ca'); $translation->title->value = $this->randomString(); $translation->field_private->value = 1; $node->save(); @@ -154,7 +154,7 @@ protected function setUp() { 'field_private' => array(array('value' => 1)), 'private' => FALSE, )); - $translation = $node->getTranslation('ca'); + $translation = $node->addTranslation('ca'); $translation->title->value = $this->randomString(); $translation->field_private->value = 1; $node->save(); @@ -165,7 +165,7 @@ protected function setUp() { 'field_private' => array(array('value' => 1)), 'private' => TRUE, )); - $translation = $node->getTranslation('ca'); + $translation = $node->addTranslation('ca'); $translation->title->value = $this->randomString(); $translation->field_private->value = 1; $node->save(); diff --git a/core/modules/system/src/Tests/Entity/ContentEntityChangedTest.php b/core/modules/system/src/Tests/Entity/ContentEntityChangedTest.php index daa85be..6f7e692 100644 --- a/core/modules/system/src/Tests/Entity/ContentEntityChangedTest.php +++ b/core/modules/system/src/Tests/Entity/ContentEntityChangedTest.php @@ -422,7 +422,7 @@ public function testRevisionChanged() { 'Changed flag of German translation is set when changing the German translation.' ); - $french = $entity->getTranslation('fr'); + $french = $entity->addTranslation('fr'); $entity->setNewRevision(); $entity->save(); diff --git a/core/modules/system/src/Tests/Entity/EntityAccessControlHandlerTest.php b/core/modules/system/src/Tests/Entity/EntityAccessControlHandlerTest.php index a048150..ab73ee1 100644 --- a/core/modules/system/src/Tests/Entity/EntityAccessControlHandlerTest.php +++ b/core/modules/system/src/Tests/Entity/EntityAccessControlHandlerTest.php @@ -137,7 +137,7 @@ function testEntityTranslationAccess() { )); $entity->save(); - $translation = $entity->getTranslation('bar'); + $translation = $entity->addTranslation('bar'); $this->assertEntityAccess(array( 'view' => TRUE, ), $translation); diff --git a/core/modules/system/src/Tests/Entity/EntityQueryTest.php b/core/modules/system/src/Tests/Entity/EntityQueryTest.php index 4130804..3124f54 100644 --- a/core/modules/system/src/Tests/Entity/EntityQueryTest.php +++ b/core/modules/system/src/Tests/Entity/EntityQueryTest.php @@ -130,7 +130,7 @@ protected function setUp() { )); // Make sure the name is set for every language that we might create. foreach (array('tr', 'pl') as $langcode) { - $entity->getTranslation($langcode)->name = $this->randomMachineName(); + $entity->addTranslation($langcode)->name = $this->randomMachineName(); } foreach (array_reverse(str_split(decbin($i))) as $key => $bit) { if ($bit) { diff --git a/core/modules/system/src/Tests/Entity/EntityTranslationFormTest.php b/core/modules/system/src/Tests/Entity/EntityTranslationFormTest.php index 4ff9f22..805f682 100644 --- a/core/modules/system/src/Tests/Entity/EntityTranslationFormTest.php +++ b/core/modules/system/src/Tests/Entity/EntityTranslationFormTest.php @@ -106,9 +106,10 @@ function testEntityFormLanguage() { // Create a body translation and check the form language. $langcode2 = $this->langcodes[1]; - $node->getTranslation($langcode2)->title->value = $this->randomString(); - $node->getTranslation($langcode2)->body->value = $this->randomMachineName(16); - $node->getTranslation($langcode2)->setOwnerId($web_user->id()); + $translation = $node->addTranslation($langcode2); + $translation->title->value = $this->randomString(); + $translation->body->value = $this->randomMachineName(16); + $translation->setOwnerId($web_user->id()); $node->save(); $this->drupalGet($langcode2 . '/node/' . $node->id() . '/edit'); $form_langcode = \Drupal::state()->get('entity_test.form_langcode'); diff --git a/core/modules/system/src/Tests/Entity/EntityTranslationTest.php b/core/modules/system/src/Tests/Entity/EntityTranslationTest.php index 21ff392..55e3050 100644 --- a/core/modules/system/src/Tests/Entity/EntityTranslationTest.php +++ b/core/modules/system/src/Tests/Entity/EntityTranslationTest.php @@ -8,7 +8,6 @@ namespace Drupal\system\Tests\Entity; use Drupal\Component\Utility\SafeMarkup; -use Drupal\Core\Entity\ContentEntityInterface; use Drupal\Core\Language\LanguageInterface; use Drupal\entity_test\Entity\EntityTestMulRev; use Drupal\language\Entity\ConfigurableLanguage; @@ -87,7 +86,7 @@ protected function doTestEntityLanguageMethods($entity_type) { $this->assertEqual($field->getLangcode(), $default_langcode, format_string('%entity_type: Field object has the expected langcode.', array('%entity_type' => $entity_type))); // Set a translation. - $entity->getTranslation($this->langcodes[1])->set($this->fieldName, array(0 => array('value' => 'translation 1'))); + $entity->addTranslation($this->langcodes[1])->set($this->fieldName, array(0 => array('value' => 'translation 1'))); $field = $entity->getTranslation($this->langcodes[1])->{$this->fieldName}; $this->assertEqual($field->value, 'translation 1', format_string('%entity_type: Translated value set.', array('%entity_type' => $entity_type))); $this->assertEqual($field->getLangcode(), $this->langcodes[1], format_string('%entity_type: Field object has the expected langcode.', array('%entity_type' => $entity_type))); @@ -100,16 +99,27 @@ protected function doTestEntityLanguageMethods($entity_type) { $translations[$this->langcodes[1]] = \Drupal::languageManager()->getLanguage($this->langcodes[1]); $this->assertEqual($entity->getTranslationLanguages(FALSE), $translations, 'Translations retrieved.'); + // Try to get a value using a language code for a non-existing translation. + $message = 'Getting a non existing translation results in an error.'; + try { + $entity->getTranslation($this->langcodes[2])->get($this->fieldName)->value; + $this->fail($message); + } + catch (\InvalidArgumentException $e) { + $this->pass($message); + } + // Try to get a not available translation. - $this->assertNull($entity->getTranslation($this->langcodes[2])->get($this->fieldName)->value, format_string('%entity_type: A translation that is not available is NULL.', array('%entity_type' => $entity_type))); + $this->assertNull($entity->addTranslation($this->langcodes[2])->get($this->fieldName)->value, format_string('%entity_type: A translation that is not available is NULL.', array('%entity_type' => $entity_type))); // Try to get a value using an invalid language code. + $message = 'Getting an invalid translation results in an error.'; try { $entity->getTranslation('invalid')->get($this->fieldName)->value; - $this->fail('Getting a translation for an invalid language is NULL.'); + $this->fail($message); } catch (\InvalidArgumentException $e) { - $this->pass('A translation for an invalid language is NULL.'); + $this->pass($message); } // Try to set a value using an invalid language code. @@ -164,10 +174,11 @@ protected function doTestMultilingualProperties($entity_type) { $this->assertEqual($name, $field->value, format_string('%entity_type: The entity name has been correctly stored as language neutral.', array('%entity_type' => $entity_type))); $this->assertEqual($default_langcode, $field->getLangcode(), format_string('%entity_type: The field object has the expect langcode.', array('%entity_type' => $entity_type))); $this->assertEqual($uid, $entity->getTranslation(LanguageInterface::LANGCODE_DEFAULT)->get('user_id')->target_id, format_string('%entity_type: The entity author has been correctly stored as language neutral.', array('%entity_type' => $entity_type))); - $field = $entity->getTranslation($langcode)->get('name'); + $translation = $entity->getTranslation($langcode); + $field = $translation->get('name'); $this->assertEqual($name, $field->value, format_string('%entity_type: The entity name defaults to neutral language.', array('%entity_type' => $entity_type))); $this->assertEqual($default_langcode, $field->getLangcode(), format_string('%entity_type: The field object has the expect langcode.', array('%entity_type' => $entity_type))); - $this->assertEqual($uid, $entity->getTranslation($langcode)->get('user_id')->target_id, format_string('%entity_type: The entity author defaults to neutral language.', array('%entity_type' => $entity_type))); + $this->assertEqual($uid, $translation->get('user_id')->target_id, format_string('%entity_type: The entity author defaults to neutral language.', array('%entity_type' => $entity_type))); $field = $entity->get('name'); $this->assertEqual($name, $field->value, format_string('%entity_type: The entity name can be retrieved without specifying a language.', array('%entity_type' => $entity_type))); $this->assertEqual($default_langcode, $field->getLangcode(), format_string('%entity_type: The field object has the expect langcode.', array('%entity_type' => $entity_type))); @@ -211,7 +222,7 @@ protected function doTestMultilingualProperties($entity_type) { 'user_id' => array(0 => $uid), ); } - $translation = $entity->getTranslation($langcode); + $translation = $entity->hasTranslation($langcode) ? $entity->getTranslation($langcode) : $entity->addTranslation($langcode); foreach ($properties[$langcode] as $field_name => $values) { $translation->set($field_name, $values); } @@ -416,7 +427,7 @@ protected function doTestEntityTranslationAPI($entity_type) { // new translation object can be obtained also by just specifying a valid // language. $langcode2 = $this->langcodes[2]; - $translation = $entity->getTranslation($langcode2); + $translation = $entity->addTranslation($langcode2); $value = $entity !== $translation && $translation->language()->getId() == $langcode2 && $entity->hasTranslation($langcode2); $this->assertTrue($value, 'A new translation object can be obtained also by specifying a valid language.'); $this->assertEqual($entity->language()->getId(), $default_langcode, 'The original language has been preserved.'); diff --git a/core/modules/views/src/Tests/Entity/FieldEntityTranslationTest.php b/core/modules/views/src/Tests/Entity/FieldEntityTranslationTest.php index f83199c..8e4515a 100644 --- a/core/modules/views/src/Tests/Entity/FieldEntityTranslationTest.php +++ b/core/modules/views/src/Tests/Entity/FieldEntityTranslationTest.php @@ -70,7 +70,7 @@ public function testTranslationRows() { ]); $node->save(); - $translation = $node->getTranslation('es'); + $translation = $node->addTranslation('es'); $translation->title->value = 'example ES'; $translation->sticky->value = true; $translation->save();