Skip to content

Commit b9cac9b

Browse files
committed
[Form] Deprecated "cascade_validation"
1 parent 09fabfe commit b9cac9b

File tree

7 files changed

+176
-30
lines changed

7 files changed

+176
-30
lines changed

UPGRADE-2.8.md

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,51 @@
11
UPGRADE FROM 2.7 to 2.8
22
=======================
33

4+
Form
5+
----
6+
7+
* The "cascade_validation" option was deprecated. Use the "constraints"
8+
option together with the `Valid` constraint instead. Contrary to
9+
"cascade_validation", "constraints" must be set on the respective child forms,
10+
not the parent form.
11+
12+
Before:
13+
14+
```php
15+
$form = $this->createForm('form', $article, array('cascade_validation' => true))
16+
->add('author', new AuthorType())
17+
->getForm();
18+
```
19+
20+
After:
21+
22+
```php
23+
use Symfony\Component\Validator\Constraints\Valid;
24+
25+
$form = $this->createForm('form', $article)
26+
->add('author', new AuthorType(), array(
27+
'constraints' => new Valid(),
28+
))
29+
->getForm();
30+
```
31+
32+
Alternatively, you can set the `Valid` constraint in the model itself:
33+
34+
```php
35+
use Symfony\Component\Validator\Constraints as Assert;
36+
37+
class Article
38+
{
39+
/**
40+
* @Assert\Valid
41+
*/
42+
private $author;
43+
}
44+
```
45+
446
Translator
547
----------
48+
649
* The `getMessages()` method of the `Symfony\Component\Translation\Translator` was deprecated and will be removed in
750
Symfony 3.0. You should use the `getCatalogue()` method of the `Symfony\Component\Translation\TranslatorBagInterface`.
851

src/Symfony/Component/Form/CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@ CHANGELOG
66

77
* deprecated option "read_only" in favor of "attr['readonly']"
88
* added the html5 "range" FormType
9+
* deprecated the "cascade_validation" option in favor of setting "constraints"
10+
with the Valid constraint
911

1012
2.7.0
1113
-----

src/Symfony/Component/Form/Extension/Validator/Constraints/FormValidator.php

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313

1414
use Symfony\Component\Form\FormInterface;
1515
use Symfony\Component\Validator\Constraint;
16+
use Symfony\Component\Validator\Constraints\Valid;
1617
use Symfony\Component\Validator\ConstraintValidator;
1718
use Symfony\Component\Validator\Context\ExecutionContextInterface;
1819
use Symfony\Component\Validator\Exception\UnexpectedTypeException;
@@ -63,6 +64,20 @@ public function validate($form, Constraint $constraint)
6364
// in the form
6465
$constraints = $config->getOption('constraints');
6566
foreach ($constraints as $constraint) {
67+
// For the "Valid" constraint, validate the data in all groups
68+
if ($constraint instanceof Valid) {
69+
if ($validator) {
70+
$validator->atPath('data')->validate($form->getData(), $constraint, $groups);
71+
} else {
72+
// 2.4 API
73+
$this->context->validateValue($form->getData(), $constraint, 'data', $groups);
74+
}
75+
76+
continue;
77+
}
78+
79+
// Otherwise validate a constraint only once for the first
80+
// matching group
6681
foreach ($groups as $group) {
6782
if (in_array($group, $constraint->groups)) {
6883
if ($validator) {

src/Symfony/Component/Form/Extension/Validator/Type/FormTypeValidatorExtension.php

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,14 @@ public function configureOptions(OptionsResolver $resolver)
6767
return is_object($constraints) ? array($constraints) : (array) $constraints;
6868
};
6969

70+
$cascadeValidationNormalizer = function (Options $options, $cascadeValidation) {
71+
if ($cascadeValidation) {
72+
@trigger_error('The "cascade_validation" option is deprecated since version 2.8 and will be removed in 3.0. Use "constraints" with a Valid constraint instead.', E_USER_DEPRECATED);
73+
}
74+
75+
return $cascadeValidation;
76+
};
77+
7078
$resolver->setDefaults(array(
7179
'error_mapping' => array(),
7280
'constraints' => array(),
@@ -78,6 +86,7 @@ public function configureOptions(OptionsResolver $resolver)
7886
));
7987

8088
$resolver->setNormalizer('constraints', $constraintsNormalizer);
89+
$resolver->setNormalizer('cascade_validation', $cascadeValidationNormalizer);
8190
}
8291

8392
/**

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

Lines changed: 64 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -18,9 +18,9 @@
1818
use Symfony\Component\Form\Extension\Validator\Constraints\Form;
1919
use Symfony\Component\Form\Extension\Validator\Constraints\FormValidator;
2020
use Symfony\Component\Form\SubmitButtonBuilder;
21-
use Symfony\Component\Validator\Context\ExecutionContextInterface;
2221
use Symfony\Component\Validator\Constraints\NotNull;
2322
use Symfony\Component\Validator\Constraints\NotBlank;
23+
use Symfony\Component\Validator\Constraints\Valid;
2424
use Symfony\Component\Validator\Tests\Constraints\AbstractConstraintValidatorTest;
2525
use Symfony\Component\Validator\Validation;
2626

@@ -109,6 +109,52 @@ public function testValidateConstraints()
109109
$this->assertNoViolation();
110110
}
111111

112+
public function testValidateIfParentWithCascadeValidation()
113+
{
114+
$object = $this->getMock('\stdClass');
115+
116+
$parent = $this->getBuilder('parent', null, array('cascade_validation' => true))
117+
->setCompound(true)
118+
->setDataMapper($this->getDataMapper())
119+
->getForm();
120+
$options = array('validation_groups' => array('group1', 'group2'));
121+
$form = $this->getBuilder('name', '\stdClass', $options)->getForm();
122+
$parent->add($form);
123+
124+
$form->setData($object);
125+
126+
$this->expectValidateAt(0, 'data', $object, 'group1');
127+
$this->expectValidateAt(1, 'data', $object, 'group2');
128+
129+
$this->validator->validate($form, new Form());
130+
131+
$this->assertNoViolation();
132+
}
133+
134+
public function testValidateIfChildWithValidConstraint()
135+
{
136+
$object = $this->getMock('\stdClass');
137+
138+
$parent = $this->getBuilder('parent')
139+
->setCompound(true)
140+
->setDataMapper($this->getDataMapper())
141+
->getForm();
142+
$options = array(
143+
'validation_groups' => array('group1', 'group2'),
144+
'constraints' => array(new Valid()),
145+
);
146+
$form = $this->getBuilder('name', '\stdClass', $options)->getForm();
147+
$parent->add($form);
148+
149+
$form->setData($object);
150+
151+
$this->expectValidateAt(0, 'data', $object, array('group1', 'group2'));
152+
153+
$this->validator->validate($form, new Form());
154+
155+
$this->assertNoViolation();
156+
}
157+
112158
public function testDontValidateIfParentWithoutCascadeValidation()
113159
{
114160
$object = $this->getMock('\stdClass');
@@ -387,12 +433,13 @@ public function testUseValidationGroupOfClickedButton()
387433
{
388434
$object = $this->getMock('\stdClass');
389435

390-
$parent = $this->getBuilder('parent', null, array('cascade_validation' => true))
436+
$parent = $this->getBuilder('parent')
391437
->setCompound(true)
392438
->setDataMapper($this->getDataMapper())
393439
->getForm();
394440
$form = $this->getForm('name', '\stdClass', array(
395441
'validation_groups' => 'form_group',
442+
'constraints' => array(new Valid()),
396443
));
397444

398445
$parent->add($form);
@@ -402,7 +449,7 @@ public function testUseValidationGroupOfClickedButton()
402449

403450
$parent->submit(array('name' => $object, 'submit' => ''));
404451

405-
$this->expectValidateAt(0, 'data', $object, 'button_group');
452+
$this->expectValidateAt(0, 'data', $object, array('button_group'));
406453

407454
$this->validator->validate($form, new Form());
408455

@@ -413,12 +460,13 @@ public function testDontUseValidationGroupOfUnclickedButton()
413460
{
414461
$object = $this->getMock('\stdClass');
415462

416-
$parent = $this->getBuilder('parent', null, array('cascade_validation' => true))
463+
$parent = $this->getBuilder('parent')
417464
->setCompound(true)
418465
->setDataMapper($this->getDataMapper())
419466
->getForm();
420467
$form = $this->getForm('name', '\stdClass', array(
421468
'validation_groups' => 'form_group',
469+
'constraints' => array(new Valid()),
422470
));
423471

424472
$parent->add($form);
@@ -428,7 +476,7 @@ public function testDontUseValidationGroupOfUnclickedButton()
428476

429477
$form->setData($object);
430478

431-
$this->expectValidateAt(0, 'data', $object, 'form_group');
479+
$this->expectValidateAt(0, 'data', $object, array('form_group'));
432480

433481
$this->validator->validate($form, new Form());
434482

@@ -439,20 +487,18 @@ public function testUseInheritedValidationGroup()
439487
{
440488
$object = $this->getMock('\stdClass');
441489

442-
$parentOptions = array(
443-
'validation_groups' => 'group',
444-
'cascade_validation' => true,
445-
);
490+
$parentOptions = array('validation_groups' => 'group');
446491
$parent = $this->getBuilder('parent', null, $parentOptions)
447492
->setCompound(true)
448493
->setDataMapper($this->getDataMapper())
449494
->getForm();
450-
$form = $this->getBuilder('name', '\stdClass')->getForm();
495+
$formOptions = array('constraints' => array(new Valid()));
496+
$form = $this->getBuilder('name', '\stdClass', $formOptions)->getForm();
451497
$parent->add($form);
452498

453499
$form->setData($object);
454500

455-
$this->expectValidateAt(0, 'data', $object, 'group');
501+
$this->expectValidateAt(0, 'data', $object, array('group'));
456502

457503
$this->validator->validate($form, new Form());
458504

@@ -463,21 +509,18 @@ public function testUseInheritedCallbackValidationGroup()
463509
{
464510
$object = $this->getMock('\stdClass');
465511

466-
$parentOptions = array(
467-
'validation_groups' => array($this, 'getValidationGroups'),
468-
'cascade_validation' => true,
469-
);
512+
$parentOptions = array('validation_groups' => array($this, 'getValidationGroups'));
470513
$parent = $this->getBuilder('parent', null, $parentOptions)
471514
->setCompound(true)
472515
->setDataMapper($this->getDataMapper())
473516
->getForm();
474-
$form = $this->getBuilder('name', '\stdClass')->getForm();
517+
$formOptions = array('constraints' => array(new Valid()));
518+
$form = $this->getBuilder('name', '\stdClass', $formOptions)->getForm();
475519
$parent->add($form);
476520

477521
$form->setData($object);
478522

479-
$this->expectValidateAt(0, 'data', $object, 'group1');
480-
$this->expectValidateAt(1, 'data', $object, 'group2');
523+
$this->expectValidateAt(0, 'data', $object, array('group1', 'group2'));
481524

482525
$this->validator->validate($form, new Form());
483526

@@ -492,19 +535,18 @@ public function testUseInheritedClosureValidationGroup()
492535
'validation_groups' => function (FormInterface $form) {
493536
return array('group1', 'group2');
494537
},
495-
'cascade_validation' => true,
496538
);
497539
$parent = $this->getBuilder('parent', null, $parentOptions)
498540
->setCompound(true)
499541
->setDataMapper($this->getDataMapper())
500542
->getForm();
501-
$form = $this->getBuilder('name', '\stdClass')->getForm();
543+
$formOptions = array('constraints' => array(new Valid()));
544+
$form = $this->getBuilder('name', '\stdClass', $formOptions)->getForm();
502545
$parent->add($form);
503546

504547
$form->setData($object);
505548

506-
$this->expectValidateAt(0, 'data', $object, 'group1');
507-
$this->expectValidateAt(1, 'data', $object, 'group2');
549+
$this->expectValidateAt(0, 'data', $object, array('group1', 'group2'));
508550

509551
$this->validator->validate($form, new Form());
510552

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

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
namespace Symfony\Component\Form\Tests\Extension\Validator\Type;
1313

1414
use Symfony\Component\Form\Extension\Validator\Type\FormTypeValidatorExtension;
15+
use Symfony\Component\Validator\Constraints\Valid;
1516
use Symfony\Component\Validator\ConstraintViolationList;
1617

1718
class FormTypeValidatorExtensionTest extends BaseValidatorExtensionTest
@@ -37,6 +38,30 @@ public function testSubmitValidatesData()
3738
$form->submit(array());
3839
}
3940

41+
public function testValidConstraint()
42+
{
43+
$form = $this->createForm(array('constraints' => $valid = new Valid()));
44+
45+
$this->assertSame(array($valid), $form->getConfig()->getOption('constraints'));
46+
}
47+
48+
/**
49+
* @group legacy
50+
*/
51+
public function testCascadeValidationCanBeSetToTrue()
52+
{
53+
$form = $this->createForm(array('cascade_validation' => true));
54+
55+
$this->assertTrue($form->getConfig()->getOption('cascade_validation'));
56+
}
57+
58+
public function testCascadeValidationCanBeSetToFalse()
59+
{
60+
$form = $this->createForm(array('cascade_validation' => false));
61+
62+
$this->assertFalse($form->getConfig()->getOption('cascade_validation'));
63+
}
64+
4065
public function testValidatorInterfaceSinceSymfony25()
4166
{
4267
// Mock of ValidatorInterface since apiVersion 2.5

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

Lines changed: 18 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -220,14 +220,24 @@ protected function expectNoValidate()
220220

221221
protected function expectValidateAt($i, $propertyPath, $value, $group)
222222
{
223-
$validator = $this->context->getValidator()->inContext($this->context);
224-
$validator->expects($this->at(2 * $i))
225-
->method('atPath')
226-
->with($propertyPath)
227-
->will($this->returnValue($validator));
228-
$validator->expects($this->at(2 * $i + 1))
229-
->method('validate')
230-
->with($value, $this->logicalOr(null, array()), $group);
223+
switch ($this->getApiVersion()) {
224+
case Validation::API_VERSION_2_4:
225+
$this->context->expects($this->at($i))
226+
->method('validate')
227+
->with($value, $propertyPath, $group);
228+
break;
229+
case Validation::API_VERSION_2_5:
230+
case Validation::API_VERSION_2_5_BC:
231+
$validator = $this->context->getValidator()->inContext($this->context);
232+
$validator->expects($this->at(2 * $i))
233+
->method('atPath')
234+
->with($propertyPath)
235+
->will($this->returnValue($validator));
236+
$validator->expects($this->at(2 * $i + 1))
237+
->method('validate')
238+
->with($value, $this->logicalOr(null, array(), $this->isInstanceOf('\Symfony\Component\Validator\Constraints\Valid')), $group);
239+
break;
240+
}
231241
}
232242

233243
protected function expectValidateValueAt($i, $propertyPath, $value, $constraints, $group = null)

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