手动调用嵌入式表单集合条目的验证

时间:2017-02-13 09:49:55

标签: forms validation symfony symfony-forms

在我的Symfony项目中,我有一个权限Booking,其中包含另一个实体Traveler的集合。最少1人,最多4人。旅行者的数量可以由travelerCount实体的字段Booking指定。

class Booking {
    /** @Assert\Range(min = 1, max = 4) */
    private $travelerCount;

    private $travelers = array();

    // ...
}

我的预订表单控制器总是会向实体添加4位旅行者。我的表单BookingType包含TravelerType表单的嵌入式表单集(CollectionType)。视图中的JavaScript会根据travelerCount的值显示或隐藏旅行者。

通常我会使用@Assert\Valid来验证旅行者收藏。但这不会在这里工作,因为我只想验证集合的第一个 travelerCount (1-4)条目。例如,如果用户指定travelerCount为2,则无法验证Traveler s 3和4.否则,Traveler中的@Assert\NotBlank注释会出现验证错误}。

class Traveler {
    /** @Assert\NotBlank */
    private $firstName;

    // ...
}

所以我的想法是不使用@Assert\Valid。但是,如何从控制器手动调用嵌入式表单集合条目的验证?我想到了这样的事情:

for ($i = 0; $i < $booking->getTravelerCount(); ++$i) {
    $this->get('validator')->startContext()
        ->atPath('booking.travelers['. $i .']')
        ->validate($booking->getTravelers()[$i]);
}

但是我不知道这是否会使错误出现在视图中,也不知道哪个参数值传递给atPath()(我猜错了,但我确定我错了)

1 个答案:

答案 0 :(得分:0)

在我的问题的评论中,LBA建议使用自定义验证器,我告诉他我有同样的问题:我不知道如何调用Traveler验证约束注释的验证。好吧,我发现了如何:

class BookingValidator extends Symfony\Component\Validator\ConstraintValidator
{
    public function validate($booking, Symfony\Component\Validator\Constraint $constraint)
    {
        for ($i = 0; $i < $booking->getTravelerCount(); ++$i) {
            $this->context->getValidator()->inContext($this->context)
                ->atPath('travelers['. $i .']')
                ->validate($booking->getTravelers()[$i])
                ;
        }
    }
}

正如您所看到的,代码与我的问题中的代码类似。但是,我没有找到在控制器中执行此操作的方法。但同时我认为在一个单独的课程中进行验证是更好的风格,无论如何。