Skip to content

[Form] Deprecate passing false as $label to ChoiceListFactoryInterface #33074

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 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions UPGRADE-4.4.md
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,7 @@ Form
reference date is deprecated.
* Using `int` or `float` as data for the `NumberType` when the `input` option is set to `string` is deprecated.
* Overriding the methods `FormIntegrationTestCase::setUp()`, `TypeTestCase::setUp()` and `TypeTestCase::tearDown()` without the `void` return-type is deprecated.
* Deprecated passing `false` as `$label` to `ChoiceListFactoryInterface::createView`, pass a callable that returns false instead.

FrameworkBundle
---------------
Expand Down
1 change: 1 addition & 0 deletions UPGRADE-5.0.md
Original file line number Diff line number Diff line change
Expand Up @@ -215,6 +215,7 @@ Form

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

FrameworkBundle
---------------
Expand Down
1 change: 1 addition & 0 deletions src/Symfony/Component/Form/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ CHANGELOG
* deprecated using `int` or `float` as data for the `NumberType` when the `input` option is set to `string`
* The type guesser guesses the HTML accept attribute when a mime type is configured in the File or Image constraint.
* Overriding the methods `FormIntegrationTestCase::setUp()`, `TypeTestCase::setUp()` and `TypeTestCase::tearDown()` without the `void` return-type is deprecated.
* deprecated passing `false` as `$label` to `ChoiceListFactoryInterface::createView`, pass a callable that returns false instead

4.3.0
-----
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -116,8 +116,18 @@ public function createListFromLoader(ChoiceLoaderInterface $loader, $value = nul
/**
* {@inheritdoc}
*/
public function createView(ChoiceListInterface $list, $preferredChoices = null, $label = null, $index = null, $groupBy = null, $attr = null)
public function createView(ChoiceListInterface $list, $preferredChoices = null, $label = null, $index = null, $groupBy = null, $attr = null/* , bool $triggerDeprecation = true */)
{
$triggerDeprecation = 6 >= \func_num_args() || func_get_arg(6);

if (false === $label) {
if ($triggerDeprecation) {
@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);
}

$label = static function () { return false; };
}

// The input is not validated on purpose. This way, the decorated
// factory may decide which input to accept and which not.
$hash = self::generateHash([$list, $preferredChoices, $label, $index, $groupBy, $attr]);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,20 +45,34 @@ public function createListFromLoader(ChoiceLoaderInterface $loader, $value = nul
/**
* {@inheritdoc}
*/
public function createView(ChoiceListInterface $list, $preferredChoices = null, $label = null, $index = null, $groupBy = null, $attr = null)
public function createView(ChoiceListInterface $list, $preferredChoices = null, $label = null, $index = null, $groupBy = null, $attr = null/* , bool $triggerDeprecation = true */)
{
$triggerDeprecation = 6 >= \func_num_args() || func_get_arg(6);

if (false === $label) {
if ($triggerDeprecation) {
@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);
}

$label = static function () { return false; };
}

$preferredViews = [];
$preferredViewsOrder = [];
$otherViews = [];
$choices = $list->getChoices();
$keys = $list->getOriginalKeys();

if (!\is_callable($preferredChoices) && !empty($preferredChoices)) {
// make sure we have keys that reflect order
$preferredChoices = array_values($preferredChoices);
$preferredChoices = static function ($choice) use ($preferredChoices) {
return array_search($choice, $preferredChoices, true);
};
if (!\is_callable($preferredChoices)) {
if (empty($preferredChoices)) {
$preferredChoices = null;
} else {
// make sure we have keys that reflect order
$preferredChoices = array_values($preferredChoices);
$preferredChoices = static function ($choice) use ($preferredChoices) {
return array_search($choice, $preferredChoices, true);
};
}
}

// The names are generated from an incrementing integer by default
Expand All @@ -76,7 +90,7 @@ public function createView(ChoiceListInterface $list, $preferredChoices = null,
self::addChoiceViewsGroupedByCallable(
$groupBy,
$choice,
(string) $value,
$value,
$label,
$keys,
$index,
Expand Down Expand Up @@ -126,7 +140,7 @@ public function createView(ChoiceListInterface $list, $preferredChoices = null,
return new ChoiceListView($otherViews, $preferredViews);
}

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

// $isPreferred may be null if no choices are preferred
if ($isPreferred && false !== $preferredKey = $isPreferred($choice, $key, $value)) {
if (null !== $isPreferred && false !== $preferredKey = $isPreferred($choice, $key, $value)) {
$preferredViews[$nextIndex] = $view;
$preferredViewsOrder[$nextIndex] = $preferredKey;
}

$otherViews[$nextIndex] = $view;
}

private static function addChoiceViewsFromStructuredValues($values, $label, $choices, $keys, &$index, $attr, $isPreferred, &$preferredViews, &$preferredViewsOrder, &$otherViews)
private static function addChoiceViewsFromStructuredValues(array $values, ?callable $label, array $choices, array $keys, &$index, $attr, ?callable $isPreferred, array &$preferredViews, array &$preferredViewsOrder, array &$otherViews)
{
foreach ($values as $key => $value) {
if (null === $value) {
Expand Down Expand Up @@ -214,7 +228,7 @@ private static function addChoiceViewsFromStructuredValues($values, $label, $cho
}
}

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

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -128,8 +128,18 @@ public function createListFromLoader(ChoiceLoaderInterface $loader, $value = nul
*
* @return ChoiceListView The choice list view
*/
public function createView(ChoiceListInterface $list, $preferredChoices = null, $label = null, $index = null, $groupBy = null, $attr = null)
public function createView(ChoiceListInterface $list, $preferredChoices = null, $label = null, $index = null, $groupBy = null, $attr = null/* , bool $triggerDeprecation = true */)
{
$triggerDeprecation = 6 >= \func_num_args() || func_get_arg(6);

if (false === $label) {
if ($triggerDeprecation) {
@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);
}

$label = static function () { return false; };
}

$accessor = $this->propertyAccessor;

if (\is_string($label)) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -410,7 +410,8 @@ private function createChoiceListView(ChoiceListInterface $choiceList, array $op
$options['choice_label'],
$options['choice_name'],
$options['group_by'],
$options['choice_attr']
$options['choice_attr'],
false
);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@

use PHPUnit\Framework\MockObject\MockObject;
use PHPUnit\Framework\TestCase;
use Symfony\Component\Form\ChoiceList\ChoiceListInterface;
use Symfony\Component\Form\ChoiceList\Factory\CachingFactoryDecorator;

/**
Expand Down Expand Up @@ -484,6 +485,19 @@ public function testCreateViewDifferentAttributesClosure()
$this->assertSame($view2, $this->factory->createView($list, null, null, null, null, $attr2));
}

/**
* @group legacy
* @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.
*/
public function testCreateViewLabelFalseDeprecation()
{
$this->factory->createView(
$this->createMock(ChoiceListInterface::class),
null, // preferred choices
false // label
);
}

public function provideSameChoices()
{
$object = (object) ['foo' => 'bar'];
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -658,6 +658,19 @@ function ($object, $key, $value) {
$this->assertFlatViewWithAttr($view);
}

/**
* @group legacy
* @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.
*/
public function testCreateViewLabelFalseDeprecation()
{
$this->factory->createView(
$this->list,
null, // preferred choices
false // label
);
}

private function assertScalarListWithChoiceValues(ChoiceListInterface $list)
{
$this->assertSame(['a', 'b', 'c', 'd'], $list->getValues());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@

use PHPUnit\Framework\MockObject\MockObject;
use PHPUnit\Framework\TestCase;
use Symfony\Component\Form\ChoiceList\ChoiceListInterface;
use Symfony\Component\Form\ChoiceList\Factory\PropertyAccessDecorator;
use Symfony\Component\PropertyAccess\PropertyPath;

Expand Down Expand Up @@ -351,4 +352,17 @@ public function testCreateViewAttrAsPropertyPathInstance()
new PropertyPath('property')
));
}

/**
* @group legacy
* @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.
*/
public function testCreateViewLabelFalseDeprecation()
{
$this->factory->createView(
$this->createMock(ChoiceListInterface::class),
null, // preferred choices
false // label
);
}
}