From 54cb6e458e7b12492ecf443fa83e1e98f1680aef Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20H=C3=B6rl?= Date: Sat, 14 Jan 2012 02:06:07 +0100 Subject: [PATCH 1/4] [Validator] Added dynamic constraints --- .../Validator/ConstraintProviderInterface.php | 27 ++++++++++++++++++ src/Symfony/Component/Validator/Validator.php | 4 +++ .../Fixtures/DynamicConstraintsEntity.php | 21 ++++++++++++++ .../Component/Validator/ValidatorTest.php | 28 +++++++++++++++++++ 4 files changed, 80 insertions(+) create mode 100644 src/Symfony/Component/Validator/ConstraintProviderInterface.php create mode 100644 tests/Symfony/Tests/Component/Validator/Fixtures/DynamicConstraintsEntity.php diff --git a/src/Symfony/Component/Validator/ConstraintProviderInterface.php b/src/Symfony/Component/Validator/ConstraintProviderInterface.php new file mode 100644 index 0000000000..4541b622e4 --- /dev/null +++ b/src/Symfony/Component/Validator/ConstraintProviderInterface.php @@ -0,0 +1,27 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Validator; + +use Symfony\Component\Validator\Mapping\ClassMetadata; + +/** + * Makes it possible to define dynamic constraints for an object. + */ +interface ConstraintProviderInterface +{ + /** + * Lets the user create dynamic constraints + * + * @param Mapping\ClassMetadata + */ + public function getConstraints(ClassMetadata $metadata); +} diff --git a/src/Symfony/Component/Validator/Validator.php b/src/Symfony/Component/Validator/Validator.php index d20a623256..a8ec922b0f 100644 --- a/src/Symfony/Component/Validator/Validator.php +++ b/src/Symfony/Component/Validator/Validator.php @@ -57,6 +57,10 @@ class Validator implements ValidatorInterface public function validate($object, $groups = null) { $metadata = $this->metadataFactory->getClassMetadata(get_class($object)); + + if ($object instanceof ConstraintProviderInterface) { + $object->getConstraints($metadata); + } $walk = function(GraphWalker $walker, $group) use ($metadata, $object) { return $walker->walkObject($metadata, $object, $group, ''); diff --git a/tests/Symfony/Tests/Component/Validator/Fixtures/DynamicConstraintsEntity.php b/tests/Symfony/Tests/Component/Validator/Fixtures/DynamicConstraintsEntity.php new file mode 100644 index 0000000000..ae30742616 --- /dev/null +++ b/tests/Symfony/Tests/Component/Validator/Fixtures/DynamicConstraintsEntity.php @@ -0,0 +1,21 @@ +addPropertyConstraint('firstValue', new FailingConstraint()); + $metadata->addGetterConstraint('secondValue', new FailingConstraint()); + } +} diff --git a/tests/Symfony/Tests/Component/Validator/ValidatorTest.php b/tests/Symfony/Tests/Component/Validator/ValidatorTest.php index 78b0386bfa..05ce9951c1 100644 --- a/tests/Symfony/Tests/Component/Validator/ValidatorTest.php +++ b/tests/Symfony/Tests/Component/Validator/ValidatorTest.php @@ -15,10 +15,12 @@ require_once __DIR__.'/Fixtures/Entity.php'; require_once __DIR__.'/Fixtures/FailingConstraint.php'; require_once __DIR__.'/Fixtures/FailingConstraintValidator.php'; require_once __DIR__.'/Fixtures/FakeClassMetadataFactory.php'; +require_once __DIR__.'/Fixtures/DynamicConstraintsEntity.php'; use Symfony\Tests\Component\Validator\Fixtures\Entity; use Symfony\Tests\Component\Validator\Fixtures\FakeClassMetadataFactory; use Symfony\Tests\Component\Validator\Fixtures\FailingConstraint; +use Symfony\Tests\Component\Validator\Fixtures\DynamicConstraintsEntity; use Symfony\Component\Validator\Validator; use Symfony\Component\Validator\ConstraintViolation; use Symfony\Component\Validator\ConstraintViolationList; @@ -121,6 +123,32 @@ class ValidatorTest extends \PHPUnit_Framework_TestCase $this->assertEquals($violations, $result); } + + public function testValidate_constraintProvider() + { + $entity = new DynamicConstraintsEntity(); + $metadata = new ClassMetadata(get_class($entity)); + $this->factory->addClassMetadata($metadata); + + // Only the constraint of group "Default" failed + $violations = new ConstraintViolationList(); + $violations->add(new ConstraintViolation( + '', + array(), + $entity, + 'firstValue', + '' + )); + $violations->add(new ConstraintViolation( + '', + array(), + $entity, + 'secondValue', + '' + )); + + $this->assertEquals($violations, $this->validator->validate($entity)); + } public function testValidateProperty() { From 09c191136ad15624eaac830996ffe4c327e155ab Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20H=C3=B6rl?= Date: Sat, 14 Jan 2012 02:24:14 +0100 Subject: [PATCH 2/4] [Validator] Improved dynamic constraints --- src/Symfony/Component/Validator/Validator.php | 6 +++++- .../Fixtures/DynamicConstraintsEntity.php | 15 ++++++++++++--- .../Tests/Component/Validator/ValidatorTest.php | 10 ++++++++-- 3 files changed, 25 insertions(+), 6 deletions(-) diff --git a/src/Symfony/Component/Validator/Validator.php b/src/Symfony/Component/Validator/Validator.php index a8ec922b0f..714090842d 100644 --- a/src/Symfony/Component/Validator/Validator.php +++ b/src/Symfony/Component/Validator/Validator.php @@ -12,6 +12,7 @@ namespace Symfony\Component\Validator; use Symfony\Component\Validator\Mapping\ClassMetadataFactoryInterface; +use Symfony\Component\Validator\Mapping\ClassMetadata; /** * The default implementation of the ValidatorInterface. @@ -59,7 +60,10 @@ class Validator implements ValidatorInterface $metadata = $this->metadataFactory->getClassMetadata(get_class($object)); if ($object instanceof ConstraintProviderInterface) { - $object->getConstraints($metadata); + $dynamicMetadata = new ClassMetadata(get_class($object)); + $dynamicMetadata->mergeConstraints($metadata); + $object->getConstraints($dynamicMetadata); + $metadata = $dynamicMetadata; } $walk = function(GraphWalker $walker, $group) use ($metadata, $object) { diff --git a/tests/Symfony/Tests/Component/Validator/Fixtures/DynamicConstraintsEntity.php b/tests/Symfony/Tests/Component/Validator/Fixtures/DynamicConstraintsEntity.php index ae30742616..1cab8339bf 100644 --- a/tests/Symfony/Tests/Component/Validator/Fixtures/DynamicConstraintsEntity.php +++ b/tests/Symfony/Tests/Component/Validator/Fixtures/DynamicConstraintsEntity.php @@ -7,15 +7,24 @@ use Symfony\Component\Validator\Mapping\ClassMetadata; class DynamicConstraintsEntity implements ConstraintProviderInterface { + protected $validationEnabled = false; protected $firstValue; - public function getSecondValue() { + public function setValidation($enabled) + { + $this->validationEnabled = $enabled; + } + + public function getSecondValue() + { return null; } public function getConstraints(ClassMetadata $metadata) { - $metadata->addPropertyConstraint('firstValue', new FailingConstraint()); - $metadata->addGetterConstraint('secondValue', new FailingConstraint()); + if ($this->validationEnabled) { + $metadata->addPropertyConstraint('firstValue', new FailingConstraint()); + $metadata->addGetterConstraint('secondValue', new FailingConstraint()); + } } } diff --git a/tests/Symfony/Tests/Component/Validator/ValidatorTest.php b/tests/Symfony/Tests/Component/Validator/ValidatorTest.php index 05ce9951c1..5bd2c7bc74 100644 --- a/tests/Symfony/Tests/Component/Validator/ValidatorTest.php +++ b/tests/Symfony/Tests/Component/Validator/ValidatorTest.php @@ -129,8 +129,9 @@ class ValidatorTest extends \PHPUnit_Framework_TestCase $entity = new DynamicConstraintsEntity(); $metadata = new ClassMetadata(get_class($entity)); $this->factory->addClassMetadata($metadata); + + $entity->setValidation(true); - // Only the constraint of group "Default" failed $violations = new ConstraintViolationList(); $violations->add(new ConstraintViolation( '', @@ -146,7 +147,12 @@ class ValidatorTest extends \PHPUnit_Framework_TestCase 'secondValue', '' )); - + + $this->assertEquals($violations, $this->validator->validate($entity)); + + $entity->setValidation(false); + + $violations = new ConstraintViolationList(); $this->assertEquals($violations, $this->validator->validate($entity)); } From dd12ff836d733cfcd3159603206a6121afc35ca5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20H=C3=B6rl?= Date: Sun, 15 Jan 2012 13:11:15 +0100 Subject: [PATCH 3/4] CS fix, getConstraints renamed --- src/Symfony/Component/Validator/ConstraintProviderInterface.php | 2 +- src/Symfony/Component/Validator/Validator.php | 2 +- .../Component/Validator/Fixtures/DynamicConstraintsEntity.php | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/Symfony/Component/Validator/ConstraintProviderInterface.php b/src/Symfony/Component/Validator/ConstraintProviderInterface.php index 4541b622e4..628fad4693 100644 --- a/src/Symfony/Component/Validator/ConstraintProviderInterface.php +++ b/src/Symfony/Component/Validator/ConstraintProviderInterface.php @@ -23,5 +23,5 @@ interface ConstraintProviderInterface * * @param Mapping\ClassMetadata */ - public function getConstraints(ClassMetadata $metadata); + function registerConstraints(ClassMetadata $metadata); } diff --git a/src/Symfony/Component/Validator/Validator.php b/src/Symfony/Component/Validator/Validator.php index 714090842d..dbbf786fe3 100644 --- a/src/Symfony/Component/Validator/Validator.php +++ b/src/Symfony/Component/Validator/Validator.php @@ -62,7 +62,7 @@ class Validator implements ValidatorInterface if ($object instanceof ConstraintProviderInterface) { $dynamicMetadata = new ClassMetadata(get_class($object)); $dynamicMetadata->mergeConstraints($metadata); - $object->getConstraints($dynamicMetadata); + $object->registerConstraints($dynamicMetadata); $metadata = $dynamicMetadata; } diff --git a/tests/Symfony/Tests/Component/Validator/Fixtures/DynamicConstraintsEntity.php b/tests/Symfony/Tests/Component/Validator/Fixtures/DynamicConstraintsEntity.php index 1cab8339bf..e0d5a66a9a 100644 --- a/tests/Symfony/Tests/Component/Validator/Fixtures/DynamicConstraintsEntity.php +++ b/tests/Symfony/Tests/Component/Validator/Fixtures/DynamicConstraintsEntity.php @@ -20,7 +20,7 @@ class DynamicConstraintsEntity implements ConstraintProviderInterface return null; } - public function getConstraints(ClassMetadata $metadata) + public function registerConstraints(ClassMetadata $metadata) { if ($this->validationEnabled) { $metadata->addPropertyConstraint('firstValue', new FailingConstraint()); From 92f820a09452c5146e31eeb872c5779b9b590623 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20H=C3=B6rl?= Date: Wed, 18 Jan 2012 22:24:42 +0100 Subject: [PATCH 4/4] Renamed registerConstraints to loadDynamicValidatorMetadata --- src/Symfony/Component/Validator/ConstraintProviderInterface.php | 2 +- src/Symfony/Component/Validator/Validator.php | 2 +- .../Component/Validator/Fixtures/DynamicConstraintsEntity.php | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/Symfony/Component/Validator/ConstraintProviderInterface.php b/src/Symfony/Component/Validator/ConstraintProviderInterface.php index 628fad4693..c081d3ad13 100644 --- a/src/Symfony/Component/Validator/ConstraintProviderInterface.php +++ b/src/Symfony/Component/Validator/ConstraintProviderInterface.php @@ -23,5 +23,5 @@ interface ConstraintProviderInterface * * @param Mapping\ClassMetadata */ - function registerConstraints(ClassMetadata $metadata); + function loadDynamicValidatorMetadata(ClassMetadata $metadata); } diff --git a/src/Symfony/Component/Validator/Validator.php b/src/Symfony/Component/Validator/Validator.php index dbbf786fe3..2327aa1c0b 100644 --- a/src/Symfony/Component/Validator/Validator.php +++ b/src/Symfony/Component/Validator/Validator.php @@ -62,7 +62,7 @@ class Validator implements ValidatorInterface if ($object instanceof ConstraintProviderInterface) { $dynamicMetadata = new ClassMetadata(get_class($object)); $dynamicMetadata->mergeConstraints($metadata); - $object->registerConstraints($dynamicMetadata); + $object->loadDynamicValidatorMetadata($dynamicMetadata); $metadata = $dynamicMetadata; } diff --git a/tests/Symfony/Tests/Component/Validator/Fixtures/DynamicConstraintsEntity.php b/tests/Symfony/Tests/Component/Validator/Fixtures/DynamicConstraintsEntity.php index e0d5a66a9a..41bfe44d39 100644 --- a/tests/Symfony/Tests/Component/Validator/Fixtures/DynamicConstraintsEntity.php +++ b/tests/Symfony/Tests/Component/Validator/Fixtures/DynamicConstraintsEntity.php @@ -20,7 +20,7 @@ class DynamicConstraintsEntity implements ConstraintProviderInterface return null; } - public function registerConstraints(ClassMetadata $metadata) + public function loadDynamicValidatorMetadata(ClassMetadata $metadata) { if ($this->validationEnabled) { $metadata->addPropertyConstraint('firstValue', new FailingConstraint());