Dheeraj Dheeraj - 11 months ago 66
PHP Question

Symfony2 how to validate unique email using validator component

Im creating an application that creates users from a CSV file, so there is no Forms. i'm using the symfony validator component to validate the data inside the controller. so far ive created a helper function that takes in the data and the constraints and returns out the error if any. here is what i mean.

The helper function

public function csverror($value, $constraint, $rowcount, $columnname){
$error = $this->container->get('validator')->validate($value, $constraint);
if(count($error) !== 0){
$this->get('session')->getFlashBag()->add('csverror', "error on line: $rowcount column: $columnname ". $error[0]->getMessage());

and calling it inside the controller action

$this->csverror($associativerow['email'], array(new NotBlank(), new Length(['max' => 100]), new Email()), $rowcount, "email");

Here i need to check if the email specified in the CSV already exists in the database, for this im assuming that UniqueEntity has to be used. It has an associated class called UniqueEntityValidator. The amazing thing is that the Validator Component has a feature that automatically checks the locale and displays the error messages in that language!! (i'm guessing its through the ConstraintViolation object). I would like to utilize this feature instead of the bland
to query the database and check if the email already exists and returning with an error message using (comparatively) messy xliff files.

so! the question is how to validate for unique email in the database using the validator component's validator service

edit: in the above code
is a string, but in practice i can have it as a
object if necessary, you can have the liberty to assume its an entity object if needed!

Answer Source

Afraid this is not possible using UniqueEntity and its UniqueEntityValidator, because this last require an entity object as value to validate. Otherwise, will throw an exception:

"get_class() expects parameter 1 to be object, string given"

You would be forced to find the entity instance for this email before and then pass this to $this->csverror(...) method:

$object = $this->getDoctrine()->getRepository('AppBundle:User')->findOneBy(['email' => $associativerow['email']]);
$this->csverror($object, new UniqueEntity(...));


If you have the user instance then don't you need settings the constraints to validate it in you csverror function. Configure the assert constraints inside you entity User class:

use Symfony\Component\Validator\Constraints as Assert;

 * ...
 * @UniqueEntity(fields={"email"}
class User 

     * @var string
     * @Assert\NotBlank()
     * @Assert\Length(max="100")
     * @ORM\Column(type="string")
    private $email;



public function csverror($object, $rowcount){
    $error = $this->container->get('validator')->validate($object);
    // ...


$user = new User();
// ...

$this->csverror($user, $rowcount);

Now, the UniqueEntity constraint validate unique user by email field.