Skip to content

Commit

Permalink
properly cascade validation to child forms
Browse files Browse the repository at this point in the history
  • Loading branch information
xabbuh committed Jun 4, 2020
1 parent 3519647 commit 7df5298
Show file tree
Hide file tree
Showing 2 changed files with 61 additions and 6 deletions.
Expand Up @@ -72,7 +72,6 @@ public function validate($form, Constraint $formConstraint)
if ($groups instanceof GroupSequence) {
// Validate the data, the form AND nested fields in sequence
$violationsCount = $this->context->getViolations()->count();
$fieldPropertyPath = \is_object($data) ? 'children[%s]' : 'children%s';

foreach ($groups->groups as $group) {
if ($validateDataGraph) {
Expand All @@ -91,7 +90,7 @@ public function validate($form, Constraint $formConstraint)
// in different steps without breaking early enough
$this->resolvedGroups[$field] = (array) $group;
$fieldFormConstraint = new Form();
$validator->atPath(sprintf($fieldPropertyPath, $field->getPropertyPath()))->validate($field, $fieldFormConstraint);
$validator->atPath(sprintf('children[%s]', $field->getName()))->validate($field, $fieldFormConstraint);
}
}

Expand All @@ -100,8 +99,6 @@ public function validate($form, Constraint $formConstraint)
}
}
} else {
$fieldPropertyPath = \is_object($data) ? 'children[%s]' : 'children%s';

if ($validateDataGraph) {
$validator->atPath('data')->validate($data, null, $groups);
}
Expand Down Expand Up @@ -132,7 +129,7 @@ public function validate($form, Constraint $formConstraint)
if ($field->isSubmitted()) {
$this->resolvedGroups[$field] = $groups;
$fieldFormConstraint = new Form();
$validator->atPath(sprintf($fieldPropertyPath, $field->getPropertyPath()))->validate($field, $fieldFormConstraint);
$validator->atPath(sprintf('children[%s]', $field->getName()))->validate($field, $fieldFormConstraint);
}
}
}
Expand Down
Expand Up @@ -18,6 +18,7 @@
use Symfony\Component\Form\Extension\Core\DataMapper\PropertyPathMapper;
use Symfony\Component\Form\Extension\Validator\Constraints\Form;
use Symfony\Component\Form\Extension\Validator\Constraints\FormValidator;
use Symfony\Component\Form\Extension\Validator\ValidatorExtension;
use Symfony\Component\Form\FormBuilder;
use Symfony\Component\Form\FormFactoryBuilder;
use Symfony\Component\Form\FormFactoryInterface;
Expand Down Expand Up @@ -51,7 +52,9 @@ class FormValidatorTest extends ConstraintValidatorTestCase
protected function setUp()
{
$this->dispatcher = new EventDispatcher();
$this->factory = (new FormFactoryBuilder())->getFormFactory();
$this->factory = (new FormFactoryBuilder())
->addExtension(new ValidatorExtension(Validation::createValidator()))
->getFormFactory();

parent::setUp();

Expand Down Expand Up @@ -791,6 +794,61 @@ public function testCompositeConstraintValidatedInSequence()
$this->assertSame('data[field1]', $context->getViolations()[0]->getPropertyPath());
}

public function testCascadeValidationToChildFormsUsingPropertyPaths()
{
$form = $this->getCompoundForm([], [
'validation_groups' => ['group1', 'group2'],
])
->add('field1', null, [
'constraints' => [new NotBlank(['groups' => 'group1'])],
'property_path' => '[foo]',
])
->add('field2', null, [
'constraints' => [new NotBlank(['groups' => 'group2'])],
'property_path' => '[bar]',
])
;

$form->submit([
'field1' => '',
'field2' => '',
]);

$context = new ExecutionContext(Validation::createValidator(), $form, new IdentityTranslator());
$this->validator->initialize($context);
$this->validator->validate($form, new Form());

$this->assertCount(2, $context->getViolations());
$this->assertSame('This value should not be blank.', $context->getViolations()[0]->getMessage());
$this->assertSame('children[field1].data', $context->getViolations()[0]->getPropertyPath());
$this->assertSame('This value should not be blank.', $context->getViolations()[1]->getMessage());
$this->assertSame('children[field2].data', $context->getViolations()[1]->getPropertyPath());
}

public function testCascadeValidationToChildFormsUsingPropertyPathsValidatedInSequence()
{
$form = $this->getCompoundForm([], [
'validation_groups' => new GroupSequence(['group1', 'group2']),
])
->add('field1', null, [
'constraints' => [new NotBlank(['groups' => 'group1'])],
'property_path' => '[foo]',
])
;

$form->submit([
'field1' => '',
]);

$context = new ExecutionContext(Validation::createValidator(), $form, new IdentityTranslator());
$this->validator->initialize($context);
$this->validator->validate($form, new Form());

$this->assertCount(1, $context->getViolations());
$this->assertSame('This value should not be blank.', $context->getViolations()[0]->getMessage());
$this->assertSame('children[field1].data', $context->getViolations()[0]->getPropertyPath());
}

protected function createValidator()
{
return new FormValidator();
Expand Down

0 comments on commit 7df5298

Please sign in to comment.