Symfony中具有Doctrine依赖注入的Validator

时间:2014-05-05 13:42:53

标签: symfony

我正在尝试以注册形式验证字段“email”。我不想要重复的电子邮件。为此,我需要在我的自定义验证器中使用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 个答案:

答案 0 :(得分:2)

你可以在CookBook上看到一个很好的例子:http://symfony.com/doc/current/cookbook/validation/custom_constraint.html

你能告诉我们你的约束类吗?因为你需要一个让它工作。 还有你的validator.yml,以确保你正确引用你的约束类。

顺便说一下,你不需要在函数validate()中返回一些东西,如果值不是addViolation,那么它将被认为是正确的。

答案 1 :(得分:2)

尝试以这种方式注入EntityManager(在config.yml中):

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 :(得分:2)

我同意ponciste所写的内容。在您编写时,您的验证器默认不是服务。你将它定义为一种服务,就像ponciste写的那样,但请不要把它放在config.yml中。而是将它放在一个bundle中的services.yml中,你的验证器类就在那里。您可以通过这种方式注入EntityManager,或者已经注入了Entity Manager的其他服务。

另一种方式,我相信一个更简单的方法是在validation.yml内部:

项目\捆绑\ UserBundle \实体\用户:     限制:        - Symfony \ Bridge \ Doctrine \ Validator \ Constraints \ UniqueEntity:           字段:[email]           消息:' person.email.already_used'

...

如果您有任何疑问或问题,请发表评论;)

答案 3 :(得分: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实体管理器注入其中。