8000 [Form] Add the html5 option to ColorType to validate the input · symfony/symfony@889c936 · GitHub
[go: up one dir, main page]

Skip to content

Commit 889c936

Browse files
committed
[Form] Add the html5 option to ColorType to validate the input
1 parent 168574d commit 889c936

File tree

7 files changed

+155
-1
lines changed

7 files changed

+155
-1
lines changed

src/Symfony/Bundle/FrameworkBundle/Resources/config/form.xml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,10 @@
7474
<tag name="form.type" />
7575
<argument type="service" id="translator" on-invalid="ignore" />
7676
</service>
77+
<service id="form.type.color" class="Symfony\Component\Form\Extension\Core\Type\ColorType">
78+
<tag name="form.type" />
79+
<argument type="service" id="translator" on-invalid="ignore" />
80+
</service>
7781

7882
<service id="form.type_extension.form.transformation_failure_handling" class="Symfony\Component\Form\Extension\Core\Type\TransformationFailureExtension">
7983
<tag name="form.type_extension" extended-type="Symfony\Component\Form\Extension\Core\Type\FormType" />

src/Symfony/Component/Form/CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ CHANGELOG
1616
* Implementing the `FormConfigBuilderInterface` without implementing the `setIsEmptyCallback()` method
1717
is deprecated. The method will be added to the interface in 6.0.
1818
* Added a `rounding_mode` option for the PercentType and correctly round the value when submitted
19+
* Added the `html5` option to the `ColorType` to validate the input
1920

2021
5.0.0
2122
-----

src/Symfony/Component/Form/Extension/Core/CoreExtension.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,7 @@ protected function loadTypes()
7575
new Type\ResetType(),
7676
new Type\CurrencyType(),
7777
new Type\TelType(),
78-
new Type\ColorType(),
78+
new Type\ColorType($this->translator),
7979
new Type\WeekType(),
8080
];
8181
}

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

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,9 +12,63 @@
1212
namespace Symfony\Component\Form\Extension\Core\Type;
1313

1414
use Symfony\Component\Form\AbstractType;
15+
use Symfony\Component\Form\FormBuilderInterface;
16+
use Symfony\Component\Form\FormError;
17+
use Symfony\Component\Form\FormEvent;
18+
use Symfony\Component\Form\FormEvents;
19+
use Symfony\Component\OptionsResolver\OptionsResolver;
20+
use Symfony\Contracts\Translation\TranslatorInterface;
1521

1622
class ColorType extends AbstractType
1723
{
24+
/**
25+
* @see https://www.w3.org/TR/html52/sec-forms.html#color-state-typecolor
26+
*/
27+
private const HTML5_PATTERN = '/^#[0-9a-f]{6}$/i';
28+
29+
private $translator;
30+
31+
public function __construct(TranslatorInterface $translator = null)
32+
{
33+
$this->translator = $translator;
34+
}
35+
36+
/**
37+
* {@inheritdoc}
38+
*/
39+
public function buildForm(FormBuilderInterface $builder, array $options)
40+
{
41+
if (!$options['html5']) {
42+
return;
43+
}
44+
45+
$builder->addEventListener(FormEvents::PRE_SUBMIT, function (FormEvent $event): void {
46+
if (\is_string($value = $event->getData()) && preg_match(self::HTML5_PATTERN, $value)) {
47+
return;
48+
}
49+
50+
$messageTemplate = 'This value is not a valid HTML5 color.';
51+
$messageParameters = [
52+
'{{ value }}' => is_scalar($value) ? (string) $value : \gettype($value), // Logically, the value can only be a string or null.
53+
];
54+
$message = $this->translator ? $this->translator->trans($messageTemplate, $messageParameters, 'validators') : strtr($messageTemplate, $messageParameters);
55+
56+
$event->getForm()->addError(new FormError($message, $messageTemplate, $messageParameters));
57+
});
58+
}
59+
60+
/**
61+
* {@inheritdoc}
62+
*/
63+
public function configureOptions(OptionsResolver $resolver)
64+
{
65+
$resolver->setDefaults([
66+
'html5' => false,
67+
]);
68+
69+
$resolver->setAllowedTypes('html5', 'bool');
70+
}
71+
1872
/**
1973
* {@inheritdoc}
2074
*/

src/Symfony/Component/Form/Resources/translations/validators.en.xlf

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,10 @@
1414
<source>The CSRF token is invalid. Please try to resubmit the form.</source>
1515
<target>The CSRF token is invalid. Please try to resubmit the form.</target>
1616
</trans-unit>
17+
<trans-unit id="99">
18+
<source>This value is not a valid HTML5 color.</source>
19+
<target>This value is not a valid HTML5 color.</target>
20+
</trans-unit>
1721
</body>
1822
</file>
1923
</xliff>

src/Symfony/Component/Form/Resources/translations/validators.fr.xlf

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,10 @@
1414
<source>The CSRF token is invalid. Please try to resubmit the form.</source>
1515
<target>Le jeton CSRF est invalide. Veuillez renvoyer le formulaire.</target>
1616
</trans-unit>
17+
<trans-unit id="99">
18+
<source>This value is not a valid HTML5 color.</source>
19+
<target>Cette valeur n'est pas une couleur HTML5 valide.</target>
20+
</trans-unit>
1721
</body>
1822
</file>
1923
</xliff>
Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,87 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the Symfony package.
5+
*
6+
* (c) Fabien Potencier <fabien@symfony.com>
7+
*
8+
* For the full copyright and license information, please view the LICENSE
9+
* file that was distributed with this source code.
10+
*/
11+
12+
namespace Symfony\Component\Form\Tests\Extension\Core\Type;
13+
14+
use Symfony\Component\Form\Extension\Core\Type\ColorType;
15+
use Symfony\Component\Form\FormError;
16+
17+
final class ColorTypeTest extends BaseTypeTest
18+
{
19+
const TESTED_TYPE = ColorType::class;
20+
21+
/**
22+
* @dataProvider validationShouldPassProvider
23+
*/
24+
public function testValidationShouldPass(bool $html5, ?string $submittedValue)
25+
{
26+
$form = $this->factory->create(static::TESTED_TYPE, null, [
27+
'html5' => $html5,
28+
'trim' => true,
29+
]);
30+
31+
$form->submit($submittedValue);
32+
33+
$this->assertEmpty($form->getErrors());
34+
}
35+
36+
public function validationShouldPassProvider()
37+
{
38+
return [
39+
[false, 'foo'],
40+
[false, null],
41+
[false, ''],
42+
[true, '#000000'],
43+
[true, '#abcabc'],
44+
[true, '#BbBbBb'],
45+
[true, '#1Ee54d'],
46+
[true, ' #1Ee54d '],
47+
];
48+
}
49+
50+
/**
51+
* @dataProvider validationShouldFailProvider
52+
*/
53+
public function testValidationShouldFail(string $expectedValueParameterValue, ?string $submittedValue, bool $trim = true)
54+
{
55+
$form = $this->factory->create(static::TESTED_TYPE, null, [
56+
'html5' => true,
57+
'trim' => $trim,
58+
]);
59+
60+
$form->submit($submittedValue);
61+
62+
$expectedFormError = new FormError('This value is not a valid HTML5 color.', 'This value is not a valid HTML5 color.', [
63+
'{{ value }}' => $expectedValueParameterValue,
64+
]);
65+
$expectedFormError->setOrigin($form);
66+
67+
$this->assertEquals([$expectedFormError], iterator_to_array($form->getErrors()));
68+
}
69+
70+
public function validationShouldFailProvider()
71+
{
72+
return [
73+
['foo', 'foo'],
74+
['NULL', null],
75+
['', ''],
76+
['000000', '000000'],
77+
['#abcabg', '#abcabg'],
78+
['#12345', '#12345'],
79+
[' #ffffff ', ' #ffffff ', false],
80+
];
81+
}
82+
83+
public function testSubmitNull($expected = null, $norm = null, $view = null)
84+
{
85+
parent::testSubmitNull($expected, $norm, '');
86+
}
87+
}

0 commit comments

Comments
 (0)
0