Ok, I decided to create my own Constraint because I can reuse it for email for example. So, this is my implementation :
UniqueEntry.php:
<?php
/**
* Ensure a value is unique in the database
*
* @author Thomas KELLER
*/
use Symfony\Component\Validator\Constraint;
use Symfony\Component\Validator\Exception\MissingOptionsException;
use Symfony\Component\Validator\Exception\InvalidArgumentException;
/**
* @Annotation
*/
class UniqueEntry extends Constraint {
public $notUniqueMessage = 'This value already exist in the database';
public $dbal_connection;
public $table;
public $field;
public function __construct($options = null)
{
parent::__construct($options);
if ($this->dbal_connection === null)
throw new MissingOptionsException(sprintf('The option "dbal_connection" is mandatory for constraint %s', __CLASS__), array('dbal_connection'));
if (!$this->dbal_connection instanceof \Doctrine\DBAL\Connection)
throw new InvalidArgumentException(sprintf('The option "dbal_connection" must be an instance of Doctrine\DBAL\Connection for constraint %s', __CLASS__));
if ($this->table === null)
throw new MissingOptionsException(sprintf('The option "table" is mandatory for constraint %s', __CLASS__), array('table'));
if (!is_string($this->table) OR $this->table == '')
throw new InvalidArgumentException(sprintf('The option "table" must be a valid string for constraint %s', __CLASS__));
if ($this->field === null)
throw new MissingOptionsException(sprintf('The option "field" is mandatory for constraint %s', __CLASS__), array('field'));
if (!is_string($this->field) OR $this->field == '')
throw new InvalidArgumentException(sprintf('The option "field" must be a valid string for constraint %s', __CLASS__));
}
}
UniqueEntryValidator.php:
<?php
use Symfony\Component\Validator\Constraint;
use Symfony\Component\Validator\ConstraintValidator;
class UniqueEntryValidator extends ConstraintValidator
{
public function validate($value, Constraint $constraint)
{
$query = sprintf('SELECT `%s` FROM `%s` WHERE `%s` = ?',
$constraint->field,
$constraint->table,
$constraint->field);
$stmt = $constraint->dbal_connection->executeQuery($query, array($value));
if ($stmt->fetch())
$this->context->addViolation($constraint->notUniqueMessage);
}
}
I post my implementation to have suggestion so feel free to comment it ;)