symfonydoctrine-ormvalidationentitymanagersymfony-2.5

Doctrine EntityManager not injected into Custom Validator


I have created a custom validator to check if an email is not present across 2 database tables.

namespace AgriHealth\AhpBundle\Validator\Constraints;

use Symfony\Component\Validator\Constraint;

/**
 * @Annotation
 */
class UniqueEmailAll extends Constraint
{
    public $message = 'This email is already in use';

    public function validatedBy()
    {
        return get_class($this).'Validator';
    }
} 

namespace AgriHealth\AhpBundle\Validator\Constraints;

use Symfony\Component\Validator\Constraint;
use Symfony\Component\Validator\ConstraintValidator;

class UniqueEmailAllValidator extends ConstraintValidator
{
    private $entityManager;

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


    public function validate($value, Constraint $constraint)
    {
        $find1 = $this->entityManager->getRepository( 'AgriHealthAhpBundle:Vet')->findOneByEmail($value);
        $find2 = $this->entityManager->getRepository( 'AgriHealthAhpBundle:Farmer')->findOneByEmail($value);

        if ($find1 || $find2) {
            // If you're using the new 2.5 validation API (you probably are!)
            $this->context->buildViolation($constraint->message)
                ->addViolation();
        }
    }
}

I'm trying to inject the Doctrine Entity Manager into the validator like so:

services:
    validator.unique.UniqueEmailAll:
        class:  AgriHealth\AhpBundle\Validator\Constraints\UniqueEmailAllValidator
        arguments:
            entityManager: "@doctrine.orm.entity_manager"
        tags:
            - { name: validator.constraint_validator, alias: UniqueEmailAllValidator }

But this doesn't seem to work:

Catchable Fatal Error: Argument 1 passed to AgriHealth\AhpBundle\Validator\Constraints\UniqueEmailAllValidator::__construct() must be an instance of AgriHealth\AhpBundle\Validator\Constraints\EntityManager, none given, called in /home/jochen/projects/ahp/trunk/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Validator/ConstraintValidatorFactory.php on line 71 and defined in /home/jochen/projects/ahp/trunk/src/AgriHealth/AhpBundle/Validator/Constraints/UniqueEmailAllValidator.php line 18

What am I missing? In config.yml I'm not sure what the service is supposed to be called. The Cookbook says to prefix validator.unique but I don't understand what the unique refers to?


Solution

  • First of all in UniqueEmailAllValidator you should declare the use of EntityManager

    namespace AgriHealth\AhpBundle\Validator\Constraints;
    
    use Doctrine\ORM\EntityManager;
    use Symfony\Component\Validator\ConstraintValidator;
    use Symfony\Component\Validator\Constraint;
    
    class UniqueEmailAllValidator extends ConstraintValidator
    {
     ...
    }
    

    Secondly in UniqueEmailAll define the validatedBy function like this

    class UniqueEmailAll extends Constraint
    {
        public $message = 'This email is already in use';
    
        public function validatedBy()
        {
            return 'unique.email.all.validator';
        }
    } 
    

    And in services.yml file do this

    services:
        validator.unique.UniqueEmailAll:
            class:  AgriHealth\AhpBundle\Validator\Constraints\UniqueEmailAllValidator
            arguments:
                entityManager: "@doctrine.orm.entity_manager"
            tags:
                - { name: validator.constraint_validator, alias: unique.email.all.validator }
    

    This will solve your problem. I don't know what is wrong with the second part that cause this issue. Maybe it is related to the uppercase characters.