自定义约束验证有时显示在近场有时不会Symfony2

时间:2016-05-25 08:44:32

标签: validation symfony constraints symfony2-easyadmin

我在Symfony 2中构建了一个自定义约束验证,它调用了Doctrine:

if($prevu != 0) {
        $total = $prevu + $consomme;
        if($total > $charge) {
            $this->context->buildViolation($constraint->message1)
                 ->setParameter('%string%', $prevu)
                 ->atPath('intervention.dureeP')
                 ->addViolation();
        }
        dump($this);    
    }elseif($realise != 0) {
        $total = $realise + $consomme;
        if($total > $charge) {
            $this->context->buildViolation($constraint->message2)
                 ->setParameter('%string%', $realise)
                 ->atPath('dureeR')
                 ->addViolation();
        }
    }

我的问题是错误不会显示在字段旁边,而是显示在表单的顶部。

我用这样的注释调用我的自定义验证器:

/**
 * @var string
 *
 * @ORM\Column(name="duree_p", type="decimal", precision=3, scale=2, nullable=true)
 * @MyAssert\ExceedCharge
 */
private $dureeP;

奇怪的是,形成一些字段,它会在旁边显示错误,但对于其他字段,它会在顶部显示错误。

我在StackOverflow上看过这篇文章:Custom constraint validation error doesn't display next to field in Symfony2但它对我没有帮助。

我尝试了选项“atPath()”但没有成功。

我不明白的是,它适用于某些领域而不适合我想要的领域......

有人有任何线索吗?

编辑:

我还注意到,当违规消息发生时,与违规消息相关的字段没有任何“has-error”类,因此没有“。

编辑2:

这是我的约束逻辑:

    class ExceedChargeValidator extends ConstraintValidator
{

    protected $em;

    public function __construct(EntityManager $em)
    {
        $this->em = $em;
    }

    public function validate($value, Constraint $constraint)
    {
        dump($value); //DEBUG
        dump($this->context); //DEBUG

        //get id to perform search
        $id = $this->context->getObject()->getCast()->getId();


        $consomme = $this->em->getRepository('AppBundle:Intervention')->getConsomme($id);

        $charge = $this->context->getObject()->getCast()->getCharge();

        $prevu = $this->context->getObject()->getDureeP();
        $realise = $this->context->getObject()->getDureeR();

        dump($prevu); //DEBUG
        dump($realise); //DEBUG

        if($value != 0) {
          $total = $value + $consomme;
          if($total > $charge) {
            $this->context->buildViolation($constraint->message1)
                 ->setParameter('%string%', $value)
                 ->addViolation();
            dump($this->context->getPropertyPath());
        }
        dump($this); //DEBUG    
    }

        dump($consomme);//DEBUG
        dump($charge); //DEBUG
    }
}

以下是我的实体的一些诅咒:

    /**
 * @var \DateTime
 *
 * @ORM\Column(name="date", type="date")
 */
private $date;

/**
 * @var string
 *
 * @ORM\Column(name="duree_p", type="decimal", precision=3, scale=2, nullable=true)
 * @MyAssert\ExceedCharge
 */
private $dureeP;

/**
 * @var string
 *
 * @ORM\Column(name="duree_r", type="decimal", precision=3, scale=2, nullable=true)
 * @Assert\GreaterThan(
 *      value = 0
 *)
 */
private $dureeR;

表单由Easy Admin软件包生成

Here is what I got if I attach the same constraint violation to different fields. We can see that it works fine on my "date" field but for the "dureeP" field the message is displayed at the top

如果我将相同的约束违规附加到不同的字段,这是我得到的。我们可以看到它在我的“日期”字段中正常工作,但对于“dureeP”字段,消息显示在顶部

2 个答案:

答案 0 :(得分:0)

你的atPath似乎没用,因为你的Constraint是一个应用于字符串的PropertyConstraint,而字符串没有子节点。

但是,当属性约束引发违规时,违规将附加到具有属性名称(如果存在)的字段。因此,如果您的表单中包含dureeP字段,则会将错误附加到该字段,否则它将位于表单的根目录。

答案 1 :(得分:0)

好的,我发现了问题!

问题出在我的专栏名称上,包括" _" (下划线)。

我替换了

@ORM\Column(name="duree_p", type="decimal", precision=3, scale=2)

通过

@ORM\Column(name="prevu", type="decimal", precision=3, scale=2)

它解决了这个问题。因此,名称中没有下划线,我们已经完成了!

我是怎么找到的? 通过创建虚拟(基本)验证器测试并将其附加到我的另一个实体的某些字段。我看到它正在所有领域工作,所以我比较了两个实体之间的差异,这是唯一的区别。

以下是我用于排除故障的验证程序:

class TestValidator extends ConstraintValidator
{

    protected $em;

    public function __construct(EntityManager $em)
    {
        $this->em = $em;
    }

    public function validate($value, Constraint $constraint)
    {

        dump($value);

        if(!preg_match('/^[0-9]+$/', $value, $matches)) {
            $this->context->buildViolation($constraint->message)
                ->setParameter('%string%', $value)
                ->addViolation();
        }

    }
}