feature #36302 [Form] Add the html5 option to ColorType to validate the input (fancyweb)
This PR was merged into the 5.1-dev branch.
Discussion
----------
[Form] Add the html5 option to ColorType to validate the input
| Q | A
| ------------- | ---
| Branch? | master
| Bug fix? | no
| New feature? | yes
| Deprecations? | no
| Tickets | no
| License | MIT
| Doc PR | TODO
Continuation of https://github.com/symfony/symfony/pull/35626.
I'm resubmitting the initial implementation, this time in the Form component.
This `Color` constraint is dedicated to the HTML5 input type="color".
Commits
-------
454b6ff48b
[Form] Add the html5 option to ColorType to validate the input
This commit is contained in:
commit
341ea45219
@ -74,6 +74,10 @@
|
||||
<tag name="form.type" />
|
||||
<argument type="service" id="translator" on-invalid="ignore" />
|
||||
</service>
|
||||
<service id="form.type.color" class="Symfony\Component\Form\Extension\Core\Type\ColorType">
|
||||
<tag name="form.type" />
|
||||
<argument type="service" id="translator" on-invalid="ignore" />
|
||||
</service>
|
||||
|
||||
<service id="form.type_extension.form.transformation_failure_handling" class="Symfony\Component\Form\Extension\Core\Type\TransformationFailureExtension">
|
||||
<tag name="form.type_extension" extended-type="Symfony\Component\Form\Extension\Core\Type\FormType" />
|
||||
|
@ -19,6 +19,7 @@ CHANGELOG
|
||||
is deprecated. The method will be added to the interface in 6.0.
|
||||
* Added a `rounding_mode` option for the PercentType and correctly round the value when submitted
|
||||
* Deprecated `Symfony\Component\Form\Extension\Validator\Util\ServerParams` in favor of its parent class `Symfony\Component\Form\Util\ServerParams`
|
||||
* Added the `html5` option to the `ColorType` to validate the input
|
||||
|
||||
5.0.0
|
||||
-----
|
||||
|
@ -75,7 +75,7 @@ class CoreExtension extends AbstractExtension
|
||||
new Type\ResetType(),
|
||||
new Type\CurrencyType(),
|
||||
new Type\TelType(),
|
||||
new Type\ColorType(),
|
||||
new Type\ColorType($this->translator),
|
||||
new Type\WeekType(),
|
||||
];
|
||||
}
|
||||
|
@ -12,9 +12,68 @@
|
||||
namespace Symfony\Component\Form\Extension\Core\Type;
|
||||
|
||||
use Symfony\Component\Form\AbstractType;
|
||||
use Symfony\Component\Form\FormBuilderInterface;
|
||||
use Symfony\Component\Form\FormError;
|
||||
use Symfony\Component\Form\FormEvent;
|
||||
use Symfony\Component\Form\FormEvents;
|
||||
use Symfony\Component\OptionsResolver\OptionsResolver;
|
||||
use Symfony\Contracts\Translation\TranslatorInterface;
|
||||
|
||||
class ColorType extends AbstractType
|
||||
{
|
||||
/**
|
||||
* @see https://www.w3.org/TR/html52/sec-forms.html#color-state-typecolor
|
||||
*/
|
||||
private const HTML5_PATTERN = '/^#[0-9a-f]{6}$/i';
|
||||
|
||||
private $translator;
|
||||
|
||||
public function __construct(TranslatorInterface $translator = null)
|
||||
{
|
||||
$this->translator = $translator;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function buildForm(FormBuilderInterface $builder, array $options)
|
||||
{
|
||||
if (!$options['html5']) {
|
||||
return;
|
||||
}
|
||||
|
||||
$builder->addEventListener(FormEvents::PRE_SUBMIT, function (FormEvent $event): void {
|
||||
$value = $event->getData();
|
||||
if (null === $value || '' === $value) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (\is_string($value) && preg_match(self::HTML5_PATTERN, $value)) {
|
||||
return;
|
||||
}
|
||||
|
||||
$messageTemplate = 'This value is not a valid HTML5 color.';
|
||||
$messageParameters = [
|
||||
'{{ value }}' => is_scalar($value) ? (string) $value : \gettype($value),
|
||||
];
|
||||
$message = $this->translator ? $this->translator->trans($messageTemplate, $messageParameters, 'validators') : $messageTemplate;
|
||||
|
||||
$event->getForm()->addError(new FormError($message, $messageTemplate, $messageParameters));
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function configureOptions(OptionsResolver $resolver)
|
||||
{
|
||||
$resolver->setDefaults([
|
||||
'html5' => false,
|
||||
]);
|
||||
|
||||
$resolver->setAllowedTypes('html5', 'bool');
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
|
@ -14,6 +14,10 @@
|
||||
<source>The CSRF token is invalid. Please try to resubmit the form.</source>
|
||||
<target>The CSRF token is invalid. Please try to resubmit the form.</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="99">
|
||||
<source>This value is not a valid HTML5 color.</source>
|
||||
<target>This value is not a valid HTML5 color.</target>
|
||||
</trans-unit>
|
||||
</body>
|
||||
</file>
|
||||
</xliff>
|
||||
|
@ -14,6 +14,10 @@
|
||||
<source>The CSRF token is invalid. Please try to resubmit the form.</source>
|
||||
<target>Le jeton CSRF est invalide. Veuillez renvoyer le formulaire.</target>
|
||||
</trans-unit>
|
||||
<trans-unit id="99">
|
||||
<source>This value is not a valid HTML5 color.</source>
|
||||
<target>Cette valeur n'est pas une couleur HTML5 valide.</target>
|
||||
</trans-unit>
|
||||
</body>
|
||||
</file>
|
||||
</xliff>
|
||||
|
@ -0,0 +1,89 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\Form\Tests\Extension\Core\Type;
|
||||
|
||||
use Symfony\Component\Form\Extension\Core\Type\ColorType;
|
||||
use Symfony\Component\Form\FormError;
|
||||
|
||||
final class ColorTypeTest extends BaseTypeTest
|
||||
{
|
||||
const TESTED_TYPE = ColorType::class;
|
||||
|
||||
/**
|
||||
* @dataProvider validationShouldPassProvider
|
||||
*/
|
||||
public function testValidationShouldPass(bool $html5, ?string $submittedValue)
|
||||
{
|
||||
$form = $this->factory->create(static::TESTED_TYPE, null, [
|
||||
'html5' => $html5,
|
||||
'trim' => true,
|
||||
]);
|
||||
|
||||
$form->submit($submittedValue);
|
||||
|
||||
$this->assertEmpty($form->getErrors());
|
||||
}
|
||||
|
||||
public function validationShouldPassProvider()
|
||||
{
|
||||
return [
|
||||
[false, 'foo'],
|
||||
[false, null],
|
||||
[false, ''],
|
||||
[false, ' '],
|
||||
[true, '#000000'],
|
||||
[true, '#abcabc'],
|
||||
[true, '#BbBbBb'],
|
||||
[true, '#1Ee54d'],
|
||||
[true, ' #1Ee54d '],
|
||||
[true, null],
|
||||
[true, ''],
|
||||
[true, ' '],
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider validationShouldFailProvider
|
||||
*/
|
||||
public function testValidationShouldFail(string $expectedValueParameterValue, ?string $submittedValue, bool $trim = true)
|
||||
{
|
||||
$form = $this->factory->create(static::TESTED_TYPE, null, [
|
||||
'html5' => true,
|
||||
'trim' => $trim,
|
||||
]);
|
||||
|
||||
$form->submit($submittedValue);
|
||||
|
||||
$expectedFormError = new FormError('This value is not a valid HTML5 color.', 'This value is not a valid HTML5 color.', [
|
||||
'{{ value }}' => $expectedValueParameterValue,
|
||||
]);
|
||||
$expectedFormError->setOrigin($form);
|
||||
|
||||
$this->assertEquals([$expectedFormError], iterator_to_array($form->getErrors()));
|
||||
}
|
||||
|
||||
public function validationShouldFailProvider()
|
||||
{
|
||||
return [
|
||||
['foo', 'foo'],
|
||||
['000000', '000000'],
|
||||
['#abcabg', '#abcabg'],
|
||||
['#12345', '#12345'],
|
||||
[' #ffffff ', ' #ffffff ', false],
|
||||
];
|
||||
}
|
||||
|
||||
public function testSubmitNull($expected = null, $norm = null, $view = null)
|
||||
{
|
||||
parent::testSubmitNull($expected, $norm, '');
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user