Skip to content

Commit ee91124

Browse files
committed
deprecate handling options in the base Constraint class
1 parent c83c34e commit ee91124

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

47 files changed

+673
-179
lines changed

UPGRADE-7.4.md

Lines changed: 127 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,3 +39,130 @@ Security
3939
* Deprecate callable firewall listeners, extend `AbstractListener` or implement `FirewallListenerInterface` instead
4040
* Deprecate `AbstractListener::__invoke`
4141
* Deprecate `LazyFirewallContext::__invoke()`
42+
43+
Validator
44+
---------
45+
46+
* Deprecate evaluating options in the base `Constraint` class. Initialize properties in the constructor of the concrete constraint
47+
class instead.
48+
49+
*Before*
50+
51+
```php
52+
class CustomConstraint extends Constraint
53+
{
54+
public $option1;
55+
public $option2;
56+
57+
public function __construct(?array $options = null)
58+
{
59+
parent::__construct($options);
60+
}
61+
}
62+
```
63+
64+
*After*
65+
66+
```php
67+
use Symfony\Component\Validator\Attribute\HasNamedArguments;
68+
69+
class CustomConstraint extends Constraint
70+
{
71+
public $option1;
72+
public $option2;
73+
74+
#[HasNamedArguments]
75+
public function __construct($option1 = null, $option2 = null, ?array $groups = null, mixed $payload = null)
76+
{
77+
parent::__construct(null, $groups, $payload);
78+
79+
$this->option1 = $option1;
80+
$this->option2 = $option2;
81+
}
82+
}
83+
```
84+
85+
* Deprecate the `getRequiredOptions()` method of the base `Constraint` class. Use mandatory constructor arguments instead.
86+
87+
*Before*
88+
89+
```php
90+
class CustomConstraint extends Constraint
91+
{
92+
public $option1;
93+
public $option2;
94+
95+
public function __construct(?array $options = null)
96+
{
97+
parent::__construct($options);
98+
}
99+
100+
public function getRequiredOptions()
101+
{
102+
return ['option1'];
103+
}
104+
}
105+
```
106+
107+
*After*
108+
109+
```php
110+
use Symfony\Component\Validator\Attribute\HasNamedArguments;
111+
112+
class CustomConstraint extends Constraint
113+
{
114+
public $option1;
115+
public $option2;
116+
117+
#[HasNamedArguments]
118+
public function __construct($option1, $option2 = null, ?array $groups = null, mixed $payload = null)
119+
{
120+
parent::__construct(null, $groups, $payload);
121+
122+
$this->option1 = $option1;
123+
$this->option2 = $option2;
124+
}
125+
}
126+
```
127+
* Deprecate the `normalizeOptions()` and `getDefaultOption()` methods of the base `Constraint` class without replacements.
128+
Overriding them in child constraint will not have any effects starting with Symfony 8.0.
129+
* Deprecate passing an array of options to the `Composite` constraint class. Initialize the properties referenced with `getNestedConstraints()`
130+
in child classes before calling the constructor of `Composite`.
131+
132+
*Before*
133+
134+
```php
135+
class CustomCompositeConstraint extends Composite
136+
{
137+
public array $constraints = [];
138+
139+
public function __construct(?array $options = null)
140+
{
141+
parent::__construct($options);
142+
}
143+
144+
protected function getCompositeOption(): string
145+
{
146+
return 'constraints';
147+
}
148+
}
149+
```
150+
151+
*After*
152+
153+
```php
154+
use Symfony\Component\Validator\Attribute\HasNamedArguments;
155+
156+
class CustomCompositeConstraint extends Composite
157+
{
158+
public array $constraints = [];
159+
160+
#[HasNamedArguments]
161+
public function __construct(array $constraints, ?array $groups = null, mixed $payload = null)
162+
{
163+
$this->constraints = $constraints;
164+
165+
parent::__construct(null, $groups, $payload);
166+
}
167+
}
168+
```

src/Symfony/Bridge/Doctrine/Validator/Constraints/UniqueEntity.php

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -66,18 +66,21 @@ public function __construct(
6666
trigger_deprecation('symfony/validator', '7.3', 'Passing an array of options to configure the "%s" constraint is deprecated, use named arguments instead.', static::class);
6767

6868
$options = array_merge($fields, $options ?? []);
69+
$fields = null;
6970
} else {
7071
if (\is_array($options)) {
7172
trigger_deprecation('symfony/validator', '7.3', 'Passing an array of options to configure the "%s" constraint is deprecated, use named arguments instead.', static::class);
73+
74+
$options['fields'] = $fields;
75+
$fields = null;
7276
} else {
73-
$options = [];
77+
$options = null;
7478
}
75-
76-
$options['fields'] = $fields;
7779
}
7880

7981
parent::__construct($options, $groups, $payload);
8082

83+
$this->fields = $fields ?? $this->fields;
8184
$this->message = $message ?? $this->message;
8285
$this->service = $service ?? $this->service;
8386
$this->em = $em ?? $this->em;

src/Symfony/Bridge/Doctrine/composer.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@
4141
"symfony/translation": "^6.4|^7.0|^8.0",
4242
"symfony/type-info": "^7.1|^8.0",
4343
"symfony/uid": "^6.4|^7.0|^8.0",
44-
"symfony/validator": "^6.4|^7.0|^8.0",
44+
"symfony/validator": "^7.4|^8.0",
4545
"symfony/var-dumper": "^6.4|^7.0|^8.0",
4646
"doctrine/collections": "^1.8|^2.0",
4747
"doctrine/data-fixtures": "^1.1|^2",
@@ -64,7 +64,7 @@
6464
"symfony/property-info": "<6.4",
6565
"symfony/security-bundle": "<6.4",
6666
"symfony/security-core": "<6.4",
67-
"symfony/validator": "<6.4"
67+
"symfony/validator": "<7.4"
6868
},
6969
"autoload": {
7070
"psr-4": { "Symfony\\Bridge\\Doctrine\\": "" },

src/Symfony/Component/Security/Core/Tests/Validator/Constraints/UserPasswordTest.php

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -35,8 +35,6 @@ public function testValidatedByService(UserPassword $constraint)
3535

3636
public static function provideServiceValidatedConstraints(): iterable
3737
{
38-
yield 'Doctrine style' => [new UserPassword(['service' => 'my_service'])];
39-
4038
yield 'named arguments' => [new UserPassword(service: 'my_service')];
4139

4240
$metadata = new ClassMetadata(UserPasswordDummy::class);
@@ -45,6 +43,14 @@ public static function provideServiceValidatedConstraints(): iterable
4543
yield 'attribute' => [$metadata->properties['b']->constraints[0]];
4644
}
4745

46+
/**
47+
* @group legacy
48+
*/
49+
public function testValidatedByServiceDoctrineStyle()
50+
{
51+
self::assertSame('my_service', (new UserPassword(['service' => 'my_service']))->validatedBy());
52+
}
53+
4854
public function testAttributes()
4955
{
5056
$metadata = new ClassMetadata(UserPasswordDummy::class);

src/Symfony/Component/Validator/CHANGELOG.md

Lines changed: 127 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,133 @@
11
CHANGELOG
22
=========
33

4+
7.4
5+
---
6+
7+
* Deprecate evaluating options in the base `Constraint` class. Initialize properties in the constructor of the concrete constraint
8+
class instead.
9+
10+
Before:
11+
12+
```php
13+
class CustomConstraint extends Constraint
14+
{
15+
public $option1;
16+
public $option2;
17+
18+
public function __construct(?array $options = null)
19+
{
20+
parent::__construct($options);
21+
}
22+
}
23+
```
24+
25+
After:
26+
27+
```php
28+
use Symfony\Component\Validator\Attribute\HasNamedArguments;
29+
30+
class CustomConstraint extends Constraint
31+
{
32+
public $option1;
33+
public $option2;
34+
35+
#[HasNamedArguments]
36+
public function __construct($option1 = null, $option2 = null, ?array $groups = null, mixed $payload = null)
37+
{
38+
parent::__construct(null, $groups, $payload);
39+
40+
$this->option1 = $option1;
41+
$this->option2 = $option2;
42+
}
43+
}
44+
```
45+
46+
* Deprecate the `getRequiredOptions()` method of the base `Constraint` class. Use mandatory constructor arguments instead.
47+
48+
Before:
49+
50+
```php
51+
class CustomConstraint extends Constraint
52+
{
53+
public $option1;
54+
public $option2;
55+
56+
public function __construct(?array $options = null)
57+
{
58+
parent::__construct($options);
59+
}
60+
61+
public function getRequiredOptions()
62+
{
63+
return ['option1'];
64+
}
65+
}
66+
```
67+
68+
After:
69+
70+
```php
71+
use Symfony\Component\Validator\Attribute\HasNamedArguments;
72+
73+
class CustomConstraint extends Constraint
74+
{
75+
public $option1;
76+
public $option2;
77+
78+
#[HasNamedArguments]
79+
public function __construct($option1, $option2 = null, ?array $groups = null, mixed $payload = null)
80+
{
81+
parent::__construct(null, $groups, $payload);
82+
83+
$this->option1 = $option1;
84+
$this->option2 = $option2;
85+
}
86+
}
87+
```
88+
* Deprecate the `normalizeOptions()` and `getDefaultOption()` methods of the base `Constraint` class without replacements.
89+
Overriding them in child constraint will not have any effects starting with Symfony 8.0.
90+
* Deprecate passing an array of options to the `Composite` constraint class. Initialize the properties referenced with `getNestedConstraints()`
91+
in child classes before calling the constructor of `Composite`.
92+
93+
Before:
94+
95+
```php
96+
class CustomCompositeConstraint extends Composite
97+
{
98+
public array $constraints = [];
99+
100+
public function __construct(?array $options = null)
101+
{
102+
parent::__construct($options);
103+
}
104+
105+
protected function getCompositeOption(): string
106+
{
107+
return 'constraints';
108+
}
109+
}
110+
```
111+
112+
After:
113+
114+
```php
115+
use Symfony\Component\Validator\Attribute\HasNamedArguments;
116+
117+
class CustomCompositeConstraint extends Composite
118+
{
119+
public array $constraints = [];
120+
121+
#[HasNamedArguments]
122+
public function __construct(array $constraints, ?array $groups = null, mixed $payload = null)
123+
{
124+
$this->constraints = $constraints;
125+
126+
parent::__construct(null, $groups, $payload);
127+
}
128+
}
129+
```
130+
4131
7.3
5132
---
6133

src/Symfony/Component/Validator/Constraint.php

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -110,6 +110,17 @@ public function __construct(mixed $options = null, ?array $groups = null, mixed
110110
{
111111
unset($this->groups); // enable lazy initialization
112112

113+
if (null === $options && (\func_num_args() > 0 || (new \ReflectionMethod($this, 'getRequiredOptions'))->getDeclaringClass()->getName() === self::class)) {
114+
if (null !== $groups) {
115+
$this->groups = $groups;
116+
}
117+
$this->payload = $payload;
118+
119+
return;
120+
}
121+
122+
trigger_deprecation('symfony/validator', '7.4', 'Support for evaluating options in the base Constraint class is deprecated. Initialize properties in the constructor of %s instead.', static::class);
123+
113124
$options = $this->normalizeOptions($options);
114125
if (null !== $groups) {
115126
$options['groups'] = $groups;
@@ -122,6 +133,8 @@ public function __construct(mixed $options = null, ?array $groups = null, mixed
122133
}
123134

124135
/**
136+
* @deprecated since Symfony 7.4
137+
*
125138
* @return array<string, mixed>
126139
*/
127140
protected function normalizeOptions(mixed $options): array
@@ -241,6 +254,8 @@ public function addImplicitGroupName(string $group): void
241254
*
242255
* Override this method to define a default option.
243256
*
257+
* @deprecated since Symfony 7.4
258+
*
244259
* @see __construct()
245260
*/
246261
public function getDefaultOption(): ?string
@@ -255,6 +270,8 @@ public function getDefaultOption(): ?string
255270
*
256271
* @return string[]
257272
*
273+
* @deprecated since Symfony 7.4
274+
*
258275
* @see __construct()
259276
*/
260277
public function getRequiredOptions(): array

0 commit comments

Comments
 (0)
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