Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit 7df5298

Browse filesBrowse files
committed
properly cascade validation to child forms
1 parent 3519647 commit 7df5298
Copy full SHA for 7df5298

File tree

2 files changed

+61
-6
lines changed
Filter options

2 files changed

+61
-6
lines changed

‎src/Symfony/Component/Form/Extension/Validator/Constraints/FormValidator.php

Copy file name to clipboardExpand all lines: src/Symfony/Component/Form/Extension/Validator/Constraints/FormValidator.php
+2-5Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,6 @@ public function validate($form, Constraint $formConstraint)
7272
if ($groups instanceof GroupSequence) {
7373
// Validate the data, the form AND nested fields in sequence
7474
$violationsCount = $this->context->getViolations()->count();
75-
$fieldPropertyPath = \is_object($data) ? 'children[%s]' : 'children%s';
7675

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

@@ -100,8 +99,6 @@ public function validate($form, Constraint $formConstraint)
10099
}
101100
}
102101
} else {
103-
$fieldPropertyPath = \is_object($data) ? 'children[%s]' : 'children%s';
104-
105102
if ($validateDataGraph) {
106103
$validator->atPath('data')->validate($data, null, $groups);
107104
}
@@ -132,7 +129,7 @@ public function validate($form, Constraint $formConstraint)
132129
if ($field->isSubmitted()) {
133130
$this->resolvedGroups[$field] = $groups;
134131
$fieldFormConstraint = new Form();
135-
$validator->atPath(sprintf($fieldPropertyPath, $field->getPropertyPath()))->validate($field, $fieldFormConstraint);
132+
$validator->atPath(sprintf('children[%s]', $field->getName()))->validate($field, $fieldFormConstraint);
136133
}
137134
}
138135
}

‎src/Symfony/Component/Form/Tests/Extension/Validator/Constraints/FormValidatorTest.php

Copy file name to clipboardExpand all lines: src/Symfony/Component/Form/Tests/Extension/Validator/Constraints/FormValidatorTest.php
+59-1Lines changed: 59 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
use Symfony\Component\Form\Extension\Core\DataMapper\PropertyPathMapper;
1919
use Symfony\Component\Form\Extension\Validator\Constraints\Form;
2020
use Symfony\Component\Form\Extension\Validator\Constraints\FormValidator;
21+
use Symfony\Component\Form\Extension\Validator\ValidatorExtension;
2122
use Symfony\Component\Form\FormBuilder;
2223
use Symfony\Component\Form\FormFactoryBuilder;
2324
use Symfony\Component\Form\FormFactoryInterface;
@@ -51,7 +52,9 @@ class FormValidatorTest extends ConstraintValidatorTestCase
5152
protected function setUp()
5253
{
5354
$this->dispatcher = new EventDispatcher();
54-
$this->factory = (new FormFactoryBuilder())->getFormFactory();
55+
$this->factory = (new FormFactoryBuilder())
56+
->addExtension(new ValidatorExtension(Validation::createValidator()))
57+
->getFormFactory();
5558

5659
parent::setUp();
5760

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

797+
public function testCascadeValidationToChildFormsUsingPropertyPaths()
798+
{
799+
$form = $this->getCompoundForm([], [
800+
'validation_groups' => ['group1', 'group2'],
801+
])
802+
->add('field1', null, [
803+
'constraints' => [new NotBlank(['groups' => 'group1'])],
804+
'property_path' => '[foo]',
805+
])
806+
->add('field2', null, [
807+
'constraints' => [new NotBlank(['groups' => 'group2'])],
808+
'property_path' => '[bar]',
809+
])
810+
;
811+
812+
$form->submit([
813+
'field1' => '',
814+
'field2' => '',
815+
]);
816+
817+
$context = new ExecutionContext(Validation::createValidator(), $form, new IdentityTranslator());
818+
$this->validator->initialize($context);
819+
$this->validator->validate($form, new Form());
820+
821+
$this->assertCount(2, $context->getViolations());
822+
$this->assertSame('This value should not be blank.', $context->getViolations()[0]->getMessage());
823+
$this->assertSame('children[field1].data', $context->getViolations()[0]->getPropertyPath());
824+
$this->assertSame('This value should not be blank.', $context->getViolations()[1]->getMessage());
825+
$this->assertSame('children[field2].data', $context->getViolations()[1]->getPropertyPath());
826+
}
827+
828+
public function testCascadeValidationToChildFormsUsingPropertyPathsValidatedInSequence()
829+
{
830+
$form = $this->getCompoundForm([], [
831+
'validation_groups' => new GroupSequence(['group1', 'group2']),
832+
])
833+
->add('field1', null, [
834+
'constraints' => [new NotBlank(['groups' => 'group1'])],
835+
'property_path' => '[foo]',
836+
])
837+
;
838+
839+
$form->submit([
840+
'field1' => '',
841+
]);
842+
843+
$context = new ExecutionContext(Validation::createValidator(), $form, new IdentityTranslator());
844+
$this->validator->initialize($context);
845+
$this->validator->validate($form, new Form());
846+
847+
$this->assertCount(1, $context->getViolations());
848+
$this->assertSame('This value should not be blank.', $context->getViolations()[0]->getMessage());
849+
$this->assertSame('children[field1].data', $context->getViolations()[0]->getPropertyPath());
850+
}
851+
794852
protected function createValidator()
795853
{
796854
return new FormValidator();

0 commit comments

Comments
0 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.