8000 Improve invalid messages for form types · symfony/symfony@200008f · GitHub
[go: up one dir, main page]

Skip to content

Commit 200008f

Browse files
hiddewiexabbuh
authored andcommitted
Improve invalid messages for form types
1 parent 2c43183 commit 200008f

File tree

93 files changed

+1836
-27
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

93 files changed

+1836
-27
lines changed

src/Symfony/Bundle/FrameworkBundle/DependencyInjection/Configuration.php

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -189,6 +189,18 @@ private function addFormSection(ArrayNodeDefinition $rootNode)
189189
->scalarNode('field_name')->defaultValue('_token')->end()
190190
->end()
191191
->end()
192+
// to be set to false in Symfony 6.0
193+
->booleanNode('legacy_error_messages')
194+
->defaultTrue()
195+
->validate()
196+
->ifTrue()
197+
->then(function ($v) {
198+
@trigger_error('Since symfony/framework-bundle 5.2: Setting the "framework.form.legacy_error_messages" option to "true" is deprecated. It will have no effect as of Symfony 6.0.', E_USER_DEPRECATED);
199+
200+
return $v;
201+
})
202+
->end()
203+
->end()
192204
->end()
193205
->end()
194206
->end()

src/Symfony/Bundle/FrameworkBundle/DependencyInjection/FrameworkExtension.php

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -514,6 +514,8 @@ private function registerFormConfiguration(array $config, ContainerBuilder $cont
514514
{
515515
$loader->load('form.php');
516516

517+
$container->getDefinition('form.type_extension.form.validator')->setArgument(1, $config['form']['legacy_error_messages']);
518+
517519
if (null === $config['form']['csrf_protection']['enabled']) {
518520
$config['form']['csrf_protection']['enabled'] = $config['csrf_protection']['enabled'];
519521
}

src/Symfony/Bundle/FrameworkBundle/Resources/config/schema/symfony-1.0.xsd

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,7 @@
5252
<xsd:element name="csrf-protection" type="form_csrf_protection" minOccurs="0" maxOccurs="1" />
5353
</xsd:all>
5454
<xsd:attribute name="enabled" type="xsd:boolean" />
55+
<xsd:attribute name="legacy-error-messages" type="xsd:boolean" />
5556
</xsd:complexType>
5657

5758
<xsd:complexType name="form_csrf_protection">

src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/ConfigurationTest.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -354,6 +354,7 @@ protected static function getBundleDefaultConfig()
354354
'enabled' => null, // defaults to csrf_protection.enabled
355355
'field_name' => '_token',
356356
],
357+
'legacy_error_messages' => true,
357358
],
358359
'esi' => ['enabled' => false],
359360
'ssi' => ['enabled' => false],

src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/php/csrf.php

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,9 @@
22

33
$container->loadFromExtension('framework', [
44
'csrf_protection' => true,
5-
'form' => true,
5+
'form' => [
6+
'legacy_error_messages' => false,
7+
],
68
'session' => [
79
'handler_id' => null,
810
],
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
<?php
2+
3+
$container->loadFromExtension('framework', [
4+
'form' => [
5+
'legacy_error_messages' => true,
6+
],
7+
]);

src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/php/form_no_csrf.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,5 +5,6 @@
55
'csrf_protection' => [
66
'enabled' => false,
77
],
8+
'legacy_error_messages' => false,
89
],
910
]);

src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/php/full.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
'csrf_protection' => [
99
'field_name' => '_csrf',
1010
],
11+
'legacy_error_messages' => false,
1112
],
1213
'http_method_override' => false,
1314
'esi' => [

src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/xml/csrf.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88

99
<framework:config>
1010
<framework:csrf-protection />
11-
<framework:form />
11+
<framework:form legacy-error-messages="false" />
1212
<framework:session />
1313
</framework:config>
1414
</container>

src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/xml/form_csrf_sets_field_name.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,6 @@
99
<framework:config>
1010
<framework:csrf-protection field-name="_custom" />
1111
<framework:session />
12-
<framework:form />
12+
<framework:form legacy-error-messages="false" />
1313
</framework:config>
1414
</container>

src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/xml/form_csrf_under_form_sets_field_name.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88

99
<framework:config>
1010
<framework:csrf-protection field-name="_custom_form" />
11-
<framework:form />
11+
<framework:form legacy-error-messages="false" />
1212
<framework:session />
1313
</framework:config>
1414
</container>
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
<?xml version="1.0" ?>
2+
3+
<container xmlns="http://symfony.com/schema/dic/services"
4+
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
5+
xmlns:framework="http://symfony.com/schema/dic/symfony"
6+
xsi:schemaLocation="http://symfony.com/schema/dic/services http://symfony.com/schema/dic/services/services-1.0.xsd
7+
http://symfony.com/schema/dic/symfony http://symfony.com/schema/dic/symfony/symfony-1.0.xsd">
8+
9+
<framework:config>
10+
<framework:form legacy-error-messages="true" />
11+
</framework:config>
12+
</container>

src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/xml/form_no_csrf.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
http://symfony.com/schema/dic/symfony https://symfony.com/schema/dic/symfony/symfony-1.0.xsd">
88

99
<framework:config>
10-
<framework:form enabled="true">
10+
<framework:form enabled="true" legacy-error-messages="false">
1111
<framework:csrf-protection enabled="false" />
1212
</framework:form>
1313
</framework:config>

src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/xml/full.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88

99
<framework:config secret="s3cr3t" ide="file%%link%%format" default-locale="fr" http-method-override="false">
1010
<framework:csrf-protection />
11-
<framework:form>
11+
<framework:form legacy-error-messages="false">
1212
<framework:csrf-protection field-name="_csrf"/>
1313
</framework:form>
1414
<framework:esi enabled="true" />
Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
framework:
22
secret: s3cr3t
33
csrf_protection: ~
4-
form: ~
4+
form:
5+
legacy_error_messages: false
56
session: ~
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
framework:
2+
form:
3+
legacy_error_messages: true

src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/yml/form_no_csrf.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,3 +2,4 @@ framework:
22
form:
33
csrf_protection:
44
enabled: false
5+
legacy_error_messages: false

src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/Fixtures/yml/full.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ framework:
55
form:
66
csrf_protection:
77
field_name: _csrf
8+
legacy_error_messages: false
89
http_method_override: false
910
esi:
1011
enabled: true

src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/FrameworkExtensionTest.php

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

1414
use Doctrine\Common\Annotations\Annotation;
1515
use Psr\Log\LoggerAwareInterface;
16+
use Symfony\Bridge\PhpUnit\ExpectDeprecationTrait;
1617
use Symfony\Bundle\FrameworkBundle\DependencyInjection\Compiler\AddAnnotationsCachedReaderPass;
1718
use Symfony\Bundle\FrameworkBundle\DependencyInjection\FrameworkExtension;
1819
use Symfony\Bundle\FrameworkBundle\Tests\Fixtures\Messenger\DummyMessage;
@@ -57,6 +58,8 @@
5758

5859
abstract class FrameworkExtensionTest extends TestCase
5960
{
61+
use ExpectDeprecationTrait;
62+
6063
private static $containerCache = [];
6164

6265
abstract protected function loadFromFile(ContainerBuilder $container, $file);
@@ -1015,6 +1018,16 @@ public function testFormsCanBeEnabledWithoutCsrfProtection()
10151018
$this->assertFalse($container->getParameter('form.type_extension.csrf.enabled'));
10161019
}
10171020

1021+
/**
1022+
* @group legacy
1023+
*/
1024+
public function testFormsWithoutImprovedValidationMessages()
1025+
{
1026+
$this->expectDeprecation('Since symfony/framework-bundle 5.2: Setting the "framework.form.legacy_error_messages" option to "true" is deprecated. It will have no effect as of Symfony 6.0.');
1027+
1028+
$this->createContainerFromFile('form_legacy_messages');
1029+
}
1030+
10181031
public function testStopwatchEnabledWithDebugModeEnabled()
10191032
{
10201033
$container = $this->createContainerFromFile('default_config', [

src/Symfony/Bundle/FrameworkBundle/Tests/Functional/app/config/framework.yml

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,9 @@ framework:
33
router: { resource: "%kernel.project_dir%/%kernel.test_case%/routing.yml", utf8: true }
44
validation: { enabled: true, enable_annotations: true }
55
csrf_protection: true
6-
form: true
6+
form:
7+
enabled: true
8+
legacy_error_messages: false
79
test: true
810
default_locale: en
911
session:

src/Symfony/Bundle/SecurityBundle/Tests/Functional/app/FirewallEntryPoint/config.yml

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,9 @@ framework:
33
router: { resource: "%kernel.project_dir%/%kernel.test_case%/routing.yml", utf8: true }
44
validation: { enabled: true, enable_annotations: true }
55
csrf_protection: true
6-
form: true
6+
form:
7+
enabled: true
8+
legacy_error_messages: false
79
test: ~
810
default_locale: en
911
session:

src/Symfony/Bundle/SecurityBundle/Tests/Functional/app/config/framework.yml

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,9 @@ framework:
44
validation: { enabled: true, enable_annotations: true }
55
assets: ~
66
csrf_protection: true
7-
form: true
7+
form:
8+
enabled: true
9+
legacy_error_messages: false
810
test: ~
911
default_locale: en
1012
session:

src/Symfony/Bundle/SecurityBundle/composer.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@
3737
"symfony/dom-crawler": "^4.4|^5.0",
3838
"symfony/expression-language": "^4.4|^5.0",
3939
"symfony/form": "^4.4|^5.0",
40-
"symfony/framework-bundle": "^4.4|^5.0",
40+
"symfony/framework-bundle": "^5.2",
4141
"symfony/process": "^4.4|^5.0",
4242
"symfony/serializer": "^4.4|^5.0",
4343
"symfony/translation": "^4.4|^5.0",

src/Symfony/Component/Form/Extension/Core/EventListener/TransformationFailureListener.php

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -51,14 +51,15 @@ public function convertTransformationFailureToFormError(FormEvent $event)
5151
}
5252

5353
$clientDataAsString = is_scalar($form->getViewData()) ? (string) $form->getViewData() : get_debug_type($form->getViewData());
54-
$messageTemplate = 'The value {{ value }} is not valid.';
54+
$messageTemplate = $form->getConfig()->getOption('invalid_message', 'The value {{ value }} is not valid.');
55+
$messageParameters = array_replace(['{{ value }}' => $clientDataAsString], $form->getConfig()->getOption('invalid_message_parameters', []));
5556

5657
if (null !== $this->translator) {
57-
$message = $this->translator->trans($messageTemplate, ['{{ value }}' => $clientDataAsString]);
58+
$message = $this->translator->trans($messageTemplate, $messageParameters);
5859
} else {
59-
$message = strtr($messageTemplate, ['{{ value }}' => $clientDataAsString]);
60+
$message = strtr($messageTemplate, $messageParameters);
6061
}
6162

62-
$form->addError(new FormError($message, $messageTemplate, ['{{ value }}' => $clientDataAsString], null, $form->getTransformationFailure()));
63+
$form->addError(new FormError($message, $messageTemplate, $messageParameters, null, $form->getTransformationFailure()));
6364
}
6465
}

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

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
namespace Symfony\Component\Form\Extension\Core\Type;
1313

1414
use Symfony\Component\Form\AbstractType;
15+
use Symfony\Component\OptionsResolver\Options;
1516
use Symfony\Component\OptionsResolver\OptionsResolver;
1617

1718
class BirthdayType extends AbstractType
@@ -21,7 +22,14 @@ class BirthdayType extends AbstractType
2122
*/
2223
public function configureOptions(OptionsResolver $resolver)
2324
{
24-
$resolver->setDefault('years', range((int) date('Y') - 120, date('Y')));
25+
$resolver->setDefaults([
26+
'years' => range((int) date('Y') - 120, date('Y')),
27+
'invalid_message' => function (Options $options, $previousValue) {
28+
return ($options['legacy_error_messages'] ?? true)
29+
? $previousValue
30+
: 'Please enter a valid birth date.';
31+
},
32+
]);
2533

2634
$resolver->setAllowedTypes('years', 'array');
2735
}

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

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
use Symfony\Component\Form\FormBuilderInterface;
1717
use Symfony\Component\Form\FormInterface;
1818
use Symfony\Component\Form\FormView;
19+
use Symfony\Component\OptionsResolver\Options;
1920
use Symfony\Component\OptionsResolver\OptionsResolver;
2021

2122
class CheckboxType extends AbstractType
@@ -60,6 +61,11 @@ public function configureOptions(OptionsResolver $resolver)
6061
'empty_data' => $emptyData,
6162
'compound' => false,
6263
'false_values' => [null],
64+
'invalid_message' => function (Options $options, $previousValue) {
65+
return ($options['legacy_error_messages'] ?? true)
66+
? $previousValue
67+
: 'The checkbox has an invalid value.';
68+
},
6369
'is_empty_callback' => static function ($modelData): bool {
6470
return false === $modelData;
6571
},

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

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -338,6 +338,11 @@ public function configureOptions(OptionsResolver $resolver)
338338
'data_class' => null,
339339
'choice_translation_domain' => true,
340340
'trim' => false,
341+
'invalid_message' => function (Options $options, $previousValue) {
342+
return ($options['legacy_error_messages'] ?? true)
343+
? $previousValue
344+
: 'The selected choice is invalid.';
345+
},
341346
]);
342347

343348
$resolver->setNormalizer('placeholder', $placeholderNormalizer);

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

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -121,6 +121,11 @@ public function configureOptions(OptionsResolver $resolver)
121121
'entry_type' => TextType::class,
122122
'entry_options' => [],
123123
'delete_empty' => false,
124+
'invalid_message' => function (Options $options, $previousValue) {
125+
return ($options['legacy_error_messages'] ?? true)
126+
? $previousValue
127+
: 'The collection is invalid.';
128+
},
124129
]);
125130

126131
$resolver->setNormalizer('entry_options', $entryOptionsNormalizer);

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

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
use Symfony\Component\Form\FormError;
1717
use Symfony\Component\Form\FormEvent;
1818
use Symfony\Component\Form\FormEvents;
19+
use Symfony\Component\OptionsResolver\Options;
1920
use Symfony\Component\OptionsResolver\OptionsResolver;
2021
use Symfony\Contracts\Translation\TranslatorInterface;
2122

@@ -69,6 +70,11 @@ public function configureOptions(OptionsResolver $resolver)
6970
{
7071
$resolver->setDefaults([
7172
'html5' => false,
73+
'invalid_message' => function (Options $options, $previousValue) {
74+
return ($options['legacy_error_messages'] ?? true)
75+
? $previousValue
76+
: 'Please select a valid color.';
77+
},
7278
]);
7379

7480
$resolver->setAllowedTypes('html5', 'bool');

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

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,11 @@ public function configureOptions(OptionsResolver $resolver)
3737
'choice_translation_domain' => false,
3838
'choice_translation_locale' => null,
3939
'alpha3' => false,
40+
'invalid_message' => function (Options $options, $previousValue) {
41+
return ($options['legacy_error_messages'] ?? true)
42+
? $previousValue
43+
: 'Please select a valid country.';
44+
},
4045
]);
4146

4247
$resolver->setAllowedTypes('choice_translation_locale', ['null', 'string']);

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

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,11 @@ public function configureOptions(OptionsResolver $resolver)
3535
},
3636
'choice_translation_domain' => false,
3737
'choice_translation_locale' => null,
38+
'invalid_message' => function (Options $options, $previousValue) {
39+
return ($options['legacy_error_messages'] ?? true)
40+
? $previousValue
41+
: 'Please select a valid currency.';
42+
},
3843
]);
3944

4045
$resolver->setAllowedTypes('choice_translation_locale', ['null', 'string']);

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

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -234,6 +234,11 @@ public function configureOptions(OptionsResolver $resolver)
234234
'compound' => $compound,
235235
'empty_data' => $emptyData,
236236
'labels' => [],
237+
'invalid_message' => function (Options $options, $previousValue) {
238+
return ($options['legacy_error_messages'] ?? true)
239+
? $previousValue
240+
: 'Please choose a valid date interval.';
241+
},
237242
]);
238243
$resolver->setNormalizer('placeholder', $placeholderNormalizer);
239244
$resolver->setNormalizer('labels', $labelsNormalizer);

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

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -273,6 +273,11 @@ public function configureOptions(OptionsResolver $resolver)
273273
return $options['compound'] ? [] : '';
274274
},
275275
'input_format' => 'Y-m-d H:i:s',
276+
'invalid_message' => function (Options $options, $previousValue) {
277+
return ($options['legacy_error_messages'] ?? true)
278+
? $previousValue
279+
: 'Please enter a valid date and time.';
280+
},
276281
]);
277282

278283
// Don't add some defaults in order to preserve the defaults

0 commit comments

Comments
 (0)
0