properly cascade validation to child forms
This commit is contained in:
parent
3519647496
commit
7df5298ddf
|
@ -72,7 +72,6 @@ class FormValidator extends ConstraintValidator
|
|||
if ($groups instanceof GroupSequence) {
|
||||
// Validate the data, the form AND nested fields in sequence
|
||||
$violationsCount = $this->context->getViolations()->count();
|
||||
$fieldPropertyPath = \is_object($data) ? 'children[%s]' : 'children%s';
|
||||
|
||||
foreach ($groups->groups as $group) {
|
||||
if ($validateDataGraph) {
|
||||
|
@ -91,7 +90,7 @@ class FormValidator extends ConstraintValidator
|
|||
// in different steps without breaking early enough
|
||||
$this->resolvedGroups[$field] = (array) $group;
|
||||
$fieldFormConstraint = new Form();
|
||||
$validator->atPath(sprintf($fieldPropertyPath, $field->getPropertyPath()))->validate($field, $fieldFormConstraint);
|
||||
$validator->atPath(sprintf('children[%s]', $field->getName()))->validate($field, $fieldFormConstraint);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -100,8 +99,6 @@ class FormValidator extends ConstraintValidator
|
|||
}
|
||||
}
|
||||
} else {
|
||||
$fieldPropertyPath = \is_object($data) ? 'children[%s]' : 'children%s';
|
||||
|
||||
if ($validateDataGraph) {
|
||||
$validator->atPath('data')->validate($data, null, $groups);
|
||||
}
|
||||
|
@ -132,7 +129,7 @@ class FormValidator extends ConstraintValidator
|
|||
if ($field->isSubmitted()) {
|
||||
$this->resolvedGroups[$field] = $groups;
|
||||
$fieldFormConstraint = new Form();
|
||||
$validator->atPath(sprintf($fieldPropertyPath, $field->getPropertyPath()))->validate($field, $fieldFormConstraint);
|
||||
$validator->atPath(sprintf('children[%s]', $field->getName()))->validate($field, $fieldFormConstraint);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -18,6 +18,7 @@ use Symfony\Component\Form\Exception\TransformationFailedException;
|
|||
use Symfony\Component\Form\Extension\Core\DataMapper\PropertyPathMapper;
|
||||
use Symfony\Component\Form\Extension\Validator\Constraints\Form;
|
||||
use Symfony\Component\Form\Extension\Validator\Constraints\FormValidator;
|
||||
use Symfony\Component\Form\Extension\Validator\ValidatorExtension;
|
||||
use Symfony\Component\Form\FormBuilder;
|
||||
use Symfony\Component\Form\FormFactoryBuilder;
|
||||
use Symfony\Component\Form\FormFactoryInterface;
|
||||
|
@ -51,7 +52,9 @@ class FormValidatorTest extends ConstraintValidatorTestCase
|
|||
protected function setUp()
|
||||
{
|
||||
$this->dispatcher = new EventDispatcher();
|
||||
$this->factory = (new FormFactoryBuilder())->getFormFactory();
|
||||
$this->factory = (new FormFactoryBuilder())
|
||||
->addExtension(new ValidatorExtension(Validation::createValidator()))
|
||||
->getFormFactory();
|
||||
|
||||
parent::setUp();
|
||||
|
||||
|
@ -791,6 +794,61 @@ class FormValidatorTest extends ConstraintValidatorTestCase
|
|||
$this->assertSame('data[field1]', $context->getViolations()[0]->getPropertyPath());
|
||||
}
|
||||
|
||||
public function testCascadeValidationToChildFormsUsingPropertyPaths()
|
||||
{
|
||||
$form = $this->getCompoundForm([], [
|
||||
'validation_groups' => ['group1', 'group2'],
|
||||
])
|
||||
->add('field1', null, [
|
||||
'constraints' => [new NotBlank(['groups' => 'group1'])],
|
||||
'property_path' => '[foo]',
|
||||
])
|
||||
->add('field2', null, [
|
||||
'constraints' => [new NotBlank(['groups' => 'group2'])],
|
||||
'property_path' => '[bar]',
|
||||
])
|
||||
;
|
||||
|
||||
$form->submit([
|
||||
'field1' => '',
|
||||
'field2' => '',
|
||||
]);
|
||||
|
||||
$context = new ExecutionContext(Validation::createValidator(), $form, new IdentityTranslator());
|
||||
$this->validator->initialize($context);
|
||||
$this->validator->validate($form, new Form());
|
||||
|
||||
$this->assertCount(2, $context->getViolations());
|
||||
$this->assertSame('This value should not be blank.', $context->getViolations()[0]->getMessage());
|
||||
$this->assertSame('children[field1].data', $context->getViolations()[0]->getPropertyPath());
|
||||
$this->assertSame('This value should not be blank.', $context->getViolations()[1]->getMessage());
|
||||
$this->assertSame('children[field2].data', $context->getViolations()[1]->getPropertyPath());
|
||||
}
|
||||
|
||||
public function testCascadeValidationToChildFormsUsingPropertyPathsValidatedInSequence()
|
||||
{
|
||||
$form = $this->getCompoundForm([], [
|
||||
'validation_groups' => new GroupSequence(['group1', 'group2']),
|
||||
])
|
||||
->add('field1', null, [
|
||||
'constraints' => [new NotBlank(['groups' => 'group1'])],
|
||||
'property_path' => '[foo]',
|
||||
])
|
||||
;
|
||||
|
||||
$form->submit([
|
||||
'field1' => '',
|
||||
]);
|
||||
|
||||
$context = new ExecutionContext(Validation::createValidator(), $form, new IdentityTranslator());
|
||||
$this->validator->initialize($context);
|
||||
$this->validator->validate($form, new Form());
|
||||
|
||||
$this->assertCount(1, $context->getViolations());
|
||||
$this->assertSame('This value should not be blank.', $context->getViolations()[0]->getMessage());
|
||||
$this->assertSame('children[field1].data', $context->getViolations()[0]->getPropertyPath());
|
||||
}
|
||||
|
||||
protected function createValidator()
|
||||
{
|
||||
return new FormValidator();
|
||||
|
|
Reference in New Issue