Description
Symfony version(s) affected
6.3
Description
Currently, \Symfony\Component\Form\Extension\Core\Type\BaseType::buildView
merges the label_translation_parameters
and attr_translation_parameters
from the parent with the one.
This was unnoticed until now because the translation parameters defined explicitly still win and the translator component does not report anything in case extra parameters (not used in the translations) are provided.
However, when using a TranslatableMessage, the Twig extension complains if you pass a non-empty array of parameters alongside that value object as those parameters would be totally ignored (as the TranslatableMessage encapsulates its own parameters).
Even defining the option explicitly does not fix this as a merge is done.
A case where this can happen is when using an expanded choice type, for which your choices use TranslatableMessage and you use label_translation_parameters
for the choice field itself (but actually, it can happen any time you use label_translation_parameters
on a compound field).
How to reproduce
// in a form type
$excludeFolderCount = 12; // Actually coming from an option
$builder
->add('folder_delete_choice', ChoiceType::class, [
'label' => 'folder.label.delete_choice',
'label_translation_parameters' => [
'%count%' => $excludeFolderCount,
],
'data' => FolderDeleteAction::MOVE_CONTENT,
'expanded' => true,
'choices' => FolderDeleteAction::cases(),
'choice_value' => 'value',
'choice_label' => fn (FolderDeleteAction $action) => $action->getLabel(),
]);
use Symfony\Component\Translation\TranslatableMessage;
enum FolderDeleteAction: string
{
case DELETE_CONTENT = 'delete_content';
case MOVE_CONTENT = 'move_content';
public function getLabel(): TranslatableMessage
{
return match ($this) {
self::DELETE_CONTENT => new TranslatableMessage('folder.delete.choice.delete_content'),
self::MOVE_CONTENT => new TranslatableMessage('folder.delete.choice.move_content'),
};
}
}
Possible Solution
Remove the inheritance of those parameters.
It might require going through a deprecation phase, requiring an opt-in (which would report a deprecation only when the parent parameters are not empty, to avoid requiring a useless opt-in for all cases where there is nothing inherited, i.e. in 99% of cases)
Additional Context
No response