如何在Symfony2中进行复杂的表单验证?

时间:2016-01-31 04:47:23

标签: php forms validation symfony

我在Symfony 2.7.x中有一个会计应用程序。

创建新交易时,交易总金额可以分为多个类别,但我需要验证类别金额的总和不大于交易总额。

ie- 交易:

收款人:埃克森

金额:$ 100.00

分类

名称:小吃

金额:$ 45.00

名称:汽油

金额:$ 55.00

每个类别也是数据库中的一个独立实体。

因此,如果用户将Gasoline更改为$ 65.00,则表单将无法通过验证。

我研究过Symfony 2表单验证,但我发现的所有内容似乎都围绕着一个对象的单个属性而不是多个实体的Constraint Annotations。

我假设我需要设置一个验证服务,但我正在努力设置它并在相应的表单上触发它。

2 个答案:

答案 0 :(得分:1)

您还可以使用Expression验证约束来节省几行代码。它可以像以下一样容易验证:

YML:

AppBundle\Entity\Transaction:
constraints:
    - Expression:
        expression: "this.getAmount() >= this.getCategorySum()"
        message: "Amount should be greater then or equal to the sum of amounts."

或者带注释:

/**
 * @Assert\Expression(
 *     "this.getAmount() >= this.getCategorySum()",
 *     message="Amount should be greater then or equal to the sum of amounts."
 * )
 */
 class Transaction{
   ...
   public function getCategorySum(){
   ...

其中Transaction对象的getCategorySum()方法将返回类别的金额总和。

答案 1 :(得分:0)

在您的情况下,是的,所有原始validators都不起作用。 你需要写一个custom callback。 来自symfony文档CallBack

  

回调

     

Callback约束的目的是创建完全自定义的验证规则并分配任何规则   验证对象上特定字段的错误。如果你正在使用   使用表单进行验证,这意味着您可以进行这些自定义   错误显示在特定字段旁边,而不是简单地显示在顶部   你的表格。

所以,在你的情况下,它将如下:

class Transaction
{
    //...
    private $amount;
    //...

    /**
     * @Assert\Callback
     */
    public function validate(ExecutionContextInterface $context)
    {
        // ...
        //Get your total category price here.
        $totalCategoryPrice = ...;
        if($this->amount<$totalCategoryPrice)
        {
            $context->buildViolation('Total amount can not be greater than the total amount of each category.')
            ->atPath('amount')
            ->addViolation();
        }

    }
}