diff --git a/core/lib/Drupal/Core/TypedData/Validation/ExecutionContext.php b/core/lib/Drupal/Core/TypedData/Validation/ExecutionContext.php index e61d6c9..066ed0a 100644 --- a/core/lib/Drupal/Core/TypedData/Validation/ExecutionContext.php +++ b/core/lib/Drupal/Core/TypedData/Validation/ExecutionContext.php @@ -241,8 +241,8 @@ public function getPropertyName() { /** * {@inheritdoc} */ - public function getPropertyPath($subPath = '') { - return PropertyPath::append($this->propertyPath, $subPath); + public function getPropertyPath($sub_path = '') { + return PropertyPath::append($this->propertyPath, $sub_path); } /** @@ -262,15 +262,15 @@ public function validate($value, $subPath = '', $groups = NULL, $traverse = FALS /** * {@inheritdoc} */ - public function markConstraintAsValidated($cacheKey, $constraintHash) { - $this->validatedConstraints[$cacheKey . ':' . $constraintHash] = TRUE; + public function markConstraintAsValidated($cache_key, $constraint_hash) { + $this->validatedConstraints[$cache_key . ':' . $constraint_hash] = TRUE; } /** * {@inheritdoc} */ - public function isConstraintValidated($cacheKey, $constraintHash) { - return isset($this->validatedConstraints[$cacheKey . ':' . $constraintHash]); + public function isConstraintValidated($cache_key, $constraint_hash) { + return isset($this->validatedConstraints[$cache_key . ':' . $constraint_hash]); } /** @@ -283,28 +283,28 @@ public function validateValue($value, $constraints, $subPath = '', $groups = NUL /** * {@inheritdoc} */ - public function markGroupAsValidated($cacheKey, $groupHash) { - $this->validatedObjects[$cacheKey][$groupHash] = TRUE; + public function markGroupAsValidated($cache_key, $group_hash) { + $this->validatedObjects[$cache_key][$group_hash] = TRUE; } /** * {@inheritdoc} */ - public function isGroupValidated($cacheKey, $groupHash) { - return isset($this->validatedObjects[$cacheKey][$groupHash]); + public function isGroupValidated($cache_key, $group_hash) { + return isset($this->validatedObjects[$cache_key][$group_hash]); } /** * {@inheritdoc} */ - public function markObjectAsInitialized($cacheKey) { + public function markObjectAsInitialized($cache_key) { // Not supported, so nothing todo. } /** * {@inheritdoc} */ - public function isObjectInitialized($cacheKey) { + public function isObjectInitialized($cache_key) { // Not supported, so nothing todo. } diff --git a/core/lib/Drupal/Core/TypedData/Validation/RecursiveContextualValidator.php b/core/lib/Drupal/Core/TypedData/Validation/RecursiveContextualValidator.php index bbbd56f..22bc398 100644 --- a/core/lib/Drupal/Core/TypedData/Validation/RecursiveContextualValidator.php +++ b/core/lib/Drupal/Core/TypedData/Validation/RecursiveContextualValidator.php @@ -104,36 +104,37 @@ public function validate($data, $constraints = NULL, $groups = NULL) { * @return $this */ protected function validateNode(TypedDataInterface $data, $constraints = NULL) { - $previousValue = $this->context->getValue(); - $previousObject = $this->context->getObject(); - $previousMetadata = $this->context->getMetadata(); - $previousPath = $this->context->getPropertyPath(); + $previous_value = $this->context->getValue(); + $previous_object = $this->context->getObject(); + $previous_metadata = $this->context->getMetadata(); + $previous_path = $this->context->getPropertyPath(); $metadata = $this->metadataFactory->getMetadataFor($data); - $cacheKey = spl_object_hash($data); - $propertyPath = PropertyPath::append($previousPath, $data->getName()); + $cache_key = spl_object_hash($data); + $property_path = PropertyPath::append($previous_path, $data->getName()); // Pass the canonical representation of the data as validated value to // constraint validators, such that they do not have to care about Typed // Data. $value = $this->typedDataManager->getCanonicalRepresentation($data); - $this->context->setNode($value, $data, $metadata, $propertyPath); + $this->context->setNode($value, $data, $metadata, $property_path); - if (!$this->context->isGroupValidated($cacheKey, Constraint::DEFAULT_GROUP)) { - $this->context->markGroupAsValidated($cacheKey, Constraint::DEFAULT_GROUP); - - $constraints = isset($constraints) ? $constraints : $metadata->findConstraints(Constraint::DEFAULT_GROUP); - $this->validateConstraints($value, $cacheKey, $constraints); + if (isset($constraints) || !$this->context->isGroupValidated($cache_key, Constraint::DEFAULT_GROUP)) { + if (!isset($constraints)) { + $this->context->markGroupAsValidated($cache_key, Constraint::DEFAULT_GROUP); + $constraints = $metadata->findConstraints(Constraint::DEFAULT_GROUP); + } + $this->validateConstraints($value, $cache_key, $constraints); } // If the data is a list or complex data, validate the contained list items - // or properties. - if ($data instanceof TraversableTypedDataInterface) { + // or properties. However, do not recurse if the data is empty. + if (($data instanceof ListInterface || $data instanceof ComplexDataInterface) && !$data->isEmpty()) { foreach ($data as $name => $property) { $this->validateNode($property); } } - $this->context->setNode($previousValue, $previousObject, $previousMetadata, $previousPath); + $this->context->setNode($previous_value, $previous_object, $previous_metadata, $previous_path); return $this; } @@ -144,18 +145,18 @@ protected function validateNode(TypedDataInterface $data, $constraints = NULL) { * @param mixed $value * The validated value. */ - protected function validateConstraints($value, $cacheKey, $constraints) { + protected function validateConstraints($value, $cache_key, $constraints) { foreach ($constraints as $constraint) { // Prevent duplicate validation of constraints, in the case // that constraints belong to multiple validated groups - if (null !== $cacheKey) { - $constraintHash = spl_object_hash($constraint); + if (isset($cache_key)) { + $constraint_hash = spl_object_hash($constraint); - if ($this->context->isConstraintValidated($cacheKey, $constraintHash)) { + if ($this->context->isConstraintValidated($cache_key, $constraint_hash)) { continue; } - $this->context->markConstraintAsValidated($cacheKey, $constraintHash); + $this->context->markConstraintAsValidated($cache_key, $constraint_hash); } $this->context->setConstraint($constraint); diff --git a/core/modules/user/src/Tests/UserValidationTest.php b/core/modules/user/src/Tests/UserValidationTest.php index 172b79d..ec44a79 100644 --- a/core/modules/user/src/Tests/UserValidationTest.php +++ b/core/modules/user/src/Tests/UserValidationTest.php @@ -122,9 +122,9 @@ function testValidation() { // https://drupal.org/node/2023465. $this->assertEqual(count($violations), 2, 'Violations found when email is too long'); $this->assertEqual($violations[0]->getPropertyPath(), 'mail.0.value'); - $this->assertEqual($violations[0]->getMessage(), t('This value is not a valid email address.')); + $this->assertEqual($violations[0]->getMessage(), t('%name: the email address can not be longer than @max characters.', array('%name' => $user->get('mail')->getFieldDefinition()->getLabel(), '@max' => Email::EMAIL_MAX_LENGTH))); $this->assertEqual($violations[1]->getPropertyPath(), 'mail.0.value'); - $this->assertEqual($violations[1]->getMessage(), t('%name: the email address can not be longer than @max characters.', array('%name' => $user->get('mail')->getFieldDefinition()->getLabel(), '@max' => Email::EMAIL_MAX_LENGTH))); + $this->assertEqual($violations[1]->getMessage(), t('This value is not a valid email address.')); // Provoke an email collision with an existing user. $user->set('mail', 'existing@example.com');