From 0bdc12a56d6572dc280ea6f0844fa05823c61334 Mon Sep 17 00:00:00 2001 From: Vincent Langlet Date: Mon, 18 May 2020 11:39:39 +0200 Subject: [PATCH 1/9] Add choice_translation_parameters option --- .../Twig/Resources/views/Form/bootstrap_4_layout.html.twig | 1 + .../Resources/views/Form/bootstrap_base_layout.html.twig | 2 ++ .../Twig/Resources/views/Form/form_div_layout.html.twig | 6 +++--- .../Component/Form/Extension/Core/Type/ChoiceType.php | 2 ++ 4 files changed, 8 insertions(+), 3 deletions(-) diff --git a/src/Symfony/Bridge/Twig/Resources/views/Form/bootstrap_4_layout.html.twig b/src/Symfony/Bridge/Twig/Resources/views/Form/bootstrap_4_layout.html.twig index 86e2715488338..542e200ea3a95 100644 --- a/src/Symfony/Bridge/Twig/Resources/views/Form/bootstrap_4_layout.html.twig +++ b/src/Symfony/Bridge/Twig/Resources/views/Form/bootstrap_4_layout.html.twig @@ -201,6 +201,7 @@ {%- for child in form %} {{- form_widget(child, { parent_label_class: label_attr.class|default(''), + label_translation_parameters: choice_translation_parameters, translation_domain: choice_translation_domain, valid: valid, }) -}} diff --git a/src/Symfony/Bridge/Twig/Resources/views/Form/bootstrap_base_layout.html.twig b/src/Symfony/Bridge/Twig/Resources/views/Form/bootstrap_base_layout.html.twig index 1b0092859dbd9..a05243dc942db 100644 --- a/src/Symfony/Bridge/Twig/Resources/views/Form/bootstrap_base_layout.html.twig +++ b/src/Symfony/Bridge/Twig/Resources/views/Form/bootstrap_base_layout.html.twig @@ -153,6 +153,7 @@ {%- for child in form %} {{- form_widget(child, { parent_label_class: label_attr.class|default(''), + label_translation_parameters: choice_translation_parameters, translation_domain: choice_translation_domain, }) -}} {% endfor -%} @@ -161,6 +162,7 @@ {%- for child in form %} {{- form_widget(child, { parent_label_class: label_attr.class|default(''), + label_translation_parameters: choice_translation_parameters, translation_domain: choice_translation_domain, }) -}} {%- endfor -%} diff --git a/src/Symfony/Bridge/Twig/Resources/views/Form/form_div_layout.html.twig b/src/Symfony/Bridge/Twig/Resources/views/Form/form_div_layout.html.twig index 2e58e26db0e67..01b3850cdb8fd 100644 --- a/src/Symfony/Bridge/Twig/Resources/views/Form/form_div_layout.html.twig +++ b/src/Symfony/Bridge/Twig/Resources/views/Form/form_div_layout.html.twig @@ -50,7 +50,7 @@
{%- for child in form %} {{- form_widget(child) -}} - {{- form_label(child, null, {translation_domain: choice_translation_domain}) -}} + {{- form_label(child, null, {label_translation_parameters: choice_translation_parameters, translation_domain: choice_translation_domain}) -}} {% endfor -%}
{%- endblock choice_widget_expanded -%} @@ -80,12 +80,12 @@ {%- block choice_widget_options -%} {% for group_label, choice in options %} {%- if choice is iterable -%} - + {% set options = choice %} {{- block('choice_widget_options') -}} {%- else -%} - + {%- endif -%} {% endfor %} {%- endblock choice_widget_options -%} diff --git a/src/Symfony/Component/Form/Extension/Core/Type/ChoiceType.php b/src/Symfony/Component/Form/Extension/Core/Type/ChoiceType.php index dbdc8744da5c1..9905fb6a25f2a 100644 --- a/src/Symfony/Component/Form/Extension/Core/Type/ChoiceType.php +++ b/src/Symfony/Component/Form/Extension/Core/Type/ChoiceType.php @@ -211,6 +211,7 @@ public function buildView(FormView $view, FormInterface $form, array $options) 'choices' => $choiceListView->choices, 'separator' => '-------------------', 'placeholder' => null, + 'choice_translation_parameters' => $options['choice_translation_parameters'], 'choice_translation_domain' => $choiceTranslationDomain, ]); @@ -336,6 +337,7 @@ public function configureOptions(OptionsResolver $resolver) // even if the "data" option is manually set to an object. // See https://github.com/symfony/symfony/pull/5582 'data_class' => null, + 'choice_translation_parameters' => [], 'choice_translation_domain' => true, 'trim' => false, 'invalid_message' => function (Options $options, $previousValue) { From 5c9a613f06e2c05963541bfa6e31344fe75180fd Mon Sep 17 00:00:00 2001 From: Vincent Langlet Date: Mon, 18 May 2020 11:44:02 +0200 Subject: [PATCH 2/9] Add changelog --- src/Symfony/Component/Form/CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/src/Symfony/Component/Form/CHANGELOG.md b/src/Symfony/Component/Form/CHANGELOG.md index 53450657d1214..da80b288bdd68 100644 --- a/src/Symfony/Component/Form/CHANGELOG.md +++ b/src/Symfony/Component/Form/CHANGELOG.md @@ -8,6 +8,7 @@ CHANGELOG * Added `DataMapper`, `ChainAccessor`, `PropertyPathAccessor` and `CallbackAccessor` with new callable `getter` and `setter` options for each form type * Deprecated `PropertyPathMapper` in favor of `DataMapper` and `PropertyPathAccessor` * Added a `html5` option to `MoneyType` and `PercentType`, to use `` + * Added a `choice_translation_parameters` option to `ChoiceType` 5.1.0 ----- From 53958d7b8a2526e34606090c4cea47e8763c5a87 Mon Sep 17 00:00:00 2001 From: Vincent Langlet Date: Tue, 19 May 2020 01:09:03 +0200 Subject: [PATCH 3/9] Fix tests --- .../views/Form/bootstrap_4_layout.html.twig | 2 +- .../Form/bootstrap_base_layout.html.twig | 4 +- .../views/Form/form_div_layout.html.twig | 6 +- .../Descriptor/resolved_form_type_1.json | 1 + .../Descriptor/resolved_form_type_1.txt | 75 +++++++++---------- 5 files changed, 44 insertions(+), 44 deletions(-) diff --git a/src/Symfony/Bridge/Twig/Resources/views/Form/bootstrap_4_layout.html.twig b/src/Symfony/Bridge/Twig/Resources/views/Form/bootstrap_4_layout.html.twig index 542e200ea3a95..b8d41528f2057 100644 --- a/src/Symfony/Bridge/Twig/Resources/views/Form/bootstrap_4_layout.html.twig +++ b/src/Symfony/Bridge/Twig/Resources/views/Form/bootstrap_4_layout.html.twig @@ -201,7 +201,7 @@ {%- for child in form %} {{- form_widget(child, { parent_label_class: label_attr.class|default(''), - label_translation_parameters: choice_translation_parameters, + label_translation_parameters: choice_translation_parameters|default([]), translation_domain: choice_translation_domain, valid: valid, }) -}} diff --git a/src/Symfony/Bridge/Twig/Resources/views/Form/bootstrap_base_layout.html.twig b/src/Symfony/Bridge/Twig/Resources/views/Form/bootstrap_base_layout.html.twig index a05243dc942db..cea9cfb1f95c4 100644 --- a/src/Symfony/Bridge/Twig/Resources/views/Form/bootstrap_base_layout.html.twig +++ b/src/Symfony/Bridge/Twig/Resources/views/Form/bootstrap_base_layout.html.twig @@ -153,7 +153,7 @@ {%- for child in form %} {{- form_widget(child, { parent_label_class: label_attr.class|default(''), - label_translation_parameters: choice_translation_parameters, + label_translation_parameters: choice_translation_parameters|default([]), translation_domain: choice_translation_domain, }) -}} {% endfor -%} @@ -162,7 +162,7 @@ {%- for child in form %} {{- form_widget(child, { parent_label_class: label_attr.class|default(''), - label_translation_parameters: choice_translation_parameters, + label_translation_parameters: choice_translation_parameters|default([]), translation_domain: choice_translation_domain, }) -}} {%- endfor -%} diff --git a/src/Symfony/Bridge/Twig/Resources/views/Form/form_div_layout.html.twig b/src/Symfony/Bridge/Twig/Resources/views/Form/form_div_layout.html.twig index 01b3850cdb8fd..dc14da8bb47c9 100644 --- a/src/Symfony/Bridge/Twig/Resources/views/Form/form_div_layout.html.twig +++ b/src/Symfony/Bridge/Twig/Resources/views/Form/form_div_layout.html.twig @@ -50,7 +50,7 @@
{%- for child in form %} {{- form_widget(child) -}} - {{- form_label(child, null, {label_translation_parameters: choice_translation_parameters, translation_domain: choice_translation_domain}) -}} + {{- form_label(child, null, {label_translation_parameters: choice_translation_parameters|default([]), translation_domain: choice_translation_domain}) -}} {% endfor -%}
{%- endblock choice_widget_expanded -%} @@ -80,12 +80,12 @@ {%- block choice_widget_options -%} {% for group_label, choice in options %} {%- if choice is iterable -%} - + {% set options = choice %} {{- block('choice_widget_options') -}} {%- else -%} - + {%- endif -%} {% endfor %} {%- endblock choice_widget_options -%} diff --git a/src/Symfony/Component/Form/Tests/Fixtures/Descriptor/resolved_form_type_1.json b/src/Symfony/Component/Form/Tests/Fixtures/Descriptor/resolved_form_type_1.json index cc7d5544a95eb..3cd6ca5ca40ca 100644 --- a/src/Symfony/Component/Form/Tests/Fixtures/Descriptor/resolved_form_type_1.json +++ b/src/Symfony/Component/Form/Tests/Fixtures/Descriptor/resolved_form_type_1.json @@ -9,6 +9,7 @@ "choice_loader", "choice_name", "choice_translation_domain", + "choice_translation_parameters", "choice_value", "choices", "expanded", diff --git a/src/Symfony/Component/Form/Tests/Fixtures/Descriptor/resolved_form_type_1.txt b/src/Symfony/Component/Form/Tests/Fixtures/Descriptor/resolved_form_type_1.txt index 74603552e0d1d..e27d4f19033cf 100644 --- a/src/Symfony/Component/Form/Tests/Fixtures/Descriptor/resolved_form_type_1.txt +++ b/src/Symfony/Component/Form/Tests/Fixtures/Descriptor/resolved_form_type_1.txt @@ -2,44 +2,43 @@ 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 help + preferred_choices 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 ------------ From 5cea241b602d98d6728d87a2da94cba1593af01a Mon Sep 17 00:00:00 2001 From: Vincent Langlet Date: Tue, 7 Jul 2020 19:21:56 +0200 Subject: [PATCH 4/9] Avoid BC-break --- .../Resources/views/Form/bootstrap_4_layout.html.twig | 3 ++- .../Resources/views/Form/bootstrap_base_layout.html.twig | 6 ++++-- .../Twig/Resources/views/Form/form_div_layout.html.twig | 9 ++++++--- 3 files changed, 12 insertions(+), 6 deletions(-) diff --git a/src/Symfony/Bridge/Twig/Resources/views/Form/bootstrap_4_layout.html.twig b/src/Symfony/Bridge/Twig/Resources/views/Form/bootstrap_4_layout.html.twig index b8d41528f2057..258f6fdadf2c4 100644 --- a/src/Symfony/Bridge/Twig/Resources/views/Form/bootstrap_4_layout.html.twig +++ b/src/Symfony/Bridge/Twig/Resources/views/Form/bootstrap_4_layout.html.twig @@ -199,9 +199,10 @@ {% block choice_widget_expanded -%}
{%- for child in form %} + {# NEXT_MAJOR: Use default([]) for choice_translation_parameters #} {{- form_widget(child, { parent_label_class: label_attr.class|default(''), - label_translation_parameters: choice_translation_parameters|default([]), + label_translation_parameters: choice_translation_parameters|default(label_translation_parameters), translation_domain: choice_translation_domain, valid: valid, }) -}} diff --git a/src/Symfony/Bridge/Twig/Resources/views/Form/bootstrap_base_layout.html.twig b/src/Symfony/Bridge/Twig/Resources/views/Form/bootstrap_base_layout.html.twig index cea9cfb1f95c4..bba4278cafb24 100644 --- a/src/Symfony/Bridge/Twig/Resources/views/Form/bootstrap_base_layout.html.twig +++ b/src/Symfony/Bridge/Twig/Resources/views/Form/bootstrap_base_layout.html.twig @@ -151,18 +151,20 @@ {% block choice_widget_expanded -%} {%- if '-inline' in label_attr.class|default('') -%} {%- for child in form %} + {# NEXT_MAJOR: Use default([]) for choice_translation_parameters #} {{- form_widget(child, { parent_label_class: label_attr.class|default(''), - label_translation_parameters: choice_translation_parameters|default([]), + label_translation_parameters: choice_translation_parameters|default(label_translation_parameters), translation_domain: choice_translation_domain, }) -}} {% endfor -%} {%- else -%}
{%- for child in form %} + {# NEXT_MAJOR: Use default([]) for choice_translation_parameters #} {{- form_widget(child, { parent_label_class: label_attr.class|default(''), - label_translation_parameters: choice_translation_parameters|default([]), + label_translation_parameters: choice_translation_parameters|default(label_translation_parameters), translation_domain: choice_translation_domain, }) -}} {%- endfor -%} diff --git a/src/Symfony/Bridge/Twig/Resources/views/Form/form_div_layout.html.twig b/src/Symfony/Bridge/Twig/Resources/views/Form/form_div_layout.html.twig index dc14da8bb47c9..134b7e03e3859 100644 --- a/src/Symfony/Bridge/Twig/Resources/views/Form/form_div_layout.html.twig +++ b/src/Symfony/Bridge/Twig/Resources/views/Form/form_div_layout.html.twig @@ -50,7 +50,8 @@
{%- for child in form %} {{- form_widget(child) -}} - {{- form_label(child, null, {label_translation_parameters: choice_translation_parameters|default([]), translation_domain: choice_translation_domain}) -}} + {# NEXT_MAJOR: Use default([]) for choice_translation_parameters #} + {{- form_label(child, null, {label_translation_parameters: choice_translation_parameters|default(label_translation_parameters), translation_domain: choice_translation_domain}) -}} {% endfor -%}
{%- endblock choice_widget_expanded -%} @@ -80,12 +81,14 @@ {%- block choice_widget_options -%} {% for group_label, choice in options %} {%- if choice is iterable -%} - + {# NEXT_MAJOR: Use default([]) for choice_translation_parameters #} + {% set options = choice %} {{- block('choice_widget_options') -}} {%- else -%} - + {# NEXT_MAJOR: Use default([]) for choice_translation_parameters #} + {%- endif -%} {% endfor %} {%- endblock choice_widget_options -%} From 3c48b9aa1a567c503ce85c367dc9a7f7206ebf4f Mon Sep 17 00:00:00 2001 From: Vincent Langlet Date: Mon, 13 Jul 2020 00:10:27 +0200 Subject: [PATCH 5/9] Make choice_translation_parameters similar to choice_attr and support callable --- .../views/Form/bootstrap_4_layout.html.twig | 2 - .../Form/bootstrap_base_layout.html.twig | 4 - .../views/Form/form_div_layout.html.twig | 9 +- .../Component/Form/ChoiceList/ChoiceList.php | 13 ++ .../Cache/ChoiceTranslationParameters.php | 27 ++++ .../Factory/CachingFactoryDecorator.php | 34 +++-- .../Factory/ChoiceListFactoryInterface.php | 11 +- .../Factory/DefaultChoiceListFactory.php | 21 ++- .../Factory/PropertyAccessDecorator.php | 33 ++++- .../Form/ChoiceList/View/ChoiceView.php | 17 ++- .../Form/Extension/Core/Type/ChoiceType.php | 10 +- .../Factory/DefaultChoiceListFactoryTest.php | 132 +++++++++++++++++- .../Extension/Core/Type/ChoiceTypeTest.php | 20 ++- .../DeprecatedChoiceListFactory.php | 2 +- 14 files changed, 280 insertions(+), 55 deletions(-) create mode 100644 src/Symfony/Component/Form/ChoiceList/Factory/Cache/ChoiceTranslationParameters.php diff --git a/src/Symfony/Bridge/Twig/Resources/views/Form/bootstrap_4_layout.html.twig b/src/Symfony/Bridge/Twig/Resources/views/Form/bootstrap_4_layout.html.twig index 258f6fdadf2c4..86e2715488338 100644 --- a/src/Symfony/Bridge/Twig/Resources/views/Form/bootstrap_4_layout.html.twig +++ b/src/Symfony/Bridge/Twig/Resources/views/Form/bootstrap_4_layout.html.twig @@ -199,10 +199,8 @@ {% block choice_widget_expanded -%}
{%- for child in form %} - {# NEXT_MAJOR: Use default([]) for choice_translation_parameters #} {{- form_widget(child, { parent_label_class: label_attr.class|default(''), - label_translation_parameters: choice_translation_parameters|default(label_translation_parameters), translation_domain: choice_translation_domain, valid: valid, }) -}} diff --git a/src/Symfony/Bridge/Twig/Resources/views/Form/bootstrap_base_layout.html.twig b/src/Symfony/Bridge/Twig/Resources/views/Form/bootstrap_base_layout.html.twig index bba4278cafb24..1b0092859dbd9 100644 --- a/src/Symfony/Bridge/Twig/Resources/views/Form/bootstrap_base_layout.html.twig +++ b/src/Symfony/Bridge/Twig/Resources/views/Form/bootstrap_base_layout.html.twig @@ -151,20 +151,16 @@ {% block choice_widget_expanded -%} {%- if '-inline' in label_attr.class|default('') -%} {%- for child in form %} - {# NEXT_MAJOR: Use default([]) for choice_translation_parameters #} {{- form_widget(child, { parent_label_class: label_attr.class|default(''), - label_translation_parameters: choice_translation_parameters|default(label_translation_parameters), translation_domain: choice_translation_domain, }) -}} {% endfor -%} {%- else -%}
{%- for child in form %} - {# NEXT_MAJOR: Use default([]) for choice_translation_parameters #} {{- form_widget(child, { parent_label_class: label_attr.class|default(''), - label_translation_parameters: choice_translation_parameters|default(label_translation_parameters), translation_domain: choice_translation_domain, }) -}} {%- endfor -%} diff --git a/src/Symfony/Bridge/Twig/Resources/views/Form/form_div_layout.html.twig b/src/Symfony/Bridge/Twig/Resources/views/Form/form_div_layout.html.twig index 134b7e03e3859..619d5475e4556 100644 --- a/src/Symfony/Bridge/Twig/Resources/views/Form/form_div_layout.html.twig +++ b/src/Symfony/Bridge/Twig/Resources/views/Form/form_div_layout.html.twig @@ -50,8 +50,7 @@
{%- for child in form %} {{- form_widget(child) -}} - {# NEXT_MAJOR: Use default([]) for choice_translation_parameters #} - {{- form_label(child, null, {label_translation_parameters: choice_translation_parameters|default(label_translation_parameters), translation_domain: choice_translation_domain}) -}} + {{- form_label(child, null, {translation_domain: choice_translation_domain}) -}} {% endfor -%}
{%- endblock choice_widget_expanded -%} @@ -81,14 +80,12 @@ {%- block choice_widget_options -%} {% for group_label, choice in options %} {%- if choice is iterable -%} - {# NEXT_MAJOR: Use default([]) for choice_translation_parameters #} - + {% set options = choice %} {{- block('choice_widget_options') -}} {%- else -%} - {# NEXT_MAJOR: Use default([]) for choice_translation_parameters #} - + {%- endif -%} {% endfor %} {%- endblock choice_widget_options -%} diff --git a/src/Symfony/Component/Form/ChoiceList/ChoiceList.php b/src/Symfony/Component/Form/ChoiceList/ChoiceList.php index 045ded01e2e05..df63c83d89dee 100644 --- a/src/Symfony/Component/Form/ChoiceList/ChoiceList.php +++ b/src/Symfony/Component/Form/ChoiceList/ChoiceList.php @@ -16,6 +16,7 @@ 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 @@ public static function attr($formType, $attr, $vary = null): ChoiceAttr 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. * diff --git a/src/Symfony/Component/Form/ChoiceList/Factory/Cache/ChoiceTranslationParameters.php b/src/Symfony/Component/Form/ChoiceList/Factory/Cache/ChoiceTranslationParameters.php new file mode 100644 index 0000000000000..e9ab5c7119922 --- /dev/null +++ b/src/Symfony/Component/Form/ChoiceList/Factory/Cache/ChoiceTranslationParameters.php @@ -0,0 +1,27 @@ + + * + * 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 + */ +final class ChoiceTranslationParameters extends AbstractStaticOption +{ +} diff --git a/src/Symfony/Component/Form/ChoiceList/Factory/CachingFactoryDecorator.php b/src/Symfony/Component/Form/ChoiceList/Factory/CachingFactoryDecorator.php index 2e1dc9a317654..ecd12d49fe0fa 100644 --- a/src/Symfony/Component/Form/ChoiceList/Factory/CachingFactoryDecorator.php +++ b/src/Symfony/Component/Form/ChoiceList/Factory/CachingFactoryDecorator.php @@ -174,13 +174,14 @@ public function createListFromLoader(ChoiceLoaderInterface $loader, $value = nul /** * {@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 = []) { $cache = true; @@ -214,11 +215,25 @@ public function createView(ChoiceListInterface $list, $preferredChoices = null, $cache = false; } + if ($labelTranslationParameters instanceof Cache\ChoiceTranslationParameters) { + $labelTranslationParameters = $labelTranslationParameters->getOption(); + } elseif ([] !== $labelTranslationParameters) { + $cache = false; + } + if (!$cache) { - return $this->decoratedFactory->createView($list, $preferredChoices, $label, $index, $groupBy, $attr); + return $this->decoratedFactory->createView( + $list, + $preferredChoices, + $label, + $index, + $groupBy, + $attr, + $labelTranslationParameters + ); } - $hash = self::generateHash([$list, $preferredChoices, $label, $index, $groupBy, $attr]); + $hash = self::generateHash([$list, $preferredChoices, $label, $index, $groupBy, $attr, $labelTranslationParameters]); if (!isset($this->views[$hash])) { $this->views[$hash] = $this->decoratedFactory->createView( @@ -227,7 +242,8 @@ public function createView(ChoiceListInterface $list, $preferredChoices = null, $label, $index, $groupBy, - $attr + $attr, + $labelTranslationParameters ); } diff --git a/src/Symfony/Component/Form/ChoiceList/Factory/ChoiceListFactoryInterface.php b/src/Symfony/Component/Form/ChoiceList/Factory/ChoiceListFactoryInterface.php index 82b1e4dc7de6b..6834009190f81 100644 --- a/src/Symfony/Component/Form/ChoiceList/Factory/ChoiceListFactoryInterface.php +++ b/src/Symfony/Component/Form/ChoiceList/Factory/ChoiceListFactoryInterface.php @@ -76,12 +76,13 @@ public function createListFromLoader(ChoiceLoaderInterface $loader, callable $va * 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 = []*/); } diff --git a/src/Symfony/Component/Form/ChoiceList/Factory/DefaultChoiceListFactory.php b/src/Symfony/Component/Form/ChoiceList/Factory/DefaultChoiceListFactory.php index 45d3d046bd36e..fd1930e50a833 100644 --- a/src/Symfony/Component/Form/ChoiceList/Factory/DefaultChoiceListFactory.php +++ b/src/Symfony/Component/Form/ChoiceList/Factory/DefaultChoiceListFactory.php @@ -69,7 +69,7 @@ public function createListFromLoader(ChoiceLoaderInterface $loader, callable $va /** * {@inheritdoc} */ - 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 = []) { $preferredViews = []; $preferredViewsOrder = []; @@ -109,6 +109,7 @@ public function createView(ChoiceListInterface $list, $preferredChoices = null, $keys, $index, $attr, + $labelTranslationParameters, $preferredChoices, $preferredViews, $preferredViewsOrder, @@ -146,6 +147,7 @@ public function createView(ChoiceListInterface $list, $preferredChoices = null, $keys, $index, $attr, + $labelTranslationParameters, $preferredChoices, $preferredViews, $preferredViewsOrder, @@ -162,7 +164,7 @@ public function createView(ChoiceListInterface $list, $preferredChoices = null, 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 +188,12 @@ private static function addChoiceView($choice, string $value, $label, array $key $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) : (isset($attr[$key]) ? $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) + : (isset($labelTranslationParameters[$key]) ? $labelTranslationParameters[$key] : []) ); // $isPreferred may be null if no choices are preferred @@ -198,7 +205,7 @@ private static function addChoiceView($choice, string $value, $label, array $key $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 +224,7 @@ private static function addChoiceViewsFromStructuredValues(array $values, $label $keys, $index, $attr, + $labelTranslationParameters, $isPreferred, $preferredViewsForGroup, $preferredViewsOrder, @@ -242,6 +250,7 @@ private static function addChoiceViewsFromStructuredValues(array $values, $label $keys, $index, $attr, + $labelTranslationParameters, $isPreferred, $preferredViews, $preferredViewsOrder, @@ -250,7 +259,7 @@ private static function addChoiceViewsFromStructuredValues(array $values, $label } } - 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 +272,7 @@ private static function addChoiceViewsGroupedByCallable(callable $groupBy, $choi $keys, $index, $attr, + $labelTranslationParameters, $isPreferred, $preferredViews, $preferredViewsOrder, @@ -292,6 +302,7 @@ private static function addChoiceViewsGroupedByCallable(callable $groupBy, $choi $keys, $index, $attr, + $labelTranslationParameters, $isPreferred, $preferredViews[$groupLabel]->choices, $preferredViewsOrder[$groupLabel], diff --git a/src/Symfony/Component/Form/ChoiceList/Factory/PropertyAccessDecorator.php b/src/Symfony/Component/Form/ChoiceList/Factory/PropertyAccessDecorator.php index bfa37973a565e..62047d08f8d27 100644 --- a/src/Symfony/Component/Form/ChoiceList/Factory/PropertyAccessDecorator.php +++ b/src/Symfony/Component/Form/ChoiceList/Factory/PropertyAccessDecorator.php @@ -145,15 +145,16 @@ public function createListFromLoader(ChoiceLoaderInterface $loader, $value = nul /** * {@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 = []) { $accessor = $this->propertyAccessor; @@ -217,6 +218,24 @@ public function createView(ChoiceListInterface $list, $preferredChoices = null, }; } - return $this->decoratedFactory->createView($list, $preferredChoices, $label, $index, $groupBy, $attr); + if (\is_string($labelTranslationParameters)) { + $labelTranslationParameters = new PropertyPath($labelTranslationParameters); + } + + if ($labelTranslationParameters instanceof PropertyPath) { + $labelTranslationParameters = function ($choice) use ($accessor, $labelTranslationParameters) { + return $accessor->getValue($choice, $labelTranslationParameters); + }; + } + + return $this->decoratedFactory->createView( + $list, + $preferredChoices, + $label, + $index, + $groupBy, + $attr, + $labelTranslationParameters + ); } } diff --git a/src/Symfony/Component/Form/ChoiceList/View/ChoiceView.php b/src/Symfony/Component/Form/ChoiceList/View/ChoiceView.php index 2b5636b17eb1d..cbb9ed540e9a9 100644 --- a/src/Symfony/Component/Form/ChoiceList/View/ChoiceView.php +++ b/src/Symfony/Component/Form/ChoiceList/View/ChoiceView.php @@ -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; } } diff --git a/src/Symfony/Component/Form/Extension/Core/Type/ChoiceType.php b/src/Symfony/Component/Form/Extension/Core/Type/ChoiceType.php index 9905fb6a25f2a..513e0e5b78ce8 100644 --- a/src/Symfony/Component/Form/Extension/Core/Type/ChoiceType.php +++ b/src/Symfony/Component/Form/Extension/Core/Type/ChoiceType.php @@ -18,6 +18,7 @@ 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; @@ -211,8 +212,8 @@ public function buildView(FormView $view, FormInterface $form, array $options) 'choices' => $choiceListView->choices, 'separator' => '-------------------', 'placeholder' => null, - 'choice_translation_parameters' => $options['choice_translation_parameters'], 'choice_translation_domain' => $choiceTranslationDomain, + 'choice_translation_parameters' => $options['choice_translation_parameters'], ]); // The decision, whether a choice is selected, is potentially done @@ -327,6 +328,7 @@ public function configureOptions(OptionsResolver $resolver) 'choice_name' => null, 'choice_value' => null, 'choice_attr' => null, + 'choice_translation_parameters' => [], 'preferred_choices' => [], 'group_by' => null, 'empty_data' => $emptyData, @@ -337,7 +339,6 @@ public function configureOptions(OptionsResolver $resolver) // even if the "data" option is manually set to an object. // See https://github.com/symfony/symfony/pull/5582 'data_class' => null, - 'choice_translation_parameters' => [], 'choice_translation_domain' => true, 'trim' => false, 'invalid_message' => function (Options $options, $previousValue) { @@ -358,6 +359,7 @@ public function configureOptions(OptionsResolver $resolver) $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]); } @@ -397,6 +399,7 @@ private function addSubForm(FormBuilderInterface $builder, string $name, ChoiceV 'value' => $choiceView->value, 'label' => $choiceView->label, 'attr' => $choiceView->attr, + 'label_translation_parameters' => $choiceView->labelTranslationParameters, 'translation_domain' => $options['choice_translation_domain'], 'block_name' => 'entry', ]; @@ -441,7 +444,8 @@ private function createChoiceListView(ChoiceListInterface $choiceList, array $op $options['choice_label'], $options['choice_name'], $options['group_by'], - $options['choice_attr'] + $options['choice_attr'], + $options['choice_translation_parameters'] ); } } diff --git a/src/Symfony/Component/Form/Tests/ChoiceList/Factory/DefaultChoiceListFactoryTest.php b/src/Symfony/Component/Form/Tests/ChoiceList/Factory/DefaultChoiceListFactoryTest.php index a124b48ffda31..c59b3840a5948 100644 --- a/src/Symfony/Component/Form/Tests/ChoiceList/Factory/DefaultChoiceListFactoryTest.php +++ b/src/Symfony/Component/Form/Tests/ChoiceList/Factory/DefaultChoiceListFactoryTest.php @@ -77,6 +77,11 @@ public function getAttr($object) 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 @@ public function getGroupAsObject($object) 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 @@ function ($object, $key, $value) { $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 @@ private function assertFlatViewWithAttr($view) ), $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( diff --git a/src/Symfony/Component/Form/Tests/Extension/Core/Type/ChoiceTypeTest.php b/src/Symfony/Component/Form/Tests/Extension/Core/Type/ChoiceTypeTest.php index 16ede19493d5d..663aac3dcc456 100644 --- a/src/Symfony/Component/Form/Tests/Extension/Core/Type/ChoiceTypeTest.php +++ b/src/Symfony/Component/Form/Tests/Extension/Core/Type/ChoiceTypeTest.php @@ -1782,14 +1782,26 @@ public function testPassChoiceDataToView() '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']); } diff --git a/src/Symfony/Component/Form/Tests/Fixtures/ChoiceList/DeprecatedChoiceListFactory.php b/src/Symfony/Component/Form/Tests/Fixtures/ChoiceList/DeprecatedChoiceListFactory.php index 6361c2eedc33f..287259a3f44e6 100644 --- a/src/Symfony/Component/Form/Tests/Fixtures/ChoiceList/DeprecatedChoiceListFactory.php +++ b/src/Symfony/Component/Form/Tests/Fixtures/ChoiceList/DeprecatedChoiceListFactory.php @@ -16,7 +16,7 @@ public function createListFromLoader(ChoiceLoaderInterface $loader, callable $va { } - 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 = []) { } } From e87b938101841d39d97ca5928fb8b869ce729f02 Mon Sep 17 00:00:00 2001 From: Vincent Langlet Date: Sun, 23 Aug 2020 20:35:43 +0200 Subject: [PATCH 6/9] Bump version --- src/Symfony/Bridge/Twig/composer.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Symfony/Bridge/Twig/composer.json b/src/Symfony/Bridge/Twig/composer.json index 659d4c8ff364d..a99fee660cc66 100644 --- a/src/Symfony/Bridge/Twig/composer.json +++ b/src/Symfony/Bridge/Twig/composer.json @@ -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", + "symfony/form": "^5.2", "symfony/http-foundation": "^4.4|^5.0", "symfony/http-kernel": "^4.4|^5.0", "symfony/mime": "^5.2", From 2762e671aaac41fbd8c62b2188b7c8f9552a4ae7 Mon Sep 17 00:00:00 2001 From: Vincent Langlet Date: Sun, 20 Sep 2020 20:46:47 +0200 Subject: [PATCH 7/9] Avoid BC break --- src/Symfony/Bridge/Twig/composer.json | 2 +- .../Form/ChoiceList/Factory/CachingFactoryDecorator.php | 3 ++- .../Form/ChoiceList/Factory/DefaultChoiceListFactory.php | 3 ++- .../Form/ChoiceList/Factory/PropertyAccessDecorator.php | 3 ++- .../Tests/Fixtures/ChoiceList/DeprecatedChoiceListFactory.php | 2 +- 5 files changed, 8 insertions(+), 5 deletions(-) diff --git a/src/Symfony/Bridge/Twig/composer.json b/src/Symfony/Bridge/Twig/composer.json index a99fee660cc66..2260aa32e7113 100644 --- a/src/Symfony/Bridge/Twig/composer.json +++ b/src/Symfony/Bridge/Twig/composer.json @@ -52,7 +52,7 @@ }, "conflict": { "symfony/console": "<4.4", - "symfony/form": "<5.1", + "symfony/form": "<5.2", "symfony/http-foundation": "<4.4", "symfony/http-kernel": "<4.4", "symfony/translation": "<5.2", diff --git a/src/Symfony/Component/Form/ChoiceList/Factory/CachingFactoryDecorator.php b/src/Symfony/Component/Form/ChoiceList/Factory/CachingFactoryDecorator.php index ecd12d49fe0fa..4fd99c8cc7fef 100644 --- a/src/Symfony/Component/Form/ChoiceList/Factory/CachingFactoryDecorator.php +++ b/src/Symfony/Component/Form/ChoiceList/Factory/CachingFactoryDecorator.php @@ -181,8 +181,9 @@ public function createListFromLoader(ChoiceLoaderInterface $loader, $value = nul * @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, $labelTranslationParameters = []) + public function createView(ChoiceListInterface $list, $preferredChoices = null, $label = null, $index = null, $groupBy = null, $attr = null/*, $labelTranslationParameters = []*/) { + $labelTranslationParameters = \func_get_args()[6] ?? []; $cache = true; if ($preferredChoices instanceof Cache\PreferredChoice) { diff --git a/src/Symfony/Component/Form/ChoiceList/Factory/DefaultChoiceListFactory.php b/src/Symfony/Component/Form/ChoiceList/Factory/DefaultChoiceListFactory.php index fd1930e50a833..a69945e75af18 100644 --- a/src/Symfony/Component/Form/ChoiceList/Factory/DefaultChoiceListFactory.php +++ b/src/Symfony/Component/Form/ChoiceList/Factory/DefaultChoiceListFactory.php @@ -69,8 +69,9 @@ public function createListFromLoader(ChoiceLoaderInterface $loader, callable $va /** * {@inheritdoc} */ - public function createView(ChoiceListInterface $list, $preferredChoices = null, $label = null, callable $index = null, callable $groupBy = null, $attr = null, $labelTranslationParameters = []) + public function createView(ChoiceListInterface $list, $preferredChoices = null, $label = null, callable $index = null, callable $groupBy = null, $attr = null/*, $labelTranslationParameters = []*/) { + $labelTranslationParameters = \func_get_args()[6] ?? []; $preferredViews = []; $preferredViewsOrder = []; $otherViews = []; diff --git a/src/Symfony/Component/Form/ChoiceList/Factory/PropertyAccessDecorator.php b/src/Symfony/Component/Form/ChoiceList/Factory/PropertyAccessDecorator.php index 62047d08f8d27..1f6cb26c0ca32 100644 --- a/src/Symfony/Component/Form/ChoiceList/Factory/PropertyAccessDecorator.php +++ b/src/Symfony/Component/Form/ChoiceList/Factory/PropertyAccessDecorator.php @@ -154,8 +154,9 @@ 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, $labelTranslationParameters = []) + public function createView(ChoiceListInterface $list, $preferredChoices = null, $label = null, $index = null, $groupBy = null, $attr = null/*, $labelTranslationParameters = []*/) { + $labelTranslationParameters = \func_get_args()[6] ?? []; $accessor = $this->propertyAccessor; if (\is_string($label)) { diff --git a/src/Symfony/Component/Form/Tests/Fixtures/ChoiceList/DeprecatedChoiceListFactory.php b/src/Symfony/Component/Form/Tests/Fixtures/ChoiceList/DeprecatedChoiceListFactory.php index 287259a3f44e6..6361c2eedc33f 100644 --- a/src/Symfony/Component/Form/Tests/Fixtures/ChoiceList/DeprecatedChoiceListFactory.php +++ b/src/Symfony/Component/Form/Tests/Fixtures/ChoiceList/DeprecatedChoiceListFactory.php @@ -16,7 +16,7 @@ public function createListFromLoader(ChoiceLoaderInterface $loader, callable $va { } - public function createView(ChoiceListInterface $list, $preferredChoices = null, $label = null, callable $index = null, callable $groupBy = null, $attr = null, $labelTranslationParameters = []) + public function createView(ChoiceListInterface $list, $preferredChoices = null, $label = null, callable $index = null, callable $groupBy = null, $attr = null) { } } From 47875dff3cf5d161c63782429fa4ae3da8928f0c Mon Sep 17 00:00:00 2001 From: Vincent Langlet Date: Sun, 27 Sep 2020 12:33:43 +0200 Subject: [PATCH 8/9] Add deprecation --- .../Form/ChoiceList/Factory/CachingFactoryDecorator.php | 4 ++++ .../Form/ChoiceList/Factory/DefaultChoiceListFactory.php | 4 ++++ .../Form/ChoiceList/Factory/PropertyAccessDecorator.php | 4 ++++ 3 files changed, 12 insertions(+) diff --git a/src/Symfony/Component/Form/ChoiceList/Factory/CachingFactoryDecorator.php b/src/Symfony/Component/Form/ChoiceList/Factory/CachingFactoryDecorator.php index 4fd99c8cc7fef..5267f9945af80 100644 --- a/src/Symfony/Component/Form/ChoiceList/Factory/CachingFactoryDecorator.php +++ b/src/Symfony/Component/Form/ChoiceList/Factory/CachingFactoryDecorator.php @@ -183,6 +183,10 @@ public function createListFromLoader(ChoiceLoaderInterface $loader, $value = nul */ public function createView(ChoiceListInterface $list, $preferredChoices = null, $label = null, $index = null, $groupBy = null, $attr = null/*, $labelTranslationParameters = []*/) { + if (\count(\func_get_args()) < 7) { + trigger_deprecation('symfony/form', '5.2', 'Calling %s without passing the label translation parameters is deprecated.', __METHOD__); + } + $labelTranslationParameters = \func_get_args()[6] ?? []; $cache = true; diff --git a/src/Symfony/Component/Form/ChoiceList/Factory/DefaultChoiceListFactory.php b/src/Symfony/Component/Form/ChoiceList/Factory/DefaultChoiceListFactory.php index a69945e75af18..0eafd7f287e22 100644 --- a/src/Symfony/Component/Form/ChoiceList/Factory/DefaultChoiceListFactory.php +++ b/src/Symfony/Component/Form/ChoiceList/Factory/DefaultChoiceListFactory.php @@ -71,6 +71,10 @@ public function createListFromLoader(ChoiceLoaderInterface $loader, callable $va */ public function createView(ChoiceListInterface $list, $preferredChoices = null, $label = null, callable $index = null, callable $groupBy = null, $attr = null/*, $labelTranslationParameters = []*/) { + if (\count(\func_get_args()) < 7) { + trigger_deprecation('symfony/form', '5.2', 'Calling %s without passing the label translation parameters is deprecated.', __METHOD__); + } + $labelTranslationParameters = \func_get_args()[6] ?? []; $preferredViews = []; $preferredViewsOrder = []; diff --git a/src/Symfony/Component/Form/ChoiceList/Factory/PropertyAccessDecorator.php b/src/Symfony/Component/Form/ChoiceList/Factory/PropertyAccessDecorator.php index 1f6cb26c0ca32..65aeceee194db 100644 --- a/src/Symfony/Component/Form/ChoiceList/Factory/PropertyAccessDecorator.php +++ b/src/Symfony/Component/Form/ChoiceList/Factory/PropertyAccessDecorator.php @@ -156,6 +156,10 @@ public function createListFromLoader(ChoiceLoaderInterface $loader, $value = nul */ public function createView(ChoiceListInterface $list, $preferredChoices = null, $label = null, $index = null, $groupBy = null, $attr = null/*, $labelTranslationParameters = []*/) { + if (\count(\func_get_args()) < 7) { + trigger_deprecation('symfony/form', '5.2', 'Calling %s without passing the label translation parameters is deprecated.', __METHOD__); + } + $labelTranslationParameters = \func_get_args()[6] ?? []; $accessor = $this->propertyAccessor; From 026ed90a159d4c06c9344b55b17dbd29b3a72822 Mon Sep 17 00:00:00 2001 From: Vincent Langlet Date: Sun, 4 Oct 2020 17:53:53 +0200 Subject: [PATCH 9/9] Fix test --- .../Factory/CachingFactoryDecorator.php | 4 - .../Factory/DefaultChoiceListFactory.php | 4 - .../Factory/PropertyAccessDecorator.php | 4 - .../Descriptor/resolved_form_type_1.txt | 75 ++++++++++--------- 4 files changed, 38 insertions(+), 49 deletions(-) diff --git a/src/Symfony/Component/Form/ChoiceList/Factory/CachingFactoryDecorator.php b/src/Symfony/Component/Form/ChoiceList/Factory/CachingFactoryDecorator.php index 5267f9945af80..4fd99c8cc7fef 100644 --- a/src/Symfony/Component/Form/ChoiceList/Factory/CachingFactoryDecorator.php +++ b/src/Symfony/Component/Form/ChoiceList/Factory/CachingFactoryDecorator.php @@ -183,10 +183,6 @@ public function createListFromLoader(ChoiceLoaderInterface $loader, $value = nul */ public function createView(ChoiceListInterface $list, $preferredChoices = null, $label = null, $index = null, $groupBy = null, $attr = null/*, $labelTranslationParameters = []*/) { - if (\count(\func_get_args()) < 7) { - trigger_deprecation('symfony/form', '5.2', 'Calling %s without passing the label translation parameters is deprecated.', __METHOD__); - } - $labelTranslationParameters = \func_get_args()[6] ?? []; $cache = true; diff --git a/src/Symfony/Component/Form/ChoiceList/Factory/DefaultChoiceListFactory.php b/src/Symfony/Component/Form/ChoiceList/Factory/DefaultChoiceListFactory.php index 0eafd7f287e22..a69945e75af18 100644 --- a/src/Symfony/Component/Form/ChoiceList/Factory/DefaultChoiceListFactory.php +++ b/src/Symfony/Component/Form/ChoiceList/Factory/DefaultChoiceListFactory.php @@ -71,10 +71,6 @@ public function createListFromLoader(ChoiceLoaderInterface $loader, callable $va */ public function createView(ChoiceListInterface $list, $preferredChoices = null, $label = null, callable $index = null, callable $groupBy = null, $attr = null/*, $labelTranslationParameters = []*/) { - if (\count(\func_get_args()) < 7) { - trigger_deprecation('symfony/form', '5.2', 'Calling %s without passing the label translation parameters is deprecated.', __METHOD__); - } - $labelTranslationParameters = \func_get_args()[6] ?? []; $preferredViews = []; $preferredViewsOrder = []; diff --git a/src/Symfony/Component/Form/ChoiceList/Factory/PropertyAccessDecorator.php b/src/Symfony/Component/Form/ChoiceList/Factory/PropertyAccessDecorator.php index 65aeceee194db..1f6cb26c0ca32 100644 --- a/src/Symfony/Component/Form/ChoiceList/Factory/PropertyAccessDecorator.php +++ b/src/Symfony/Component/Form/ChoiceList/Factory/PropertyAccessDecorator.php @@ -156,10 +156,6 @@ public function createListFromLoader(ChoiceLoaderInterface $loader, $value = nul */ public function createView(ChoiceListInterface $list, $preferredChoices = null, $label = null, $index = null, $groupBy = null, $attr = null/*, $labelTranslationParameters = []*/) { - if (\count(\func_get_args()) < 7) { - trigger_deprecation('symfony/form', '5.2', 'Calling %s without passing the label translation parameters is deprecated.', __METHOD__); - } - $labelTranslationParameters = \func_get_args()[6] ?? []; $accessor = $this->propertyAccessor; diff --git a/src/Symfony/Component/Form/Tests/Fixtures/Descriptor/resolved_form_type_1.txt b/src/Symfony/Component/Form/Tests/Fixtures/Descriptor/resolved_form_type_1.txt index e27d4f19033cf..0952ccc3e54ec 100644 --- a/src/Symfony/Component/Form/Tests/Fixtures/Descriptor/resolved_form_type_1.txt +++ b/src/Symfony/Component/Form/Tests/Fixtures/Descriptor/resolved_form_type_1.txt @@ -2,43 +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_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 help - preferred_choices 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 ------------