diff --git a/core/lib/Drupal/Core/Field/WidgetBase.php b/core/lib/Drupal/Core/Field/WidgetBase.php index d0cf50c7b3eadfba8819aa7affd3b9f482138470..50f67a58695c70dda29fe3c37afd57b41679d77e 100644 --- a/core/lib/Drupal/Core/Field/WidgetBase.php +++ b/core/lib/Drupal/Core/Field/WidgetBase.php @@ -406,10 +406,6 @@ public function flagErrors(FieldItemListInterface $items, ConstraintViolationLis // Separate violations by delta. $property_path = explode('.', $violation->getPropertyPath()); $delta = array_shift($property_path); - // Violations at the ItemList level are not associated to any delta, - // we file them under $delta NULL. - $delta = is_numeric($delta) ? $delta : NULL; - $violations_by_delta[$delta][] = $violation; $violation->arrayPropertyPath = $property_path; } @@ -419,7 +415,7 @@ public function flagErrors(FieldItemListInterface $items, ConstraintViolationLis // Pass violations to the main element: // - if this is a multiple-value widget, // - or if the violations are at the ItemList level. - if ($handles_multiple || $delta === NULL) { + if ($handles_multiple || !is_numeric($delta)) { $delta_element = $element; } // Otherwise, pass errors by delta to the corresponding sub-element. diff --git a/core/modules/system/src/Tests/Entity/FieldWidgetConstraintValidatorTest.php b/core/modules/system/src/Tests/Entity/FieldWidgetConstraintValidatorTest.php new file mode 100644 index 0000000000000000000000000000000000000000..5fa873d5d5c4c727fb8003d042ad55e7bbbdf1d0 --- /dev/null +++ b/core/modules/system/src/Tests/Entity/FieldWidgetConstraintValidatorTest.php @@ -0,0 +1,46 @@ +<?php + +/** + * @file + * Contains Drupal\system\Tests\Entity\FieldWidgetConstraintValidatorTest. + */ + +namespace Drupal\system\Tests\Entity; + +use Drupal\Core\Form\FormState; +use Drupal\simpletest\KernelTestBase; +use Drupal\system\Tests\TypedData; + +/** + * Tests validation constraints for FieldWidgetConstraintValidatorTest. + * + * @group Entity + */ +class FieldWidgetConstraintValidatorTest extends KernelTestBase { + + public static $modules = array('entity', 'entity_test', 'field', 'user'); + + /** + * Tests widget constraint validation. + */ + public function testValidation() { + $entity_type = 'entity_test_constraint_violation'; + $entity = entity_create($entity_type, array('id' => 1, 'revision_id' => 1)); + $display = entity_get_form_display($entity_type, $entity_type, 'default'); + $form = array(); + $form_state = new FormState(); + $display->buildForm($entity, $form, $form_state); + + // Pretend the form has been built. + $form_state['build_info']['callback_object'] = \Drupal::entityManager()->getFormObject($entity_type, 'default'); + \Drupal::formBuilder()->prepareForm('field_test_entity_form', $form, $form_state); + \Drupal::formBuilder()->processForm('field_test_entity_form', $form, $form_state); + + // Validate the field constraint. + $display->validateFormValues($entity, $form, $form_state); + + $errors = $form_state->getErrors(); + $this->assertEqual($errors['name'], 'Widget constraint has failed.', 'Constraint violation is generated correctly'); + } + +} diff --git a/core/modules/system/tests/modules/entity_test/src/Entity/EntityTestConstraintViolation.php b/core/modules/system/tests/modules/entity_test/src/Entity/EntityTestConstraintViolation.php new file mode 100644 index 0000000000000000000000000000000000000000..f90698d62bcf4a46d395cf726920af797e158fa3 --- /dev/null +++ b/core/modules/system/tests/modules/entity_test/src/Entity/EntityTestConstraintViolation.php @@ -0,0 +1,51 @@ +<?php + +/** + * @file + * Contains \Drupal\entity_test\Entity\EntityTestConstraintViolation. + */ + +namespace Drupal\entity_test\Entity; + +use Drupal\Core\Entity\EntityTypeInterface; + +/** + * Defines the test entity class for testing entity constraint violations. + * + * @ContentEntityType( + * id = "entity_test_constraint_violation", + * label = @Translation("Test entity constraint violation"), + * controllers = { + * "form" = { + * "default" = "Drupal\entity_test\EntityTestForm" + * } + * }, + * base_table = "entity_test", + * fieldable = TRUE, + * persistent_cache = FALSE, + * entity_keys = { + * "id" = "id", + * "uuid" = "uuid", + * "bundle" = "type", + * "label" = "name" + * } + * ) + */ +class EntityTestConstraintViolation extends EntityTest { + + /** + * {@inheritdoc} + */ + public static function baseFieldDefinitions(EntityTypeInterface $entity_type) { + $fields = parent::baseFieldDefinitions($entity_type); + + $fields['name']->setDisplayOptions('form', array( + 'type' => 'string', + 'weight' => 0, + )); + $fields['name']->addConstraint('FieldWidgetConstraint', array()); + + return $fields; + } + +} diff --git a/core/modules/system/tests/modules/entity_test/src/Plugin/Validation/Constraint/FieldWidgetConstraint.php b/core/modules/system/tests/modules/entity_test/src/Plugin/Validation/Constraint/FieldWidgetConstraint.php new file mode 100644 index 0000000000000000000000000000000000000000..ea2f44893537088afdd449e49002a819ca29db51 --- /dev/null +++ b/core/modules/system/tests/modules/entity_test/src/Plugin/Validation/Constraint/FieldWidgetConstraint.php @@ -0,0 +1,23 @@ +<?php +/** + * @file + * Contains \Drupal\entity_test\Plugin\Validation\Constraint\FieldWidgetConstraint. + */ + +namespace Drupal\entity_test\Plugin\Validation\Constraint; + +use Symfony\Component\Validator\Constraint; + +/** + * Supports validating widget constraints. + * + * @Plugin( + * id = "FieldWidgetConstraint", + * label = @Translation("Field widget constraint.") + * ) + */ +class FieldWidgetConstraint extends Constraint { + + public $message = 'Widget constraint has failed.'; + +} diff --git a/core/modules/system/tests/modules/entity_test/src/Plugin/Validation/Constraint/FieldWidgetConstraintValidator.php b/core/modules/system/tests/modules/entity_test/src/Plugin/Validation/Constraint/FieldWidgetConstraintValidator.php new file mode 100644 index 0000000000000000000000000000000000000000..6e3c8b856eaac1890d32a971bafe150cab2054eb --- /dev/null +++ b/core/modules/system/tests/modules/entity_test/src/Plugin/Validation/Constraint/FieldWidgetConstraintValidator.php @@ -0,0 +1,24 @@ +<?php +/** + * @file + * Contains \Drupal\entity_test\Plugin\Validation\Constraint\FieldWidgetConstraintValidator. + */ + +namespace Drupal\entity_test\Plugin\Validation\Constraint; + +use Symfony\Component\Validator\Constraint; +use Symfony\Component\Validator\ConstraintValidator; + +/** + * Validates the FieldWidgetConstraint constraint. + */ +class FieldWidgetConstraintValidator extends ConstraintValidator { + + /** + * {@inheritdoc} + */ + public function validate($field_item, Constraint $constraint) { + $this->context->addViolation($constraint->message); + } + +}