bug #14551 [2.7][Form] Fixed ChoiceType with legacy ChoiceList (xelaris)
This PR was merged into the 2.7 branch.
Discussion
----------
[2.7][Form] Fixed ChoiceType with legacy ChoiceList
| Q | A
| ------------- | ---
| Bug fix? | yes
| New feature? | no
| BC breaks? | no
| Deprecations? | no
| Tests pass? | yes
| Fixed tickets | #14382
| License | MIT
| Doc PR |
The "Backwards compatibility" condition doesn't grap (e.g. when passing a `SimpleChoiceList` as `choice_list` on `ChoiceType`), as the default value for the `ChoiceType` option `preferred_choices` is `array()` instead of `null`. So I changed the condition from `null === $preferredChoices` to `empty($preferredChoices)`.
Then there was an issue with accessing `attr` in `form_div_layout.html.twig`, since the deprecated `Symfony\Component\Form\Extension\Core\View\ChoiceView` doesn't provide an `attr` attribute. Since the docblocks of `Symfony\Component\Form\ChoiceList\View\ChoiceListView` state `$choices` and `$preferredChoices` to be instances of `Symfony\Component\Form\ChoiceList\View\ChoiceView` instead of `Symfony\Component\Form\Extension\Core\View\ChoiceView` I fixed the template issue by mapping the deprecated `ChoiceView` objects to the new one with an empty `attr`.
@webmozart Could you have a look at it, please?
Without this PR the following example would render numeric values as labels:
```php
$formBuilder->add('choices', 'choice', array(
'choice_list' => new SimpleChoiceList(array(
'creditcard' => 'Credit card payment',
'cash' => 'Cash payment'
))
));
```
Commits
-------
a98e484
[Form] Fix ChoiceType with legacy ChoiceList
This commit is contained in:
commit
e9ecd0e00b
@ -20,6 +20,7 @@ use Symfony\Component\Form\ChoiceList\View\ChoiceGroupView;
|
||||
use Symfony\Component\Form\ChoiceList\View\ChoiceListView;
|
||||
use Symfony\Component\Form\ChoiceList\View\ChoiceView;
|
||||
use Symfony\Component\Form\Extension\Core\ChoiceList\ChoiceListInterface as LegacyChoiceListInterface;
|
||||
use Symfony\Component\Form\Extension\Core\View\ChoiceView as LegacyChoiceView;
|
||||
|
||||
/**
|
||||
* Default implementation of {@link ChoiceListFactoryInterface}.
|
||||
@ -140,9 +141,16 @@ class DefaultChoiceListFactory implements ChoiceListFactoryInterface
|
||||
public function createView(ChoiceListInterface $list, $preferredChoices = null, $label = null, $index = null, $groupBy = null, $attr = null)
|
||||
{
|
||||
// Backwards compatibility
|
||||
if ($list instanceof LegacyChoiceListInterface && null === $preferredChoices
|
||||
if ($list instanceof LegacyChoiceListInterface && empty($preferredChoices)
|
||||
&& null === $label && null === $index && null === $groupBy && null === $attr) {
|
||||
return new ChoiceListView($list->getRemainingViews(), $list->getPreferredViews());
|
||||
$mapToNonLegacyChoiceView = function (LegacyChoiceView $choiceView) {
|
||||
return new ChoiceView($choiceView->label, $choiceView->value, $choiceView->data);
|
||||
};
|
||||
|
||||
return new ChoiceListView(
|
||||
array_map($mapToNonLegacyChoiceView, $list->getRemainingViews()),
|
||||
array_map($mapToNonLegacyChoiceView, $list->getPreferredViews())
|
||||
);
|
||||
}
|
||||
|
||||
$preferredViews = array();
|
||||
|
@ -18,6 +18,7 @@ use Symfony\Component\Form\ChoiceList\LazyChoiceList;
|
||||
use Symfony\Component\Form\ChoiceList\View\ChoiceGroupView;
|
||||
use Symfony\Component\Form\ChoiceList\View\ChoiceListView;
|
||||
use Symfony\Component\Form\ChoiceList\View\ChoiceView;
|
||||
use Symfony\Component\Form\Extension\Core\View\ChoiceView as LegacyChoiceView;
|
||||
|
||||
class DefaultChoiceListFactoryTest extends \PHPUnit_Framework_TestCase
|
||||
{
|
||||
@ -735,8 +736,9 @@ class DefaultChoiceListFactoryTest extends \PHPUnit_Framework_TestCase
|
||||
*/
|
||||
public function testCreateViewForLegacyChoiceList()
|
||||
{
|
||||
$preferred = array(new ChoiceView('Preferred', 'x', 'x'));
|
||||
$other = array(new ChoiceView('Other', 'y', 'y'));
|
||||
// legacy ChoiceList instances provide legacy ChoiceView objects
|
||||
$preferred = array(new LegacyChoiceView('x', 'x', 'Preferred'));
|
||||
$other = array(new LegacyChoiceView('y', 'y', 'Other'));
|
||||
|
||||
$list = $this->getMock('Symfony\Component\Form\Extension\Core\ChoiceList\ChoiceListInterface');
|
||||
|
||||
@ -749,8 +751,8 @@ class DefaultChoiceListFactoryTest extends \PHPUnit_Framework_TestCase
|
||||
|
||||
$view = $this->factory->createView($list);
|
||||
|
||||
$this->assertSame($other, $view->choices);
|
||||
$this->assertSame($preferred, $view->preferredChoices);
|
||||
$this->assertEquals(array(new ChoiceView('Other', 'y', 'y')), $view->choices);
|
||||
$this->assertEquals(array(new ChoiceView('Preferred', 'x', 'x')), $view->preferredChoices);
|
||||
}
|
||||
|
||||
private function assertScalarListWithGeneratedValues(ChoiceListInterface $list)
|
||||
|
Reference in New Issue
Block a user