Issue #2941062 by plach, Wim Leers: EntityUntranslatableFieldsConstraintValidator always allows changes in default revisions

8.6.x
effulgentsia 2018-02-21 21:30:54 -08:00
parent a2ae6fd09c
commit 122b663779
3 changed files with 44 additions and 7 deletions

View File

@ -15,6 +15,7 @@ use Symfony\Component\Validator\Constraint;
*/
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.';
}

View File

@ -49,10 +49,14 @@ class EntityUntranslatableFieldsConstraintValidator extends ConstraintValidator
*/
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 @@ class EntityUntranslatableFieldsConstraintValidator extends ConstraintValidator
// 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);
}
}
}

View File

@ -234,6 +234,7 @@ class EntityDecoupledTranslationRevisionsTest extends EntityKernelTestBase {
['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 @@ class EntityDecoupledTranslationRevisionsTest extends EntityKernelTestBase {
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.
*/