Skip to content

Commit

Permalink
feature #318 [SF Validator] Handle PatternMatch separate (sstok)
Browse files Browse the repository at this point in the history
This PR was merged into the 2.0-dev branch.
labels: bc-break

Discussion
----------

| Q             | A
| ------------- | ---
| Bug fix?      | no
| New feature?  | yes
| BC breaks?    | yes
| Deprecations? | 
| Tickets       | 
| License       | MIT

Don't validate PatternMatch by default, use a separate constraints option as a PatternMatch is cannot use full values for constraints.

_For a field that expects an email it's not possible to use a PatternMatch with a constraint that enforces a valid email address._

Commits
-------

07e4617 [SF Validator] Handle PatternMatch separate
  • Loading branch information
sstok authored Sep 16, 2024
2 parents 2345ebe + 07e4617 commit d2e9170
Show file tree
Hide file tree
Showing 5 changed files with 68 additions and 15 deletions.
10 changes: 10 additions & 0 deletions UPGRADE-2.0.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,13 @@
UPGRADE FROM 2.0-BETA5 to 2.0-BETA6
===================================

* The Symfony Input Validator no longer validates a `PatternMatch` value type.
Set the `pattern_match_constraints` option to validate this specific type, with
it's own constraints.

**Note:** A PatternMatch will likely not contain a full value, for more advanced
validating it's best to create your own input validator.

UPGRADE FROM 2.0-BETA4 to 2.0-BETA5
===================================

Expand Down
9 changes: 9 additions & 0 deletions docs/integration/symfony_validator.rst
Original file line number Diff line number Diff line change
Expand Up @@ -78,4 +78,13 @@ part of the field type using the ``configureOptions`` method of the field type.
);
}

.. note::

For a field that expects an email it's not possible to use a ``PatternMatch``
with a constraint that enforces a valid email address.

Since RollerworksSearch v2.0-BETA6 the ``PatternMatch`` is no longer validated as
part of the the ``constraints`` option, use the ``pattern_match_constraints`` for
this specific type.

.. _`Symfony Validator component`: http://symfony.com/doc/current/validation.html
28 changes: 15 additions & 13 deletions lib/Symfony/Validator/InputValidator.php
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@
use Rollerworks\Component\Search\ErrorList;
use Rollerworks\Component\Search\Field\FieldConfig;
use Rollerworks\Component\Search\Input\Validator;
use Rollerworks\Component\Search\Value\PatternMatch;
use Symfony\Component\Validator\Constraint;
use Symfony\Component\Validator\Validator\ValidatorInterface;

/**
Expand All @@ -29,17 +31,14 @@
*/
final class InputValidator implements Validator
{
/** @var ValidatorInterface */
private $validator;
private ValidatorInterface $validator;

/** @var FieldConfig */
private $field;

/** @var ErrorList */
private $errorList;

/** @var array */
private $constraints = [];
private FieldConfig $field;
private ErrorList $errorList;
/** @var Constraint[]|null */
private ?array $constraints = [];
/** @var Constraint[]|null */
private ?array $patternMatchConstraints;

public function __construct(ValidatorInterface $validator)
{
Expand All @@ -51,16 +50,19 @@ public function initializeContext(FieldConfig $field, ErrorList $errorList): voi
$this->field = $field;
$this->errorList = $errorList;

$this->constraints = $field->getOption('constraints', null);
$this->constraints = $field->getOption('constraints');
$this->patternMatchConstraints = $field->getOption('pattern_match_constraints');
}

public function validate($value, string $type, $originalValue, string $path): bool
{
if ($this->constraints === null) {
$constraints = $type === PatternMatch::class ? $this->patternMatchConstraints : $this->constraints;

if ($constraints === null) {
return true;
}

$violations = $this->validator->validate($value, $this->constraints);
$violations = $this->validator->validate($value, $constraints);

foreach ($violations as $violation) {
$this->errorList[] = new ConditionErrorMessage(
Expand Down
34 changes: 32 additions & 2 deletions lib/Symfony/Validator/Tests/InputValidatorTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,37 @@ protected function getExtensions(): array
return [new ValidatorExtension()];
}

/** @test */
public function it_works_without_constraints(): void
{
$fieldSet = $this->getFactory()->createFieldSetBuilder()
->add('id', IntegerType::class)
->add('date', DateType::class)
->add('type', TextType::class)
->getFieldSet()
;

$errorList = new ErrorList();
$this->validator->initializeContext($fieldSet->get('id'), $errorList);
$this->validator->validate(10, 'simple', 10, 'simpleValues[0]');
$this->validator->validate(3, 'simple', 3, 'simpleValues[1]');
$this->validator->validate(4, 'simple', 4, 'simpleValues[2]');

$errorList2 = new ErrorList();
$this->validator->initializeContext($fieldSet->get('date'), $errorList2);
$this->validator->validate(new \DateTimeImmutable('2014-12-13 14:35:05 UTC'), 'simple', '2014-12-13 14:35:05', 'simpleValues[0]');
$this->validator->validate(new \DateTimeImmutable('2014-12-21 14:35:05 UTC'), 'simple', '2014-12-17 14:35:05', 'simpleValues[1]');
$this->validator->validate(new \DateTimeImmutable('2014-12-10 14:35:05 UTC'), 'simple', '2014-12-10 14:35:05', 'simpleValues[2]');

$errorList3 = new ErrorList();
$this->validator->initializeContext($fieldSet->get('type'), $errorList3);
$this->validator->validate('something', PatternMatch::class, 'something', 'simpleValues[0]');

self::assertEmpty($errorList);
self::assertEmpty($errorList2);
self::assertEmpty($errorList3);
}

/** @test */
public function it_validates_fields_with_constraints(): void
{
Expand All @@ -94,7 +125,6 @@ public function it_validates_fields_with_constraints(): void

$errorList3 = new ErrorList();
$this->validator->initializeContext($fieldSet->get('type'), $errorList3);

$this->validator->validate('something', 'simple', 'something', 'simpleValues[0]');

$this->assertContainsErrors(
Expand Down Expand Up @@ -122,7 +152,7 @@ public function it_validates_fields_with_constraints(): void
public function it_validates_matchers(): void
{
$fieldSet = $this->getFieldSet(false);
$fieldSet->add('username', TextType::class, ['constraints' => new Assert\NotBlank()]);
$fieldSet->add('username', TextType::class, ['constraints' => new Assert\Url(), 'pattern_match_constraints' => new Assert\NotBlank()]);
$fieldSet = $fieldSet->getFieldSet();

$errorList = new ErrorList();
Expand Down
2 changes: 2 additions & 0 deletions lib/Symfony/Validator/Type/FieldTypeValidatorExtension.php
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,8 @@ public function configureOptions(OptionsResolver $resolver): void
$constraintsNormalizer = static fn (Options $options, $constraints) => \is_object($constraints) ? [$constraints] : (array) $constraints;

$resolver->setDefault('constraints', []);
$resolver->setDefault('pattern_match_constraints', []);
$resolver->setNormalizer('constraints', $constraintsNormalizer);
$resolver->setNormalizer('pattern_match_constraints', $constraintsNormalizer);
}
}

0 comments on commit d2e9170

Please sign in to comment.