Symfony中使用Doctrine依赖注入的验证器

3

我正在尝试验证注册表单中的“电子邮件”字段。我不想要重复的电子邮件。为此,我需要在自定义验证器中使用Doctrine。我知道我必须将此依赖项定义为DI容器中的服务。

阅读了一些文档后,我仍然无法做到。现在我有以下内容:

Validation.yml

...
  properties:
    email:
      - NotBlank: ~
      - Email:    ~
      - Cgboard\SignupBundle\Validator\Constraints\EmailDoesntExist: ~
...

config.yml

services:
  validator.unique.EmailDoesntExist:
    class: Cgboard\SignupBundle\Validator\Constraints\EmailDoesntExistValidator
    tags:
      - { name: validator.constraint_validator, alias: EmailDoesntExistValidator }

EmailDoesntExistValidator.php

...
public function validate($value, Constraint $constraint)
{
    $em     = $this->get('doctrine')->getEntityManager(); // save our entity in DB
    $result = $em->getRepository('CgboardSignupBundle:User')->userExist($value);

    if (empty($result)) {
        return true;
    }

    $this->context->addViolation($constraint->message, array());
    return false;
}
...

我遇到了困难,任何形式的帮助都会对我有所帮助(例如互联网上的示例或其他资料)……谢谢!

4个回答

4
尝试按照以下方式(在config.yml中)注入EntityManager
email_doesnt_exist_validator:
    class: Cgboard\SignupBundle\Validator\Constraints\EmailDoesntExistValidator
    arguments:
        - "@doctrine.orm.entity_manager"

然后你需要将它设置为类属性:
class EmailDoesntExistValidator {

   private $em;

   public function __construct(EntityManager $em) { // i guess it's EntityManager the type
       $this->em = $em;
   }

   // here you should be able to access the EntityManager
   public function validate($value, Constraint $constraint){
       $result = $this->em->getRepository('Cgboard\SignupBundle:User')->userExist($value);

       // ...
   }
}

我在这里编写了代码,希望它能正常运行,无论如何,这应该是正确的方法!

2
您可以在CookBook上看到一个真正的例子:http://symfony.com/doc/current/cookbook/validation/custom_constraint.html 您能展示一下您的约束类吗?因为您需要一个来使其工作。还有您的validator.yml,以确保您正确引用了约束类。
顺便说一下,在您的validate()函数中不需要返回任何内容,如果该值不addViolation,它将被认为是okay的。

2

我同意ponciste所写的内容。你的验证器不是一个默认的服务,就像你所写的那样。你按照ponciste所写的定义它为一个服务,但请不要将其放在config.yml中。相反,将其放在服务目录下的services.yml文件中,其中包含你的验证器类。你可以通过这种方式注入EntityManager,或者其他已经注入了EntityManager的服务。

另一种方式,我认为更简单的方法是在validation.yml中进行如下设置:

Project\Bundle\UserBundle\Entity\User:     constraints:       - Symfony\Bridge\Doctrine\Validator\Constraints\UniqueEntity:           fields:[email]           message:'person.email.already_used'

...

如果你有任何问题或困难,请留言;)


2

您应该使用Symfony提供的UniqueEntity约束(http://symfony.com/doc/current/reference/constraints/UniqueEntity.html)。

...
    constraints:
        - Symfony\Bridge\Doctrine\Validator\Constraints\UniqueEntity: email
    properties:
        email:
            - NotBlank: ~
            - Email: ~

如果您需要更具体的约束条件,请像您所做的那样使用声明为服务的验证器,并将Doctrine实体管理器注入其中。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接