From 535c874fffb98da246a2cc8bc451e99cbbe8eda7 Mon Sep 17 00:00:00 2001 From: Mathieu Piot Date: Wed, 28 Sep 2022 15:53:25 +0200 Subject: [PATCH 1/2] [Validator] Unique should support objects fields --- .../Validator/Constraints/UniqueValidator.php | 31 +++++++++++++++++-- .../Tests/Constraints/UniqueValidatorTest.php | 13 ++++++++ 2 files changed, 41 insertions(+), 3 deletions(-) diff --git a/src/Symfony/Component/Validator/Constraints/UniqueValidator.php b/src/Symfony/Component/Validator/Constraints/UniqueValidator.php index de2edce631837..8ef994b152a73 100644 --- a/src/Symfony/Component/Validator/Constraints/UniqueValidator.php +++ b/src/Symfony/Component/Validator/Constraints/UniqueValidator.php @@ -11,6 +11,8 @@ namespace Symfony\Component\Validator\Constraints; +use Symfony\Component\PropertyAccess\PropertyAccess; +use Symfony\Component\PropertyAccess\PropertyAccessorInterface; use Symfony\Component\Validator\Constraint; use Symfony\Component\Validator\ConstraintValidator; use Symfony\Component\Validator\Exception\UnexpectedTypeException; @@ -21,6 +23,13 @@ */ class UniqueValidator extends ConstraintValidator { + private ?PropertyAccessorInterface $propertyAccessor; + + public function __construct(PropertyAccessorInterface $propertyAccessor = null) + { + $this->propertyAccessor = $propertyAccessor; + } + public function validate(mixed $value, Constraint $constraint) { if (!$constraint instanceof Unique) { @@ -69,18 +78,34 @@ private function getNormalizer(Unique $unique): callable return $unique->normalizer; } - private function reduceElementKeys(array $fields, array $element): array + private function reduceElementKeys(array $fields, array|object $element): array { $output = []; foreach ($fields as $field) { if (!\is_string($field)) { throw new UnexpectedTypeException($field, 'string'); } - if (isset($element[$field])) { - $output[$field] = $element[$field]; + + // For no BC, because PropertyAccessor require brackets for array keys + // Previous implementation, only check in array + if (\is_array($element) && !str_contains($field, '[')) { + $field = "[{$field}]"; + } + + if (null !== $value = $this->getPropertyAccessor()->getValue($element, $field)) { + $output[$field] = $value; } } return $output; } + + private function getPropertyAccessor(): PropertyAccessorInterface + { + if (null === $this->propertyAccessor) { + $this->propertyAccessor = PropertyAccess::createPropertyAccessor(); + } + + return $this->propertyAccessor; + } } diff --git a/src/Symfony/Component/Validator/Tests/Constraints/UniqueValidatorTest.php b/src/Symfony/Component/Validator/Tests/Constraints/UniqueValidatorTest.php index 2f045ccf64ff7..74585fe03d859 100644 --- a/src/Symfony/Component/Validator/Tests/Constraints/UniqueValidatorTest.php +++ b/src/Symfony/Component/Validator/Tests/Constraints/UniqueValidatorTest.php @@ -280,6 +280,19 @@ public function getInvalidCollectionValues(): array ['id' => 1, 'email' => 'bar@email.com'], ['id' => 1, 'email' => 'foo@email.com'], ], ['id']], + 'unique string attribute' => [[ + (object) ['lang' => 'eng', 'translation' => 'hi'], + (object) ['lang' => 'eng', 'translation' => 'hello'], + ], ['lang']], + 'unique float attribute' => [[ + (object) ['latitude' => 51.509865, 'longitude' => -0.118092, 'poi' => 'capital'], + (object) ['latitude' => 52.520008, 'longitude' => 13.404954], + (object) ['latitude' => 51.509865, 'longitude' => -0.118092], + ], ['latitude', 'longitude']], + 'unique int attribute' => [[ + (object) ['id' => 1, 'email' => 'bar@email.com'], + (object) ['id' => 1, 'email' => 'foo@email.com'], + ], ['id']], ]; } } From 889cb8d0644e227a01588f1ba8aa38500292bf2e Mon Sep 17 00:00:00 2001 From: Mathieu Piot Date: Wed, 28 Sep 2022 16:12:16 +0200 Subject: [PATCH 2/2] Test if PropertyAccess component is available --- .../Component/Validator/Constraints/UniqueValidator.php | 7 ++++++- .../Validator/Tests/Constraints/UniqueValidatorTest.php | 8 ++++++++ 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/src/Symfony/Component/Validator/Constraints/UniqueValidator.php b/src/Symfony/Component/Validator/Constraints/UniqueValidator.php index 8ef994b152a73..2233a75e837a2 100644 --- a/src/Symfony/Component/Validator/Constraints/UniqueValidator.php +++ b/src/Symfony/Component/Validator/Constraints/UniqueValidator.php @@ -12,9 +12,11 @@ namespace Symfony\Component\Validator\Constraints; use Symfony\Component\PropertyAccess\PropertyAccess; +use Symfony\Component\PropertyAccess\PropertyAccessor; use Symfony\Component\PropertyAccess\PropertyAccessorInterface; use Symfony\Component\Validator\Constraint; use Symfony\Component\Validator\ConstraintValidator; +use Symfony\Component\Validator\Exception\LogicException; use Symfony\Component\Validator\Exception\UnexpectedTypeException; use Symfony\Component\Validator\Exception\UnexpectedValueException; @@ -100,9 +102,12 @@ private function reduceElementKeys(array $fields, array|object $element): array return $output; } - private function getPropertyAccessor(): PropertyAccessorInterface + private function getPropertyAccessor(): PropertyAccessor { if (null === $this->propertyAccessor) { + if (!class_exists(PropertyAccess::class)) { + throw new LogicException('Unable to use property path as the Symfony PropertyAccess component is not installed.'); + } $this->propertyAccessor = PropertyAccess::createPropertyAccessor(); } diff --git a/src/Symfony/Component/Validator/Tests/Constraints/UniqueValidatorTest.php b/src/Symfony/Component/Validator/Tests/Constraints/UniqueValidatorTest.php index 74585fe03d859..7c39dd521da02 100644 --- a/src/Symfony/Component/Validator/Tests/Constraints/UniqueValidatorTest.php +++ b/src/Symfony/Component/Validator/Tests/Constraints/UniqueValidatorTest.php @@ -280,6 +280,10 @@ public function getInvalidCollectionValues(): array ['id' => 1, 'email' => 'bar@email.com'], ['id' => 1, 'email' => 'foo@email.com'], ], ['id']], + 'unique string sub array' => [[ + ['id' => 1, 'translation' => ['lang' => 'eng', 'translation' => 'hi']], + ['id' => 2, 'translation' => ['lang' => 'eng', 'translation' => 'hello']], + ], ['[translation][lang]']], 'unique string attribute' => [[ (object) ['lang' => 'eng', 'translation' => 'hi'], (object) ['lang' => 'eng', 'translation' => 'hello'], @@ -293,6 +297,10 @@ public function getInvalidCollectionValues(): array (object) ['id' => 1, 'email' => 'bar@email.com'], (object) ['id' => 1, 'email' => 'foo@email.com'], ], ['id']], + 'unique string sub object attribute' => [[ + (object) ['id' => 1, 'translation' => (object) ['lang' => 'eng', 'translation' => 'hi']], + (object) ['id' => 2, 'translation' => (object) ['lang' => 'eng', 'translation' => 'hello']], + ], ['translation.lang']], ]; } } pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy