Skip to content

[Form] ChoiceType undefined index issue when using $resolver->setNormalizer('choices', #17270

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
jrattue opened this issue Jan 5, 2016 · 8 comments

Comments

@jrattue
Copy link

jrattue commented Jan 5, 2016

In 2.7.8 using setNormalizer to update 'choices' in a Form causes the below error:

CRITICAL - Uncaught PHP Exception Symfony\Component\Debug\Exception\ContextErrorException: 
"Notice: Undefined index: Attribute 1" at 
.../vendor/symfony/symfony/src/Symfony/Component/Form/Extension/Core/Type/ChoiceType.php line 288 

A new fork has been created to show this issue. This can be found here.

@xabbuh
Copy link
Member

xabbuh commented Jan 5, 2016

Did this work for you with any patch version of the 2.7 release?

@xabbuh xabbuh added the Form label Jan 5, 2016
@gseidel
Copy link
Contributor

gseidel commented Jan 5, 2016

I have the same issue with Symfony version 2.8.1

@gseidel
Copy link
Contributor

gseidel commented Jan 5, 2016

It only occurs if you also have a choice field define before your custom type which use the setNormalizer function.

https://github.com/Rattler3/symfony-standard/blob/example/src/AppBundle/Controller/DefaultController.php

If you changed the order choice and choiceTwoit works for me. Maybe this helps for now if the order of the builder doesn't matter.

I guess it has something to do with this comment a few lines before in ChoiceType, because the fields have some dependencies on each other.

// Don't pass the labels by reference. We do want to create a
// copy here so that every form has an own version of that
// variable (contrary to the $choiceLabels object shared by all
// forms)

@xabbuh
Copy link
Member

xabbuh commented Jan 5, 2016

It only occurs if you also have a choice field define before your custom type which use the setNormalizer function.

What do you mean with that?

@gseidel
Copy link
Contributor

gseidel commented Jan 5, 2016

What do you mean with that?

Look at the DefaultController in the example. If you remove

        $builder->add('choice', 'choice', array(
            'choices' => array(
                '1' => '1',
                '2' => '2',
                '3' => '3',
                '4' => '4',
                '5' => '5'
            )
        ));

It works also if you change the order like that.

        $builder->add('choiceTwo', new ExampleChoiceType(), array(
            'show_all' => false
        ));

        $builder->add('choice', 'choice', array(
            'choices' => array(
                '1' => '1',
                '2' => '2',
                '3' => '3',
                '4' => '4',
                '5' => '5'
            )
        ));

Please remind that i didn't try that with Rattler3 example, but on my issue that works before. I only transfer that behaviour i found to this example.

@gseidel
Copy link
Contributor

gseidel commented Jan 5, 2016

Maybe @Rattler3 can confirm that behaviour.

@jrattue
Copy link
Author

jrattue commented Jan 5, 2016

@xabbuh This worked in the previous version (2.7.7) also not working when I tested in 2.8.0.

I can also confirm what @gseidel is saying. This only happens if both choice fields are present and the choice field with the setNormalizer is the second item. This can be seen in the example controller

@paradajozsef
Copy link
Contributor

I can confirm this behaviour. It occurs in 2.7.9 and 2.8.0. I proposed a PR: #17406. @gseidel has been right with this statement:

I guess it has something to do with this comment a few lines before in ChoiceType, because the fields have some dependencies on each other.

@xabbuh xabbuh added the Bug label Jan 17, 2016
fabpot added a commit that referenced this issue Jan 19, 2016
…is replaced (paradajozsef)

This PR was squashed before being merged into the 2.7 branch (closes #17406).

Discussion
----------

[Form] ChoiceType: Fix a notice when 'choices' normalizer is replaced

| Q             | A
| ------------- | ---
| Bug fix?      | yes
| New feature?  | no
| BC breaks?    | no
| Deprecations? | no
| Tests pass?   | yes
| Fixed tickets | #17270
| License       | MIT
| Doc PR        | -

As @gseidel [mentioned](#17270 (comment)), the notice only occurs, when a custom choice field added after a choice field **and** the custom type is expanded, **and** the ```'choices'``` normalizer is replaced. The problem is that when ```'choices'``` option is replaced, the [default choiceNormalizer](https://github.com/symfony/symfony/blob/2.7/src/Symfony/Component/Form/Extension/Core/Type/ChoiceType.php#L262) is not invoked. This normalizer would [clear](https://github.com/symfony/symfony/blob/2.7/src/Symfony/Component/Form/Extension/Core/Type/ChoiceType.php#L264) the labels from previous invocation, but it's been replaced in the custom choice type. As a result [$choiceLabel](https://github.com/symfony/symfony/blob/2.7/src/Symfony/Component/Form/Extension/Core/Type/ChoiceType.php#L279) normalizer will get the wrong labels because it shares the same scope with [$choiceNormalizer](https://github.com/symfony/symfony/blob/2.7/src/Symfony/Component/Form/Extension/Core/Type/ChoiceType.php#L262). Resetting the label values after copy solves this problem.

Commits
-------

be056fd [Form] ChoiceType: Fix a notice when 'choices' normalizer is replaced
@fabpot fabpot closed this as completed Jan 19, 2016
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

6 participants