Skip to content

Commit d17a4d2

Browse files
committed
validate subforms in all validation groups
1 parent 8f2c68f commit d17a4d2

File tree

3 files changed

+42
-6
lines changed

3 files changed

+42
-6
lines changed

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

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -86,7 +86,8 @@ public function validate($form, Constraint $formConstraint)
8686
// sequence recursively, thus some fields could fail
8787
// in different steps without breaking early enough
8888
$this->resolvedGroups[$field] = (array) $group;
89-
$validator->atPath(sprintf($fieldPropertyPath, $field->getPropertyPath()))->validate($field, $formConstraint);
89+
$fieldFormConstraint = new Form();
90+
$validator->atPath(sprintf($fieldPropertyPath, $field->getPropertyPath()))->validate($field, $fieldFormConstraint);
9091
}
9192
}
9293

@@ -100,6 +101,8 @@ public function validate($form, Constraint $formConstraint)
100101
$this->resolvedGroups = null;
101102
}
102103
} else {
104+
$fieldPropertyPath = \is_object($data) ? 'children[%s]' : 'children%s';
105+
103106
if ($validateDataGraph) {
104107
$validator->atPath('data')->validate($data, null, $groups);
105108
}
@@ -125,6 +128,13 @@ public function validate($form, Constraint $formConstraint)
125128
}
126129
}
127130
}
131+
132+
foreach ($form->all() as $field) {
133+
if ($field->isSubmitted()) {
134+
$fieldFormConstraint = new Form();
135+
$validator->atPath(sprintf($fieldPropertyPath, $field->getPropertyPath()))->validate($field, $fieldFormConstraint);
136+
}
137+
}
128138
}
129139
} elseif (!$form->isSynchronized()) {
130140
$childrenSynchronized = true;

src/Symfony/Component/Form/Extension/Validator/ValidatorExtension.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,8 @@
1313

1414
use Symfony\Component\Form\AbstractExtension;
1515
use Symfony\Component\Form\Extension\Validator\Constraints\Form;
16-
use Symfony\Component\Validator\Constraints\Valid;
1716
use Symfony\Component\Validator\Mapping\ClassMetadata;
17+
use Symfony\Component\Validator\Mapping\TraversalStrategy;
1818
use Symfony\Component\Validator\Validator\ValidatorInterface;
1919

2020
/**
@@ -37,7 +37,7 @@ public function __construct(ValidatorInterface $validator)
3737

3838
/* @var $metadata ClassMetadata */
3939
$metadata->addConstraint(new Form());
40-
$metadata->addPropertyConstraint('children', new Valid());
40+
$metadata->traversalStrategy = TraversalStrategy::NONE;
4141

4242
$this->validator = $validator;
4343
}

src/Symfony/Component/Form/Tests/Extension/Validator/ValidatorExtensionTest.php

Lines changed: 29 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -54,9 +54,8 @@ public function test2Dot5ValidationApi()
5454
$this->assertInstanceOf(FormConstraint::class, $metadata->getConstraints()[0]);
5555

5656
$this->assertSame(CascadingStrategy::NONE, $metadata->cascadingStrategy);
57-
$this->assertSame(TraversalStrategy::IMPLICIT, $metadata->traversalStrategy);
58-
$this->assertSame(CascadingStrategy::CASCADE, $metadata->getPropertyMetadata('children')[0]->cascadingStrategy);
59-
$this->assertSame(TraversalStrategy::IMPLICIT, $metadata->getPropertyMetadata('children')[0]->traversalStrategy);
57+
$this->assertSame(TraversalStrategy::NONE, $metadata->traversalStrategy);
58+
$this->assertCount(0, $metadata->getPropertyMetadata('children'));
6059
}
6160

6261
public function testDataConstraintsInvalidateFormEvenIfFieldIsNotSubmitted()
@@ -138,6 +137,33 @@ public function testFieldsValidateInSequenceWithNestedGroupsArray()
138137
$this->assertInstanceOf(Length::class, $errors[1]->getCause()->getConstraint());
139138
}
140139

140+
public function testConstraintsInDifferentGroupsOnSingleField()
141+
{
142+
$form = $this->createForm(FormType::class, null, [
143+
'validation_groups' => new GroupSequence(['group1', 'group2']),
144+
])
145+
->add('foo', TextType::class, [
146+
'constraints' => [
147+
new NotBlank([
148+
'groups' => ['group1'],
149+
]),
150+
new Length([
151+
'groups' => ['group2'],
152+
'max' => 3,
153+
]),
154+
],
155+
]);
156+
$form->submit([
157+
'foo' => 'test@example.com',
158+
]);
159+
160+
$errors = $form->getErrors(true);
161+
162+
$this->assertFalse($form->isValid());
163+
$this->assertCount(1, $errors);
164+
$this->assertInstanceOf(Length::class, $errors[0]->getCause()->getConstraint());
165+
}
166+
141167
private function createForm($type, $data = null, array $options = [])
142168
{
143169
$validator = Validation::createValidatorBuilder()

0 commit comments

Comments
 (0)