Commit a469aa22 authored by catch's avatar catch

Issue #2666032 by hchonov, Gábor Hojtsy, mkalkbrenner: Add...

Issue #2666032 by hchonov, Gábor Hojtsy, mkalkbrenner: Add TranslationStatusInterface to ask for the status of an entity translation and fix statuses in ContentEntityBase
parent 2f7924b3
......@@ -9,6 +9,7 @@
use Drupal\Core\Language\LanguageInterface;
use Drupal\Core\Session\AccountInterface;
use Drupal\Core\StringTranslation\TranslatableMarkup;
use Drupal\Core\TypedData\TranslationStatusInterface;
use Drupal\Core\TypedData\TypedDataInterface;
/**
......@@ -16,22 +17,7 @@
*
* @ingroup entity_api
*/
abstract class ContentEntityBase extends Entity implements \IteratorAggregate, ContentEntityInterface {
/**
* Status code identifying a removed translation.
*/
const TRANSLATION_REMOVED = 0;
/**
* Status code identifying an existing translation.
*/
const TRANSLATION_EXISTING = 1;
/**
* Status code identifying a newly created translation.
*/
const TRANSLATION_CREATED = 2;
abstract class ContentEntityBase extends Entity implements \IteratorAggregate, ContentEntityInterface, TranslationStatusInterface {
/**
* The plain data values of the contained fields.
......@@ -220,7 +206,10 @@ public function __construct(array $values, $entity_type, $bundle = FALSE, $trans
// Initialize translations. Ensure we have at least an entry for the default
// language.
$data = array('status' => static::TRANSLATION_EXISTING);
// We determine if the entity is new by checking in the entity values for
// the presence of the id entity key, as the usage of ::isNew() is not
// possible in the constructor.
$data = isset($values[$this->getEntityType()->getKey('id')]) ? ['status' => static::TRANSLATION_EXISTING] : ['status' => static::TRANSLATION_CREATED];
$this->translations[LanguageInterface::LANGCODE_DEFAULT] = $data;
$this->setDefaultLangcode();
if ($translations) {
......@@ -365,6 +354,25 @@ public function preSave(EntityStorageInterface $storage) {
public function preSaveRevision(EntityStorageInterface $storage, \stdClass $record) {
}
/**
* {@inheritdoc}
*/
public function postSave(EntityStorageInterface $storage, $update = TRUE) {
parent::postSave($storage, $update);
// Update the status of all saved translations.
$removed = [];
foreach ($this->translations as $langcode => &$data) {
if ($data['status'] == static::TRANSLATION_REMOVED) {
$removed[$langcode] = TRUE;
}
else {
$data['status'] = static::TRANSLATION_EXISTING;
}
}
$this->translations = array_diff_key($this->translations, $removed);
}
/**
* {@inheritdoc}
*/
......@@ -829,7 +837,7 @@ public function addTranslation($langcode, array $values = array()) {
// Initialize the translation object.
/** @var \Drupal\Core\Entity\ContentEntityStorageInterface $storage */
$storage = $this->entityManager()->getStorage($this->getEntityTypeId());
$this->translations[$langcode]['status'] = static::TRANSLATION_CREATED;
$this->translations[$langcode]['status'] = !isset($this->translations[$langcode]['status_existed']) ? static::TRANSLATION_CREATED : static::TRANSLATION_EXISTING;
return $storage->createTranslation($this, $langcode, $values);
}
......@@ -844,13 +852,34 @@ public function removeTranslation($langcode) {
unset($this->fields[$name][$langcode]);
}
}
$this->translations[$langcode]['status'] = static::TRANSLATION_REMOVED;
// If removing a translation which has not been saved yet, then we have
// to remove it completely so that ::getTranslationStatus returns the
// proper status.
if ($this->translations[$langcode]['status'] == static::TRANSLATION_CREATED) {
unset($this->translations[$langcode]);
}
else {
if ($this->translations[$langcode]['status'] == static::TRANSLATION_EXISTING) {
$this->translations[$langcode]['status_existed'] = TRUE;
}
$this->translations[$langcode]['status'] = static::TRANSLATION_REMOVED;
}
}
else {
throw new \InvalidArgumentException("The specified translation ($langcode) cannot be removed.");
}
}
/**
* {@inheritdoc}
*/
public function getTranslationStatus($langcode) {
if ($langcode == $this->defaultLangcode) {
$langcode = LanguageInterface::LANGCODE_DEFAULT;
}
return isset($this->translations[$langcode]) ? $this->translations[$langcode]['status'] : NULL;
}
/**
* {@inheritdoc}
*/
......
<?php
namespace Drupal\Core\TypedData;
/**
* Defines an interface for checking the status of an entity translation.
*/
interface TranslationStatusInterface {
/**
* Status code identifying a removed translation.
*/
const TRANSLATION_REMOVED = 0;
/**
* Status code identifying an existing translation.
*/
const TRANSLATION_EXISTING = 1;
/**
* Status code identifying a newly created translation.
*/
const TRANSLATION_CREATED = 2;
/**
* Returns the translation status.
*
* @param string $langcode
* The language code identifying the translation.
*
* @return int|null
* One of the TRANSLATION_* constants or NULL if the given translation does
* not exist.
*/
public function getTranslationStatus($langcode);
}
......@@ -4,6 +4,7 @@
use Drupal\Component\Utility\SafeMarkup;
use Drupal\Core\Language\LanguageInterface;
use Drupal\Core\TypedData\TranslationStatusInterface;
use Drupal\entity_test\Entity\EntityTestMulRev;
use Drupal\field\Entity\FieldConfig;
use Drupal\field\Entity\FieldStorageConfig;
......@@ -931,4 +932,85 @@ public function testDeleteEntityTranslation() {
$this->assertEqual($actual, $expected_untranslatable);
}
/**
* Tests the getTranslationStatus method.
*/
public function testTranslationStatus() {
$entity_type = 'entity_test_mul';
$storage = $this->entityManager->getStorage($entity_type);
// Create an entity with both translatable and untranslatable test fields.
$values = array(
'name' => $this->randomString(),
'translatable_test_field' => $this->randomString(),
'untranslatable_test_field' => $this->randomString(),
);
/** @var \Drupal\Core\Entity\ContentEntityInterface|\Drupal\Core\TypedData\TranslationStatusInterface $entity */
// Test that newly created entity has the translation status
// TRANSLATION_CREATED.
$entity = $storage->create($values);
$this->assertEquals(TranslationStatusInterface::TRANSLATION_CREATED, $entity->getTranslationStatus($entity->language()->getId()));
// Test that after saving a newly created entity it has the translation
// status TRANSLATION_EXISTING.
$entity->save();
$this->assertEquals(TranslationStatusInterface::TRANSLATION_EXISTING, $entity->getTranslationStatus($entity->language()->getId()));
// Test that after loading an existing entity it has the translation status
// TRANSLATION_EXISTING.
$storage->resetCache();
$entity = $storage->load($entity->id());
$this->assertEquals(TranslationStatusInterface::TRANSLATION_EXISTING, $entity->getTranslationStatus($entity->language()->getId()));
foreach ($this->langcodes as $key => $langcode) {
// Test that after adding a new translation it has the translation status
// TRANSLATION_CREATED.
$entity->addTranslation($langcode, $values);
$this->assertEquals(TranslationStatusInterface::TRANSLATION_CREATED, $entity->getTranslationStatus($langcode));
// Test that after removing a newly added and not yet saved translation
// it does not have any translation status for the removed translation.
$entity->removeTranslation($langcode);
$this->assertEquals(NULL, $entity->getTranslationStatus($langcode));
// Test that after adding a new translation and saving the entity it has
// the translation status TRANSLATION_EXISTING.
$entity->addTranslation($langcode, $values)
->save();
$this->assertEquals(TranslationStatusInterface::TRANSLATION_EXISTING, $entity->getTranslationStatus($langcode));
// Test that after removing an existing translation its translation
// status has changed to TRANSLATION_REMOVED.
$entity->removeTranslation($langcode);
$this->assertEquals(TranslationStatusInterface::TRANSLATION_REMOVED, $entity->getTranslationStatus($langcode));
// Test that after removing an existing translation and adding it again
// its translation status has changed back to TRANSLATION_EXISTING.
$entity->addTranslation($langcode, $values);
$this->assertEquals(TranslationStatusInterface::TRANSLATION_EXISTING, $entity->getTranslationStatus($langcode));
// Test that after removing an existing translation and saving the entity
// it does not have any translation status for the removed translation.
$entity->removeTranslation($langcode);
$entity->save();
$this->assertEquals(NULL, $entity->getTranslationStatus($langcode));
// Tests that after removing an existing translation, saving the entity,
// adding the translation again, the translation status of this
// translation is TRANSLATION_CREATED.
$entity->addTranslation($langcode, $values);
$this->assertEquals(TranslationStatusInterface::TRANSLATION_CREATED, $entity->getTranslationStatus($langcode));
$entity->save();
}
// Test that after loading an existing entity it has the translation status
// TRANSLATION_EXISTING for all of its translations.
$storage->resetCache();
$entity = $storage->load($entity->id());
foreach (array_keys($entity->getTranslationLanguages()) as $langcode) {
$this->assertEquals(TranslationStatusInterface::TRANSLATION_EXISTING, $entity->getTranslationStatus($langcode));
}
}
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment