diff --git a/core/lib/Drupal/Core/Entity/Field/FieldItemBase.php b/core/lib/Drupal/Core/Entity/Field/FieldItemBase.php index 1c9eced..fa28bc6 100644 --- a/core/lib/Drupal/Core/Entity/Field/FieldItemBase.php +++ b/core/lib/Drupal/Core/Entity/Field/FieldItemBase.php @@ -91,6 +91,7 @@ public function set($property_name, $value, $notify = TRUE) { // value that needs to be updated. if (isset($this->properties[$property_name])) { $this->properties[$property_name]->setValue($value, FALSE); + unset($this->values[$property_name]); } // Allow setting plain values for not-defined properties also. else { diff --git a/core/lib/Drupal/Core/Entity/Field/Type/Field.php b/core/lib/Drupal/Core/Entity/Field/Type/Field.php index 4829bb7..469bab7 100644 --- a/core/lib/Drupal/Core/Entity/Field/Type/Field.php +++ b/core/lib/Drupal/Core/Entity/Field/Type/Field.php @@ -194,4 +194,19 @@ public function defaultAccess($operation = 'view', User $account = NULL) { // Grant access per default. return TRUE; } + + /** + * {@inheritdoc} + */ + public function getConstraints() { + // Constraints usually apply to the field item, but required does make + // sense on the field only. So we special-case it to apply to the field for + // now. + // @todo: Separate list and list item definitions to separate constraints. + $constraints = array(); + if (!empty($this->definition['required'])) { + $constraints[] = \Drupal::typedData()->getValidationConstraintManager()->create('NotNull', array()); + } + return $constraints; + } } diff --git a/core/lib/Drupal/Core/Validation/Plugin/Validation/Constraint/ComplexDataConstraintValidator.php b/core/lib/Drupal/Core/Validation/Plugin/Validation/Constraint/ComplexDataConstraintValidator.php index 1dbcc94..663b570 100644 --- a/core/lib/Drupal/Core/Validation/Plugin/Validation/Constraint/ComplexDataConstraintValidator.php +++ b/core/lib/Drupal/Core/Validation/Plugin/Validation/Constraint/ComplexDataConstraintValidator.php @@ -41,7 +41,7 @@ public function validate($value, Constraint $constraint) { // @see \Drupal\Core\TypedData\Validation\PropertyContainerMetadata::accept(); $property = NULL; } - $this->context->validateValue($property, $constraints, '[' . $name . ']', $group); + $this->context->validateValue($property, $constraints, $name, $group); } } } diff --git a/core/modules/system/lib/Drupal/system/Tests/Entity/EntityValidationTest.php b/core/modules/system/lib/Drupal/system/Tests/Entity/EntityValidationTest.php index df430f2..df4d8f4 100644 --- a/core/modules/system/lib/Drupal/system/Tests/Entity/EntityValidationTest.php +++ b/core/modules/system/lib/Drupal/system/Tests/Entity/EntityValidationTest.php @@ -56,6 +56,7 @@ public function setUp() { * Creates a test entity. * * @return \Drupal\Core\Entity\EntityInterface + * The created test entity. */ protected function createTestEntity($entity_type) { $this->entity_name = $this->randomName(); @@ -97,16 +98,29 @@ protected function checkValidation($entity_type) { // Test triggering a fail for each of the constraints specified. $test_entity = clone $entity; - $test_entity->uuid->value = $this->randomString(150); + $test_entity->uuid->value = $this->randomString(129); $this->assertEqual($test_entity->validate()->count(), 1, 'Validation failed.'); $test_entity = clone $entity; - $test_entity->langcode->value = $this->randomString(40); + $test_entity->langcode->value = $this->randomString(13); $this->assertEqual($test_entity->validate()->count(), 1, 'Validation failed.'); $test_entity = clone $entity; - $test_entity->name->value = $this->randomString(40); + $test_entity->type->value = NULL; $this->assertEqual($test_entity->validate()->count(), 1, 'Validation failed.'); + + $test_entity = clone $entity; + $test_entity->name->value = $this->randomString(33); + $this->assertEqual($test_entity->validate()->count(), 1, 'Validation failed.'); + + // Make sure the violation is correct. + $violations = $test_entity->validate(); + $violation = $violations->get(0); + $this->assertEqual($violation->getRoot(), $test_entity, 'Violation root is entity.'); + $this->assertEqual($violation->getPropertyPath(), 'name.0.value', 'Violation property path is correct.'); + + $this->assertEqual($violation->getInvalidValue(), $test_entity->name->value, 'Violation contains invalid value.'); + $this->assertEqual($violation->getMessage(), t('This value is too long. It should have %limit characters or less.', array('%limit' => '32'))); } }