|
11 | 11 |
|
12 | 12 | namespace Symfony\Component\Validator\Constraints;
|
13 | 13 |
|
| 14 | +use Symfony\Component\PropertyAccess\PropertyAccess; |
| 15 | +use Symfony\Component\PropertyAccess\PropertyAccessorInterface; |
14 | 16 | use Symfony\Component\Validator\Constraint;
|
15 | 17 | use Symfony\Component\Validator\ConstraintValidator;
|
16 | 18 | use Symfony\Component\Validator\Exception\UnexpectedTypeException;
|
|
21 | 23 | */
|
22 | 24 | class UniqueValidator extends ConstraintValidator
|
23 | 25 | {
|
| 26 | + private ?PropertyAccessorInterface $propertyAccessor; |
| 27 | + |
| 28 | + public function __construct(PropertyAccessorInterface $propertyAccessor = null) |
| 29 | + { |
| 30 | + $this->propertyAccessor = $propertyAccessor; |
| 31 | + } |
| 32 | + |
24 | 33 | public function validate(mixed $value, Constraint $constraint)
|
25 | 34 | {
|
26 | 35 | if (!$constraint instanceof Unique) {
|
@@ -69,18 +78,34 @@ private function getNormalizer(Unique $unique): callable
|
69 | 78 | return $unique->normalizer;
|
70 | 79 | }
|
71 | 80 |
|
72 |
| - private function reduceElementKeys(array $fields, array $element): array |
| 81 | + private function reduceElementKeys(array $fields, array|object $element): array |
73 | 82 | {
|
74 | 83 | $output = [];
|
75 | 84 | foreach ($fields as $field) {
|
76 | 85 | if (!\is_string($field)) {
|
77 | 86 | throw new UnexpectedTypeException($field, 'string');
|
78 | 87 | }
|
79 |
| - if (isset($element[$field])) { |
80 |
| - $output[$field] = $element[$field]; |
| 88 | + |
| 89 | + // For no BC, because PropertyAccessor require brackets for array keys |
| 90 | + // Previous implementation, only check in array |
| 91 | + if (\is_array($element) && !str_contains($field, '[')) { |
| 92 | + $field = "[{$field}]"; |
| 93 | + } |
| 94 | + |
| 95 | + if (null !== $value = $this->getPropertyAccessor()->getValue($element, $field)) { |
| 96 | + $output[$field] = $value; |
81 | 97 | }
|
82 | 98 | }
|
83 | 99 |
|
84 | 100 | return $output;
|
85 | 101 | }
|
| 102 | + |
| 103 | + private function getPropertyAccessor(): PropertyAccessorInterface |
| 104 | + { |
| 105 | + if (null === $this->propertyAccessor) { |
| 106 | + $this->propertyAccessor = PropertyAccess::createPropertyAccessor(); |
| 107 | + } |
| 108 | + |
| 109 | + return $this->propertyAccessor; |
| 110 | + } |
86 | 111 | }
|
0 commit comments