From fb91f74b34f2ea8064ad790677c4cb8207848ef0 Mon Sep 17 00:00:00 2001 From: Christian Flothmann Date: Sat, 17 Dec 2016 23:43:59 +0100 Subject: [PATCH] [Form] fix group sequence based validation --- .../Validator/Constraints/FormValidator.php | 15 ++++-- .../Validator/Type/BaseValidatorExtension.php | 5 ++ .../Constraints/FormValidatorTest.php | 50 +++++++++++-------- .../Type/BaseValidatorExtensionTest.php | 10 ++++ 4 files changed, 56 insertions(+), 24 deletions(-) diff --git a/src/Symfony/Component/Form/Extension/Validator/Constraints/FormValidator.php b/src/Symfony/Component/Form/Extension/Validator/Constraints/FormValidator.php index 8333e7c216..5b989f1a60 100644 --- a/src/Symfony/Component/Form/Extension/Validator/Constraints/FormValidator.php +++ b/src/Symfony/Component/Form/Extension/Validator/Constraints/FormValidator.php @@ -13,6 +13,7 @@ namespace Symfony\Component\Form\Extension\Validator\Constraints; use Symfony\Component\Form\FormInterface; use Symfony\Component\Validator\Constraint; +use Symfony\Component\Validator\Constraints\GroupSequence; use Symfony\Component\Validator\ConstraintValidator; use Symfony\Component\Validator\Context\ExecutionContextInterface; use Symfony\Component\Validator\Exception\UnexpectedTypeException; @@ -49,10 +50,12 @@ class FormValidator extends ConstraintValidator // Validate the data against its own constraints if (self::allowDataWalking($form)) { - foreach ($groups as $group) { - if ($validator) { - $validator->atPath('data')->validate($form->getData(), null, $group); - } else { + if ($validator) { + if (is_array($groups) && count($groups) > 0 || $groups instanceof GroupSequence && count($groups->groups) > 0) { + $validator->atPath('data')->validate($form->getData(), null, $groups); + } + } else { + foreach ($groups as $group) { // 2.4 API $this->context->validate($form->getData(), 'data', $group, true); } @@ -218,6 +221,10 @@ class FormValidator extends ConstraintValidator $groups = call_user_func($groups, $form); } + if ($groups instanceof GroupSequence) { + return $groups; + } + return (array) $groups; } } diff --git a/src/Symfony/Component/Form/Extension/Validator/Type/BaseValidatorExtension.php b/src/Symfony/Component/Form/Extension/Validator/Type/BaseValidatorExtension.php index 512d8184e4..4f52003c0d 100644 --- a/src/Symfony/Component/Form/Extension/Validator/Type/BaseValidatorExtension.php +++ b/src/Symfony/Component/Form/Extension/Validator/Type/BaseValidatorExtension.php @@ -14,6 +14,7 @@ namespace Symfony\Component\Form\Extension\Validator\Type; use Symfony\Component\Form\AbstractTypeExtension; use Symfony\Component\OptionsResolver\Options; use Symfony\Component\OptionsResolver\OptionsResolver; +use Symfony\Component\Validator\Constraints\GroupSequence; /** * Encapsulates common logic of {@link FormTypeValidatorExtension} and @@ -42,6 +43,10 @@ abstract class BaseValidatorExtension extends AbstractTypeExtension return $groups; } + if ($groups instanceof GroupSequence) { + return $groups; + } + return (array) $groups; }; diff --git a/src/Symfony/Component/Form/Tests/Extension/Validator/Constraints/FormValidatorTest.php b/src/Symfony/Component/Form/Tests/Extension/Validator/Constraints/FormValidatorTest.php index 9e7bdee25e..5047ecabd5 100644 --- a/src/Symfony/Component/Form/Tests/Extension/Validator/Constraints/FormValidatorTest.php +++ b/src/Symfony/Component/Form/Tests/Extension/Validator/Constraints/FormValidatorTest.php @@ -18,6 +18,7 @@ use Symfony\Component\Form\FormInterface; use Symfony\Component\Form\Extension\Validator\Constraints\Form; use Symfony\Component\Form\Extension\Validator\Constraints\FormValidator; use Symfony\Component\Form\SubmitButtonBuilder; +use Symfony\Component\Validator\Constraints\GroupSequence; use Symfony\Component\Validator\Constraints\NotNull; use Symfony\Component\Validator\Constraints\NotBlank; use Symfony\Component\Validator\Tests\Constraints\AbstractConstraintValidatorTest; @@ -73,8 +74,7 @@ class FormValidatorTest extends AbstractConstraintValidatorTest ->setData($object) ->getForm(); - $this->expectValidateAt(0, 'data', $object, 'group1'); - $this->expectValidateAt(1, 'data', $object, 'group2'); + $this->expectValidateAt(0, 'data', $object, array('group1', 'group2')); $this->validator->validate($form, new Form()); @@ -96,12 +96,11 @@ class FormValidatorTest extends AbstractConstraintValidatorTest ->getForm(); // First default constraints - $this->expectValidateAt(0, 'data', $object, 'group1'); - $this->expectValidateAt(1, 'data', $object, 'group2'); + $this->expectValidateAt(0, 'data', $object, array('group1', 'group2')); // Then custom constraints - $this->expectValidateValueAt(2, 'data', $object, $constraint1, 'group1'); - $this->expectValidateValueAt(3, 'data', $object, $constraint2, 'group2'); + $this->expectValidateValueAt(1, 'data', $object, $constraint1, 'group1'); + $this->expectValidateValueAt(2, 'data', $object, $constraint2, 'group2'); $this->validator->validate($form, new Form()); @@ -135,7 +134,7 @@ class FormValidatorTest extends AbstractConstraintValidatorTest $form = new FormBuilder('name', '\stdClass', $this->dispatcher, $this->factory); $form = $form->setData($object)->getForm(); - $this->expectValidateAt(0, 'data', $object, 'Default'); + $this->expectValidateAt(0, 'data', $object, array('Default')); $this->validator->validate($form, new Form()); @@ -347,6 +346,21 @@ class FormValidatorTest extends AbstractConstraintValidatorTest } public function testHandleCallbackValidationGroups() + { + $object = $this->getMock('\stdClass'); + $options = array('validation_groups' => new GroupSequence(array('group1', 'group2'))); + $form = $this->getBuilder('name', '\stdClass', $options) + ->setData($object) + ->getForm(); + + $this->expectValidateAt(0, 'data', $object, new GroupSequence(array('group1', 'group2'))); + + $this->validator->validate($form, new Form()); + + $this->assertNoViolation(); + } + + public function testHandleGroupSequenceValidationGroups() { $object = $this->getMock('\stdClass'); $options = array('validation_groups' => array($this, 'getValidationGroups')); @@ -354,8 +368,7 @@ class FormValidatorTest extends AbstractConstraintValidatorTest ->setData($object) ->getForm(); - $this->expectValidateAt(0, 'data', $object, 'group1'); - $this->expectValidateAt(1, 'data', $object, 'group2'); + $this->expectValidateAt(0, 'data', $object, array('group1', 'group2')); $this->validator->validate($form, new Form()); @@ -370,7 +383,7 @@ class FormValidatorTest extends AbstractConstraintValidatorTest ->setData($object) ->getForm(); - $this->expectValidateAt(0, 'data', $object, 'header'); + $this->expectValidateAt(0, 'data', $object, array('header')); $this->validator->validate($form, new Form()); @@ -387,8 +400,7 @@ class FormValidatorTest extends AbstractConstraintValidatorTest ->setData($object) ->getForm(); - $this->expectValidateAt(0, 'data', $object, 'group1'); - $this->expectValidateAt(1, 'data', $object, 'group2'); + $this->expectValidateAt(0, 'data', $object, array('group1', 'group2')); $this->validator->validate($form, new Form()); @@ -414,7 +426,7 @@ class FormValidatorTest extends AbstractConstraintValidatorTest $parent->submit(array('name' => $object, 'submit' => '')); - $this->expectValidateAt(0, 'data', $object, 'button_group'); + $this->expectValidateAt(0, 'data', $object, array('button_group')); $this->validator->validate($form, new Form()); @@ -440,7 +452,7 @@ class FormValidatorTest extends AbstractConstraintValidatorTest $form->setData($object); - $this->expectValidateAt(0, 'data', $object, 'form_group'); + $this->expectValidateAt(0, 'data', $object, array('form_group')); $this->validator->validate($form, new Form()); @@ -464,7 +476,7 @@ class FormValidatorTest extends AbstractConstraintValidatorTest $form->setData($object); - $this->expectValidateAt(0, 'data', $object, 'group'); + $this->expectValidateAt(0, 'data', $object, array('group')); $this->validator->validate($form, new Form()); @@ -488,8 +500,7 @@ class FormValidatorTest extends AbstractConstraintValidatorTest $form->setData($object); - $this->expectValidateAt(0, 'data', $object, 'group1'); - $this->expectValidateAt(1, 'data', $object, 'group2'); + $this->expectValidateAt(0, 'data', $object, array('group1', 'group2')); $this->validator->validate($form, new Form()); @@ -515,8 +526,7 @@ class FormValidatorTest extends AbstractConstraintValidatorTest $form->setData($object); - $this->expectValidateAt(0, 'data', $object, 'group1'); - $this->expectValidateAt(1, 'data', $object, 'group2'); + $this->expectValidateAt(0, 'data', $object, array('group1', 'group2')); $this->validator->validate($form, new Form()); @@ -530,7 +540,7 @@ class FormValidatorTest extends AbstractConstraintValidatorTest ->setData($object) ->getForm(); - $this->expectValidateAt(0, 'data', $object, 'Default'); + $this->expectValidateAt(0, 'data', $object, array('Default')); $this->validator->validate($form, new Form()); diff --git a/src/Symfony/Component/Form/Tests/Extension/Validator/Type/BaseValidatorExtensionTest.php b/src/Symfony/Component/Form/Tests/Extension/Validator/Type/BaseValidatorExtensionTest.php index 01f20c4127..f12b915b9a 100644 --- a/src/Symfony/Component/Form/Tests/Extension/Validator/Type/BaseValidatorExtensionTest.php +++ b/src/Symfony/Component/Form/Tests/Extension/Validator/Type/BaseValidatorExtensionTest.php @@ -12,6 +12,7 @@ namespace Symfony\Component\Form\Tests\Extension\Validator\Type; use Symfony\Component\Form\Test\FormInterface; +use Symfony\Component\Validator\Constraints\GroupSequence; /** * @author Bernhard Schussek @@ -70,5 +71,14 @@ abstract class BaseValidatorExtensionTest extends TypeTestCase $this->assertInternalType('callable', $form->getConfig()->getOption('validation_groups')); } + public function testValidationGroupsCanBeSetToGroupSequence() + { + $form = $this->createForm(array( + 'validation_groups' => new GroupSequence(array('group1', 'group2')), + )); + + $this->assertInstanceOf('Symfony\Component\Validator\Constraints\GroupSequence', $form->getConfig()->getOption('validation_groups')); + } + abstract protected function createForm(array $options = array()); }