Symfony Form Validation Constraint Expression

孤者浪人 提交于 2019-12-21 06:07:32

问题


I have form, and need to create inline validation:

$builder
        ->add('Count1', 'integer', [
            'data'        => 1,
            'constraints' => [
                new NotBlank(),
                new NotNull(),
            ],
        ])
        ->add('Count2', 'integer', [
            'constraints' => [
                new NotBlank(),
                new NotNull(),
            ],
        ])
        ->add('Count3', 'integer', [
            'data'        => 0,
            'constraints' => [
                new NotBlank(),
                new NotNull(),
            ],
        ])

How white inline validation Expression for rules

  1. Count2 >=Count1
  2. Count3 <=Count2
  3. Count2 >= $someVariable

回答1:


Other solution by using Expression Constraint for cases 1 and 2.

use Symfony\Component\Validator\Constraints as Assert;

// ...

public function configureOptions(OptionsResolver $resolver)
{
    $resolver->setDefaults([
        'constraints' => [
            new Assert\Expression([
                'expression' => 'value["Count2"] >= value["Count1"]',
                'message' => 'count2 must be greater than or equal to count1'
            ]),
            new Assert\Expression([
                'expression' => 'value["Count3"] <= value["Count2"]',
                'message' => 'count3 must be less than or equal to count2'
            ]),
        ],
    ]);
}

For case 3 you can use Assert\GreaterThanOrEqual constraint directly on Count2 field.

I guess your form doesn't have a binding object model, otherwise to read the documentation referred is enough and better because you could use these expression on your properties directly.




回答2:


You can utilize CallbackValidator (docs):

In your case, in order to validate one field againt another, you need to add constraint to a form type, not the field:

public function setDefaultOptions(OptionsResolverInterface $resolver)
{
    $resolver->setDefaults(array(
        'constraints' => array(
            new Assert\Callback(function($data){
                // $data is instance of object (or array) with all properties
                // you can compare Count1, Count2 and Count 3 
                // and raise validation errors
            });
        )
    ));
}

You can also pass constraints option while creating a form if you don't want to set it in setDefaultOptions.




回答3:


Starting from easiest

3) Count2 >= $someVariable

    ->add('Count3', 'integer', [
        'data'        => 0,
        'constraints' => [
            new NotBlank(),
            new NotNull(),
            new GreaterThanOrEqual($someVariable),
        ],
    ])

1) As for two first, you must implement constraint for a class scope, rather than property scope. And assign these constraints for a whole form

public function buildForm(FormBuilderInterface $builder, array $options)
{
   $builder
    ->add('Count1', 'integer', [
        'data'        => 1,
        'constraints' => [
            new NotBlank(),
            new NotNull(),
        ],
    ])
    ->add('Count2', 'integer', [
        'constraints' => [
            new NotBlank(),
            new NotNull(),
        ],
    ])
    ->add('Count3', 'integer', [
        'data'        => 0,
        'constraints' => [
            new NotBlank(),
            new NotNull(),
        ],
    ])
}

public function setDefaultOptions(OptionsResolverInterface $resolver)
{
     $resolver->setDefaults(['constraints' => [
            new YourCustomConstraint(),
          ]]);
}

How to implement validator, see in the documentation. But in your YourCustomConstraintValidator you will have something like

public function validate($value, Constraint $constraint)
{
     if ($value->getCount1() > $value->getCount2() {
           $this->context->addViolation(...);
     }
}


来源:https://stackoverflow.com/questions/40287266/symfony-form-validation-constraint-expression

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!