Commit 122b6637 authored by effulgentsia's avatar effulgentsia

Issue #2941062 by plach, Wim Leers:...

Issue #2941062 by plach, Wim Leers: EntityUntranslatableFieldsConstraintValidator always allows changes in default revisions
parent a2ae6fd0
......@@ -15,6 +15,7 @@
*/
class EntityUntranslatableFieldsConstraint extends Constraint {
public $message = 'Non translatable fields can only be changed when updating the current revision or the original language.';
public $defaultRevisionMessage = 'Non-translatable fields can only be changed when updating the current revision.';
public $defaultTranslationMessage = 'Non-translatable fields can only be changed when updating the original language.';
}
......@@ -49,10 +49,14 @@ public static function create(ContainerInterface $container) {
*/
public function validate($entity, Constraint $constraint) {
/** @var \Drupal\Core\Entity\ContentEntityInterface $entity */
/** @var \Drupal\Core\Entity\Plugin\Validation\Constraint\EntityUntranslatableFieldsConstraint $constraint */
// Untranslatable field restrictions apply only to pending revisions of
// multilingual entities.
if ($entity->isNew() || $entity->isDefaultRevision() || !$entity->isTranslatable() || !$entity->getEntityType()->isRevisionable()) {
// Untranslatable field restrictions apply only to revisions of multilingual
// entities.
if ($entity->isNew() || !$entity->isTranslatable() || !$entity->getEntityType()->isRevisionable()) {
return;
}
if ($entity->isDefaultRevision() && !$entity->isDefaultTranslationAffectedOnly()) {
return;
}
......@@ -63,18 +67,20 @@ public function validate($entity, Constraint $constraint) {
// a pending revision contains only one affected translation. Even in this
// case, multiple translations would be affected in a single revision, if we
// allowed changes to untranslatable fields while editing non-default
// translations, so that is forbidden too.
// translations, so that is forbidden too. For the same reason, when changes
// to untranslatable fields affect all translations, we can only allow them
// in default revisions.
if ($this->hasUntranslatableFieldsChanges($entity)) {
if ($entity->isDefaultTranslationAffectedOnly()) {
foreach ($entity->getTranslationLanguages(FALSE) as $langcode => $language) {
if ($entity->getTranslation($langcode)->hasTranslationChanges()) {
$this->context->addViolation($constraint->message);
$this->context->addViolation($constraint->defaultTranslationMessage);
break;
}
}
}
else {
$this->context->addViolation($constraint->message);
$this->context->addViolation($constraint->defaultRevisionMessage);
}
}
}
......
......@@ -234,6 +234,7 @@ public function dataTestUntranslatableFields() {
['en', TRUE, TRUE],
['it', FALSE, TRUE, FALSE],
['en', FALSE, TRUE],
['it', TRUE, TRUE, FALSE],
['it', FALSE],
['it', TRUE],
['en', TRUE, TRUE],
......@@ -492,6 +493,35 @@ protected function formatMessage($message) {
return call_user_func_array('sprintf', $params);
}
/**
* Checks that changes to multiple translations are handled correctly.
*
* @covers ::createRevision
* @covers \Drupal\Core\Entity\Plugin\Validation\Constraint\EntityUntranslatableFieldsConstraintValidator::validate
*/
public function testMultipleTranslationChanges() {
// Configure the untranslatable fields edit mode.
$this->state->set('entity_test.untranslatable_fields.default_translation_affected', TRUE);
$this->bundleInfo->clearCachedBundles();
$entity = EntityTestMulRev::create();
$entity->get('name')->value = 'Test 1.1 EN';
$entity->get('non_mul_field')->value = 'Test 1.1';
$this->storage->save($entity);
/** @var \Drupal\Core\Entity\ContentEntityInterface $revision */
$revision = $this->storage->createRevision($entity->addTranslation('it'));
$revision->get('name')->value = 'Test 1.2 IT';
$this->storage->save($revision);
$revision = $this->storage->createRevision($revision->getTranslation('en'), FALSE);
$revision->get('non_mul_field')->value = 'Test 1.3';
$revision->getTranslation('it')->get('name')->value = 'Test 1.3 IT';
$violations = $revision->validate();
$this->assertCount(1, $violations);
$this->assertEquals('Non-translatable fields can only be changed when updating the original language.', $violations[0]->getMessage());
}
/**
* Tests that internal properties are preserved while creating a new revision.
*/
......
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