diff --git a/core/lib/Drupal/Core/Entity/Plugin/Validation/Constraint/CompositeConstraintBase.php b/core/lib/Drupal/Core/Entity/Plugin/Validation/Constraint/CompositeConstraintBase.php new file mode 100644 index 0000000..9c78572 --- /dev/null +++ b/core/lib/Drupal/Core/Entity/Plugin/Validation/Constraint/CompositeConstraintBase.php @@ -0,0 +1,32 @@ +entity = $value->getEntity(); + $field_names = $constraint->coversFields(); + + $values = []; + foreach ($field_names as $field_name) { + $values[$field_name] = $this->entity->get($field_name); + } + $this->doValidate($values, $constraint); + } + + /** + * Does the actual validation of a composite validator. + * + * @param \Drupal\Core\Field\FieldItemListInterface[] $values + * The field values which are validated. Keys are field names and values + * field item lists. + * @param \Symfony\Component\Validator\Constraint $constraint + * The constraint for the validation. + */ + abstract protected function doValidate(array $values, Constraint $constraint); + +} diff --git a/core/lib/Drupal/Core/Validation/Plugin/Validation/Constraint/CompositeConstraintBase.php b/core/lib/Drupal/Core/Validation/Plugin/Validation/Constraint/CompositeConstraintBase.php deleted file mode 100644 index a2c3b5d..0000000 --- a/core/lib/Drupal/Core/Validation/Plugin/Validation/Constraint/CompositeConstraintBase.php +++ /dev/null @@ -1,43 +0,0 @@ -addConstraint('CommentName', ['fields' => ['name', 'uid', 'entity']]); - * @encode - * on entities. - * - * With that the $values in CompositeConstraintValidatorBase::doValidate() will - * return an array keyed with 'name', 'uid' and 'entity', with 'entity' being - * the actual full entity. - */ -abstract class CompositeConstraintBase extends Constraint { - - /** - * An array of entity fields which should be passed to the validator. - * - * @return string[] - */ - protected $fields = []; - - /** - * The composited fields. - * - * @return array - */ - public function getFields() { - return $this->fields; - } - -} diff --git a/core/lib/Drupal/Core/Validation/Plugin/Validation/Constraint/CompositeConstraintValidatorBase.php b/core/lib/Drupal/Core/Validation/Plugin/Validation/Constraint/CompositeConstraintValidatorBase.php deleted file mode 100644 index ce3ec42..0000000 --- a/core/lib/Drupal/Core/Validation/Plugin/Validation/Constraint/CompositeConstraintValidatorBase.php +++ /dev/null @@ -1,66 +0,0 @@ -getEntity(); - $fields = $constraint->getFields(); - - $values = []; - foreach ($fields as $field) { - if ($field === 'entity') { - $values['entity'] = $entity; - continue; - } - - $split = explode('.', $field); - if (count($split) == 2) { - list($field, $property) = $split; - } - else { - $field = $split[0]; - $property = $entity->{$field}->first()->mainPropertyName(); - } - - $values[$field] = $entity->{$field}->first()->{$property}; - } - - $this->doValidate($values, $constraint); - } - - /** - * Does the actual validation of a composite validator. - * - * @param array $values - * The available values, as configured in the constraint. - * - * @param \Symfony\Component\Validator\Constraint $constraint - * The constraint for the validation. - */ - abstract protected function doValidate(array $values, Constraint $constraint); - -} diff --git a/core/modules/comment/src/Entity/Comment.php b/core/modules/comment/src/Entity/Comment.php index 3c30c79..d6b8452 100644 --- a/core/modules/comment/src/Entity/Comment.php +++ b/core/modules/comment/src/Entity/Comment.php @@ -256,7 +256,7 @@ public static function baseFieldDefinitions(EntityTypeInterface $entity_type) { ->setTranslatable(TRUE) ->setSetting('max_length', 60) ->setDefaultValue('') - ->addConstraint('CommentName', ['fields' => ['name', 'uid', 'entity']]); + ->addConstraint('CommentName'); $fields['mail'] = BaseFieldDefinition::create('email') ->setLabel(t('Email')) diff --git a/core/modules/comment/src/Plugin/Validation/Constraint/CommentNameConstraint.php b/core/modules/comment/src/Plugin/Validation/Constraint/CommentNameConstraint.php index ec3ef1b..15611e1 100644 --- a/core/modules/comment/src/Plugin/Validation/Constraint/CommentNameConstraint.php +++ b/core/modules/comment/src/Plugin/Validation/Constraint/CommentNameConstraint.php @@ -7,7 +7,7 @@ namespace Drupal\comment\Plugin\Validation\Constraint; -use Drupal\Core\Validation\Plugin\Validation\Constraint\CompositeConstraintBase; +use Drupal\Core\Entity\Plugin\Validation\Constraint\CompositeConstraintBase; /** * Supports validating comment author names. @@ -40,4 +40,11 @@ class CommentNameConstraint extends CompositeConstraintBase { */ public $messageMatch = 'The specified author name does not match the comment author.'; + /** + * {@inheritdoc} + */ + public function coversFields() { + return ['name', 'uid']; + } + } diff --git a/core/modules/comment/src/Plugin/Validation/Constraint/CommentNameConstraintValidator.php b/core/modules/comment/src/Plugin/Validation/Constraint/CommentNameConstraintValidator.php index a1cc844..e13953c 100644 --- a/core/modules/comment/src/Plugin/Validation/Constraint/CommentNameConstraintValidator.php +++ b/core/modules/comment/src/Plugin/Validation/Constraint/CommentNameConstraintValidator.php @@ -8,7 +8,7 @@ namespace Drupal\comment\Plugin\Validation\Constraint; use Drupal\Core\DependencyInjection\ContainerInjectionInterface; -use Drupal\Core\Validation\Plugin\Validation\Constraint\CompositeConstraintValidatorBase; +use Drupal\Core\Entity\Plugin\Validation\Constraint\CompositeConstraintValidatorBase; use Drupal\user\UserStorageInterface; use Symfony\Component\DependencyInjection\ContainerInterface; use Drupal\comment\CommentInterface; @@ -47,10 +47,8 @@ public static function create(ContainerInterface $container) { * {@inheritdoc} */ protected function doValidate(array $values, Constraint $constraint) { - $author_name = $values['name']; - $owner_id = (int) $values['uid']; - - $comment = $values['entity']; + $author_name = $values['name']->value; + $owner_id = (int) $values['uid']->target_id; // Do not allow unauthenticated comment authors to use a name that is // taken by a registered user. @@ -70,7 +68,7 @@ protected function doValidate(array $values, Constraint $constraint) { // Anonymous account might be required - depending on field settings. if ($owner_id === 0 && empty($author_name) && - $this->getAnonymousContactDetailsSetting($comment) === COMMENT_ANONYMOUS_MUST_CONTACT) { + $this->getAnonymousContactDetailsSetting($this->entity) === COMMENT_ANONYMOUS_MUST_CONTACT) { $this->context->addViolation($constraint->messageRequired); } } diff --git a/core/tests/Drupal/Tests/Core/Entity/Plugin/Validation/Constraint/CompositeConstraintValidatorBaseTest.php b/core/tests/Drupal/Tests/Core/Entity/Plugin/Validation/Constraint/CompositeConstraintValidatorBaseTest.php new file mode 100644 index 0000000..7ef0cbc --- /dev/null +++ b/core/tests/Drupal/Tests/Core/Entity/Plugin/Validation/Constraint/CompositeConstraintValidatorBaseTest.php @@ -0,0 +1,116 @@ +getMock('Symfony\Component\Validator\ExecutionContextInterface'); + $context->expects($this->never()) + ->method('addViolation'); + $validator->initialize($context); + + $items = $this->getMockedFieldItems('example value'); + $validator->validate($items, $constraint); + + $validator = new TestConstraintValidator(); + $context = $this->getMock('Symfony\Component\Validator\ExecutionContextInterface'); + $context->expects($this->once()) + ->method('addViolation'); + $validator->initialize($context); + $items = $this->getMockedFieldItems('invalid value'); + $validator->validate($items, $constraint); + } + + /** + * Get Mocked field items for the given value. + * + * @param string $value + * The value to set. + * + * @return \Drupal\Core\Field\FieldItemList + */ + protected function getMockedFieldItems($value) { + $entity = $this->getMock('Drupal\Core\Entity\ContentEntityInterface'); + + $definition = $this->getMock('\Drupal\Core\TypedData\ComplexDataDefinitionInterface'); + $definition->expects($this->any()) + ->method('getPropertyDefinitions') + ->willReturn([]); + $item = new StringItem($definition); + $item->value = $value; + + $items = $this->getMock('\Drupal\Core\Field\FieldItemListInterface'); + $items->expects($this->any())->method('first')->willReturn($item); + + $entity->expects($this->once()) + ->method('get') + ->with('normal_field') + ->willReturn($items); + + $entity_adapter = EntityAdapter::createFromEntity($entity); + $definition = $this->getMock('\Drupal\Core\TypedData\DataDefinitionInterface'); + return new FieldItemList($definition, NULL, $entity_adapter); + } + +} + +namespace Drupal\Tests\Core\Entity\Plugin\Validation\Constraint; + +use Drupal\Core\Entity\Plugin\Validation\Constraint\CompositeConstraintBase; +use Drupal\Core\Entity\Plugin\Validation\Constraint\CompositeConstraintValidatorBase; +use Symfony\Component\Validator\Constraint; + +/** + * Test composite constraint. + */ +class TestConstraint extends CompositeConstraintBase { + + public $message = "invalid"; + + /** + * An array of entity fields which should be passed to the validator. + * + * @return string[] + * An array of field names. + */ + public function coversFields() { + return ['normal_field']; + } +} + +/** + * Test composite constraint validator. + */ +class TestConstraintValidator extends CompositeConstraintValidatorBase { + + /** + * {@inheritdoc} + */ + protected function doValidate(array $values, Constraint $constraint) { + if (!isset($values['normal_field']) || $values['normal_field']->first()->value !== 'example value') { + $this->context->addViolation($constraint->message); + } + + } + +} diff --git a/core/tests/Drupal/Tests/Core/Validation/Plugin/Validation/Constraint/CompositeConstraintValidatorBaseTest.php b/core/tests/Drupal/Tests/Core/Validation/Plugin/Validation/Constraint/CompositeConstraintValidatorBaseTest.php deleted file mode 100644 index beebdfa..0000000 --- a/core/tests/Drupal/Tests/Core/Validation/Plugin/Validation/Constraint/CompositeConstraintValidatorBaseTest.php +++ /dev/null @@ -1,83 +0,0 @@ - ['normal_field', 'entity']]); - $validator = new TestConstraintValidator(); - - $context = $this->getMock('Symfony\Component\Validator\ExecutionContextInterface'); - $context->expects($this->never()) - ->method('addViolation'); - - $validator->initialize($context); - - $entity = $this->getMock('Drupal\Core\Entity\ContentEntityInterface'); - - $definition = $this->getMock('\Drupal\Core\TypedData\ComplexDataDefinitionInterface'); - $definition->expects($this->any()) - ->method('getPropertyDefinitions') - ->willReturn([]); - $item = new StringItem($definition); - $item->value = 'example value'; - - $items = $this->getMock('\Drupal\Core\Field\FieldItemListInterface'); - $items->expects($this->any()) - ->method('first') - ->willReturn($item); - $entity->normal_field = $items; - - $entity_adapter = EntityAdapter::createFromEntity($entity); - $definition = $this->getMock('\Drupal\Core\TypedData\DataDefinitionInterface'); - $items = new FieldItemList($definition, NULL, $entity_adapter); - - $validator->validate($items, $constaint); - } - -} - -class TestConstraint extends CompositeConstraintBase { - - public $message = "invalid"; - -} - -class TestConstraintValidator extends CompositeConstraintValidatorBase { - - /** - * {@inheritdoc} - */ - protected function doValidate(array $values, Constraint $constraint) { - if (!isset($values['normal_field']) || $values['normal_field'] !== 'example value') { - $this->context->addViolation($constraint->message); - } - - if (!isset($values['entity']) || !($values['entity'] instanceof ContentEntityInterface)) { - $this->context->addViolation($constraint->message); - } - - } - -}