Reputation: 1711
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!
Upvotes: 3
Views: 6726
Reputation: 6238
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.
Upvotes: 2
Reputation: 2167
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;)
Upvotes: 2
Reputation: 2229
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!
Upvotes: 4
Reputation: 125
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.
Upvotes: 2