summaryrefslogtreecommitdiffstats
path: root/core/lib/Drupal/Core
diff options
context:
space:
mode:
Diffstat (limited to 'core/lib/Drupal/Core')
-rw-r--r--core/lib/Drupal/Core/Entity/ContentEntityBase.php73
-rw-r--r--core/lib/Drupal/Core/Entity/ContentEntityInterface.php35
-rw-r--r--core/lib/Drupal/Core/Entity/ContentEntityStorageBase.php15
3 files changed, 104 insertions, 19 deletions
diff --git a/core/lib/Drupal/Core/Entity/ContentEntityBase.php b/core/lib/Drupal/Core/Entity/ContentEntityBase.php
index 2c62589..5376644 100644
--- a/core/lib/Drupal/Core/Entity/ContentEntityBase.php
+++ b/core/lib/Drupal/Core/Entity/ContentEntityBase.php
@@ -157,6 +157,22 @@ abstract class ContentEntityBase extends Entity implements \IteratorAggregate, C
protected $loadedRevisionId;
/**
+ * The revision translation affected entity key.
+ *
+ * @var string
+ */
+ protected $revisionTranslationAffectedKey;
+
+ /**
+ * Whether the revision translation affected flag has been enforced.
+ *
+ * An array, keyed by the translation language code.
+ *
+ * @var bool[]
+ */
+ protected $enforceRevisionTranslationAffected = [];
+
+ /**
* {@inheritdoc}
*/
public function __construct(array $values, $entity_type, $bundle = FALSE, $translations = []) {
@@ -164,6 +180,7 @@ abstract class ContentEntityBase extends Entity implements \IteratorAggregate, C
$this->entityKeys['bundle'] = $bundle ? $bundle : $this->entityTypeId;
$this->langcodeKey = $this->getEntityType()->getKey('langcode');
$this->defaultLangcodeKey = $this->getEntityType()->getKey('default_langcode');
+ $this->revisionTranslationAffectedKey = $this->getEntityType()->getKey('revision_translation_affected');
foreach ($values as $key => $value) {
// If the key matches an existing property set the value to the property
@@ -269,15 +286,11 @@ abstract class ContentEntityBase extends Entity implements \IteratorAggregate, C
// When saving a new revision, set any existing revision ID to NULL so as
// to ensure that a new revision will actually be created.
$this->set($this->getEntityType()->getKey('revision'), NULL);
-
- // Make sure that the flag tracking which translations are affected by the
- // current revision is reset.
- foreach ($this->translations as $langcode => $data) {
- // But skip removed translations.
- if ($this->hasTranslation($langcode)) {
- $this->getTranslation($langcode)->setRevisionTranslationAffected(NULL);
- }
- }
+ }
+ elseif (!$value && $this->newRevision) {
+ // If ::setNewRevision(FALSE) is called after ::setNewRevision(TRUE) we
+ // have to restore the loaded revision ID.
+ $this->set($this->getEntityType()->getKey('revision'), $this->getLoadedRevisionId());
}
$this->newRevision = $value;
@@ -322,17 +335,15 @@ abstract class ContentEntityBase extends Entity implements \IteratorAggregate, C
* {@inheritdoc}
*/
public function isRevisionTranslationAffected() {
- $field_name = $this->getEntityType()->getKey('revision_translation_affected');
- return $this->hasField($field_name) ? $this->get($field_name)->value : TRUE;
+ return $this->hasField($this->revisionTranslationAffectedKey) ? $this->get($this->revisionTranslationAffectedKey)->value : TRUE;
}
/**
* {@inheritdoc}
*/
public function setRevisionTranslationAffected($affected) {
- $field_name = $this->getEntityType()->getKey('revision_translation_affected');
- if ($this->hasField($field_name)) {
- $this->set($field_name, $affected);
+ if ($this->hasField($this->revisionTranslationAffectedKey)) {
+ $this->set($this->revisionTranslationAffectedKey, $affected);
}
return $this;
}
@@ -340,6 +351,21 @@ abstract class ContentEntityBase extends Entity implements \IteratorAggregate, C
/**
* {@inheritdoc}
*/
+ public function isRevisionTranslationAffectedEnforced() {
+ return !empty($this->enforceRevisionTranslationAffected[$this->activeLangcode]);
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function setRevisionTranslationAffectedEnforced($enforced) {
+ $this->enforceRevisionTranslationAffected[$this->activeLangcode] = $enforced;
+ return $this;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
public function isDefaultTranslation() {
return $this->activeLangcode === LanguageInterface::LANGCODE_DEFAULT;
}
@@ -401,6 +427,12 @@ abstract class ContentEntityBase extends Entity implements \IteratorAggregate, C
}
}
$this->translations = array_diff_key($this->translations, $removed);
+
+ // Reset the new revision flag.
+ $this->newRevision = FALSE;
+
+ // Reset the enforcement of the revision translation affected flag.
+ $this->enforceRevisionTranslationAffected = [];
}
/**
@@ -748,6 +780,12 @@ abstract class ContentEntityBase extends Entity implements \IteratorAggregate, C
throw new \LogicException($message);
}
break;
+
+ case $this->revisionTranslationAffectedKey:
+ // If the revision translation affected flag is being set then enforce
+ // its value.
+ $this->setRevisionTranslationAffectedEnforced(TRUE);
+ break;
}
}
@@ -831,6 +869,7 @@ abstract class ContentEntityBase extends Entity implements \IteratorAggregate, C
$translation->typedData = NULL;
$translation->loadedRevisionId = &$this->loadedRevisionId;
$translation->isDefaultRevision = &$this->isDefaultRevision;
+ $translation->enforceRevisionTranslationAffected = &$this->enforceRevisionTranslationAffected;
return $translation;
}
@@ -1098,7 +1137,8 @@ abstract class ContentEntityBase extends Entity implements \IteratorAggregate, C
// Ensure that the following properties are actually cloned by
// overwriting the original references with ones pointing to copies of
// them: enforceIsNew, newRevision, loadedRevisionId, fields, entityKeys,
- // translatableEntityKeys, values and isDefaultRevision.
+ // translatableEntityKeys, values, isDefaultRevision and
+ // enforceRevisionTranslationAffected.
$enforce_is_new = $this->enforceIsNew;
$this->enforceIsNew = &$enforce_is_new;
@@ -1123,6 +1163,9 @@ abstract class ContentEntityBase extends Entity implements \IteratorAggregate, C
$default_revision = $this->isDefaultRevision;
$this->isDefaultRevision = &$default_revision;
+ $is_revision_translation_affected_enforced = $this->enforceRevisionTranslationAffected;
+ $this->enforceRevisionTranslationAffected = &$is_revision_translation_affected_enforced;
+
foreach ($this->fields as $name => $fields_by_langcode) {
$this->fields[$name] = [];
// Untranslatable fields may have multiple references for the same field
diff --git a/core/lib/Drupal/Core/Entity/ContentEntityInterface.php b/core/lib/Drupal/Core/Entity/ContentEntityInterface.php
index d045152..3053d23 100644
--- a/core/lib/Drupal/Core/Entity/ContentEntityInterface.php
+++ b/core/lib/Drupal/Core/Entity/ContentEntityInterface.php
@@ -33,6 +33,12 @@ interface ContentEntityInterface extends \Traversable, FieldableEntityInterface,
/**
* Marks the current revision translation as affected.
*
+ * Setting the revision translation affected flag through the setter or
+ * through the field directly will always enforce it, which will be used by
+ * the entity storage to determine if the flag should be recomputed or the set
+ * value should be used instead.
+ * @see \Drupal\Core\Entity\ContentEntityStorageBase::populateAffectedRevisionTranslations()
+ *
* @param bool|null $affected
* The flag value. A NULL value can be specified to reset the current value
* and make sure a new value will be computed by the system.
@@ -51,6 +57,35 @@ interface ContentEntityInterface extends \Traversable, FieldableEntityInterface,
public function isRevisionTranslationAffected();
/**
+ * Checks if the revision translation affected flag value has been enforced.
+ *
+ * @return bool
+ * TRUE if revision translation affected flag is enforced, FALSE otherwise.
+ *
+ * @internal
+ */
+ public function isRevisionTranslationAffectedEnforced();
+
+ /**
+ * Enforces the revision translation affected flag value.
+ *
+ * Note that this method call will not have any influence on the storage if
+ * the value of the revision translation affected flag is NULL which is used
+ * as an indication for the storage to recompute the flag.
+ * @see \Drupal\Core\Entity\ContentEntityInterface::setRevisionTranslationAffected()
+ *
+ * @param bool $enforced
+ * If TRUE, the value of the revision translation affected flag will be
+ * enforced so that on entity save the entity storage will not recompute it.
+ * Otherwise the storage will recompute it.
+ *
+ * @return $this
+ *
+ * @internal
+ */
+ public function setRevisionTranslationAffectedEnforced($enforced);
+
+ /**
* Gets the loaded Revision ID of the entity.
*
* @return int
diff --git a/core/lib/Drupal/Core/Entity/ContentEntityStorageBase.php b/core/lib/Drupal/Core/Entity/ContentEntityStorageBase.php
index 874a341..2b06b92 100644
--- a/core/lib/Drupal/Core/Entity/ContentEntityStorageBase.php
+++ b/core/lib/Drupal/Core/Entity/ContentEntityStorageBase.php
@@ -587,10 +587,17 @@ abstract class ContentEntityStorageBase extends EntityStorageBase implements Con
$languages = $entity->getTranslationLanguages();
foreach ($languages as $langcode => $language) {
$translation = $entity->getTranslation($langcode);
- // Avoid populating the value if it was already manually set.
- $affected = $translation->isRevisionTranslationAffected();
- if (!isset($affected) && $translation->hasTranslationChanges()) {
- $translation->setRevisionTranslationAffected(TRUE);
+ $current_affected = $translation->isRevisionTranslationAffected();
+ if (!isset($current_affected) || ($entity->isNewRevision() && !$translation->isRevisionTranslationAffectedEnforced())) {
+ // When setting the revision translation affected flag we have to
+ // explicitly set it to not be enforced. By default it will be
+ // enforced automatically when being set, which allows us to determine
+ // if the flag has been already set outside the storage in which case
+ // we should not recompute it.
+ // @see \Drupal\Core\Entity\ContentEntityBase::setRevisionTranslationAffected().
+ $new_affected = $translation->hasTranslationChanges() ? TRUE : NULL;
+ $translation->setRevisionTranslationAffected($new_affected);
+ $translation->setRevisionTranslationAffectedEnforced(FALSE);
}
}
}