Skip to content

Commit 79a3ee2

Browse files
committed
Deprecate passing false as $label to ChoiceListFactoryInterface
1 parent 43739db commit 79a3ee2

10 files changed

+95
-16
lines changed

UPGRADE-4.4.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,7 @@ Form
8585
reference date is deprecated.
8686
* Using `int` or `float` as data for the `NumberType` when the `input` option is set to `string` is deprecated.
8787
* Overriding the methods `FormIntegrationTestCase::setUp()`, `TypeTestCase::setUp()` and `TypeTestCase::tearDown()` without the `void` return-type is deprecated.
88+
* Deprecated passing `false` as `$label` to `ChoiceListFactoryInterface::createView`, pass a callable that returns false instead.
8889

8990
FrameworkBundle
9091
---------------

UPGRADE-5.0.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -215,6 +215,7 @@ Form
215215

216216
* The `regions` option was removed from the `TimezoneType`.
217217
* Added support for PHPUnit 8. A `void` return-type was added to the `FormIntegrationTestCase::setUp()`, `TypeTestCase::setUp()` and `TypeTestCase::tearDown()` methods.
218+
* Passing `false` as `$label` to `ChoiceListFactoryInterface::createView` now throws a `TypeError`, pass a callable that returns false instead.
218219

219220
FrameworkBundle
220221
---------------

src/Symfony/Component/Form/CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ CHANGELOG
1010
* deprecated using `int` or `float` as data for the `NumberType` when the `input` option is set to `string`
1111
* The type guesser guesses the HTML accept attribute when a mime type is configured in the File or Image constraint.
1212
* Overriding the methods `FormIntegrationTestCase::setUp()`, `TypeTestCase::setUp()` and `TypeTestCase::tearDown()` without the `void` return-type is deprecated.
13+
* deprecated passing `false` as `$label` to `ChoiceListFactoryInterface::createView`, pass a callable that returns false instead
1314

1415
4.3.0
1516
-----

src/Symfony/Component/Form/ChoiceList/Factory/CachingFactoryDecorator.php

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -116,8 +116,18 @@ public function createListFromLoader(ChoiceLoaderInterface $loader, $value = nul
116116
/**
117117
* {@inheritdoc}
118118
*/
119-
public function createView(ChoiceListInterface $list, $preferredChoices = null, $label = null, $index = null, $groupBy = null, $attr = null)
119+
public function createView(ChoiceListInterface $list, $preferredChoices = null, $label = null, $index = null, $groupBy = null, $attr = null/* , bool $triggerDeprecation = true */)
120120
{
121+
$triggerDeprecation = 6 >= \func_num_args() || func_get_arg(6);
122+
123+
if (false === $label) {
124+
if ($triggerDeprecation) {
125+
@trigger_error(sprintf('Passing false as $label to %s is deprecated in Symfony 4.4 and will trigger a TypeError in 5.0, pass a callable that returns false instead.', __METHOD__), E_USER_DEPRECATED);
126+
}
127+
128+
$label = static function () { return false; };
129+
}
130+
121131
// The input is not validated on purpose. This way, the decorated
122132
// factory may decide which input to accept and which not.
123133
$hash = self::generateHash([$list, $preferredChoices, $label, $index, $groupBy, $attr]);

src/Symfony/Component/Form/ChoiceList/Factory/DefaultChoiceListFactory.php

Lines changed: 27 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -45,20 +45,34 @@ public function createListFromLoader(ChoiceLoaderInterface $loader, $value = nul
4545
/**
4646
* {@inheritdoc}
4747
*/
48-
public function createView(ChoiceListInterface $list, $preferredChoices = null, $label = null, $index = null, $groupBy = null, $attr = null)
48+
public function createView(ChoiceListInterface $list, $preferredChoices = null, $label = null, $index = null, $groupBy = null, $attr = null/* , bool $triggerDeprecation = true */)
4949
{
50+
$triggerDeprecation = 6 >= \func_num_args() || func_get_arg(6);
51+
52+
if (false === $label) {
53+
if ($triggerDeprecation) {
54+
@trigger_error(sprintf('Passing false as $label to %s is deprecated in Symfony 4.4 and will trigger a TypeError in 5.0, pass a callable that returns false instead.', __METHOD__), E_USER_DEPRECATED);
55+
}
56+
57+
$label = static function () { return false; };
58+
}
59+
5060
$preferredViews = [];
5161
$preferredViewsOrder = [];
5262
$otherViews = [];
5363
$choices = $list->getChoices();
5464
$keys = $list->getOriginalKeys();
5565

56-
if (!\is_callable($preferredChoices) && !empty($preferredChoices)) {
57-
// make sure we have keys that reflect order
58-
$preferredChoices = array_values($preferredChoices);
59-
$preferredChoices = static function ($choice) use ($preferredChoices) {
60-
return array_search($choice, $preferredChoices, true);
61-
};
66+
if (!\is_callable($preferredChoices)) {
67+
if (empty($preferredChoices)) {
68+
$preferredChoices = null;
69+
} else {
70+
// make sure we have keys that reflect order
71+
$preferredChoices = array_values($preferredChoices);
72+
$preferredChoices = static function ($choice) use ($preferredChoices) {
73+
return array_search($choice, $preferredChoices, true);
74+
};
75+
}
6276
}
6377

6478
// The names are generated from an incrementing integer by default
@@ -76,7 +90,7 @@ public function createView(ChoiceListInterface $list, $preferredChoices = null,
7690
self::addChoiceViewsGroupedByCallable(
7791
$groupBy,
7892
$choice,
79-
(string) $value,
93+
$value,
8094
$label,
8195
$keys,
8296
$index,
@@ -126,7 +140,7 @@ public function createView(ChoiceListInterface $list, $preferredChoices = null,
126140
return new ChoiceListView($otherViews, $preferredViews);
127141
}
128142

129-
private static function addChoiceView($choice, $value, $label, $keys, &$index, $attr, $isPreferred, &$preferredViews, &$preferredViewsOrder, &$otherViews)
143+
private static function addChoiceView($choice, string $value, ?callable $label, array $keys, &$index, $attr, ?callable $isPreferred, array &$preferredViews, array &$preferredViewsOrder, array &$otherViews)
130144
{
131145
// $value may be an integer or a string, since it's stored in the array
132146
// keys. We want to guarantee it's a string though.
@@ -137,7 +151,7 @@ private static function addChoiceView($choice, $value, $label, $keys, &$index, $
137151
if (null === $label) {
138152
// If the labels are null, use the original choice key by default
139153
$label = (string) $key;
140-
} elseif (false !== $label) {
154+
} else {
141155
// If "choice_label" is set to false and "expanded" is true, the value false
142156
// should be passed on to the "label" option of the checkboxes/radio buttons
143157
$dynamicLabel = $label($choice, $key, $value);
@@ -154,15 +168,15 @@ private static function addChoiceView($choice, $value, $label, $keys, &$index, $
154168
);
155169

156170
// $isPreferred may be null if no choices are preferred
157-
if ($isPreferred && false !== $preferredKey = $isPreferred($choice, $key, $value)) {
171+
if (null !== $isPreferred && false !== $preferredKey = $isPreferred($choice, $key, $value)) {
158172
$preferredViews[$nextIndex] = $view;
159173
$preferredViewsOrder[$nextIndex] = $preferredKey;
160174
}
161175

162176
$otherViews[$nextIndex] = $view;
163177
}
164178

165-
private static function addChoiceViewsFromStructuredValues($values, $label, $choices, $keys, &$index, $attr, $isPreferred, &$preferredViews, &$preferredViewsOrder, &$otherViews)
179+
private static function addChoiceViewsFromStructuredValues(array $values, ?callable $label, array $choices, array $keys, &$index, $attr, ?callable $isPreferred, array &$preferredViews, array &$preferredViewsOrder, array &$otherViews)
166180
{
167181
foreach ($values as $key => $value) {
168182
if (null === $value) {
@@ -214,7 +228,7 @@ private static function addChoiceViewsFromStructuredValues($values, $label, $cho
214228
}
215229
}
216230

217-
private static function addChoiceViewsGroupedByCallable($groupBy, $choice, $value, $label, $keys, &$index, $attr, $isPreferred, &$preferredViews, &$preferredViewsOrder, &$otherViews)
231+
private static function addChoiceViewsGroupedByCallable(callable $groupBy, $choice, string $value, ?callable $label, array $keys, &$index, $attr, ?callable $isPreferred, array &$preferredViews, array &$preferredViewsOrder, array &$otherViews)
218232
{
219233
$groupLabels = $groupBy($choice, $keys[$value], $value);
220234

src/Symfony/Component/Form/ChoiceList/Factory/PropertyAccessDecorator.php

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -128,8 +128,18 @@ public function createListFromLoader(ChoiceLoaderInterface $loader, $value = nul
128128
*
129129
* @return ChoiceListView The choice list view
130130
*/
131-
public function createView(ChoiceListInterface $list, $preferredChoices = null, $label = null, $index = null, $groupBy = null, $attr = null)
131+
public function createView(ChoiceListInterface $list, $preferredChoices = null, $label = null, $index = null, $groupBy = null, $attr = null/* , bool $triggerDeprecation = true */)
132132
{
133+
$triggerDeprecation = 6 >= \func_num_args() || func_get_arg(6);
134+
135+
if (false === $label) {
136+
if ($triggerDeprecation) {
137+
@trigger_error(sprintf('Passing false as $label to %s is deprecated in Symfony 4.4 and will trigger a TypeError in 5.0, pass a callable that returns false instead.', __METHOD__), E_USER_DEPRECATED);
138+
}
139+
140+
$label = static function () { return false; };
141+
}
142+
133143
$accessor = $this->propertyAccessor;
134144

135145
if (\is_string($label)) {

src/Symfony/Component/Form/Extension/Core/Type/ChoiceType.php

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -410,7 +410,8 @@ private function createChoiceListView(ChoiceListInterface $choiceList, array $op
410410
$options['choice_label'],
411411
$options['choice_name'],
412412
$options['group_by'],
413-
$options['choice_attr']
413+
$options['choice_attr'],
414+
false
414415
);
415416
}
416417
}

src/Symfony/Component/Form/Tests/ChoiceList/Factory/CachingFactoryDecoratorTest.php

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313

1414
use PHPUnit\Framework\MockObject\MockObject;
1515
use PHPUnit\Framework\TestCase;
16+
use Symfony\Component\Form\ChoiceList\ChoiceListInterface;
1617
use Symfony\Component\Form\ChoiceList\Factory\CachingFactoryDecorator;
1718

1819
/**
@@ -484,6 +485,19 @@ public function testCreateViewDifferentAttributesClosure()
484485
$this->assertSame($view2, $this->factory->createView($list, null, null, null, null, $attr2));
485486
}
486487

488+
/**
489+
* @group legacy
490+
* @expectedDeprecation Passing false as $label to Symfony\Component\Form\ChoiceList\Factory\CachingFactoryDecorator::createView is deprecated in Symfony 4.4 and will trigger a TypeError in 5.0, pass a callable that returns false instead.
491+
*/
492+
public function testCreateViewLabelFalseDeprecation()
493+
{
494+
$this->factory->createView(
495+
$this->createMock(ChoiceListInterface::class),
496+
null, // preferred choices
497+
false // label
498+
);
499+
}
500+
487501
public function provideSameChoices()
488502
{
489503
$object = (object) ['foo' => 'bar'];

src/Symfony/Component/Form/Tests/ChoiceList/Factory/DefaultChoiceListFactoryTest.php

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -658,6 +658,19 @@ function ($object, $key, $value) {
658658
$this->assertFlatViewWithAttr($view);
659659
}
660660

661+
/**
662+
* @group legacy
663+
* @expectedDeprecation Passing false as $label to Symfony\Component\Form\ChoiceList\Factory\DefaultChoiceListFactory::createView is deprecated in Symfony 4.4 and will trigger a TypeError in 5.0, pass a callable that returns false instead.
664+
*/
665+
public function testCreateViewLabelFalseDeprecation()
666+
{
667+
$this->factory->createView(
668+
$this->list,
669+
null, // preferred choices
670+
false // label
671+
);
672+
}
673+
661674
private function assertScalarListWithChoiceValues(ChoiceListInterface $list)
662675
{
663676
$this->assertSame(['a', 'b', 'c', 'd'], $list->getValues());

src/Symfony/Component/Form/Tests/ChoiceList/Factory/PropertyAccessDecoratorTest.php

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313

1414
use PHPUnit\Framework\MockObject\MockObject;
1515
use PHPUnit\Framework\TestCase;
16+
use Symfony\Component\Form\ChoiceList\ChoiceListInterface;
1617
use Symfony\Component\Form\ChoiceList\Factory\PropertyAccessDecorator;
1718
use Symfony\Component\PropertyAccess\PropertyPath;
1819

@@ -351,4 +352,17 @@ public function testCreateViewAttrAsPropertyPathInstance()
351352
new PropertyPath('property')
352353
));
353354
}
355+
356+
/**
357+
* @group legacy
358+
* @expectedDeprecation Passing false as $label to Symfony\Component\Form\ChoiceList\Factory\PropertyAccessDecorator::createView is deprecated in Symfony 4.4 and will trigger a TypeError in 5.0, pass a callable that returns false instead.
359+
*/
360+
public function testCreateViewLabelFalseDeprecation()
361+
{
362+
$this->factory->createView(
363+
$this->createMock(ChoiceListInterface::class),
364+
null, // preferred choices
365+
false // label
366+
);
367+
}
354368
}

0 commit comments

Comments
 (0)