8000 merged branch bschussek/optional-form-child-validation (PR #3128) · symfony/symfony@b8d8cab · GitHub
[go: up one dir, main page]

Skip to content

Commit b8d8cab

Browse files
committed
merged branch bschussek/optional-form-child-validation (PR #3128)
Commits ------- 0c70a41 [Form] Made validation of form children configurable. Set the option "cascade_validation" to `true` if you need it. Discussion ---------- [Form] Made validation of form children configurable Bug fix: yes Feature addition: yes Backwards compatibility break: yes Symfony2 tests pass: yes Fixes the following tickets: #797 Todo: adapt documentation ![Travis Build Status](https://secure.travis-ci.org/bschussek/symfony.png?branch=optional-form-child-validation) Child forms now aren't validated anymore by default. This is not a problem as long as @Valid constraints are properly put in your model. If you want to enable cascading validation, for example when there is no connection between the parent and the child model, you can set the option "cascade_validation" in the parent form to true. This change is not backwards compatible, but from my estimation the break should not affect many applications. --------------------------------------------------------------------------- by kriswallsmith at 2012-01-16T19:59:25Z :+1:
2 parents efada56 + 0c70a41 commit b8d8cab

File tree

4 files changed

+104
-3
lines changed

4 files changed

+104
-3
lines changed

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

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ public function buildForm(FormBuilder $builder, array $options)
3838
$builder
3939
->setAttribute('validation_groups', $options['validation_groups'])
4040
->setAttribute('validation_constraint', $options['validation_constraint'])
41+
->setAttribute('cascade_validation', $options['cascade_validation'])
4142
->addValidator(new DelegatingValidator($this->validator));
4243
}
4344

@@ -46,6 +47,7 @@ public function getDefaultOptions(array $options)
4647
return array(
4748
'validation_groups' => null,
4849
'validation_constraint' => null,
50+
'cascade_validation' => false,
4951
);
5052
}
5153

src/Symfony/Component/Form/Extension/Validator/Validator/DelegatingValidator.php

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -127,6 +127,29 @@ static public function validateFormData(FormInterface $form, ExecutionContext $c
127127
}
128128
}
129129

130+
static public function validateFormChildren(FormInterface $form, ExecutionContext $context)
131+
{
132+
if ($form->getAttribute('cascade_validation')) {
133+
$propertyPath = $context->getPropertyPath();
134+
$graphWalker = $context->getGraphWalker();
135+
136+
// The Execute constraint is called on class level, so we need to
137+
// set the property manually
138+
$context->setCurrentProperty('children');
139+
140+
// Adjust the property path accordingly
141+
if (!empty($propertyPath)) {
142+
$propertyPath .= '.';
143+
}
144+
145+
$propertyPath .= 'children';
146+
147+
foreach (self::getFormValidationGroups($form) as $group) {
148+
$graphWalker->walkReference($form->getChildren(), $group, $propertyPath, true);
149+
}
150+
}
151+
}
152+
130153
static protected function getFormValidationGroups(FormInterface $form)
131154
{
132155
$groups = null;

src/Symfony/Component/Form/Resources/config/validation.xml

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,9 +10,10 @@
1010
<value>Symfony\Component\Form\Extension\Validator\Validator\DelegatingValidator</value>
1111
<value>validateFormData</value>
1212
</value>
13+
<value>
14+
<value>Symfony\Component\Form\Extension\Validator\Validator\DelegatingValidator</value>
15+
<value>validateFormChildren</value>
16+
</value>
1317
</constraint>
14-
<property name="children">
15-
<constraint name="Valid" />
16-
</property>
1718
</class>
1819
</constraint-mapping>

tests/Symfony/Tests/Component/Form/Extension/Validator/Validator/DelegatingValidatorTest.php

Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -798,6 +798,81 @@ public function testValidateFormDataDoesNotWalkScalars()
798798
DelegatingValidator::validateFormData($form, $context);
799799
}
800800

801+
public function testValidateFormChildren()
802+
{
803+
$graphWalker = $this->getMockGraphWalker();
804+
$metadataFactory = $this->getMockMetadataFactory();
805+
$context = new ExecutionContext('Root', $graphWalker, $metadataFactory);
806+
$form = $this->getBuilder()
807+
->setAttribute('cascade_validation', true)
808+
->setAttribute('validation_groups', array('group1', 'group2'))
809+
->getForm();
810+
$form->add($this->getForm('firstName'));
811+
812+
$graphWalker->expects($this->at(0))
813+
->method('walkReference')
814+
->with($form->getChildren(), 'group1', 'children', true);
815+
$graphWalker->expects($this->at(1))
816+
->method('walkReference')
817+
->with($form->getChildren(), 'group2', 'children', true);
818+
819+
DelegatingValidator::validateFormChildren($form, $context);
820+
}
821+
822+
public function testValidateFormChildrenAppendsPropertyPath()
823+
{
824+
$graphWalker = $this->getMockGraphWalker();
825+
$metadataFactory = $this->getMockMetadataFactory();
826+
$context = new ExecutionContext('Root', $graphWalker, $metadataFactory);
827+
$context->setPropertyPath('path');
828+
$form = $this->getBuilder()
829+
->setAttribute('cascade_validation', true)
830+
->getForm();
831+
$form->add($this->getForm('firstName'));
832+
833+
$graphWalker->expects($this->once())
834+
->method('walkReference')
835+
->with($form->getChildren(), 'Default', 'path.children', true);
836+
837+
DelegatingValidator::validateFormChildren($form, $context);
838+
}
839+
840+
public function testValidateFormChildrenSetsCurrentPropertyToData()
841+
{
842+
$graphWalker = $this->getMockGraphWalker();
843+
$metadataFactory = $this->getMockMetadataFactory();
844+
$context = new ExecutionContext('Root', $graphWalker, $metadataFactory);
845+
$form = $this->getBuilder()
846+
->setAttribute('cascade_validation', true)
847+
->getForm();
848+
$form->add($this->getForm('firstName'));
849+
$test = $this;
850+
851+
$graphWalker->expects($this->once())
852+
->method('walkReference')
853+
->will($this->returnCallback(function () use ($context, $test) {
854+
$test->assertEquals('children', $context->getCurrentProperty());
855+
}));
856+
857+
DelegatingValidator::validateFormChildren($form, $context);
858+
}
859+
860+
public function testValidateFormChildrenDoesNothingIfDisabled()
861+
{
862+
$graphWalker = $this->getMockGraphWalker();
863+
$metadataFactory = $this->getMockMetadataFactory();
864+
$context = new ExecutionContext('Root', $graphWalker, $metadataFactory);
865+
$form = $this->getBuilder()
866+
->setAttribute('cascade_validation', false)
867+
->getForm();
868+
$form->add($this->getForm('firstName'));
869+
870+
$graphWalker->expects($this->never())
871+
->method('walkReference');
872+
873+
DelegatingValidator::validateFormChildren($form, $context);
874+
}
875+
801876
public function testValidateIgnoresNonRoot()
802877
{
803878
$form = $this->getMockForm();

0 commit comments

Comments
 (0)
0