Skip to content

Commit a8ae27e

Browse files
committed
deprecate the use of option arrays to configure validation constraints
1 parent c3615e6 commit a8ae27e

File tree

153 files changed

+2327
-1924
lines changed

Some content is hidden

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

153 files changed

+2327
-1924
lines changed

src/Symfony/Bridge/Doctrine/Tests/Validator/Constraints/UniqueEntityValidatorTest.php

Lines changed: 102 additions & 170 deletions
Large diffs are not rendered by default.

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

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111

1212
namespace Symfony\Bridge\Doctrine\Validator\Constraints;
1313

14+
use Symfony\Component\Validator\Attribute\HasNamedArguments;
1415
use Symfony\Component\Validator\Constraint;
1516

1617
/**
@@ -46,6 +47,7 @@ class UniqueEntity extends Constraint
4647
* a fieldName => value associative array according to the fields option configuration
4748
* @param string|null $errorPath Bind the constraint violation to this field instead of the first one in the fields option configuration
4849
*/
50+
#[HasNamedArguments]
4951
public function __construct(
5052
array|string $fields,
5153
?string $message = null,
@@ -61,6 +63,8 @@ public function __construct(
6163
array $options = [],
6264
) {
6365
if (\is_array($fields) && \is_string(key($fields))) {
66+
trigger_deprecation('symfony/validator', '7.2', 'Passing an array of options to configure the %s constraint is deprecated, use named arguments instead.', static::class);
67+
6468
$options = array_merge($fields, $options);
6569
} elseif (null !== $fields) {
6670
$options['fields'] = $fields;

src/Symfony/Bridge/Doctrine/Validator/DoctrineLoader.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -90,7 +90,7 @@ public function loadClassMetadata(ClassMetadata $metadata): bool
9090
}
9191

9292
if (true === (self::getFieldMappingValue($mapping, 'unique') ?? false) && !isset($existingUniqueFields[self::getFieldMappingValue($mapping, 'fieldName')])) {
93-
$metadata->addConstraint(new UniqueEntity(['fields' => self::getFieldMappingValue($mapping, 'fieldName')]));
93+
$metadata->addConstraint(new UniqueEntity(fields: self::getFieldMappingValue($mapping, 'fieldName')));
9494
$loaded = true;
9595
}
9696

@@ -103,7 +103,7 @@ public function loadClassMetadata(ClassMetadata $metadata): bool
103103
$metadata->addPropertyConstraint(self::getFieldMappingValue($mapping, 'declaredField'), new Valid());
104104
$loaded = true;
105105
} elseif (property_exists($className, self::getFieldMappingValue($mapping, 'fieldName')) && (!$doctrineMetadata->isMappedSuperclass || $metadata->getReflectionClass()->getProperty(self::getFieldMappingValue($mapping, 'fieldName'))->isPrivate())) {
106-
$metadata->addPropertyConstraint(self::getFieldMappingValue($mapping, 'fieldName'), new Length(['max' => self::getFieldMappingValue($mapping, 'length')]));
106+
$metadata->addPropertyConstraint(self::getFieldMappingValue($mapping, 'fieldName'), new Length(max: self::getFieldMappingValue($mapping, 'length')));
107107
$loaded = true;
108108
}
109109
} elseif (null === $lengthConstraint->max) {

src/Symfony/Component/Form/Tests/Extension/Validator/Constraints/FormValidatorFunctionalTest.php

Lines changed: 31 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -88,9 +88,9 @@ public function testFieldConstraintsInvalidateFormIfFieldIsSubmitted()
8888
public function testNonCompositeConstraintValidatedOnce()
8989
{
9090
$form = $this->formFactory->create(TextType::class, null, [
91-
'constraints' => [new NotBlank(['groups' => ['foo', 'bar']])],
92-
'validation_groups' => ['foo', 'bar'],
93-
]);
91+
'constraints' => [new NotBlank(groups: ['foo', 'bar'])],
92+
'validation_groups' => ['foo', 'bar'],
93+
]);
9494
$form->submit('');
9595

9696
$violations = $this->validator->validate($form);
@@ -105,12 +105,8 @@ public function testCompositeConstraintValidatedInEachGroup()
105105
$form = $this->formFactory->create(FormType::class, null, [
106106
'constraints' => [
107107
new Collection([
108-
'field1' => new NotBlank([
109-
'groups' => ['field1'],
110-
]),
111-
'field2' => new NotBlank([
112-
'groups' => ['field2'],
113-
]),
108+
'field1' => new NotBlank(groups: ['field1']),
109+
'field2' => new NotBlank(groups: ['field2']),
114110
]),
115111
],
116112
'validation_groups' => ['field1', 'field2'],
@@ -136,12 +132,8 @@ public function testCompositeConstraintValidatedInSequence()
136132
$form = $this->formFactory->create(FormType::class, null, [
137133
'constraints' => [
138134
new Collection([
139-
'field1' => new NotBlank([
140-
'groups' => ['field1'],
141-
]),
142-
'field2' => new NotBlank([
143-
'groups' => ['field2'],
144-
]),
135+
'field1' => new NotBlank(groups: ['field1']),
136+
'field2' => new NotBlank(groups: ['field2']),
145137
]),
146138
],
147139
'validation_groups' => new GroupSequence(['field1', 'field2']),
@@ -167,10 +159,10 @@ public function testFieldsValidateInSequence()
167159
'validation_groups' => new GroupSequence(['group1', 'group2']),
168160
])
169161
->add('foo', TextType::class, [
170-
'constraints' => [new Length(['min' => 10, 'groups' => ['group1']])],
162+
'constraints' => [new Length(min: 10, groups: ['group1'])],
171163
])
172164
->add('bar', TextType::class, [
173-
'constraints' => [new NotBlank(['groups' => ['group2']])],
165+
'constraints' => [new NotBlank(groups: ['group2'])],
174166
])
175167
;
176168

@@ -188,13 +180,13 @@ public function testFieldsValidateInSequenceWithNestedGroupsArray()
188180
'validation_groups' => new GroupSequence([['group1', 'group2'], 'group3']),
189181
])
190182
->add('foo', TextType::class, [
191-
'constraints' => [new Length(['min' => 10, 'groups' => ['group1']])],
183+
'constraints' => [new Length(min: 10, groups: ['group1'])],
192184
])
193185
->add('bar', TextType::class, [
194-
'constraints' => [new Length(['min' => 10, 'groups' => ['group2']])],
186+
'constraints' => [new Length(min: 10, groups: ['group2'])],
195187
])
196188
->add('baz', TextType::class, [
197-
'constraints' => [new NotBlank(['groups' => ['group3']])],
189+
'constraints' => [new NotBlank(groups: ['group3'])],
198190
])
199191
;
200192

@@ -214,13 +206,11 @@ public function testConstraintsInDifferentGroupsOnSingleField()
214206
])
215207
->add('foo', TextType::class, [
216208
'constraints' => [
217-
new NotBlank([
218-
'groups' => ['group1'],
219-
]),
220-
new Length([
221-
'groups' => ['group2'],
222-
'max' => 3,
223-
]),
209+
new NotBlank(groups: ['group1']),
210+
new Length(
211+
groups: ['group2'],
212+
max: 3,
213+
),
224214
],
225215
]);
226216
$form->submit([
@@ -242,13 +232,11 @@ public function testConstraintsInDifferentGroupsOnSingleFieldWithAdditionalField
242232
->add('bar')
243233
->add('foo', TextType::class, [
244234
'constraints' => [
245-
new NotBlank([
246-
'groups' => ['group1'],
247-
]),
248-
new Length([
249-
'groups' => ['group2'],
250-
'max' => 3,
251-
]),
235+
new NotBlank(groups: ['group1']),
236+
new Length(
237+
groups: ['group2'],
238+
max: 3,
239+
),
252240
],
253241
]);
254242
$form->submit([
@@ -268,11 +256,11 @@ public function testCascadeValidationToChildFormsUsingPropertyPaths()
268256
'validation_groups' => ['group1', 'group2'],
269257
])
270258
->add('field1', null, [
271-
'constraints' => [new NotBlank(['groups' => 'group1'])],
259+
'constraints' => [new NotBlank(groups: ['group1'])],
272260
'property_path' => '[foo]',
273261
])
274262
->add('field2', null, [
275-
'constraints' => [new NotBlank(['groups' => 'group2'])],
263+
'constraints' => [new NotBlank(groups: ['group2'])],
276264
'property_path' => '[bar]',
277265
])
278266
;
@@ -359,11 +347,11 @@ public function testCascadeValidationToChildFormsUsingPropertyPathsValidatedInSe
359347
'validation_groups' => new GroupSequence(['group1', 'group2']),
360348
])
361349
->add('field1', null, [
362-
'constraints' => [new NotBlank(['groups' => 'group1'])],
350+
'constraints' => [new NotBlank(groups: ['group1'])],
363351
'property_path' => '[foo]',
364352
])
365353
->add('field2', null, [
366-
'constraints' => [new NotBlank(['groups' => 'group2'])],
354+
'constraints' => [new NotBlank(groups: ['group2'])],
367355
'property_path' => '[bar]',
368356
])
369357
;
@@ -384,9 +372,7 @@ public function testContextIsPopulatedWithFormBeingValidated()
384372
{
385373
$form = $this->formFactory->create(FormType::class)
386374
->add('field1', null, [
387-
'constraints' => [new Expression([
388-
'expression' => '!this.getParent().get("field2").getData()',
389-
])],
375+
'constraints' => [new Expression('!this.getParent().get("field2").getData()')],
390376
])
391377
->add('field2')
392378
;
@@ -407,10 +393,10 @@ public function testContextIsPopulatedWithFormBeingValidatedUsingGroupSequence()
407393
'validation_groups' => new GroupSequence(['group1']),
408394
])
409395
->add('field1', null, [
410-
'constraints' => [new Expression([
411-
'expression' => '!this.getParent().get("field2").getData()',
412-
'groups' => ['group1'],
413-
])],
396+
'constraints' => [new Expression(
397+
expression: '!this.getParent().get("field2").getData()',
398+
groups: ['group1'],
399+
)],
414400
])
415401
->add('field2')
416402
;

src/Symfony/Component/Form/Tests/Extension/Validator/Constraints/FormValidatorTest.php

Lines changed: 16 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -70,9 +70,9 @@ public function testValidate()
7070
public function testValidateConstraints()
7171
{
7272
$object = new \stdClass();
73-
$constraint1 = new NotNull(['groups' => ['group1', 'group2']]);
74-
$constraint2 = new NotBlank(['groups' => 'group2']);
75-
$constraint3 = new Length(['groups' => 'group2', 'min' => 3]);
73+
$constraint1 = new NotNull(groups: ['group1', 'group2']);
74+
$constraint2 = new NotBlank(groups: ['group2']);
75+
$constraint3 = new Length(groups: ['group2'], min: 3);
7676

7777
$options = [
7878
'validation_groups' => ['group1', 'group2'],
@@ -156,8 +156,8 @@ public function testMissingConstraintIndex()
156156
public function testValidateConstraintsOptionEvenIfNoValidConstraint()
157157
{
158158
$object = new \stdClass();
159-
$constraint1 = new NotNull(['groups' => ['group1', 'group2']]);
160-
$constraint2 = new NotBlank(['groups' => 'group2']);
159+
$constraint1 = new NotNull(groups: ['group1', 'group2']);
160+
$constraint2 = new NotBlank(groups: ['group2']);
161161

162162
$parent = $this->getBuilder('parent', null)
163163
->setCompound(true)
@@ -184,8 +184,8 @@ public function testDontValidateIfNoValidationGroups()
184184
$object = new \stdClass();
185185

186186
$form = $this->getBuilder('name', '\stdClass', [
187-
'validation_groups' => [],
188-
])
187+
'validation_groups' => [],
188+
])
189189
->setData($object)
190190
->setCompound(true)
191191
->setDataMapper(new DataMapper())
@@ -256,12 +256,12 @@ public function testDontValidateIfNotSynchronized()
256256
$object = new \stdClass();
257257

258258
$form = $this->getBuilder('name', '\stdClass', [
259-
'invalid_message' => 'invalid_message_key',
260-
// Invalid message parameters must be supported, because the
261-
// invalid message can be a translation key
262-
// see https://github.com/symfony/symfony/issues/5144
263-
'invalid_message_parameters' => ['{{ foo }}' => 'bar'],
264-
])
259+
'invalid_message' => 'invalid_message_key',
260+
// Invalid message parameters must be supported, because the
261+
// invalid message can be a translation key
262+
// see https://github.com/symfony/symfony/issues/5144
263+
'invalid_message_parameters' => ['{{ foo }}' => 'bar'],
264+
])
265265
->setData($object)
266266
->addViewTransformer(new CallbackTransformer(
267267
static fn ($data) => $data,
@@ -291,7 +291,8 @@ public function testAddInvalidErrorEvenIfNoValidationGroups()
291291
{
292292
$object = new \stdClass();
293293

294-
$form = $this->getBuilder('name', '\stdClass', [
294+
$form = $this
295+
->getBuilder('name', '\stdClass', [
295296
'invalid_message' => 'invalid_message_key',
296297
// Invalid message parameters must be supported, because the
297298
// invalid message can be a translation key
@@ -684,7 +685,7 @@ public function getValidationGroups(FormInterface $form)
684685
public function testCauseForNotAllowedExtraFieldsIsTheFormConstraint()
685686
{
686687
$form = $this
687-
->getBuilder('form', null, ['constraints' => [new NotBlank(['groups' => ['foo']])]])
688+
->getBuilder('form', null, ['constraints' => [new NotBlank(groups: ['foo'])]])
688689
->setCompound(true)
689690
->setDataMapper(new DataMapper())
690691
->getForm();

src/Symfony/Component/Form/Tests/Extension/Validator/Type/FormTypeValidatorExtensionTest.php

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -84,8 +84,8 @@ public function testGroupSequenceWithConstraintsOption()
8484
->create(FormTypeTest::TESTED_TYPE, null, ['validation_groups' => new GroupSequence(['First', 'Second'])])
8585
->add('field', TextTypeTest::TESTED_TYPE, [
8686
'constraints' => [
87-
new Length(['min' => 10, 'groups' => ['First']]),
88-
new NotBlank(['groups' => ['Second']]),
87+
new Length(min: 10, groups: ['First']),
88+
new NotBlank(groups: ['Second']),
8989
],
9090
])
9191
;
@@ -102,7 +102,7 @@ public function testManyFieldsGroupSequenceWithConstraintsOption()
102102
{
103103
$formMetadata = new ClassMetadata(Form::class);
104104
$authorMetadata = (new ClassMetadata(Author::class))
105-
->addPropertyConstraint('firstName', new NotBlank(['groups' => 'Second']))
105+
->addPropertyConstraint('firstName', new NotBlank(groups: ['Second']))
106106
;
107107
$metadataFactory = $this->createMock(MetadataFactoryInterface::class);
108108
$metadataFactory->expects($this->any())
@@ -131,12 +131,12 @@ public function testManyFieldsGroupSequenceWithConstraintsOption()
131131
->add('firstName', TextTypeTest::TESTED_TYPE)
132132
->add('lastName', TextTypeTest::TESTED_TYPE, [
133133
'constraints' => [
134-
new Length(['min' => 10, 'groups' => ['First']]),
134+
new Length(min: 10, groups: ['First']),
135135
],
136136
])
137137
->add('australian', TextTypeTest::TESTED_TYPE, [
138138
'constraints' => [
139-
new NotBlank(['groups' => ['Second']]),
139+
new NotBlank(groups: ['Second']),
140140
],
141141
])
142142
;

src/Symfony/Component/Form/Tests/Extension/Validator/ValidatorTypeGuesserTest.php

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -96,8 +96,8 @@ public static function guessRequiredProvider()
9696
[new NotNull(), new ValueGuess(true, Guess::HIGH_CONFIDENCE)],
9797
[new NotBlank(), new ValueGuess(true, Guess::HIGH_CONFIDENCE)],
9898
[new IsTrue(), new ValueGuess(true, Guess::HIGH_CONFIDENCE)],
99-
[new Length(['min' => 10, 'max' => 10]), new ValueGuess(false, Guess::LOW_CONFIDENCE)],
100-
[new Range(['min' => 1, 'max' => 20]), new ValueGuess(false, Guess::LOW_CONFIDENCE)],
99+
[new Length(min: 10, max: 10), new ValueGuess(false, Guess::LOW_CONFIDENCE)],
100+
[new Range(min: 1, max: 20), new ValueGuess(false, Guess::LOW_CONFIDENCE)],
101101
];
102102
}
103103

@@ -122,7 +122,7 @@ public function testGuessRequiredReturnsFalseForUnmappedProperties()
122122

123123
public function testGuessMaxLengthForConstraintWithMaxValue()
124124
{
125-
$constraint = new Length(['max' => '2']);
125+
$constraint = new Length(max: '2');
126126

127127
$result = $this->guesser->guessMaxLengthForConstraint($constraint);
128128
$this->assertInstanceOf(ValueGuess::class, $result);
@@ -132,7 +132,7 @@ public function testGuessMaxLengthForConstraintWithMaxValue()
132132

133133
public function testGuessMaxLengthForConstraintWithMinValue()
134134
{
135-
$constraint = new Length(['min' => '2']);
135+
$constraint = new Length(min: '2');
136136

137137
$result = $this->guesser->guessMaxLengthForConstraint($constraint);
138138
$this->assertNull($result);
@@ -141,7 +141,7 @@ public function testGuessMaxLengthForConstraintWithMinValue()
141141
public function testGuessMimeTypesForConstraintWithMimeTypesValue()
142142
{
143143
$mimeTypes = ['image/png', 'image/jpeg'];
144-
$constraint = new File(['mimeTypes' => $mimeTypes]);
144+
$constraint = new File(mimeTypes: $mimeTypes);
145145
$typeGuess = $this->guesser->guessTypeForConstraint($constraint);
146146
$this->assertInstanceOf(TypeGuess::class, $typeGuess);
147147
$this->assertArrayHasKey('attr', $typeGuess->getOptions());
@@ -159,7 +159,7 @@ public function testGuessMimeTypesForConstraintWithoutMimeTypesValue()
159159

160160
public function testGuessMimeTypesForConstraintWithMimeTypesStringValue()
161161
{
162-
$constraint = new File(['mimeTypes' => 'image/*']);
162+
$constraint = new File(mimeTypes: 'image/*');
163163
$typeGuess = $this->guesser->guessTypeForConstraint($constraint);
164164
$this->assertInstanceOf(TypeGuess::class, $typeGuess);
165165
$this->assertArrayHasKey('attr', $typeGuess->getOptions());
@@ -169,7 +169,7 @@ public function testGuessMimeTypesForConstraintWithMimeTypesStringValue()
169169

170170
public function testGuessMimeTypesForConstraintWithMimeTypesEmptyStringValue()
171171
{
172-
$constraint = new File(['mimeTypes' => '']);
172+
$constraint = new File(mimeTypes: '');
173173
$typeGuess = $this->guesser->guessTypeForConstraint($constraint);
174174
$this->assertInstanceOf(TypeGuess::class, $typeGuess);
175175
$this->assertArrayNotHasKey('attr', $typeGuess->getOptions());

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

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
namespace Symfony\Component\Validator\Constraints;
1313

1414
use Symfony\Component\PropertyAccess\PropertyAccess;
15+
use Symfony\Component\Validator\Attribute\HasNamedArguments;
1516
use Symfony\Component\Validator\Constraint;
1617
use Symfony\Component\Validator\Exception\ConstraintDefinitionException;
1718
use Symfony\Component\Validator\Exception\LogicException;
@@ -28,9 +29,12 @@ abstract class AbstractComparison extends Constraint
2829
public mixed $value = null;
2930
public ?string $propertyPath = null;
3031

32+
#[HasNamedArguments]
3133
public function __construct(mixed $value = null, ?string $propertyPath = null, ?string $message = null, ?array $groups = null, mixed $payload = null, array $options = [])
3234
{
3335
if (\is_array($value)) {
36+
trigger_deprecation('symfony/validator', '7.2', 'Passing an array of options to configure the %s constraint is deprecated, use named arguments instead.', static::class);
37+
3438
$options = array_merge($value, $options);
3539
} elseif (null !== $value) {
3640
$options['value'] = $value;

0 commit comments

Comments
 (0)