bug #39333 [Form] do not apply the Valid constraint on scalar form data (lchrusciel, xabbuh)
This PR was merged into the 4.4 branch. Discussion ---------- [Form] do not apply the Valid constraint on scalar form data | Q | A | ------------- | --- | Branch? | 4.4 | Bug fix? | yes | New feature? | no | Deprecations? | no | Tickets | Fix #38039 | License | MIT | Doc PR | #SymfonyHackday Commits -------453bb3ebde
do not apply the Valid constraint on scalar form data41b9457887
[Test] Reproduce issue with cascading validation
This commit is contained in:
commit
21ef411cc9
@ -110,7 +110,9 @@ class FormValidator extends ConstraintValidator
|
|||||||
foreach ($constraints as $constraint) {
|
foreach ($constraints as $constraint) {
|
||||||
// For the "Valid" constraint, validate the data in all groups
|
// For the "Valid" constraint, validate the data in all groups
|
||||||
if ($constraint instanceof Valid) {
|
if ($constraint instanceof Valid) {
|
||||||
$validator->atPath('data')->validate($data, $constraint, $groups);
|
if (\is_object($data)) {
|
||||||
|
$validator->atPath('data')->validate($data, $constraint, $groups);
|
||||||
|
}
|
||||||
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
@ -17,6 +17,7 @@ use Symfony\Component\Form\CallbackTransformer;
|
|||||||
use Symfony\Component\Form\Exception\TransformationFailedException;
|
use Symfony\Component\Form\Exception\TransformationFailedException;
|
||||||
use Symfony\Component\Form\Extension\Core\Type\DateType;
|
use Symfony\Component\Form\Extension\Core\Type\DateType;
|
||||||
use Symfony\Component\Form\Extension\Core\Type\FormType;
|
use Symfony\Component\Form\Extension\Core\Type\FormType;
|
||||||
|
use Symfony\Component\Form\Extension\Core\Type\IntegerType;
|
||||||
use Symfony\Component\Form\Extension\Core\Type\TextType;
|
use Symfony\Component\Form\Extension\Core\Type\TextType;
|
||||||
use Symfony\Component\Form\Extension\Validator\ValidatorExtension;
|
use Symfony\Component\Form\Extension\Validator\ValidatorExtension;
|
||||||
use Symfony\Component\Form\FormBuilderInterface;
|
use Symfony\Component\Form\FormBuilderInterface;
|
||||||
@ -28,6 +29,7 @@ use Symfony\Component\Validator\Constraints\Expression;
|
|||||||
use Symfony\Component\Validator\Constraints\GroupSequence;
|
use Symfony\Component\Validator\Constraints\GroupSequence;
|
||||||
use Symfony\Component\Validator\Constraints\Length;
|
use Symfony\Component\Validator\Constraints\Length;
|
||||||
use Symfony\Component\Validator\Constraints\NotBlank;
|
use Symfony\Component\Validator\Constraints\NotBlank;
|
||||||
|
use Symfony\Component\Validator\Constraints\Valid;
|
||||||
use Symfony\Component\Validator\Mapping\ClassMetadata;
|
use Symfony\Component\Validator\Mapping\ClassMetadata;
|
||||||
use Symfony\Component\Validator\Mapping\Factory\LazyLoadingMetadataFactory;
|
use Symfony\Component\Validator\Mapping\Factory\LazyLoadingMetadataFactory;
|
||||||
use Symfony\Component\Validator\Mapping\Loader\StaticMethodLoader;
|
use Symfony\Component\Validator\Mapping\Loader\StaticMethodLoader;
|
||||||
@ -293,6 +295,39 @@ class FormValidatorFunctionalTest extends TestCase
|
|||||||
$this->assertSame('children[field2].data', $violations[1]->getPropertyPath());
|
$this->assertSame('children[field2].data', $violations[1]->getPropertyPath());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function testCascadeValidationToChildFormsWithTwoValidConstraints()
|
||||||
|
{
|
||||||
|
$form = $this->formFactory->create(ReviewType::class);
|
||||||
|
|
||||||
|
$form->submit([
|
||||||
|
'rating' => 1,
|
||||||
|
'title' => 'Sample Title',
|
||||||
|
]);
|
||||||
|
|
||||||
|
$violations = $this->validator->validate($form);
|
||||||
|
|
||||||
|
$this->assertCount(1, $violations);
|
||||||
|
$this->assertSame('This value should not be blank.', $violations[0]->getMessage());
|
||||||
|
$this->assertSame('children[author].data.email', $violations[0]->getPropertyPath());
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testCascadeValidationToChildFormsWithTwoValidConstraints2()
|
||||||
|
{
|
||||||
|
$form = $this->formFactory->create(ReviewType::class);
|
||||||
|
|
||||||
|
$form->submit([
|
||||||
|
'title' => 'Sample Title',
|
||||||
|
]);
|
||||||
|
|
||||||
|
$violations = $this->validator->validate($form);
|
||||||
|
|
||||||
|
$this->assertCount(2, $violations);
|
||||||
|
$this->assertSame('This value should not be blank.', $violations[0]->getMessage());
|
||||||
|
$this->assertSame('data.rating', $violations[0]->getPropertyPath());
|
||||||
|
$this->assertSame('This value should not be blank.', $violations[1]->getMessage());
|
||||||
|
$this->assertSame('children[author].data.email', $violations[1]->getPropertyPath());
|
||||||
|
}
|
||||||
|
|
||||||
public function testCascadeValidationToChildFormsUsingPropertyPathsValidatedInSequence()
|
public function testCascadeValidationToChildFormsUsingPropertyPathsValidatedInSequence()
|
||||||
{
|
{
|
||||||
$form = $this->formFactory->create(FormType::class, null, [
|
$form = $this->formFactory->create(FormType::class, null, [
|
||||||
@ -451,3 +486,62 @@ class FooType extends AbstractType
|
|||||||
$resolver->setDefault('data_class', Foo::class);
|
$resolver->setDefault('data_class', Foo::class);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class Review
|
||||||
|
{
|
||||||
|
public $rating;
|
||||||
|
public $title;
|
||||||
|
public $author;
|
||||||
|
|
||||||
|
public static function loadValidatorMetadata(ClassMetadata $metadata)
|
||||||
|
{
|
||||||
|
$metadata->addPropertyConstraint('title', new NotBlank());
|
||||||
|
$metadata->addPropertyConstraint('rating', new NotBlank());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class ReviewType extends AbstractType
|
||||||
|
{
|
||||||
|
public function buildForm(FormBuilderInterface $builder, array $options)
|
||||||
|
{
|
||||||
|
$builder
|
||||||
|
->add('rating', IntegerType::class, [
|
||||||
|
'constraints' => [new Valid()],
|
||||||
|
])
|
||||||
|
->add('title')
|
||||||
|
->add('author', CustomerType::class, [
|
||||||
|
'constraints' => [new Valid()],
|
||||||
|
])
|
||||||
|
;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function configureOptions(OptionsResolver $resolver)
|
||||||
|
{
|
||||||
|
$resolver->setDefault('data_class', Review::class);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class Customer
|
||||||
|
{
|
||||||
|
public $email;
|
||||||
|
|
||||||
|
public static function loadValidatorMetadata(ClassMetadata $metadata)
|
||||||
|
{
|
||||||
|
$metadata->addPropertyConstraint('email', new NotBlank());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class CustomerType extends AbstractType
|
||||||
|
{
|
||||||
|
public function buildForm(FormBuilderInterface $builder, array $options)
|
||||||
|
{
|
||||||
|
$builder
|
||||||
|
->add('email')
|
||||||
|
;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function configureOptions(OptionsResolver $resolver)
|
||||||
|
{
|
||||||
|
$resolver->setDefault('data_class', Customer::class);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Reference in New Issue
Block a user