Skip to content

Commit 8ea3e7a

Browse files
Merge branch '4.4' into 5.1
* 4.4: disallow FrameworkBundle 4.4+ propagate validation groups to subforms [Form] [Validator] Add failing testcase to demonstrate group sequence issue
2 parents 56679fe + 3d39874 commit 8ea3e7a

File tree

2 files changed

+37
-2
lines changed

2 files changed

+37
-2
lines changed

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

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
class FormValidator extends ConstraintValidator
2626
{
2727
private $resolvedGroups;
28+
private $fieldFormConstraints;
2829

2930
/**
3031
* {@inheritdoc}
@@ -67,6 +68,7 @@ public function validate($form, Constraint $formConstraint)
6768

6869
if ($hasChildren && $form->isRoot()) {
6970
$this->resolvedGroups = new \SplObjectStorage();
71+
$this->fieldFormConstraints = [];
7072
}
7173

7274
if ($groups instanceof GroupSequence) {
@@ -84,14 +86,16 @@ public function validate($form, Constraint $formConstraint)
8486

8587
foreach ($form->all() as $field) {
8688
if ($field->isSubmitted()) {
87-
// remember to validate this field is one group only
89+
// remember to validate this field in one group only
8890
// otherwise resolving the groups would reuse the same
8991
// sequence recursively, thus some fields could fail
9092
// in different steps without breaking early enough
9193
$this->resolvedGroups[$field] = (array) $group;
9294
$fieldFormConstraint = new Form();
95+
$fieldFormConstraint->groups = $group;
96+
$this->fieldFormConstraints[] = $fieldFormConstraint;
9397
$this->context->setNode($this->context->getValue(), $field, $this->context->getMetadata(), $this->context->getPropertyPath());
94-
$validator->atPath(sprintf('children[%s]', $field->getName()))->validate($field, $fieldFormConstraint);
98+
$validator->atPath(sprintf('children[%s]', $field->getName()))->validate($field, $fieldFormConstraint, $group);
9599
}
96100
}
97101

@@ -136,6 +140,7 @@ public function validate($form, Constraint $formConstraint)
136140
if ($field->isSubmitted()) {
137141
$this->resolvedGroups[$field] = $groups;
138142
$fieldFormConstraint = new Form();
143+
$this->fieldFormConstraints[] = $fieldFormConstraint;
139144
$this->context->setNode($this->context->getValue(), $field, $this->context->getMetadata(), $this->context->getPropertyPath());
140145
$validator->atPath(sprintf('children[%s]', $field->getName()))->validate($field, $fieldFormConstraint);
141146
}
@@ -145,6 +150,7 @@ public function validate($form, Constraint $formConstraint)
145150
if ($hasChildren && $form->isRoot()) {
146151
// destroy storage to avoid memory leaks
147152
$this->resolvedGroups = new \SplObjectStorage();
153+
$this->fieldFormConstraints = [];
148154
}
149155
} elseif (!$form->isSynchronized()) {
150156
$childrenSynchronized = true;
@@ -155,6 +161,7 @@ public function validate($form, Constraint $formConstraint)
155161
$childrenSynchronized = false;
156162

157163
$fieldFormConstraint = new Form();
164+
$this->fieldFormConstraints[] = $fieldFormConstraint;
158165
$this->context->setNode($this->context->getValue(), $child, $this->context->getMetadata(), $this->context->getPropertyPath());
159166
$validator->atPath(sprintf('children[%s]', $child->getName()))->validate($child, $fieldFormConstraint);
160167
}

src/Symfony/Component/Form/Tests/Extension/Validator/Constraints/FormValidatorFunctionalTest.php

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -233,6 +233,34 @@ public function testConstraintsInDifferentGroupsOnSingleField()
233233
$this->assertInstanceOf(Length::class, $errors[0]->getCause()->getConstraint());
234234
}
235235

236+
public function testConstraintsInDifferentGroupsOnSingleFieldWithAdditionalFieldThatHasNoConstraintsAddedBeforeTheFieldWithConstraints()
237+
{
238+
$form = $this->formFactory->create(FormType::class, null, [
239+
'validation_groups' => new GroupSequence(['group1', 'group2']),
240+
])
241+
->add('bar')
242+
->add('foo', TextType::class, [
243+
'constraints' => [
244+
new NotBlank([
245+
'groups' => ['group1'],
246+
]),
247+
new Length([
248+
'groups' => ['group2'],
249+
'max' => 3,
250+
]),
251+
],
252+
]);
253+
$form->submit([
254+
'foo' => '[email protected]',
255+
]);
256+
257+
$errors = $form->getErrors(true);
258+
259+
$this->assertFalse($form->isValid());
260+
$this->assertCount(1, $errors);
261+
$this->assertInstanceOf(Length::class, $errors[0]->getCause()->getConstraint());
262+
}
263+
236264
public function testCascadeValidationToChildFormsUsingPropertyPaths()
237265
{
238266
$form = $this->formFactory->create(FormType::class, null, [

0 commit comments

Comments
 (0)