首页 文章

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

提问于
浏览
0

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

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

ie- Transaction:

收款人:埃克森

金额:100.00美元

Categories:


名称:小吃

金额:45.00美元


名称:汽油

金额:55.00美元

每个类别也是数据库中的单独实体 .

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

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

我假设我需要设置一个验证服务,但我正在努力设置它并让它在适当的表单上触发 .

2 回答

  • 0

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

    阳明:

    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

    在你的情况下,是的,所有原始 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();
            }
    
        }
    }
    

相关问题