Skip to content

[Validator] Handle object properties in Unique validator #48951

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 11 commits into
base: 7.4
Choose a base branch
from
Prev Previous commit
Next Next commit
CS fix
  • Loading branch information
plfort committed Mar 25, 2025
commit a225a6df2015afbd550b5f17aad46533d3ac2fa3
13 changes: 5 additions & 8 deletions src/Symfony/Component/Validator/Constraints/UniqueValidator.php
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,6 @@
*/
class UniqueValidator extends ConstraintValidator
{

private ?PropertyAccessorInterface $propertyAccessor;

/**
Expand Down Expand Up @@ -97,9 +96,9 @@ private function reduceElementKeys(array $fields, array|object $element): array
}

$elementAsArray = null;
//handle public object property
if (\is_object($element) && \property_exists($element, $field)) {
$elementAsArray = (array)$element;
// handle public object property
if (\is_object($element) && property_exists($element, $field)) {
$elementAsArray = (array) $element;
} elseif (\is_array($element)) {
$elementAsArray = $element;
}
Expand All @@ -112,7 +111,7 @@ private function reduceElementKeys(array $fields, array|object $element): array
try {
$output[$field] = $this->getPropertyAccessor()->getValue($element, $field);
} catch (AccessException) {
//fields are optional
// fields are optional
}
}

Expand All @@ -123,9 +122,7 @@ 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.'
);
throw new LogicException('Unable to use property path as the Symfony PropertyAccess component is not installed.');
}
$this->propertyAccessor = PropertyAccess::createPropertyAccessor();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -57,26 +57,26 @@ public static function getValidValues()
yield 'unique objects' => [[new \stdClass(), new \stdClass()], []],
yield 'unique objects public field' => [
[
new class {
new class() {
public int $fieldA = 1;
},
new class {
new class() {
public int $fieldA = 2;
},
],
['fieldA'],
],
yield 'unique objects private field' => [
[
new class {
new class() {
private int $fieldB = 1;

public function getFieldB(): int
{
return $this->fieldB;
}
},
new class {
new class() {
private int $fieldB = 2;

public function getFieldB(): int
Expand All @@ -89,30 +89,30 @@ public function getFieldB(): int
],
yield 'unique objects property accessor field' => [
[
new class {
new class() {
public array $fieldA = ['fieldB' => 1];
},
new class {
new class() {
public array $fieldA = ['fieldB' => 2];
},
],
['fieldA[fieldB]'],
],
'unique objects polymorph field' => [
[
new class {
new class() {
private int $fieldB = 1;

public function getFieldB(): int
{
return $this->fieldB;
}
},
new class {
new class() {
public int $fieldB = 2;
},
[
'fieldB'=>3
'fieldB' => 3,
],
],
['fieldB'],
Expand Down Expand Up @@ -280,10 +280,10 @@ public function testCollectionFieldsAreOptional()
public function testCollectionObjectFieldsAreOptional()
{
$this->validator->validate([
new class {
new class() {
public int $value = 5;
},
new class {
new class() {
public int $id = 1;
public int $value = 5;
},
Expand All @@ -295,11 +295,11 @@ public function testCollectionObjectFieldsAreOptional()
public function testCollectionObjectPrivateFieldsAreOptional()
{
$this->validator->validate([
new class {
new class() {
private int $id = 2;
public int $value = 5;
},
new class {
new class() {
private int $id = 2;
public int $value = 5;

Expand All @@ -308,7 +308,6 @@ public function getId(): int
return $this->id;
}
},

], new Unique(fields: 'id'));

$this->assertNoViolation();
Expand Down Expand Up @@ -367,38 +366,38 @@ public static function getInvalidCollectionValues(): array
['id' => 1, 'email' => 'foo@email.com'],
], ['id'], 'array'],
'unique object string' => [[
(object)['lang' => 'eng', 'translation' => 'hi'],
(object)['lang' => 'eng', 'translation' => 'hello'],
(object) ['lang' => 'eng', 'translation' => 'hi'],
(object) ['lang' => 'eng', 'translation' => 'hello'],
],
['lang'], 'array'],
'unique objects public field' => [[
new class {
new class() {
public int $fieldA = 1;
},
new class {
new class() {
public int $fieldA = 1;
},
],
['fieldA'], 'array'],
'unique objects property accessor field' => [[
new class {
new class() {
public array $fieldA = ['fieldB' => 1];
},
new class {
new class() {
public array $fieldA = ['fieldB' => 1];
},
],
['fieldA[fieldB]'], 'array'],
'unique objects private field' => [[
new class {
new class() {
private int $fieldB = 1;

public function getFieldB(): int
{
return $this->fieldB;
}
},
new class {
new class() {
private int $fieldB = 1;

public function getFieldB(): int
Expand All @@ -409,19 +408,19 @@ public function getFieldB(): int
],
['fieldB'], 'array'],
'unique objects polymorph field' => [[
new class {
new class() {
private int $fieldB = 1;

public function getFieldB(): int
{
return $this->fieldB;
}
},
new class {
new class() {
public int $fieldB = 1;
},
[
'fieldB'=>1
'fieldB' => 1,
],
],
['fieldB'], 'array'],
Expand Down