Skip to content

Commit 585e9df

Browse files
feature symfony#61255 [Validator] deprecate passing choices as $options argument to Choice constraint (xabbuh)
This PR was merged into the 7.4 branch. Discussion ---------- [Validator] deprecate passing choices as `$options` argument to `Choice` constraint | Q | A | ------------- | --- | Branch? | 7.4 | Bug fix? | no | New feature? | no | Deprecations? | yes | Issues | | License | MIT Commits ------- 08678a4 deprecate passing choices as $options argument to Choice constraint
2 parents 9986cfe + 08678a4 commit 585e9df

File tree

12 files changed

+92
-35
lines changed

12 files changed

+92
-35
lines changed

UPGRADE-7.4.md

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -58,10 +58,11 @@ Translation
5858
Validator
5959
---------
6060

61+
* Deprecate passing a list of choices to the first argument of the `Choice` constraint. Use the `choices` option instead
6162
* Deprecate `getRequiredOptions()` and `getDefaultOption()` methods of the `All`, `AtLeastOneOf`, `CardScheme`, `Collection`,
6263
`CssColor`, `Expression`, `Regex`, `Sequentially`, `Type`, and `When` constraints
6364
* Deprecate evaluating options in the base `Constraint` class. Initialize properties in the constructor of the concrete constraint
64-
class instead.
65+
class instead
6566

6667
*Before*
6768

@@ -97,7 +98,7 @@ Validator
9798
}
9899
```
99100

100-
* Deprecate the `getRequiredOptions()` method of the base `Constraint` class. Use mandatory constructor arguments instead.
101+
* Deprecate the `getRequiredOptions()` method of the base `Constraint` class. Use mandatory constructor arguments instead
101102

102103
*Before*
103104

@@ -137,10 +138,10 @@ Validator
137138
}
138139
}
139140
```
140-
* Deprecate the `normalizeOptions()` and `getDefaultOption()` methods of the base `Constraint` class without replacements.
141-
Overriding them in child constraint will not have any effects starting with Symfony 8.0.
141+
* Deprecate the `normalizeOptions()` and `getDefaultOption()` methods of the base `Constraint` class without replacements;
142+
overriding them in child constraint will not have any effects starting with Symfony 8.0
142143
* Deprecate passing an array of options to the `Composite` constraint class. Initialize the properties referenced with `getNestedConstraints()`
143-
in child classes before calling the constructor of `Composite`.
144+
in child classes before calling the constructor of `Composite`
144145

145146
*Before*
146147

src/Symfony/Component/Validator/CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ CHANGELOG
44
7.4
55
---
66

7+
* Deprecate passing a list of choices to the first argument of the `Choice` constraint. Use the `choices` option instead
78
* Add the `min` and `max` parameter to the `Length` constraint violation
89
* Deprecate `getRequiredOptions()` and `getDefaultOption()` methods of the `All`, `AtLeastOneOf`, `CardScheme`, `Collection`,
910
`CssColor`, `Expression`, `Regex`, `Sequentially`, `Type`, and `When` constraints

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,7 @@ public function __construct(
8585
?bool $match = null,
8686
) {
8787
if (\is_array($options) && $options && array_is_list($options)) {
88+
trigger_deprecation('symfony/validator', '7.4', 'Support for passing the choices as the first argument to %s is deprecated.', static::class);
8889
$choices ??= $options;
8990
$options = null;
9091
} elseif (\is_array($options) && [] !== $options) {

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -317,7 +317,7 @@ public function testValidateNestedAtLeaseOneOfConstraints()
317317
new Collection([
318318
'bar' => new AtLeastOneOf([
319319
new Type('int'),
320-
new Choice(['test1', 'test2']),
320+
new Choice(choices: ['test1', 'test2']),
321321
]),
322322
]),
323323
new Collection([

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,7 @@ class ChoiceDummy
6666
#[Choice(choices: ['foo', 'bar'], message: 'myMessage')]
6767
private $b;
6868

69-
#[Choice([1, 2], groups: ['my_group'], payload: 'some attached data')]
69+
#[Choice(choices: [1, 2], groups: ['my_group'], payload: 'some attached data')]
7070
private $c;
7171

7272
#[Choice(choices: ['one' => 1, 'two' => 2])]

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

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -74,20 +74,21 @@ public function testValidCallbackExpected()
7474
$this->validator->validate('foobar', new Choice(callback: 'abcd'));
7575
}
7676

77-
/**
78-
* @dataProvider provideConstraintsWithChoicesArray
79-
*/
80-
public function testValidChoiceArray(Choice $constraint)
77+
public function testValidChoiceArray()
8178
{
82-
$this->validator->validate('bar', $constraint);
79+
$this->validator->validate('bar', new Choice(choices: ['foo', 'bar']));
8380

8481
$this->assertNoViolation();
8582
}
8683

87-
public static function provideConstraintsWithChoicesArray(): iterable
84+
/**
85+
* @group legacy
86+
*/
87+
public function testValidChoiceArrayFirstArgument()
8888
{
89-
yield 'first argument' => [new Choice(['foo', 'bar'])];
90-
yield 'named arguments' => [new Choice(choices: ['foo', 'bar'])];
89+
$this->validator->validate('bar', new Choice(['foo', 'bar']));
90+
91+
$this->assertNoViolation();
9192
}
9293

9394
/**

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

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
use Symfony\Component\Validator\Constraints\Range;
2323
use Symfony\Component\Validator\Constraints\Regex;
2424
use Symfony\Component\Validator\Constraints\Traverse;
25+
use Symfony\Component\Validator\Constraints\Type;
2526
use Symfony\Component\Validator\Exception\MappingException;
2627
use Symfony\Component\Validator\Mapping\ClassMetadata;
2728
use Symfony\Component\Validator\Mapping\Loader\XmlFileLoader;
@@ -76,8 +77,6 @@ public function testLoadClassMetadata()
7677
$expected->addConstraint(new ConstraintWithNamedArguments(['foo', 'bar']));
7778
$expected->addConstraint(new ConstraintWithoutValueWithNamedArguments(['foo']));
7879
$expected->addPropertyConstraint('firstName', new NotNull());
79-
$expected->addPropertyConstraint('firstName', new Range(min: 3));
80-
$expected->addPropertyConstraint('firstName', new Choice(['A', 'B']));
8180
$expected->addPropertyConstraint('firstName', new All(constraints: [new NotNull(), new Range(min: 3)]));
8281
$expected->addPropertyConstraint('firstName', new All(constraints: [new NotNull(), new Range(min: 3)]));
8382
$expected->addPropertyConstraint('firstName', new Collection(fields: [
@@ -95,6 +94,23 @@ public function testLoadClassMetadata()
9594
$this->assertEquals($expected, $metadata);
9695
}
9796

97+
/**
98+
* @group legacy
99+
*/
100+
public function testLoadClassMetadataValueOption()
101+
{
102+
$loader = new XmlFileLoader(__DIR__.'/constraint-mapping-value-option.xml');
103+
$metadata = new ClassMetadata(Entity::class);
104+
105+
$loader->loadClassMetadata($metadata);
106+
107+
$expected = new ClassMetadata(Entity::class);
108+
$expected->addPropertyConstraint('firstName', new Type(type: 'string'));
109+
$expected->addPropertyConstraint('firstName', new Choice(choices: ['A', 'B']));
110+
111+
$this->assertEquals($expected, $metadata);
112+
}
113+
98114
public function testLoadClassMetadataWithNonStrings()
99115
{
100116
$loader = new XmlFileLoader(__DIR__.'/constraint-mapping-non-strings.xml');

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

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
use Symfony\Component\Validator\Constraints\IsTrue;
2121
use Symfony\Component\Validator\Constraints\NotNull;
2222
use Symfony\Component\Validator\Constraints\Range;
23+
use Symfony\Component\Validator\Constraints\Type;
2324
use Symfony\Component\Validator\Mapping\ClassMetadata;
2425
use Symfony\Component\Validator\Mapping\Loader\YamlFileLoader;
2526
use Symfony\Component\Validator\Tests\Dummy\DummyGroupProvider;
@@ -120,8 +121,6 @@ public function testLoadClassMetadata()
120121
$expected->addConstraint(new ConstraintWithNamedArguments('foo'));
121122
$expected->addConstraint(new ConstraintWithNamedArguments(['foo', 'bar']));
122123
$expected->addPropertyConstraint('firstName', new NotNull());
123-
$expected->addPropertyConstraint('firstName', new Range(min: 3));
124-
$expected->addPropertyConstraint('firstName', new Choice(['A', 'B']));
125124
$expected->addPropertyConstraint('firstName', new All(constraints: [new NotNull(), new Range(min: 3)]));
126125
$expected->addPropertyConstraint('firstName', new All(constraints: [new NotNull(), new Range(min: 3)]));
127126
$expected->addPropertyConstraint('firstName', new Collection(fields: [
@@ -139,6 +138,23 @@ public function testLoadClassMetadata()
139138
$this->assertEquals($expected, $metadata);
140139
}
141140

141+
/**
142+
* @group legacy
143+
*/
144+
public function testLoadClassMetadataValueOption()
145+
{
146+
$loader = new YamlFileLoader(__DIR__.'/constraint-mapping-value-option.yml');
147+
$metadata = new ClassMetadata(Entity::class);
148+
149+
$loader->loadClassMetadata($metadata);
150+
151+
$expected = new ClassMetadata(Entity::class);
152+
$expected->addPropertyConstraint('firstName', new Type(type: 'string'));
153+
$expected->addPropertyConstraint('firstName', new Choice(choices: ['A', 'B']));
154+
155+
$this->assertEquals($expected, $metadata);
156+
}
157+
142158
public function testLoadClassMetadataWithConstants()
143159
{
144160
$loader = new YamlFileLoader(__DIR__.'/mapping-with-constants.yml');
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
<?xml version="1.0" ?>
2+
3+
<constraint-mapping xmlns="http://symfony.com/schema/dic/constraint-mapping"
4+
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
5+
xsi:schemaLocation="http://symfony.com/schema/dic/constraint-mapping https://symfony.com/schema/dic/constraint-mapping/constraint-mapping-1.0.xsd">
6+
7+
<namespace prefix="custom">Symfony\Component\Validator\Tests\Fixtures\</namespace>
8+
9+
<class name="Symfony\Component\Validator\Tests\Fixtures\NestedAttribute\Entity">
10+
11+
<!-- PROPERTY CONSTRAINTS -->
12+
13+
<property name="firstName">
14+
15+
<!-- Constraint with single value -->
16+
<constraint name="Type">string</constraint>
17+
18+
<!-- Constraint with multiple values -->
19+
<constraint name="Choice">
20+
<value>A</value>
21+
<value>B</value>
22+
</constraint>
23+
24+
</property>
25+
26+
</class>
27+
</constraint-mapping>
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
namespaces:
2+
custom: Symfony\Component\Validator\Tests\Fixtures\
3+
4+
Symfony\Component\Validator\Tests\Fixtures\NestedAttribute\Entity:
5+
properties:
6+
firstName:
7+
# Constraint with single value
8+
- Type: string
9+
# Constraint with multiple values
10+
- Choice: [A, B]

0 commit comments

Comments
 (0)