feature #38469 [Form] Add "choice_translation_parameters" option (VincentLanglet)

This PR was squashed before being merged into the 5.3-dev branch.

Discussion
----------

[Form] Add "choice_translation_parameters" option

| Q             | A
| ------------- | ---
| Branch?       | 5.x
| Bug fix?      | no
| New feature?  | yes <!-- please update src/**/CHANGELOG.md files -->
| Deprecations? | no <!-- please update UPGRADE-*.md and src/**/CHANGELOG.md files -->
| Tickets       | Fix #36845 <!-- prefix each issue number with "Fix #", if any -->
| License       | MIT
| Doc PR        | https://github.com/symfony/symfony-docs/pull/13677

Original PR: https://github.com/symfony/symfony/pull/36851

Commits
-------

1ce5b03c2a [Form] Add "choice_translation_parameters" option
This commit is contained in:
Fabien Potencier 2020-12-10 08:13:10 +01:00
commit 9b64be8895
15 changed files with 323 additions and 82 deletions

View File

@ -85,7 +85,7 @@
{{- block('choice_widget_options') -}}
</optgroup>
{%- else -%}
<option value="{{ choice.value }}"{% if choice.attr %}{% with { attr: choice.attr } %}{{ block('attributes') }}{% endwith %}{% endif %}{% if not render_preferred_choices|default(false) and choice is selectedchoice(value) %} selected="selected"{% endif %}>{{ choice_translation_domain is same as(false) ? choice.label : choice.label|trans({}, choice_translation_domain) }}</option>
<option value="{{ choice.value }}"{% if choice.attr %}{% with { attr: choice.attr } %}{{ block('attributes') }}{% endwith %}{% endif %}{% if not render_preferred_choices|default(false) and choice is selectedchoice(value) %} selected="selected"{% endif %}>{{ choice_translation_domain is same as(false) ? choice.label : choice.label|trans(choice.labelTranslationParameters, choice_translation_domain) }}</option>
{%- endif -%}
{% endfor %}
{%- endblock choice_widget_options -%}

View File

@ -27,7 +27,7 @@
"symfony/asset": "^4.4|^5.0",
"symfony/dependency-injection": "^4.4|^5.0",
"symfony/finder": "^4.4|^5.0",
"symfony/form": "^5.1.9",
"symfony/form": "^5.3",
"symfony/http-foundation": "^4.4|^5.0",
"symfony/http-kernel": "^4.4|^5.0",
"symfony/mime": "^5.2",
@ -52,7 +52,7 @@
},
"conflict": {
"symfony/console": "<4.4",
"symfony/form": "<5.1",
"symfony/form": "<5.3",
"symfony/http-foundation": "<4.4",
"symfony/http-kernel": "<4.4",
"symfony/translation": "<5.2",

View File

@ -12,6 +12,7 @@ CHANGELOG
* Deprecated passing an array as the first argument of the `CheckboxListMapper::mapFormsToData()` method, pass `\Traversable` instead.
* Deprecated passing an array as the second argument of the `RadioListMapper::mapDataToForms()` method, pass `\Traversable` instead.
* Deprecated passing an array as the first argument of the `RadioListMapper::mapFormsToData()` method, pass `\Traversable` instead.
* Added a `choice_translation_parameters` option to `ChoiceType`
5.2.0
-----

View File

@ -16,6 +16,7 @@ use Symfony\Component\Form\ChoiceList\Factory\Cache\ChoiceFieldName;
use Symfony\Component\Form\ChoiceList\Factory\Cache\ChoiceFilter;
use Symfony\Component\Form\ChoiceList\Factory\Cache\ChoiceLabel;
use Symfony\Component\Form\ChoiceList\Factory\Cache\ChoiceLoader;
use Symfony\Component\Form\ChoiceList\Factory\Cache\ChoiceTranslationParameters;
use Symfony\Component\Form\ChoiceList\Factory\Cache\ChoiceValue;
use Symfony\Component\Form\ChoiceList\Factory\Cache\GroupBy;
use Symfony\Component\Form\ChoiceList\Factory\Cache\PreferredChoice;
@ -113,6 +114,18 @@ final class ChoiceList
return new ChoiceAttr($formType, $attr, $vary);
}
/**
* Decorates a "choice_translation_parameters" option to make it cacheable.
*
* @param FormTypeInterface|FormTypeExtensionInterface $formType A form type or type extension configuring a cacheable choice list
* @param callable|array $translationParameters Any pseudo callable or array to create translation parameters from a choice
* @param mixed|null $vary Dynamic data used to compute a unique hash when caching the option
*/
public static function translationParameters($formType, $translationParameters, $vary = null): ChoiceTranslationParameters
{
return new ChoiceTranslationParameters($formType, $translationParameters, $vary);
}
/**
* Decorates a "group_by" callback to make it cacheable.
*

View File

@ -0,0 +1,27 @@
<?php
/*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <fabien@symfony.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Symfony\Component\Form\ChoiceList\Factory\Cache;
use Symfony\Component\Form\FormTypeExtensionInterface;
use Symfony\Component\Form\FormTypeInterface;
/**
* A cacheable wrapper for any {@see FormTypeInterface} or {@see FormTypeExtensionInterface}
* which configures a "choice_translation_parameters" option.
*
* @internal
*
* @author Vincent Langlet <vincentlanglet@users.noreply.github.com>
*/
final class ChoiceTranslationParameters extends AbstractStaticOption
{
}

View File

@ -174,14 +174,16 @@ class CachingFactoryDecorator implements ChoiceListFactoryInterface, ResetInterf
/**
* {@inheritdoc}
*
* @param array|callable|Cache\PreferredChoice|null $preferredChoices The preferred choices
* @param callable|false|Cache\ChoiceLabel|null $label The option or static option generating the choice labels
* @param callable|Cache\ChoiceFieldName|null $index The option or static option generating the view indices
* @param callable|Cache\GroupBy|null $groupBy The option or static option generating the group names
* @param array|callable|Cache\ChoiceAttr|null $attr The option or static option generating the HTML attributes
* @param array|callable|Cache\PreferredChoice|null $preferredChoices The preferred choices
* @param callable|false|Cache\ChoiceLabel|null $label The option or static option generating the choice labels
* @param callable|Cache\ChoiceFieldName|null $index The option or static option generating the view indices
* @param callable|Cache\GroupBy|null $groupBy The option or static option generating the group names
* @param array|callable|Cache\ChoiceAttr|null $attr The option or static option generating the HTML attributes
* @param array|callable|Cache\ChoiceTranslationParameters $labelTranslationParameters The parameters used to translate the choice labels
*/
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/*, $labelTranslationParameters = []*/)
{
$labelTranslationParameters = \func_num_args() > 6 ? func_get_arg(6) : [];
$cache = true;
if ($preferredChoices instanceof Cache\PreferredChoice) {
@ -214,11 +216,25 @@ class CachingFactoryDecorator implements ChoiceListFactoryInterface, ResetInterf
$cache = false;
}
if (!$cache) {
return $this->decoratedFactory->createView($list, $preferredChoices, $label, $index, $groupBy, $attr);
if ($labelTranslationParameters instanceof Cache\ChoiceTranslationParameters) {
$labelTranslationParameters = $labelTranslationParameters->getOption();
} elseif ([] !== $labelTranslationParameters) {
$cache = false;
}
$hash = self::generateHash([$list, $preferredChoices, $label, $index, $groupBy, $attr]);
if (!$cache) {
return $this->decoratedFactory->createView(
$list,
$preferredChoices,
$label,
$index,
$groupBy,
$attr,
$labelTranslationParameters
);
}
$hash = self::generateHash([$list, $preferredChoices, $label, $index, $groupBy, $attr, $labelTranslationParameters]);
if (!isset($this->views[$hash])) {
$this->views[$hash] = $this->decoratedFactory->createView(
@ -227,7 +243,8 @@ class CachingFactoryDecorator implements ChoiceListFactoryInterface, ResetInterf
$label,
$index,
$groupBy,
$attr
$attr,
$labelTranslationParameters
);
}

View File

@ -76,12 +76,13 @@ interface ChoiceListFactoryInterface
* match the keys of the choices. The values should be arrays of HTML
* attributes that should be added to the respective choice.
*
* @param array|callable|null $preferredChoices The preferred choices
* @param callable|false|null $label The callable generating the choice labels;
* pass false to discard the label
* @param array|callable|null $attr The callable generating the HTML attributes
* @param array|callable|null $preferredChoices The preferred choices
* @param callable|false|null $label The callable generating the choice labels;
* pass false to discard the label
* @param array|callable|null $attr The callable generating the HTML attributes
* @param array|callable $labelTranslationParameters The parameters used to translate the choice labels
*
* @return ChoiceListView The choice list view
*/
public function createView(ChoiceListInterface $list, $preferredChoices = null, $label = null, callable $index = null, callable $groupBy = null, $attr = null);
public function createView(ChoiceListInterface $list, $preferredChoices = null, $label = null, callable $index = null, callable $groupBy = null, $attr = null/*, $labelTranslationParameters = []*/);
}

View File

@ -68,9 +68,12 @@ class DefaultChoiceListFactory implements ChoiceListFactoryInterface
/**
* {@inheritdoc}
*
* @param array|callable $labelTranslationParameters The parameters used to translate the choice labels
*/
public function createView(ChoiceListInterface $list, $preferredChoices = null, $label = null, callable $index = null, callable $groupBy = null, $attr = null)
public function createView(ChoiceListInterface $list, $preferredChoices = null, $label = null, callable $index = null, callable $groupBy = null, $attr = null/*, $labelTranslationParameters = []*/)
{
$labelTranslationParameters = \func_num_args() > 6 ? func_get_arg(6) : [];
$preferredViews = [];
$preferredViewsOrder = [];
$otherViews = [];
@ -109,6 +112,7 @@ class DefaultChoiceListFactory implements ChoiceListFactoryInterface
$keys,
$index,
$attr,
$labelTranslationParameters,
$preferredChoices,
$preferredViews,
$preferredViewsOrder,
@ -146,6 +150,7 @@ class DefaultChoiceListFactory implements ChoiceListFactoryInterface
$keys,
$index,
$attr,
$labelTranslationParameters,
$preferredChoices,
$preferredViews,
$preferredViewsOrder,
@ -162,7 +167,7 @@ class DefaultChoiceListFactory implements ChoiceListFactoryInterface
return new ChoiceListView($otherViews, $preferredViews);
}
private static function addChoiceView($choice, string $value, $label, array $keys, &$index, $attr, ?callable $isPreferred, array &$preferredViews, array &$preferredViewsOrder, array &$otherViews)
private static function addChoiceView($choice, string $value, $label, array $keys, &$index, $attr, $labelTranslationParameters, ?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.
@ -186,7 +191,10 @@ class DefaultChoiceListFactory implements ChoiceListFactoryInterface
$label,
// The attributes may be a callable or a mapping from choice indices
// to nested arrays
\is_callable($attr) ? $attr($choice, $key, $value) : (isset($attr[$key]) ? $attr[$key] : [])
\is_callable($attr) ? $attr($choice, $key, $value) : ($attr[$key] ?? []),
// The label translation parameters may be a callable or a mapping from choice indices
// to nested arrays
\is_callable($labelTranslationParameters) ? $labelTranslationParameters($choice, $key, $value) : ($labelTranslationParameters[$key] ?? [])
);
// $isPreferred may be null if no choices are preferred
@ -198,7 +206,7 @@ class DefaultChoiceListFactory implements ChoiceListFactoryInterface
$otherViews[$nextIndex] = $view;
}
private static function addChoiceViewsFromStructuredValues(array $values, $label, array $choices, array $keys, &$index, $attr, ?callable $isPreferred, array &$preferredViews, array &$preferredViewsOrder, array &$otherViews)
private static function addChoiceViewsFromStructuredValues(array $values, $label, array $choices, array $keys, &$index, $attr, $labelTranslationParameters, ?callable $isPreferred, array &$preferredViews, array &$preferredViewsOrder, array &$otherViews)
{
foreach ($values as $key => $value) {
if (null === $value) {
@ -217,6 +225,7 @@ class DefaultChoiceListFactory implements ChoiceListFactoryInterface
$keys,
$index,
$attr,
$labelTranslationParameters,
$isPreferred,
$preferredViewsForGroup,
$preferredViewsOrder,
@ -242,6 +251,7 @@ class DefaultChoiceListFactory implements ChoiceListFactoryInterface
$keys,
$index,
$attr,
$labelTranslationParameters,
$isPreferred,
$preferredViews,
$preferredViewsOrder,
@ -250,7 +260,7 @@ class DefaultChoiceListFactory implements ChoiceListFactoryInterface
}
}
private static function addChoiceViewsGroupedByCallable(callable $groupBy, $choice, string $value, $label, array $keys, &$index, $attr, ?callable $isPreferred, array &$preferredViews, array &$preferredViewsOrder, array &$otherViews)
private static function addChoiceViewsGroupedByCallable(callable $groupBy, $choice, string $value, $label, array $keys, &$index, $attr, $labelTranslationParameters, ?callable $isPreferred, array &$preferredViews, array &$preferredViewsOrder, array &$otherViews)
{
$groupLabels = $groupBy($choice, $keys[$value], $value);
@ -263,6 +273,7 @@ class DefaultChoiceListFactory implements ChoiceListFactoryInterface
$keys,
$index,
$attr,
$labelTranslationParameters,
$isPreferred,
$preferredViews,
$preferredViewsOrder,
@ -292,6 +303,7 @@ class DefaultChoiceListFactory implements ChoiceListFactoryInterface
$keys,
$index,
$attr,
$labelTranslationParameters,
$isPreferred,
$preferredViews[$groupLabel]->choices,
$preferredViewsOrder[$groupLabel],

View File

@ -145,16 +145,18 @@ class PropertyAccessDecorator implements ChoiceListFactoryInterface
/**
* {@inheritdoc}
*
* @param array|callable|string|PropertyPath|null $preferredChoices The preferred choices
* @param callable|string|PropertyPath|null $label The callable or path generating the choice labels
* @param callable|string|PropertyPath|null $index The callable or path generating the view indices
* @param callable|string|PropertyPath|null $groupBy The callable or path generating the group names
* @param array|callable|string|PropertyPath|null $attr The callable or path generating the HTML attributes
* @param array|callable|string|PropertyPath|null $preferredChoices The preferred choices
* @param callable|string|PropertyPath|null $label The callable or path generating the choice labels
* @param callable|string|PropertyPath|null $index The callable or path generating the view indices
* @param callable|string|PropertyPath|null $groupBy The callable or path generating the group names
* @param array|callable|string|PropertyPath|null $attr The callable or path generating the HTML attributes
* @param array|callable|string|PropertyPath $labelTranslationParameters The callable or path generating the parameters used to translate the choice labels
*
* @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/*, $labelTranslationParameters = []*/)
{
$labelTranslationParameters = \func_num_args() > 6 ? func_get_arg(6) : [];
$accessor = $this->propertyAccessor;
if (\is_string($label)) {
@ -217,6 +219,24 @@ class PropertyAccessDecorator implements ChoiceListFactoryInterface
};
}
return $this->decoratedFactory->createView($list, $preferredChoices, $label, $index, $groupBy, $attr);
if (\is_string($labelTranslationParameters)) {
$labelTranslationParameters = new PropertyPath($labelTranslationParameters);
}
if ($labelTranslationParameters instanceof PropertyPath) {
$labelTranslationParameters = static function ($choice) use ($accessor, $labelTranslationParameters) {
return $accessor->getValue($choice, $labelTranslationParameters);
};
}
return $this->decoratedFactory->createView(
$list,
$preferredChoices,
$label,
$index,
$groupBy,
$attr,
$labelTranslationParameters
);
}
}

View File

@ -27,19 +27,26 @@ class ChoiceView
*/
public $attr;
/**
* Additional parameters used to translate the label.
*/
public $labelTranslationParameters;
/**
* Creates a new choice view.
*
* @param mixed $data The original choice
* @param string $value The view representation of the choice
* @param string|false $label The label displayed to humans; pass false to discard the label
* @param array $attr Additional attributes for the HTML tag
* @param mixed $data The original choice
* @param string $value The view representation of the choice
* @param string|false $label The label displayed to humans; pass false to discard the label
* @param array $attr Additional attributes for the HTML tag
* @param array $labelTranslationParameters Additional parameters used to translate the label
*/
public function __construct($data, string $value, $label, array $attr = [])
public function __construct($data, string $value, $label, array $attr = [], array $labelTranslationParameters = [])
{
$this->data = $data;
$this->value = $value;
$this->label = $label;
$this->attr = $attr;
$this->labelTranslationParameters = $labelTranslationParameters;
}
}

View File

@ -18,6 +18,7 @@ use Symfony\Component\Form\ChoiceList\Factory\Cache\ChoiceFieldName;
use Symfony\Component\Form\ChoiceList\Factory\Cache\ChoiceFilter;
use Symfony\Component\Form\ChoiceList\Factory\Cache\ChoiceLabel;
use Symfony\Component\Form\ChoiceList\Factory\Cache\ChoiceLoader;
use Symfony\Component\Form\ChoiceList\Factory\Cache\ChoiceTranslationParameters;
use Symfony\Component\Form\ChoiceList\Factory\Cache\ChoiceValue;
use Symfony\Component\Form\ChoiceList\Factory\Cache\GroupBy;
use Symfony\Component\Form\ChoiceList\Factory\Cache\PreferredChoice;
@ -212,6 +213,7 @@ class ChoiceType extends AbstractType
'separator' => '-------------------',
'placeholder' => null,
'choice_translation_domain' => $choiceTranslationDomain,
'choice_translation_parameters' => $options['choice_translation_parameters'],
]);
// The decision, whether a choice is selected, is potentially done
@ -326,6 +328,7 @@ class ChoiceType extends AbstractType
'choice_name' => null,
'choice_value' => null,
'choice_attr' => null,
'choice_translation_parameters' => [],
'preferred_choices' => [],
'group_by' => null,
'empty_data' => $emptyData,
@ -356,6 +359,7 @@ class ChoiceType extends AbstractType
$resolver->setAllowedTypes('choice_name', ['null', 'callable', 'string', 'Symfony\Component\PropertyAccess\PropertyPath', ChoiceFieldName::class]);
$resolver->setAllowedTypes('choice_value', ['null', 'callable', 'string', 'Symfony\Component\PropertyAccess\PropertyPath', ChoiceValue::class]);
$resolver->setAllowedTypes('choice_attr', ['null', 'array', 'callable', 'string', 'Symfony\Component\PropertyAccess\PropertyPath', ChoiceAttr::class]);
$resolver->setAllowedTypes('choice_translation_parameters', ['null', 'array', 'callable', ChoiceTranslationParameters::class]);
$resolver->setAllowedTypes('preferred_choices', ['array', '\Traversable', 'callable', 'string', 'Symfony\Component\PropertyAccess\PropertyPath', PreferredChoice::class]);
$resolver->setAllowedTypes('group_by', ['null', 'callable', 'string', 'Symfony\Component\PropertyAccess\PropertyPath', GroupBy::class]);
}
@ -395,6 +399,7 @@ class ChoiceType extends AbstractType
'value' => $choiceView->value,
'label' => $choiceView->label,
'attr' => $choiceView->attr,
'label_translation_parameters' => $choiceView->labelTranslationParameters,
'translation_domain' => $options['choice_translation_domain'],
'block_name' => 'entry',
];
@ -439,7 +444,8 @@ class ChoiceType extends AbstractType
$options['choice_label'],
$options['choice_name'],
$options['group_by'],
$options['choice_attr']
$options['choice_attr'],
$options['choice_translation_parameters']
);
}
}

View File

@ -77,6 +77,11 @@ class DefaultChoiceListFactoryTest extends TestCase
return $object->attr;
}
public function getLabelTranslationParameters($object)
{
return $object->labelTranslationParameters;
}
public function getGroup($object)
{
return $this->obj1 === $object || $this->obj2 === $object ? 'Group 1' : 'Group 2';
@ -96,10 +101,10 @@ class DefaultChoiceListFactoryTest extends TestCase
protected function setUp(): void
{
$this->obj1 = (object) ['label' => 'A', 'index' => 'w', 'value' => 'a', 'preferred' => false, 'group' => 'Group 1', 'attr' => []];
$this->obj2 = (object) ['label' => 'B', 'index' => 'x', 'value' => 'b', 'preferred' => true, 'group' => 'Group 1', 'attr' => ['attr1' => 'value1']];
$this->obj3 = (object) ['label' => 'C', 'index' => 'y', 'value' => 1, 'preferred' => true, 'group' => 'Group 2', 'attr' => ['attr2' => 'value2']];
$this->obj4 = (object) ['label' => 'D', 'index' => 'z', 'value' => 2, 'preferred' => false, 'group' => 'Group 2', 'attr' => []];
$this->obj1 = (object) ['label' => 'A', 'index' => 'w', 'value' => 'a', 'preferred' => false, 'group' => 'Group 1', 'attr' => [], 'labelTranslationParameters' => []];
$this->obj2 = (object) ['label' => 'B', 'index' => 'x', 'value' => 'b', 'preferred' => true, 'group' => 'Group 1', 'attr' => ['attr1' => 'value1'], 'labelTranslationParameters' => []];
$this->obj3 = (object) ['label' => 'C', 'index' => 'y', 'value' => 1, 'preferred' => true, 'group' => 'Group 2', 'attr' => ['attr2' => 'value2'], 'labelTranslationParameters' => []];
$this->obj4 = (object) ['label' => 'D', 'index' => 'z', 'value' => 2, 'preferred' => false, 'group' => 'Group 2', 'attr' => [], 'labelTranslationParameters' => ['%placeholder1%' => 'value1']];
$this->list = new ArrayChoiceList(['A' => $this->obj1, 'B' => $this->obj2, 'C' => $this->obj3, 'D' => $this->obj4]);
$this->factory = new DefaultChoiceListFactory();
}
@ -753,6 +758,110 @@ class DefaultChoiceListFactoryTest extends TestCase
$this->assertFlatViewWithAttr($view);
}
public function testCreateViewFlatLabelTranslationParametersAsArray()
{
$view = $this->factory->createView(
$this->list,
[$this->obj2, $this->obj3],
null, // label
null, // index
null, // group
null, // attr
[
'D' => ['%placeholder1%' => 'value1'],
]
);
$this->assertFlatViewWithlabelTranslationParameters($view);
}
public function testCreateViewFlatlabelTranslationParametersEmpty()
{
$view = $this->factory->createView(
$this->list,
[$this->obj2, $this->obj3],
null, // label
null, // index
null, // group
null, // attr
[]
);
$this->assertFlatView($view);
}
public function testCreateViewFlatlabelTranslationParametersAsCallable()
{
$view = $this->factory->createView(
$this->list,
[$this->obj2, $this->obj3],
null, // label
null, // index
null, // group
null, // attr
[$this, 'getlabelTranslationParameters']
);
$this->assertFlatViewWithlabelTranslationParameters($view);
}
public function testCreateViewFlatlabelTranslationParametersAsClosure()
{
$view = $this->factory->createView(
$this->list,
[$this->obj2, $this->obj3],
null, // label
null, // index
null, // group
null, // attr
function ($object) {
return $object->labelTranslationParameters;
}
);
$this->assertFlatViewWithlabelTranslationParameters($view);
}
public function testCreateViewFlatlabelTranslationParametersClosureReceivesKey()
{
$view = $this->factory->createView(
$this->list,
[$this->obj2, $this->obj3],
null, // label
null, // index
null, // group
null, // attr
function ($object, $key) {
switch ($key) {
case 'D': return ['%placeholder1%' => 'value1'];
default: return [];
}
}
);
$this->assertFlatViewWithlabelTranslationParameters($view);
}
public function testCreateViewFlatlabelTranslationParametersClosureReceivesValue()
{
$view = $this->factory->createView(
$this->list,
[$this->obj2, $this->obj3],
null, // label
null, // index
null, // group
null, // attr
function ($object, $key, $value) {
switch ($value) {
case '3': return ['%placeholder1%' => 'value1'];
default: return [];
}
}
);
$this->assertFlatViewWithlabelTranslationParameters($view);
}
private function assertScalarListWithChoiceValues(ChoiceListInterface $list)
{
$this->assertSame(['a', 'b', 'c', 'd'], $list->getValues());
@ -894,6 +1003,21 @@ class DefaultChoiceListFactoryTest extends TestCase
), $view);
}
private function assertFlatViewWithlabelTranslationParameters($view)
{
$this->assertEquals(new ChoiceListView(
[
0 => new ChoiceView($this->obj1, '0', 'A'),
1 => new ChoiceView($this->obj2, '1', 'B'),
2 => new ChoiceView($this->obj3, '2', 'C'),
3 => new ChoiceView($this->obj4, '3', 'D', [], ['%placeholder1%' => 'value1']),
], [
1 => new ChoiceView($this->obj2, '1', 'B'),
2 => new ChoiceView($this->obj3, '2', 'C'),
]
), $view);
}
private function assertGroupedView($view)
{
$this->assertEquals(new ChoiceListView(

View File

@ -1782,14 +1782,26 @@ class ChoiceTypeTest extends BaseTypeTest
'choices' => [$obj1, $obj2, $obj3, $obj4],
'choice_label' => 'label',
'choice_value' => 'value',
'choice_attr' => [
['attr1' => 'value1'],
['attr2' => 'value2'],
['attr3' => 'value3'],
['attr4' => 'value4'],
],
'choice_translation_parameters' => [
['%placeholder1%' => 'value1'],
['%placeholder2%' => 'value2'],
['%placeholder3%' => 'value3'],
['%placeholder4%' => 'value4'],
],
])
->createView();
$this->assertEquals([
new ChoiceView($obj1, 'a', 'A'),
new ChoiceView($obj2, 'b', 'B'),
new ChoiceView($obj3, 'c', 'C'),
new ChoiceView($obj4, 'd', 'D'),
new ChoiceView($obj1, 'a', 'A', ['attr1' => 'value1'], ['%placeholder1%' => 'value1']),
new ChoiceView($obj2, 'b', 'B', ['attr2' => 'value2'], ['%placeholder2%' => 'value2']),
new ChoiceView($obj3, 'c', 'C', ['attr3' => 'value3'], ['%placeholder3%' => 'value3']),
new ChoiceView($obj4, 'd', 'D', ['attr4' => 'value4'], ['%placeholder4%' => 'value4']),
], $view->vars['choices']);
}

View File

@ -9,6 +9,7 @@
"choice_loader",
"choice_name",
"choice_translation_domain",
"choice_translation_parameters",
"choice_value",
"choices",
"expanded",

View File

@ -2,44 +2,44 @@
Symfony\Component\Form\Extension\Core\Type\ChoiceType (Block prefix: "choice")
==============================================================================
--------------------------- -------------------- ------------------------------ -----------------------
Options Overridden options Parent options Extension options
--------------------------- -------------------- ------------------------------ -----------------------
choice_attr FormType FormType FormTypeCsrfExtension
choice_filter -------------------- ------------------------------ -----------------------
choice_label compound action csrf_field_name
choice_loader data_class allow_file_upload csrf_message
choice_name empty_data attr csrf_protection
choice_translation_domain error_bubbling attr_translation_parameters csrf_token_id
choice_value invalid_message auto_initialize csrf_token_manager
choices trim block_name
expanded block_prefix
group_by by_reference
multiple data
placeholder disabled
preferred_choices getter
help
help_attr
help_html
help_translation_parameters
inherit_data
invalid_message_parameters
is_empty_callback
label
label_attr
label_format
label_html
label_translation_parameters
mapped
method
post_max_size_message
property_path
required
row_attr
setter
translation_domain
upload_max_size_message
--------------------------- -------------------- ------------------------------ -----------------------
------------------------------- -------------------- ------------------------------ -----------------------
Options Overridden options Parent options Extension options
------------------------------- -------------------- ------------------------------ -----------------------
choice_attr FormType FormType FormTypeCsrfExtension
choice_filter -------------------- ------------------------------ -----------------------
choice_label compound action csrf_field_name
choice_loader data_class allow_file_upload csrf_message
choice_name empty_data attr csrf_protection
choice_translation_domain error_bubbling attr_translation_parameters csrf_token_id
choice_translation_parameters invalid_message auto_initialize csrf_token_manager
choice_value trim block_name
choices block_prefix
expanded by_reference
group_by data
multiple disabled
placeholder getter
preferred_choices help
help_attr
help_html
help_translation_parameters
inherit_data
invalid_message_parameters
is_empty_callback
label
label_attr
label_format
label_html
label_translation_parameters
mapped
method
post_max_size_message
property_path
required
row_attr
setter
translation_domain
upload_max_size_message
------------------------------- -------------------- ------------------------------ -----------------------
Parent types
------------