Symfony表单验证约束表达式

时间:2016-10-27 14:28:22

标签: validation symfony symfony-forms symfony-validator

我有表格,需要创建内联验证:

$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(),
            ],
        ])

白色内联验证如何表达规则

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

4 个答案:

答案 0 :(得分:5)

对案例1和案例2使用Expression Constraint的其他解决方案。

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'
            ]),
        ],
    ]);
}

对于案例3,您可以直接在Assert\GreaterThanOrEqual字段上使用Count2约束。

  

我猜你的表单没有绑定对象模型,否则读取the documentation引用就足够了,因为你可以直接在属性上使用这些表达式。

答案 1 :(得分:4)

您可以使用CallbackValidatordocs):

在您的情况下,为了再次验证一个字段,您需要将约束添加到表单类型,而不是字段:

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
            });
        )
    ));
}

如果您不想在constraints中设置表单,也可以在创建表单时传递setDefaultOptions选项。

答案 2 :(得分:3)

从最简单的

开始

3)Count2&gt; = $ someVariable

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

1)首先,必须对类范围实现约束,而不是属性范围。并为整个表单分配这些约束

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(),
          ]]);
}

如何实现验证器,请参阅the documentation。 但是在你的YourCustomConstraintValidator中,你会有类似

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

答案 3 :(得分:0)

使用Symfony的表达式比较两个日期时,我遇到了一些问题。

这是有效的代码:

i = 0
for line in file_content:
    if line.strip() == "#TypeA":
        file_content.insert(i+1, "var_0 = ('some code...')\n")
        break
    i += 1