0

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?

jdog
  • 2,465
  • 6
  • 40
  • 74

1 Answers1

5

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.

Saman
  • 5,044
  • 3
  • 28
  • 27