Skip to content

Commit 08428b9

Browse files
committed
[Validator] Unique should support objects fields
1 parent f841389 commit 08428b9

File tree

2 files changed

+41
-3
lines changed

2 files changed

+41
-3
lines changed

src/Symfony/Component/Validator/Constraints/UniqueValidator.php

Lines changed: 28 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,8 @@
1111

1212
namespace Symfony\Component\Validator\Constraints;
1313

14+
use Symfony\Component\PropertyAccess\PropertyAccess;
15+
use Symfony\Component\PropertyAccess\PropertyAccessorInterface;
1416
use Symfony\Component\Validator\Constraint;
1517
use Symfony\Component\Validator\ConstraintValidator;
1618
use Symfony\Component\Validator\Exception\UnexpectedTypeException;
@@ -21,6 +23,13 @@
2123
*/
2224
class UniqueValidator extends ConstraintValidator
2325
{
26+
private ?PropertyAccessorInterface $propertyAccessor;
27+
28+
public function __construct(PropertyAccessorInterface $propertyAccessor = null)
29+
{
30+
$this->propertyAccessor = $propertyAccessor;
31+
}
32+
2433
/**
2534
* {@inheritdoc}
2635
*/
@@ -72,18 +81,34 @@ private function getNormalizer(Unique $unique): callable
7281
return $unique->normalizer;
7382
}
7483

75-
private function reduceElementKeys(array $fields, array $element): array
84+
private function reduceElementKeys(array $fields, array|object $element): array
7685
{
7786
$output = [];
7887
foreach ($fields as $field) {
7988
if (!\is_string($field)) {
8089
throw new UnexpectedTypeException($field, 'string');
8190
}
82-
if (isset($element[$field])) {
83-
$output[$field] = $element[$field];
91+
92+
// For no BC, because PropertyAccessor require brackets for array keys
93+
// Previous implementation, only check in array
94+
if (\is_array($element) && !str_contains($field, '[')) {
95+
$field = "[{$field}]";
96+
}
97+
98+
if (null !== $value = $this->getPropertyAccessor()->getValue($element, $field)) {
99+
$output[$field] = $value;
84100
}
85101
}
86102

87103
return $output;
88104
}
105+
106+
private function getPropertyAccessor(): PropertyAccessorInterface
107+
{
108+
if (null === $this->propertyAccessor) {
109+
$this->propertyAccessor = PropertyAccess::createPropertyAccessor();
110+
}
111+
112+
return $this->propertyAccessor;
113+
}
89114
}

src/Symfony/Component/Validator/Tests/Constraints/UniqueValidatorTest.php

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -280,6 +280,19 @@ public function getInvalidCollectionValues(): array
280280
['id' => 1, 'email' => 'bar@email.com'],
281281
['id' => 1, 'email' => 'foo@email.com'],
282282
], ['id']],
283+
'unique string attribute' => [[
284+
(object) ['lang' => 'eng', 'translation' => 'hi'],
285+
(object) ['lang' => 'eng', 'translation' => 'hello'],
286+
], ['lang']],
287+
'unique float attribute' => [[
288+
(object) ['latitude' => 51.509865, 'longitude' => -0.118092, 'poi' => 'capital'],
289+
(object) ['latitude' => 52.520008, 'longitude' => 13.404954],
290+
(object) ['latitude' => 51.509865, 'longitude' => -0.118092],
291+
], ['latitude', 'longitude']],
292+
'unique int attribute' => [[
293+
(object) ['id' => 1, 'email' => 'bar@email.com'],
294+
(object) ['id' => 1, 'email' => 'foo@email.com'],
295+
], ['id']],
283296
];
284297
}
285298
}

0 commit comments

Comments
 (0)