Skip to content

Commit f6a14b0

Browse files
committed
deprecate implicit constraint option names in YAML/XML mapping files
1 parent 120b8cc commit f6a14b0

File tree

11 files changed

+102
-22
lines changed

11 files changed

+102
-22
lines changed
Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,11 @@
11
Symfony\Bundle\FrameworkBundle\Tests\Fixtures\Validation\Category:
22
properties:
33
id:
4-
- Type: int
4+
- Type:
5+
type: int
56

67
Symfony\Bundle\FrameworkBundle\Tests\Fixtures\Validation\SubCategory:
78
properties:
89
id:
9-
- Type: int
10+
- Type:
11+
type: int

src/Symfony/Component/Validator/CHANGELOG.md

Lines changed: 44 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,50 @@ CHANGELOG
44
7.4
55
---
66

7+
* Deprecate configuring constraint options implicitly with the XML format
8+
9+
Before:
10+
11+
```xml
12+
<class name="Symfony\Component\Validator\Tests\Fixtures\NestedAttribute\Entity">
13+
<constraint name="Callback">
14+
<value>Symfony\Component\Validator\Tests\Fixtures\CallbackClass</value>
15+
<value>callback</value>
16+
</constraint>
17+
</class>
18+
```
19+
20+
After:
21+
22+
```xml
23+
<class name="Symfony\Component\Validator\Tests\Fixtures\NestedAttribute\Entity">
24+
<option name="callback">
25+
<value>Symfony\Component\Validator\Tests\Fixtures\CallbackClass</value>
26+
<value>callback</value>
27+
</option>
28+
</class>
29+
```
30+
* Deprecate configuring constraint options implicitly with the YAML format
31+
32+
Before:
33+
34+
```yaml
35+
Symfony\Component\Validator\Tests\Fixtures\NestedAttribute\Entity:
36+
constraints:
37+
- Callback:
38+
callback: validateMeStatic
39+
- Callback:
40+
callback: [Symfony\Component\Validator\Tests\Fixtures\CallbackClass, callback]
41+
```
42+
43+
After:
44+
45+
```yaml
46+
Symfony\Component\Validator\Tests\Fixtures\NestedAttribute\Entity:
47+
constraints:
48+
- Callback: validateMeStatic
49+
- Callback: [Symfony\Component\Validator\Tests\Fixtures\CallbackClass, callback]
50+
```
751
* Add `#[ExtendsValidationFor]` to declare new constraints for a class
852
* Add `ValidatorBuilder::addAttributeMappings()` and `AttributeMetadataPass` to declare compile-time constraint metadata using attributes
953
* Add the `Video` constraint for validating video files
@@ -48,7 +92,6 @@ CHANGELOG
4892
}
4993
}
5094
```
51-
5295
* Deprecate the `getRequiredOptions()` method of the base `Constraint` class. Use mandatory constructor arguments instead.
5396

5497
Before:

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

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -94,17 +94,25 @@ protected function newConstraint(string $name, mixed $options = null): Constrain
9494
}
9595

9696
if (1 === \count($options) && isset($options['value'])) {
97+
if (\func_num_args() < 3 || !func_get_arg(2)) {
98+
trigger_deprecation('symfony/validator', '7.4', 'Using the "value" option to configure the "%s" constraint is deprecated.', $className);
99+
}
100+
97101
return new $className($options['value']);
98102
}
99103

100104
if (array_is_list($options)) {
105+
trigger_deprecation('symfony/validator', '7.4', 'Configuring the "%s" without passing its option names is deprecated.', $className);
106+
101107
return new $className($options);
102108
}
103109

104110
try {
105111
return new $className(...$options);
106112
} catch (\Error $e) {
107113
if (str_starts_with($e->getMessage(), 'Unknown named parameter ')) {
114+
trigger_deprecation('symfony/validator', '7.4', 'Using option names not matching the named arguments of the "%s" constraint is deprecated.', $className);
115+
108116
return new $className($options);
109117
}
110118

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

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,8 @@ protected function parseConstraints(\SimpleXMLElement $nodes): array
8080
foreach ($nodes as $node) {
8181
if (\count($node) > 0) {
8282
if (\count($node->value) > 0) {
83+
trigger_deprecation('symfony/validator', '7.4', 'Using the "value" XML element to configure an option for the "%s" is deprecated. Use the "option" element instead.', (string) $node['name']);
84+
8385
$options = [
8486
'value' => $this->parseValues($node->value),
8587
];
@@ -100,7 +102,7 @@ protected function parseConstraints(\SimpleXMLElement $nodes): array
100102
$options['groups'] = (array) $options['groups'];
101103
}
102104

103-
$constraints[] = $this->newConstraint((string) $node['name'], $options);
105+
$constraints[] = $this->newConstraint((string) $node['name'], $options, true);
104106
}
105107

106108
return $constraints;

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

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -87,12 +87,14 @@ protected function parseNodes(array $nodes): array
8787
}
8888

8989
if (null !== $options && (!\is_array($options) || array_is_list($options))) {
90+
trigger_deprecation('symfony/validator', '7.4', 'Not using a YAML mapping of constraint option names to their values to configure the "%s" constraint is deprecated.', key($childNodes));
91+
9092
$options = [
9193
'value' => $options,
9294
];
9395
}
9496

95-
$values[] = $this->newConstraint(key($childNodes), $options);
97+
$values[] = $this->newConstraint(key($childNodes), $options, true);
9698
} else {
9799
if (\is_array($childNodes)) {
98100
$childNodes = $this->parseNodes($childNodes);

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

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@
3030
use Symfony\Component\Validator\Mapping\Loader\XmlFileLoader;
3131
use Symfony\Component\Validator\Tests\Dummy\DummyGroupProvider;
3232
use Symfony\Component\Validator\Tests\Fixtures\Attribute\GroupProviderDto;
33+
use Symfony\Component\Validator\Tests\Fixtures\CallbackClass;
3334
use Symfony\Component\Validator\Tests\Fixtures\ConstraintA;
3435
use Symfony\Component\Validator\Tests\Fixtures\ConstraintB;
3536
use Symfony\Component\Validator\Tests\Fixtures\ConstraintWithRequiredArgument;
@@ -104,6 +105,7 @@ public function testLoadClassMetadataValueOption()
104105
$loader->loadClassMetadata($metadata);
105106

106107
$expected = new ClassMetadata(Entity::class);
108+
$expected->addConstraint(new Callback([CallbackClass::class, 'callback']));
107109
$expected->addPropertyConstraint('firstName', new Type(type: 'string'));
108110
$expected->addPropertyConstraint('firstName', new Choice(choices: ['A', 'B']));
109111

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

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@
2727
use Symfony\Component\Validator\Mapping\Loader\YamlFileLoader;
2828
use Symfony\Component\Validator\Tests\Dummy\DummyGroupProvider;
2929
use Symfony\Component\Validator\Tests\Fixtures\Attribute\GroupProviderDto;
30+
use Symfony\Component\Validator\Tests\Fixtures\CallbackClass;
3031
use Symfony\Component\Validator\Tests\Fixtures\ConstraintA;
3132
use Symfony\Component\Validator\Tests\Fixtures\ConstraintB;
3233
use Symfony\Component\Validator\Tests\Fixtures\ConstraintWithRequiredArgument;
@@ -146,6 +147,8 @@ public function testLoadClassMetadataValueOption()
146147
$loader->loadClassMetadata($metadata);
147148

148149
$expected = new ClassMetadata(Entity::class);
150+
$expected->addConstraint(new Callback('validateMeStatic'));
151+
$expected->addConstraint(new Callback([CallbackClass::class, 'callback']));
149152
$expected->addPropertyConstraint('firstName', new Type(type: 'string'));
150153
$expected->addPropertyConstraint('firstName', new Choice(choices: ['A', 'B']));
151154

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

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,10 @@
77
<namespace prefix="custom">Symfony\Component\Validator\Tests\Fixtures\</namespace>
88

99
<class name="Symfony\Component\Validator\Tests\Fixtures\NestedAttribute\Entity">
10+
<constraint name="Callback">
11+
<value>Symfony\Component\Validator\Tests\Fixtures\CallbackClass</value>
12+
<value>callback</value>
13+
</constraint>
1014

1115
<!-- PROPERTY CONSTRAINTS -->
1216

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

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,9 @@ namespaces:
22
custom: Symfony\Component\Validator\Tests\Fixtures\
33

44
Symfony\Component\Validator\Tests\Fixtures\NestedAttribute\Entity:
5+
constraints:
6+
- Callback: validateMeStatic
7+
- Callback: [Symfony\Component\Validator\Tests\Fixtures\CallbackClass, callback]
58
properties:
69
firstName:
710
# Constraint with single value

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

Lines changed: 14 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -27,8 +27,10 @@
2727
<constraint name="Callback">validateMeStatic</constraint>
2828

2929
<constraint name="Callback">
30-
<value>Symfony\Component\Validator\Tests\Fixtures\CallbackClass</value>
31-
<value>callback</value>
30+
<option name="callback">
31+
<value>Symfony\Component\Validator\Tests\Fixtures\CallbackClass</value>
32+
<value>callback</value>
33+
</option>
3234
</constraint>
3335

3436
<!-- Traverse with boolean default option -->
@@ -43,8 +45,10 @@
4345

4446
<!-- Constraint with named arguments support with array value -->
4547
<constraint name="Symfony\Component\Validator\Tests\Mapping\Loader\Fixtures\ConstraintWithNamedArguments">
46-
<value>foo</value>
47-
<value>bar</value>
48+
<option name="choices">
49+
<value>foo</value>
50+
<value>bar</value>
51+
</option>
4852
</constraint>
4953

5054
<!-- Constraint with named arguments support with exactly one group -->
@@ -61,11 +65,12 @@
6165

6266
<!-- Constraint with child constraints -->
6367
<constraint name="All">
64-
<constraint name="NotNull" />
65-
<constraint name="Range">
66-
<option name="min">3</option>
67-
</constraint>
68-
68+
<option name="constraints">
69+
<constraint name="NotNull" />
70+
<constraint name="Range">
71+
<option name="min">3</option>
72+
</constraint>
73+
</option>
6974
</constraint>
7075

7176
<!-- Option with child constraints -->

0 commit comments

Comments
 (0)