From 5ea0e3ae8db073ec0d0e18244c0dedfa7107776c Mon Sep 17 00:00:00 2001 From: Lee Rowlands Date: Sat, 15 Jul 2017 18:09:13 +1000 Subject: [PATCH] Issue #2894634 by amateescu: Allow entity-level validations to flag errors on form elements --- core/lib/Drupal/Core/Entity/ContentEntityForm.php | 2 +- .../lib/Drupal/Core/Entity/EntityConstraintViolationList.php | 5 +++++ .../Validation/Constraint/EntityTestEntityLevelValidator.php | 5 +++++ .../Core/Entity/FieldWidgetConstraintValidatorTest.php | 4 ++++ 4 files changed, 15 insertions(+), 1 deletion(-) diff --git a/core/lib/Drupal/Core/Entity/ContentEntityForm.php b/core/lib/Drupal/Core/Entity/ContentEntityForm.php index 14e910d1e16..02eee80f1cd 100644 --- a/core/lib/Drupal/Core/Entity/ContentEntityForm.php +++ b/core/lib/Drupal/Core/Entity/ContentEntityForm.php @@ -235,7 +235,7 @@ class ContentEntityForm extends EntityForm implements ContentEntityFormInterface // Flag entity level violations. foreach ($violations->getEntityViolations() as $violation) { /** @var \Symfony\Component\Validator\ConstraintViolationInterface $violation */ - $form_state->setErrorByName('', $violation->getMessage()); + $form_state->setErrorByName(str_replace('.', '][', $violation->getPropertyPath()), $violation->getMessage()); } // Let the form display flag violations of its fields. $this->getFormDisplay($form_state)->flagWidgetsErrorsFromViolations($violations, $form, $form_state); diff --git a/core/lib/Drupal/Core/Entity/EntityConstraintViolationList.php b/core/lib/Drupal/Core/Entity/EntityConstraintViolationList.php index c3404b6fa7f..6081a8de168 100644 --- a/core/lib/Drupal/Core/Entity/EntityConstraintViolationList.php +++ b/core/lib/Drupal/Core/Entity/EntityConstraintViolationList.php @@ -68,6 +68,11 @@ class EntityConstraintViolationList extends ConstraintViolationList implements E if ($this->entity->hasField($field_name)) { $this->violationOffsetsByField[$field_name][$offset] = $offset; } + // If the first part of the violation property path is not a valid + // field name, we're dealing with an entity-level validation. + else { + $this->entityViolationOffsets[$offset] = $offset; + } } else { $this->entityViolationOffsets[$offset] = $offset; diff --git a/core/modules/system/tests/modules/entity_test/src/Plugin/Validation/Constraint/EntityTestEntityLevelValidator.php b/core/modules/system/tests/modules/entity_test/src/Plugin/Validation/Constraint/EntityTestEntityLevelValidator.php index 6602fdcdc8b..3b84ada069c 100644 --- a/core/modules/system/tests/modules/entity_test/src/Plugin/Validation/Constraint/EntityTestEntityLevelValidator.php +++ b/core/modules/system/tests/modules/entity_test/src/Plugin/Validation/Constraint/EntityTestEntityLevelValidator.php @@ -25,6 +25,11 @@ class EntityTestEntityLevelValidator extends ConstraintValidator { $this->context->buildViolation($constraint->message) ->addViolation(); } + if ($value->name->value === 'entity-level-violation-with-path') { + $this->context->buildViolation($constraint->message) + ->atPath('test.form.element') + ->addViolation(); + } } } diff --git a/core/tests/Drupal/KernelTests/Core/Entity/FieldWidgetConstraintValidatorTest.php b/core/tests/Drupal/KernelTests/Core/Entity/FieldWidgetConstraintValidatorTest.php index 5ae824b71a2..041b062f452 100644 --- a/core/tests/Drupal/KernelTests/Core/Entity/FieldWidgetConstraintValidatorTest.php +++ b/core/tests/Drupal/KernelTests/Core/Entity/FieldWidgetConstraintValidatorTest.php @@ -149,6 +149,10 @@ class FieldWidgetConstraintValidatorTest extends KernelTestBase { $errors = $this->getErrorsForEntity($entity); $this->assertEqual($errors[''], 'Entity level validation'); + + $entity->name->value = 'entity-level-violation-with-path'; + $errors = $this->getErrorsForEntity($entity); + $this->assertEqual($errors['test][form][element'], 'Entity level validation'); } }