diff --git a/core/modules/content_translation/src/Plugin/Validation/Constraint/ContentTranslationSynchronizedFieldsConstraintValidator.php b/core/modules/content_translation/src/Plugin/Validation/Constraint/ContentTranslationSynchronizedFieldsConstraintValidator.php index 35e4358892..f46ef526ac 100644 --- a/core/modules/content_translation/src/Plugin/Validation/Constraint/ContentTranslationSynchronizedFieldsConstraintValidator.php +++ b/core/modules/content_translation/src/Plugin/Validation/Constraint/ContentTranslationSynchronizedFieldsConstraintValidator.php @@ -28,6 +28,7 @@ * new default revision. * * @see \Drupal\content_translation\Plugin\Validation\Constraint\ContentTranslationSynchronizedFieldsConstraint + * @see \Drupal\Core\Entity\Plugin\Validation\Constraint\EntityUntranslatableFieldsConstraintValidator * * @internal */ @@ -96,12 +97,6 @@ public function validate($value, Constraint $constraint) { if ($entity->isDefaultRevision() && !$entity->isDefaultTranslationAffectedOnly()) { return; } - // When changes to untranslatable fields are configured to affect only the - // default revision translation, we always allow changes in default - // translation. - if ($entity->isDefaultTranslation() && $entity->isDefaultTranslationAffectedOnly()) { - return; - } $entity_type_id = $entity->getEntityTypeId(); if (!$this->contentTranslationManager->isEnabled($entity_type_id, $entity->bundle())) { return; @@ -114,29 +109,18 @@ public function validate($value, Constraint $constraint) { /** @var \Drupal\Core\Entity\ContentEntityInterface $original */ $original = $this->getOriginalEntity($entity); $original_translation = $this->getOriginalTranslation($entity, $original); - $has_changes = $this->hasSynchronizedPropertyChanges($entity, $original_translation, $synchronized_properties); - - if ($entity->isDefaultTranslationAffectedOnly()) { - if ($has_changes) { - $this->context->addViolation($constraint->defaultTranslationMessage); - } - else { - $active_langcode = $entity->language()->getId(); + if ($this->hasSynchronizedPropertyChanges($entity, $original_translation, $synchronized_properties)) { + if ($entity->isDefaultTranslationAffectedOnly()) { foreach ($entity->getTranslationLanguages(FALSE) as $langcode => $language) { - // We already checked the active translation above. - if ($langcode !== $active_langcode) { - $translation = $entity->getTranslation($langcode); - $original_translation = $this->getOriginalTranslation($entity, $original); - if ($this->hasSynchronizedPropertyChanges($translation, $original_translation, $synchronized_properties)) { - $this->context->addViolation($constraint->defaultTranslationMessage); - break; - } + if ($entity->getTranslation($langcode)->hasTranslationChanges()) { + $this->context->addViolation($constraint->defaultTranslationMessage); + break; } } } - } - elseif ($has_changes) { - $this->context->addViolation($constraint->defaultRevisionMessage); + else { + $this->context->addViolation($constraint->defaultRevisionMessage); + } } } @@ -164,6 +148,8 @@ protected function hasSynchronizedPropertyChanges(ContentEntityInterface $entity return TRUE; } foreach ($items as $delta => $item) { + // @todo This loose comparison is not fully reliable. Revisit this + // after https://www.drupal.org/project/drupal/issues/xxx. if ($items[$delta][$property] != $original_items[$delta][$property]) { return TRUE; } diff --git a/core/modules/content_translation/tests/src/Kernel/ContentTranslationFieldSyncValidationTest.php b/core/modules/content_translation/tests/src/Kernel/ContentTranslationFieldSyncValidationTest.php index a0d73b4125..4c75e62785 100644 --- a/core/modules/content_translation/tests/src/Kernel/ContentTranslationFieldSyncValidationTest.php +++ b/core/modules/content_translation/tests/src/Kernel/ContentTranslationFieldSyncValidationTest.php @@ -308,6 +308,30 @@ public function testPendingRevisionValidation() { $this->assertEmpty($violations); $this->storage->save($it_revision); $this->assertLatestRevisionFieldValues($entity_id, [20, 4, 4, 'Alt 4 EN', 'Alt 6 IT']); + + // Check that we are not allowed to perform changes to multiple translations + // in pending revisions when synchronized properties are involved. + $this->setUntranslatableFieldWidgetsDisplay(FALSE); + $entity = $this->saveNewEntity(); + $entity_id = $entity->id(); + $this->assertLatestRevisionFieldValues($entity_id, [21, 1, 1, 'Alt 1 EN']); + + $it_translation = $entity->addTranslation('it', $entity->toArray()); + /** @var \Drupal\Core\Entity\ContentEntityInterface $it_revision */ + $it_revision = $this->createRevision($it_translation); + $metadata = $this->contentTranslationManager->getTranslationMetadata($it_revision); + $metadata->setSource('en'); + $it_revision->get($this->fieldName)->alt = 'Alt 2 IT'; + $violations = $it_revision->validate(); + $this->assertEmpty($violations); + $this->storage->save($it_revision); + $this->assertLatestRevisionFieldValues($entity_id, [22, 1, 1, 'Alt 1 EN', 'Alt 2 IT']); + + $en_revision = $this->createRevision($entity, FALSE); + $en_revision->get($this->fieldName)->target_id = 2; + $en_revision->getTranslation('it')->get($this->fieldName)->alt = 'Alt 3 IT'; + $violations = $en_revision->validate(); + $this->assertViolations($violations); } /**