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

[2.8] [Form] Modified iterator_to_array's 2nd parameter to false in ViolationMapper #18747

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 2 commits into from

Conversation

issei-m
Copy link
Contributor

@issei-m issei-m commented May 11, 2016

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:

$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:

$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 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:

[
    '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.

@issei-m
Copy link
Contributor Author

issei-m commented May 12, 2016

ping @alekitto @webmozart

@alekitto
Copy link
Contributor

Yes, you're right, elements are overwritten in the $children array, but it was used to avoid to evaluate forms that surely are not a match, removing it will affect performances on complex forms.
Passing $use_keys = false to iterator_to_array should be sufficient.

However, the fix was originally submitted to the 2.3 branch, probably that branch is affected from this bug too...

@issei-m
Copy link
Contributor Author

issei-m commented May 12, 2016

@alekitto

$use_keys = false to iterator_to_array

Great! It's exactly what I want. I will fix soon.

2.3 branch

Indeed. I'm also gonna fix target branch.

@issei-m issei-m force-pushed the fix-violation-mapper-bug branch from fb920b0 to cf520b5 Compare May 12, 2016 10:31
@issei-m issei-m changed the title [Form] [Bug] Don't use iterator_to_array to collect the sub forms in ViolationMapper [2.8] [Form] Modified iterator_to_array's 2nd parameter to false in ViolationMapper May 12, 2016
@issei-m
Copy link
Contributor Author

issei-m commented May 12, 2016

@alekitto Updated. But cf520b5 cannot be merged into 2.3 as it is because it's using iterator_to_array for Form::getErrors().
So I'm gonna open the another PR for 2.3.

@issei-m
Copy link
Contributor Author

issei-m commented May 12, 2016

For 2.3: #18761

fabpot added a commit that referenced this pull request May 13, 2016
… false in ViolationMapper (issei-m)

This PR was squashed before being merged into the 2.3 branch (closes #18761).

Discussion
----------

[2.3] [Form] Modified iterator_to_array's 2nd parameter to false in ViolationMapper

| Q             | A
| ------------- | ---
| Branch?       | 2.3
| Bug fix?      | yes
| New feature?  | no
| BC breaks?    | no
| Deprecations? | no
| Tests pass?   | yes
| Fixed tickets | n/a
| License       | MIT
| Doc PR        | n/a

For #18747

Commits
-------

7101cab [2.3] [Form] Modified iterator_to_array's 2nd parameter to false in ViolationMapper
@fabpot
Copy link
Member

fabpot commented May 13, 2016

Thank you @issei-m.

fabpot added a commit that referenced this pull request May 13, 2016
… 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
@fabpot fabpot closed this May 13, 2016
@issei-m issei-m deleted the fix-violation-mapper-bug branch May 13, 2016 15:47
@fabpot fabpot mentioned this pull request May 13, 2016
This was referenced Jun 6, 2016
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants
Morty Proxy This is a proxified and sanitized view of the page, visit original site.