8000 bug #18747 [2.8] [Form] Modified iterator_to_array's 2nd parameter to… · symfony/symfony@0753bd7 · GitHub
[go: up one dir, main page]

Skip to content
< 8000 script crossorigin="anonymous" defer="defer" type="application/javascript" src="https://github.githubassets.com/assets/sessions-1e75b15ae60a.js">

Commit 0753bd7

Browse files
committed
bug #18747 [2.8] [Form] Modified iterator_to_array's 2nd parameter to false in ViolationMapper (issei-m)
This PR was submitted for the 2.8 branch but it was merged into the 2.7 branch instead (closes #18747). Discussion ---------- [2.8] [Form] Modified iterator_to_array's 2nd parameter to false in ViolationMapper | Q | A | ------------- | --- | Branch? | 2.8 | Bug fix? | yes | New feature? | no | BC breaks? | no | Deprecations? | no | Tests pass? | yes | Fixed tickets | n/a | License | MIT | Doc PR | n/a This bug was introduced in PR #17099. So does not represent in 2.8.2 or older. If we have the following structure form: ```php $builder = $formFactory->createBuilder(); $form = $builder ->add( $builder->create('person1_name', FormType::class, ['inherit_data' => true]) ->add('first', TextType::class, ['property_path' => '[person1_first_name]']) ->add('last', TextType::class, ['property_path' => '[person1_last_name]']) ) ->add( $builder->create('person2_name', FormType::class, ['inherit_data' => true]) ->add('first', TextType::class, ['property_path' => '[person2_first_name]']) ->add('last', TextType::class, ['property_path' => '[person2_last_name]']) ) ->getForm() ; ``` The following mapping for this form doesn't work correctly: ```php $mapper = new ViolationMapper(); $mapper->mapViolation(new ConstraintViolation('', '', [], null, 'data[person1_first_name]', null), $form); $form['person1_name']['first']->getErrors(); // empty $form->getErrors(); // The violation is mapped to here instead. ``` ## Cause Because ViolationMapper uses `iterator_to_array` in [here](https://github.com/symfony/symfony/blob/f29d46f29b91ea5c30699cf6bdb8e65545d1dd26/src/Symfony/Component/Form/Extension/Validator/ViolationMapper/ViolationMapper.php#L165) to collect the sub forms. `person1_name` and `person2_name` enable `inherit_data` option. So ViolationMapper will attempt to collect the sub forms of root form like this: ```php [ 'first' => Form object, // root.person1_name.first 'last' => Form object, // root.person1_name.last 'first' => Form object, // root.person2_name.first 'last' => Form object, // root.person2_name.last ] ``` As you can see, The name `first` and `last` are used in two places, thus we cannot get result like that. (first/last of person1_name are overwritten by person2_name's) So the violation will finally lost the form where it should map to. It should pass `false` to `iterator_to_array`'s 2nd parameter. Commits ------- ae38660 [2.8] [Form] Modified iterator_to_array's 2nd parameter to false in ViolationMapper
2 parents 4a065b4 + ae38660 commit 0753bd7

File tree

1 file changed

+21
-6
lines changed

1 file changed

+21
-6
lines changed

src/Symfony/Component/Form/Tests/Extension/Validator/ViolationMapper/ViolationMapperTest.php

Lines changed: 21 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1542,24 +1542,39 @@ public function testErrorMappingForFormInheritingParentData($target, $childName,
15421542

15431543
public function testBacktrackIfSeveralSubFormsWithSamePropertyPath()
15441544
{
1545-
$violation = $this->getConstraintViolation('data.address[street]');
15461545
$parent = $this->getForm('parent');
15471546
$child1 = $this->getForm('subform1', 'address');
15481547
$child2 = $this->getForm('subform2', 'address');
1549-
$grandChild = $this->getForm('street');
1548+
$child3 = $this->getForm('subform3', null, null, array(), true);
1549+
$child4 = $this->getForm('subform4', null, null, array(), true);
1550+
$grandChild1 = $this->getForm('street');
1551+
$grandChild2 = $this->getForm('street', '[sub_address1_street]');
1552+
$grandChild3 = $this->getForm('street', '[sub_address2_street]');
15501553

15511554
$parent->add($child1);
15521555
$parent->add($child2);
1553-
$child2->add($grandChild);
1556+
$parent->add($child3);
1557+
$parent->add($child4);
1558+
$child2->add($grandChild1);
1559+
$child3->add($grandChild2);
1560+
$child4->add($grandChild3);
15541561

15551562
$parent->submit(array());
15561563

1557-
$this->mapper->mapViolation($violation, $parent);
1564+
$violation1 = $this->getConstraintViolation('data.address[street]');
1565+
$violation2 = $this->getConstraintViolation('data[sub_address1_street]');
1566+
$violation3 = $this->getConstraintViolation('data[sub_address2_street]');
1567+
$this->mapper->mapViolation($violation1, $parent);
1568+
$this->mapper->mapViolation($violation2, $parent);
1569+
$this->mapper->mapViolation($violation3, $parent);
15581570

1559-
// The error occurred on the child of the second form with the same path
15601571
$this->assertCount(0, $parent->getErrors(), $parent->getName().' should not have an error, but has one');
15611572
$this->assertCount(0, $child1->getErrors(), $child1->getName().' should not have an error, but has one');
15621573
$this->assertCount(0, $child2->getErrors(), $child2->getName().' should not have an error, but has one');
1563-
$this->assertEquals(array($this->getFormError($violation, $grandChild)), iterator_to_array($grandChild->getErrors()), $grandChild->getName().' should have an error, but has none');
1574+
$this->assertCount(0, $child3->getErrors(), $child3->getName().' should not have an error, but has one');
1575+
$this->assertCount(0, $child4->getErrors(), $child4->getName().' should not have an error, but has one');
1576+
$this->assertEquals(array($this->getFormError($violation1, $grandChild1)), iterator_to_array($grandChild1->getErrors()), $grandChild1->getName().' should have an error, but has none');
1577+
$this->assertEquals(array($this->getFormError($violation2, $grandChild2)), iterator_to_array($grandChild2->getErrors()), $grandChild2->getName().' should have an error, but has none');
1578+
$this->assertEquals(array($this->getFormError($violation3, $grandChild3)), iterator_to_array($grandChild3->getErrors()), $grandChild3->getName().' should have an error, but has none');
15641579
}
15651580
}

0 commit comments

Comments
 (0)
0