[Form] Made validation of form children configurable. Set the option "cascade_validation" to true if you need it.

This commit is contained in:
Bernhard Schussek 2012-01-16 20:44:37 +01:00
parent efada56312
commit 0c70a410e5
4 changed files with 104 additions and 3 deletions

View File

@ -38,6 +38,7 @@ class FieldTypeValidatorExtension extends AbstractTypeExtension
$builder
->setAttribute('validation_groups', $options['validation_groups'])
->setAttribute('validation_constraint', $options['validation_constraint'])
->setAttribute('cascade_validation', $options['cascade_validation'])
->addValidator(new DelegatingValidator($this->validator));
}
@ -46,6 +47,7 @@ class FieldTypeValidatorExtension extends AbstractTypeExtension
return array(
'validation_groups' => null,
'validation_constraint' => null,
'cascade_validation' => false,
);
}

View File

@ -127,6 +127,29 @@ class DelegatingValidator implements FormValidatorInterface
}
}
static public function validateFormChildren(FormInterface $form, ExecutionContext $context)
{
if ($form->getAttribute('cascade_validation')) {
$propertyPath = $context->getPropertyPath();
$graphWalker = $context->getGraphWalker();
// The Execute constraint is called on class level, so we need to
// set the property manually
$context->setCurrentProperty('children');
// Adjust the property path accordingly
if (!empty($propertyPath)) {
$propertyPath .= '.';
}
$propertyPath .= 'children';
foreach (self::getFormValidationGroups($form) as $group) {
$graphWalker->walkReference($form->getChildren(), $group, $propertyPath, true);
}
}
}
static protected function getFormValidationGroups(FormInterface $form)
{
$groups = null;

View File

@ -10,9 +10,10 @@
<value>Symfony\Component\Form\Extension\Validator\Validator\DelegatingValidator</value>
<value>validateFormData</value>
</value>
<value>
<value>Symfony\Component\Form\Extension\Validator\Validator\DelegatingValidator</value>
<value>validateFormChildren</value>
</value>
</constraint>
<property name="children">
<constraint name="Valid" />
</property>
</class>
</constraint-mapping>

View File

@ -798,6 +798,81 @@ class DelegatingValidatorTest extends \PHPUnit_Framework_TestCase
DelegatingValidator::validateFormData($form, $context);
}
public function testValidateFormChildren()
{
$graphWalker = $this->getMockGraphWalker();
$metadataFactory = $this->getMockMetadataFactory();
$context = new ExecutionContext('Root', $graphWalker, $metadataFactory);
$form = $this->getBuilder()
->setAttribute('cascade_validation', true)
->setAttribute('validation_groups', array('group1', 'group2'))
->getForm();
$form->add($this->getForm('firstName'));
$graphWalker->expects($this->at(0))
->method('walkReference')
->with($form->getChildren(), 'group1', 'children', true);
$graphWalker->expects($this->at(1))
->method('walkReference')
->with($form->getChildren(), 'group2', 'children', true);
DelegatingValidator::validateFormChildren($form, $context);
}
public function testValidateFormChildrenAppendsPropertyPath()
{
$graphWalker = $this->getMockGraphWalker();
$metadataFactory = $this->getMockMetadataFactory();
$context = new ExecutionContext('Root', $graphWalker, $metadataFactory);
$context->setPropertyPath('path');
$form = $this->getBuilder()
->setAttribute('cascade_validation', true)
->getForm();
$form->add($this->getForm('firstName'));
$graphWalker->expects($this->once())
->method('walkReference')
->with($form->getChildren(), 'Default', 'path.children', true);
DelegatingValidator::validateFormChildren($form, $context);
}
public function testValidateFormChildrenSetsCurrentPropertyToData()
{
$graphWalker = $this->getMockGraphWalker();
$metadataFactory = $this->getMockMetadataFactory();
$context = new ExecutionContext('Root', $graphWalker, $metadataFactory);
$form = $this->getBuilder()
->setAttribute('cascade_validation', true)
->getForm();
$form->add($this->getForm('firstName'));
$test = $this;
$graphWalker->expects($this->once())
->method('walkReference')
->will($this->returnCallback(function () use ($context, $test) {
$test->assertEquals('children', $context->getCurrentProperty());
}));
DelegatingValidator::validateFormChildren($form, $context);
}
public function testValidateFormChildrenDoesNothingIfDisabled()
{
$graphWalker = $this->getMockGraphWalker();
$metadataFactory = $this->getMockMetadataFactory();
$context = new ExecutionContext('Root', $graphWalker, $metadataFactory);
$form = $this->getBuilder()
->setAttribute('cascade_validation', false)
->getForm();
$form->add($this->getForm('firstName'));
$graphWalker->expects($this->never())
->method('walkReference');
DelegatingValidator::validateFormChildren($form, $context);
}
public function testValidateIgnoresNonRoot()
{
$form = $this->getMockForm();