Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit 0c764e7

Browse filesBrowse files
committed
bug #54758 [Validator] handle edge cases when constructing constraints with named arguments (xabbuh)
This PR was merged into the 6.4 branch. Discussion ---------- [Validator] handle edge cases when constructing constraints with named arguments | Q | A | ------------- | --- | Branch? | 6.4 | Bug fix? | yes | New feature? | no | Deprecations? | no | Issues | | License | MIT spotted while working on #54744 Commits ------- 93eb8a0 handle edge cases when constructing constraints with named arguments
2 parents 2722fb5 + 93eb8a0 commit 0c764e7
Copy full SHA for 0c764e7

File tree

Expand file treeCollapse file tree

9 files changed

+119
-1
lines changed
Filter options
Expand file treeCollapse file tree

9 files changed

+119
-1
lines changed

‎src/Symfony/Component/Validator/Mapping/Loader/AbstractLoader.php

Copy file name to clipboardExpand all lines: src/Symfony/Component/Validator/Mapping/Loader/AbstractLoader.php
+12Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,18 @@ protected function newConstraint(string $name, mixed $options = null): Constrain
8787
}
8888

8989
if ($this->namedArgumentsCache[$className] ??= (bool) (new \ReflectionMethod($className, '__construct'))->getAttributes(HasNamedArguments::class)) {
90+
if (null === $options) {
91+
return new $className();
92+
}
93+
94+
if (!\is_array($options)) {
95+
return new $className($options);
96+
}
97+
98+
if (1 === \count($options) && isset($options['value'])) {
99+
return new $className($options['value']);
100+
}
101+
90102
return new $className(...$options);
91103
}
92104

‎src/Symfony/Component/Validator/Mapping/Loader/XmlFileLoader.php

Copy file name to clipboardExpand all lines: src/Symfony/Component/Validator/Mapping/Loader/XmlFileLoader.php
+7-1Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -80,7 +80,9 @@ protected function parseConstraints(\SimpleXMLElement $nodes): array
8080
foreach ($nodes as $node) {
8181
if (\count($node) > 0) {
8282
if (\count($node->value) > 0) {
83-
$options = $this->parseValues($node->value);
83+
$options = [
84+
'value' => $this->parseValues($node->value),
85+
];
8486
} elseif (\count($node->constraint) > 0) {
8587
$options = $this->parseConstraints($node->constraint);
8688
} elseif (\count($node->option) > 0) {
@@ -94,6 +96,10 @@ protected function parseConstraints(\SimpleXMLElement $nodes): array
9496
$options = null;
9597
}
9698

99+
if (isset($options['groups']) && !\is_array($options['groups'])) {
100+
$options['groups'] = (array) $options['groups'];
101+
}
102+
97103
$constraints[] = $this->newConstraint((string) $node['name'], $options);
98104
}
99105

‎src/Symfony/Component/Validator/Mapping/Loader/YamlFileLoader.php

Copy file name to clipboardExpand all lines: src/Symfony/Component/Validator/Mapping/Loader/YamlFileLoader.php
+6Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,12 @@ protected function parseNodes(array $nodes): array
9191
$options = $this->parseNodes($options);
9292
}
9393

94+
if (null !== $options && (!\is_array($options) || array_is_list($options))) {
95+
$options = [
96+
'value' => $options,
97+
];
98+
}
99+
94100
$values[] = $this->newConstraint(key($childNodes), $options);
95101
} else {
96102
if (\is_array($childNodes)) {
+33Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the Symfony package.
5+
*
6+
* (c) Fabien Potencier <fabien@symfony.com>
7+
*
8+
* For the full copyright and license information, please view the LICENSE
9+
* file that was distributed with this source code.
10+
*/
11+
12+
namespace Symfony\Component\Validator\Tests\Mapping\Loader\Fixtures;
13+
14+
use Symfony\Component\Validator\Attribute\HasNamedArguments;
15+
use Symfony\Component\Validator\Constraint;
16+
17+
class ConstraintWithNamedArguments extends Constraint
18+
{
19+
public $choices;
20+
21+
#[HasNamedArguments]
22+
public function __construct(array|string|null $choices = [], ?array $groups = null)
23+
{
24+
parent::__construct([], $groups);
25+
26+
$this->choices = $choices;
27+
}
28+
29+
public function getTargets(): string
30+
{
31+
return self::CLASS_CONSTRAINT;
32+
}
33+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the Symfony package.
5+
*
6+
* (c) Fabien Potencier <fabien@symfony.com>
7+
*
8+
* For the full copyright and license information, please view the LICENSE
9+
* file that was distributed with this source code.
10+
*/
11+
12+
namespace Symfony\Component\Validator\Tests\Mapping\Loader\Fixtures;
13+
14+
use Symfony\Component\Validator\Attribute\HasNamedArguments;
15+
use Symfony\Component\Validator\Constraint;
16+
17+
class ConstraintWithoutValueWithNamedArguments extends Constraint
18+
{
19+
#[HasNamedArguments]
20+
public function __construct(?array $groups = null)
21+
{
22+
parent::__construct([], $groups);
23+
}
24+
25+
public function getTargets(): string
26+
{
27+
return self::CLASS_CONSTRAINT;
28+
}
29+
}

‎src/Symfony/Component/Validator/Tests/Mapping/Loader/XmlFileLoaderTest.php

Copy file name to clipboardExpand all lines: src/Symfony/Component/Validator/Tests/Mapping/Loader/XmlFileLoaderTest.php
+5Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,8 @@
3232
use Symfony\Component\Validator\Tests\Fixtures\Entity_81;
3333
use Symfony\Component\Validator\Tests\Fixtures\NestedAttribute\Entity;
3434
use Symfony\Component\Validator\Tests\Fixtures\NestedAttribute\GroupSequenceProviderEntity;
35+
use Symfony\Component\Validator\Tests\Mapping\Loader\Fixtures\ConstraintWithNamedArguments;
36+
use Symfony\Component\Validator\Tests\Mapping\Loader\Fixtures\ConstraintWithoutValueWithNamedArguments;
3537

3638
class XmlFileLoaderTest extends TestCase
3739
{
@@ -66,6 +68,9 @@ public function testLoadClassMetadata()
6668
$expected->addConstraint(new Callback('validateMeStatic'));
6769
$expected->addConstraint(new Callback(['Symfony\Component\Validator\Tests\Fixtures\CallbackClass', 'callback']));
6870
$expected->addConstraint(new Traverse(false));
71+
$expected->addConstraint(new ConstraintWithNamedArguments('foo'));
72+
$expected->addConstraint(new ConstraintWithNamedArguments(['foo', 'bar']));
73+
$expected->addConstraint(new ConstraintWithoutValueWithNamedArguments(['foo']));
6974
$expected->addPropertyConstraint('firstName', new NotNull());
7075
$expected->addPropertyConstraint('firstName', new Range(['min' => 3]));
7176
$expected->addPropertyConstraint('firstName', new Choice(['A', 'B']));

‎src/Symfony/Component/Validator/Tests/Mapping/Loader/YamlFileLoaderTest.php

Copy file name to clipboardExpand all lines: src/Symfony/Component/Validator/Tests/Mapping/Loader/YamlFileLoaderTest.php
+5Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,8 @@
2929
use Symfony\Component\Validator\Tests\Fixtures\Entity_81;
3030
use Symfony\Component\Validator\Tests\Fixtures\NestedAttribute\Entity;
3131
use Symfony\Component\Validator\Tests\Fixtures\NestedAttribute\GroupSequenceProviderEntity;
32+
use Symfony\Component\Validator\Tests\Mapping\Loader\Fixtures\ConstraintWithNamedArguments;
33+
use Symfony\Component\Validator\Tests\Mapping\Loader\Fixtures\ConstraintWithoutValueWithNamedArguments;
3234

3335
class YamlFileLoaderTest extends TestCase
3436
{
@@ -109,6 +111,9 @@ public function testLoadClassMetadata()
109111
$expected->addConstraint(new Callback('validateMe'));
110112
$expected->addConstraint(new Callback('validateMeStatic'));
111113
$expected->addConstraint(new Callback(['Symfony\Component\Validator\Tests\Fixtures\CallbackClass', 'callback']));
114+
$expected->addConstraint(new ConstraintWithoutValueWithNamedArguments());
115+
$expected->addConstraint(new ConstraintWithNamedArguments('foo'));
116+
$expected->addConstraint(new ConstraintWithNamedArguments(['foo', 'bar']));
112117
$expected->addPropertyConstraint('firstName', new NotNull());
113118
$expected->addPropertyConstraint('firstName', new Range(['min' => 3]));
114119
$expected->addPropertyConstraint('firstName', new Choice(['A', 'B']));

‎src/Symfony/Component/Validator/Tests/Mapping/Loader/constraint-mapping.xml

Copy file name to clipboardExpand all lines: src/Symfony/Component/Validator/Tests/Mapping/Loader/constraint-mapping.xml
+16Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,22 @@
3636
false
3737
</constraint>
3838

39+
<!-- Constraint with named arguments support with scalar value -->
40+
<constraint name="Symfony\Component\Validator\Tests\Mapping\Loader\Fixtures\ConstraintWithNamedArguments">
41+
foo
42+
</constraint>
43+
44+
<!-- Constraint with named arguments support with array value -->
45+
<constraint name="Symfony\Component\Validator\Tests\Mapping\Loader\Fixtures\ConstraintWithNamedArguments">
46+
<value>foo</value>
47+
<value>bar</value>
48+
</constraint>
49+
50+
<!-- Constraint with named arguments support with exactly one group -->
51+
<constraint name="Symfony\Component\Validator\Tests\Mapping\Loader\Fixtures\ConstraintWithoutValueWithNamedArguments">
52+
<option name="groups">foo</option>
53+
</constraint>
54+
3955
<!-- PROPERTY CONSTRAINTS -->
4056

4157
<property name="firstName">

‎src/Symfony/Component/Validator/Tests/Mapping/Loader/constraint-mapping.yml

Copy file name to clipboardExpand all lines: src/Symfony/Component/Validator/Tests/Mapping/Loader/constraint-mapping.yml
+6Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,12 @@ Symfony\Component\Validator\Tests\Fixtures\NestedAttribute\Entity:
1515
- Callback: validateMe
1616
- Callback: validateMeStatic
1717
- Callback: [Symfony\Component\Validator\Tests\Fixtures\CallbackClass, callback]
18+
# Constraint with named arguments support without value
19+
- Symfony\Component\Validator\Tests\Mapping\Loader\Fixtures\ConstraintWithoutValueWithNamedArguments: ~
20+
# Constraint with named arguments support with scalar value
21+
- Symfony\Component\Validator\Tests\Mapping\Loader\Fixtures\ConstraintWithNamedArguments: foo
22+
# Constraint with named arguments support with array value
23+
- Symfony\Component\Validator\Tests\Mapping\Loader\Fixtures\ConstraintWithNamedArguments: [foo, bar]
1824

1925
properties:
2026
firstName:

0 commit comments

Comments
0 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.