From 55f49c25cbf09a727f5b246a9a7e531e86000eaa Mon Sep 17 00:00:00 2001 From: plfort Date: Mon, 9 Jan 2023 21:38:44 +0100 Subject: [PATCH 01/11] Handle object field in UniqueValidator --- .../Validator/Constraints/UniqueValidator.php | 55 +++++- .../Tests/Constraints/UniqueValidatorTest.php | 184 ++++++++++++++++-- 2 files changed, 222 insertions(+), 17 deletions(-) diff --git a/src/Symfony/Component/Validator/Constraints/UniqueValidator.php b/src/Symfony/Component/Validator/Constraints/UniqueValidator.php index bd78cac721d1f..5094052186a60 100644 --- a/src/Symfony/Component/Validator/Constraints/UniqueValidator.php +++ b/src/Symfony/Component/Validator/Constraints/UniqueValidator.php @@ -11,8 +11,13 @@ namespace Symfony\Component\Validator\Constraints; +use Symfony\Component\PropertyAccess\Exception\AccessException; +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; @@ -21,7 +26,18 @@ */ class UniqueValidator extends ConstraintValidator { - public function validate(mixed $value, Constraint $constraint): void + + private ?PropertyAccessorInterface $propertyAccessor; + + /** + * @param PropertyAccessorInterface|null $propertyAccessor + */ + public function __construct(?PropertyAccessorInterface $propertyAccessor = null) + { + $this->propertyAccessor = $propertyAccessor; + } + + public function validate(mixed $value, Constraint $constraint) { if (!$constraint instanceof Unique) { throw new UnexpectedTypeException($constraint, Unique::class); @@ -72,18 +88,49 @@ private function getNormalizer(Unique $unique): callable return $unique->normalizer ?? static fn ($value) => $value; } - 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 (\array_key_exists($field, $element)) { - $output[$field] = $element[$field]; + + $elementAsArray = null; + + //handle public object property + if (\is_object($element) && \property_exists($element, $field)) { + $elementAsArray = (array)$element; + } elseif (\is_array($element)) { + $elementAsArray = $element; + } + + if ($elementAsArray && \array_key_exists($field, $element)) { + $output[$field] = $elementAsArray[$field]; + continue; + } + + try { + $output[$field] = $this->getPropertyAccessor()->getValue($element, $field); + } catch (AccessException) { + //fields are optional } } return $output; } + + 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(); + } + + return $this->propertyAccessor; + } } diff --git a/src/Symfony/Component/Validator/Tests/Constraints/UniqueValidatorTest.php b/src/Symfony/Component/Validator/Tests/Constraints/UniqueValidatorTest.php index 12efb76982e24..3634687864a38 100644 --- a/src/Symfony/Component/Validator/Tests/Constraints/UniqueValidatorTest.php +++ b/src/Symfony/Component/Validator/Tests/Constraints/UniqueValidatorTest.php @@ -34,9 +34,9 @@ public function testExpectsUniqueConstraintCompatibleType() /** * @dataProvider getValidValues */ - public function testValidValues($value) + public function testValidValues($value, array $fields) { - $this->validator->validate($value, new Unique()); + $this->validator->validate($value, new Unique(fields: $fields)); $this->assertNoViolation(); } @@ -44,17 +44,79 @@ public function testValidValues($value) public static function getValidValues() { return [ - yield 'null' => [[null]], - yield 'empty array' => [[]], - yield 'single integer' => [[5]], - yield 'single string' => [['a']], - yield 'single object' => [[new \stdClass()]], - yield 'unique booleans' => [[true, false]], - yield 'unique integers' => [[1, 2, 3, 4, 5, 6]], - yield 'unique floats' => [[0.1, 0.2, 0.3]], - yield 'unique strings' => [['a', 'b', 'c']], - yield 'unique arrays' => [[[1, 2], [2, 4], [4, 6]]], - yield 'unique objects' => [[new \stdClass(), new \stdClass()]], + yield 'null' => [[null], []], + yield 'empty array' => [[], []], + yield 'single integer' => [[5], []], + yield 'single string' => [['a'], []], + yield 'single object' => [[new \stdClass()], []], + yield 'unique booleans' => [[true, false], []], + yield 'unique integers' => [[1, 2, 3, 4, 5, 6], []], + yield 'unique floats' => [[0.1, 0.2, 0.3], []], + yield 'unique strings' => [['a', 'b', 'c'], []], + yield 'unique arrays' => [[[1, 2], [2, 4], [4, 6]], []], + yield 'unique objects' => [[new \stdClass(), new \stdClass()], []], + yield 'unique objects public field' => [ + [ + new class { + public int $fieldA = 1; + }, + new class { + public int $fieldA = 2; + }, + ], + ['fieldA'], + ], + yield 'unique objects private field' => [ + [ + new class { + private int $fieldB = 1; + + public function getFieldB(): int + { + return $this->fieldB; + } + }, + new class { + private int $fieldB = 2; + + public function getFieldB(): int + { + return $this->fieldB; + } + }, + ], + ['fieldB'], + ], + yield 'unique objects property accessor field' => [ + [ + new class { + public array $fieldA = ['fieldB' => 1]; + }, + new class { + public array $fieldA = ['fieldB' => 2]; + }, + ], + ['fieldA[fieldB]'], + ], + 'unique objects polymorph field' => [ + [ + new class { + private int $fieldB = 1; + + public function getFieldB(): int + { + return $this->fieldB; + } + }, + new class { + public int $fieldB = 2; + }, + [ + 'fieldB'=>3 + ], + ], + ['fieldB'], + ], ]; } @@ -215,6 +277,43 @@ public function testCollectionFieldsAreOptional() $this->assertNoViolation(); } + public function testCollectionObjectFieldsAreOptional() + { + $this->validator->validate([ + new class { + public int $value = 5; + }, + new class { + public int $id = 1; + public int $value = 5; + }, + ], new Unique(fields: 'id')); + + $this->assertNoViolation(); + } + + public function testCollectionObjectPrivateFieldsAreOptional() + { + $this->validator->validate([ + new class { + private int $id = 2; + public int $value = 5; + }, + new class { + private int $id = 2; + public int $value = 5; + + public function getId(): int + { + return $this->id; + } + }, + + ], new Unique(fields: 'id')); + + $this->assertNoViolation(); + } + /** * @dataProvider getInvalidFieldNames */ @@ -267,6 +366,65 @@ public static function getInvalidCollectionValues(): array ['id' => 1, 'email' => 'bar@email.com'], ['id' => 1, 'email' => 'foo@email.com'], ], ['id'], 'array'], + 'unique object string' => [[ + (object)['lang' => 'eng', 'translation' => 'hi'], + (object)['lang' => 'eng', 'translation' => 'hello'], + ], + ['lang'], 'array'], + 'unique objects public field' => [[ + new class { + public int $fieldA = 1; + }, + new class { + public int $fieldA = 1; + }, + ], + ['fieldA'], 'array'], + 'unique objects property accessor field' => [[ + new class { + public array $fieldA = ['fieldB' => 1]; + }, + new class { + public array $fieldA = ['fieldB' => 1]; + }, + ], + ['fieldA[fieldB]'], 'array'], + 'unique objects private field' => [[ + new class { + private int $fieldB = 1; + + public function getFieldB(): int + { + return $this->fieldB; + } + }, + new class { + private int $fieldB = 1; + + public function getFieldB(): int + { + return $this->fieldB; + } + }, + ], + ['fieldB'], 'array'], + 'unique objects polymorph field' => [[ + new class { + private int $fieldB = 1; + + public function getFieldB(): int + { + return $this->fieldB; + } + }, + new class { + public int $fieldB = 1; + }, + [ + 'fieldB'=>1 + ], + ], + ['fieldB'], 'array'], 'unique null' => [ [null, null], [], From 4d719d79bf6fc012052879890c33f3eabd160bfb Mon Sep 17 00:00:00 2001 From: plfort Date: Tue, 10 Jan 2023 18:35:18 +0100 Subject: [PATCH 02/11] Change CHANGELOG entry order Fix after rebase Update CHANGELOG.md --- src/Symfony/Component/Validator/CHANGELOG.md | 2 +- .../Component/Validator/Constraints/UniqueValidator.php | 3 +-- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/src/Symfony/Component/Validator/CHANGELOG.md b/src/Symfony/Component/Validator/CHANGELOG.md index ae1ae20da804d..87f36af06b44d 100644 --- a/src/Symfony/Component/Validator/CHANGELOG.md +++ b/src/Symfony/Component/Validator/CHANGELOG.md @@ -78,7 +78,7 @@ CHANGELOG 6.3 --- - + * Add support for reading objects properties with `Unique` constraint `fields` option * Add method `getConstraint()` to `ConstraintViolationInterface` * Add `Uuid::TIME_BASED_VERSIONS` to match that a UUID being validated embeds a timestamp * Add the `pattern` parameter in violations of the `Regex` constraint diff --git a/src/Symfony/Component/Validator/Constraints/UniqueValidator.php b/src/Symfony/Component/Validator/Constraints/UniqueValidator.php index 5094052186a60..69d7c5061b4c9 100644 --- a/src/Symfony/Component/Validator/Constraints/UniqueValidator.php +++ b/src/Symfony/Component/Validator/Constraints/UniqueValidator.php @@ -97,7 +97,6 @@ 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; @@ -105,7 +104,7 @@ private function reduceElementKeys(array $fields, array|object $element): array $elementAsArray = $element; } - if ($elementAsArray && \array_key_exists($field, $element)) { + if ($elementAsArray && \array_key_exists($field, $elementAsArray)) { $output[$field] = $elementAsArray[$field]; continue; } From a225a6df2015afbd550b5f17aad46533d3ac2fa3 Mon Sep 17 00:00:00 2001 From: plfort Date: Wed, 11 Jan 2023 14:38:26 +0100 Subject: [PATCH 03/11] CS fix --- .../Validator/Constraints/UniqueValidator.php | 13 ++--- .../Tests/Constraints/UniqueValidatorTest.php | 49 +++++++++---------- 2 files changed, 29 insertions(+), 33 deletions(-) diff --git a/src/Symfony/Component/Validator/Constraints/UniqueValidator.php b/src/Symfony/Component/Validator/Constraints/UniqueValidator.php index 69d7c5061b4c9..1cf83bda901c5 100644 --- a/src/Symfony/Component/Validator/Constraints/UniqueValidator.php +++ b/src/Symfony/Component/Validator/Constraints/UniqueValidator.php @@ -26,7 +26,6 @@ */ class UniqueValidator extends ConstraintValidator { - private ?PropertyAccessorInterface $propertyAccessor; /** @@ -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; } @@ -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 } } @@ -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(); } diff --git a/src/Symfony/Component/Validator/Tests/Constraints/UniqueValidatorTest.php b/src/Symfony/Component/Validator/Tests/Constraints/UniqueValidatorTest.php index 3634687864a38..bf5173e9ad91e 100644 --- a/src/Symfony/Component/Validator/Tests/Constraints/UniqueValidatorTest.php +++ b/src/Symfony/Component/Validator/Tests/Constraints/UniqueValidatorTest.php @@ -57,10 +57,10 @@ 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; }, ], @@ -68,7 +68,7 @@ public static function getValidValues() ], yield 'unique objects private field' => [ [ - new class { + new class() { private int $fieldB = 1; public function getFieldB(): int @@ -76,7 +76,7 @@ public function getFieldB(): int return $this->fieldB; } }, - new class { + new class() { private int $fieldB = 2; public function getFieldB(): int @@ -89,10 +89,10 @@ 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]; }, ], @@ -100,7 +100,7 @@ public function getFieldB(): int ], 'unique objects polymorph field' => [ [ - new class { + new class() { private int $fieldB = 1; public function getFieldB(): int @@ -108,11 +108,11 @@ public function getFieldB(): int return $this->fieldB; } }, - new class { + new class() { public int $fieldB = 2; }, [ - 'fieldB'=>3 + 'fieldB' => 3, ], ], ['fieldB'], @@ -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; }, @@ -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; @@ -308,7 +308,6 @@ public function getId(): int return $this->id; } }, - ], new Unique(fields: 'id')); $this->assertNoViolation(); @@ -367,30 +366,30 @@ 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 @@ -398,7 +397,7 @@ public function getFieldB(): int return $this->fieldB; } }, - new class { + new class() { private int $fieldB = 1; public function getFieldB(): int @@ -409,7 +408,7 @@ public function getFieldB(): int ], ['fieldB'], 'array'], 'unique objects polymorph field' => [[ - new class { + new class() { private int $fieldB = 1; public function getFieldB(): int @@ -417,11 +416,11 @@ public function getFieldB(): int return $this->fieldB; } }, - new class { + new class() { public int $fieldB = 1; }, [ - 'fieldB'=>1 + 'fieldB' => 1, ], ], ['fieldB'], 'array'], From 2d8dff436a9f7699f5ee39cfd5b6b4f81bfddc88 Mon Sep 17 00:00:00 2001 From: plfort Date: Wed, 11 Jan 2023 22:07:30 +0100 Subject: [PATCH 04/11] Use constructor property promotion --- .../Component/Validator/Constraints/UniqueValidator.php | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/src/Symfony/Component/Validator/Constraints/UniqueValidator.php b/src/Symfony/Component/Validator/Constraints/UniqueValidator.php index 1cf83bda901c5..7447dbe8fa012 100644 --- a/src/Symfony/Component/Validator/Constraints/UniqueValidator.php +++ b/src/Symfony/Component/Validator/Constraints/UniqueValidator.php @@ -26,14 +26,11 @@ */ class UniqueValidator extends ConstraintValidator { - private ?PropertyAccessorInterface $propertyAccessor; - /** - * @param PropertyAccessorInterface|null $propertyAccessor - */ - public function __construct(?PropertyAccessorInterface $propertyAccessor = null) + public function __construct( + private ?PropertyAccessorInterface $propertyAccessor = null + ) { - $this->propertyAccessor = $propertyAccessor; } public function validate(mixed $value, Constraint $constraint) From 0b309497485c15a44615dc40245118039a83a103 Mon Sep 17 00:00:00 2001 From: plfort Date: Wed, 11 Jan 2023 22:09:16 +0100 Subject: [PATCH 05/11] Update src/Symfony/Component/Validator/Constraints/UniqueValidator.php Co-authored-by: Alexandre Daubois <2144837+alexandre-daubois@users.noreply.github.com> --- src/Symfony/Component/Validator/Constraints/UniqueValidator.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Symfony/Component/Validator/Constraints/UniqueValidator.php b/src/Symfony/Component/Validator/Constraints/UniqueValidator.php index 7447dbe8fa012..24973caccde63 100644 --- a/src/Symfony/Component/Validator/Constraints/UniqueValidator.php +++ b/src/Symfony/Component/Validator/Constraints/UniqueValidator.php @@ -119,7 +119,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('Property path requires symfony/property-access package to be installed.'); } $this->propertyAccessor = PropertyAccess::createPropertyAccessor(); } From 5eac0394c0a3e892f6be2d608c7f61d5aa3efc1d Mon Sep 17 00:00:00 2001 From: plfort Date: Thu, 12 Jan 2023 08:31:22 +0100 Subject: [PATCH 06/11] Update src/Symfony/Component/Validator/Constraints/UniqueValidator.php Co-authored-by: Artyum --- src/Symfony/Component/Validator/Constraints/UniqueValidator.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Symfony/Component/Validator/Constraints/UniqueValidator.php b/src/Symfony/Component/Validator/Constraints/UniqueValidator.php index 24973caccde63..d1f615e479e54 100644 --- a/src/Symfony/Component/Validator/Constraints/UniqueValidator.php +++ b/src/Symfony/Component/Validator/Constraints/UniqueValidator.php @@ -119,7 +119,7 @@ private function getPropertyAccessor(): PropertyAccessor { if (null === $this->propertyAccessor) { if (!class_exists(PropertyAccess::class)) { - throw new LogicException('Property path requires symfony/property-access package to be installed.'); + throw new LogicException('Property path requires symfony/property-access package to be installed. Try running "composer require symfony/property-access".'); } $this->propertyAccessor = PropertyAccess::createPropertyAccessor(); } From 777e28d4ea3f545cbf0a8de70fef3c8d260c0608 Mon Sep 17 00:00:00 2001 From: plfort Date: Thu, 12 Jan 2023 08:34:08 +0100 Subject: [PATCH 07/11] CS fix --- .../Component/Validator/Constraints/UniqueValidator.php | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/Symfony/Component/Validator/Constraints/UniqueValidator.php b/src/Symfony/Component/Validator/Constraints/UniqueValidator.php index d1f615e479e54..9892ef95fac15 100644 --- a/src/Symfony/Component/Validator/Constraints/UniqueValidator.php +++ b/src/Symfony/Component/Validator/Constraints/UniqueValidator.php @@ -26,11 +26,9 @@ */ class UniqueValidator extends ConstraintValidator { - public function __construct( private ?PropertyAccessorInterface $propertyAccessor = null - ) - { + ) { } public function validate(mixed $value, Constraint $constraint) From a54a768e3eda71408e81023bbeb004397c23e0b0 Mon Sep 17 00:00:00 2001 From: plfort Date: Fri, 13 Jan 2023 13:44:30 +0100 Subject: [PATCH 08/11] Add newline in CHANGELOG.md --- src/Symfony/Component/Validator/CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/src/Symfony/Component/Validator/CHANGELOG.md b/src/Symfony/Component/Validator/CHANGELOG.md index 87f36af06b44d..891e0d883c61a 100644 --- a/src/Symfony/Component/Validator/CHANGELOG.md +++ b/src/Symfony/Component/Validator/CHANGELOG.md @@ -78,6 +78,7 @@ CHANGELOG 6.3 --- + * Add support for reading objects properties with `Unique` constraint `fields` option * Add method `getConstraint()` to `ConstraintViolationInterface` * Add `Uuid::TIME_BASED_VERSIONS` to match that a UUID being validated embeds a timestamp From 3da875860b65b9662127bab7f5b2ee0a75af41c4 Mon Sep 17 00:00:00 2001 From: plfort Date: Wed, 17 Jul 2024 13:02:00 +0200 Subject: [PATCH 09/11] Add validate return type --- src/Symfony/Component/Validator/Constraints/UniqueValidator.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Symfony/Component/Validator/Constraints/UniqueValidator.php b/src/Symfony/Component/Validator/Constraints/UniqueValidator.php index 9892ef95fac15..389a11cd1624c 100644 --- a/src/Symfony/Component/Validator/Constraints/UniqueValidator.php +++ b/src/Symfony/Component/Validator/Constraints/UniqueValidator.php @@ -31,7 +31,7 @@ public function __construct( ) { } - public function validate(mixed $value, Constraint $constraint) + public function validate(mixed $value, Constraint $constraint): void { if (!$constraint instanceof Unique) { throw new UnexpectedTypeException($constraint, Unique::class); From 3f169ad3a68a8b9b334b7eb2b749621b52401025 Mon Sep 17 00:00:00 2001 From: plfort Date: Tue, 25 Mar 2025 14:31:50 +0100 Subject: [PATCH 10/11] Apply suggestions from code review Co-authored-by: Alexandre Daubois <2144837+alexandre-daubois@users.noreply.github.com> --- .../Validator/Constraints/UniqueValidator.php | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/src/Symfony/Component/Validator/Constraints/UniqueValidator.php b/src/Symfony/Component/Validator/Constraints/UniqueValidator.php index 389a11cd1624c..fd0c2a0273902 100644 --- a/src/Symfony/Component/Validator/Constraints/UniqueValidator.php +++ b/src/Symfony/Component/Validator/Constraints/UniqueValidator.php @@ -27,7 +27,7 @@ class UniqueValidator extends ConstraintValidator { public function __construct( - private ?PropertyAccessorInterface $propertyAccessor = null + private ?PropertyAccessorInterface $propertyAccessor = null, ) { } @@ -115,13 +115,10 @@ private function reduceElementKeys(array $fields, array|object $element): array private function getPropertyAccessor(): PropertyAccessor { - if (null === $this->propertyAccessor) { - if (!class_exists(PropertyAccess::class)) { - throw new LogicException('Property path requires symfony/property-access package to be installed. Try running "composer require symfony/property-access".'); - } - $this->propertyAccessor = PropertyAccess::createPropertyAccessor(); + if (!class_exists(PropertyAccess::class)) { + throw new LogicException('Property path requires symfony/property-access package to be installed. Try running "composer require symfony/property-access".'); } - return $this->propertyAccessor; + return $this->propertyAccessor ??= PropertyAccess::createPropertyAccessor(); } } From acb1fa0df7c06b26578404592b0e27b99d7d157f Mon Sep 17 00:00:00 2001 From: plfort Date: Tue, 25 Mar 2025 20:37:09 +0100 Subject: [PATCH 11/11] Misplaced changelog entry --- src/Symfony/Component/Validator/CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Symfony/Component/Validator/CHANGELOG.md b/src/Symfony/Component/Validator/CHANGELOG.md index 891e0d883c61a..2b190274dd309 100644 --- a/src/Symfony/Component/Validator/CHANGELOG.md +++ b/src/Symfony/Component/Validator/CHANGELOG.md @@ -13,6 +13,7 @@ CHANGELOG * Add support for multiple fields containing nested constraints in `Composite` constraints * Add the `stopOnFirstError` option to the `Unique` constraint to validate all elements * Add support for closures in the `When` constraint + * Add support for reading objects properties with `Unique` constraint `fields` option 7.2 --- @@ -79,7 +80,6 @@ CHANGELOG 6.3 --- - * Add support for reading objects properties with `Unique` constraint `fields` option * Add method `getConstraint()` to `ConstraintViolationInterface` * Add `Uuid::TIME_BASED_VERSIONS` to match that a UUID being validated embeds a timestamp * Add the `pattern` parameter in violations of the `Regex` constraint 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