3

I'm trying to validate a field "email" in a signup form. I don't want duplicate emails. For this I need to use Doctrine inside my custom validator. I know I have to define this dependency as a service in the DI container.

After reading some doc I couldn't yet. I have this now:

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;
}
...

I'm stuck, anything would help me (example in internet or whatever)...thanks!

0

4 Answers 4

4

Try to inject the EntityManager this way (in config.yml):

email_doesnt_exist_validator:
    class: Cgboard\SignupBundle\Validator\Constraints\EmailDoesntExistValidator
    arguments:
        - "@doctrine.orm.entity_manager"

Then you have to set it as class attribute:

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);

       // ...
   }
}

I wrote the code right here, I hope it works, anyway this should be the right approach!

Sign up to request clarification or add additional context in comments.

Comments

2

You can see a realy great example on the CookBook : http://symfony.com/doc/current/cookbook/validation/custom_constraint.html

Can you show us your constraint class? Because you need one to make it work. And your validator.yml, to be sure you are correctly referencing your constraint class.

By the way you dont need to return something in your function validate(), if the value dont addViolation, it will be considered ok.

Comments

2

I agree with what ponciste wrote. Your validator is not a service by default, as you write it. You define it as a service, the way ponciste wrote, but please do not put that in config.yml. Instead put it in services.yml inside a bundle, where your validator class lives. You can inject EntityManager that way, or and other service which already has Entity Manager injected.

Another way and I believe a more simple way would be to this inside validation.yml:

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

...

If you have any question or problem, just comment;)

Comments

2

You should use the UniqueEntity constraint (http://symfony.com/doc/current/reference/constraints/UniqueEntity.html) provided with Symfony.

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

Would you need a more specific constraint, use a validator declared as a service as you did, and inject the Doctrine entity manager into it.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.