Joeri Timmermans
Joeri Timmermans
PHP/Symfony Developer with
a passion for food and drinks
Developer @ Intracto

Silex Custom Constraint with DI

Wednesday February 26, 2014 - Permalink - Tags: silex, orm, dependency, injection, constraints, custom

Earlier this week i wanted to implement ORM in my Silex-Skeleton. Since I was already using Forms and Validation I decided to create a custom constraint to validate if an Entity field is unique. Dependency injection works a bit different in Silex compared to Symfony so i had to find a way to inject my EntityManager into my Validator.

So here are my steps

Step 1: Create your constraint

class Unique extends Constraint
{
    public $notUniqueMessage = '%string% has already been used.';
    public $entity;
    public $field;

    public function validatedBy()
    {
        return 'validator.unique';
    }
}

Step 2: Create your validator

We will inject the EntityManager via Setter injection later on in our ServiceProvider.

class UniqueValidator extends ConstraintValidator
{
    private $em;

    public function validate($value, Constraint $constraint)
    {
        $exists = $this->em
             ->getRepository($constraint->entity)
             ->findOneBy(array($constraint->field => $value));

        if ($exists) {
            $this->context->addViolation($constraint->notUniqueMessage, array('%string%' => $value));

            return false;
        }

        return true;
    }

    public function setEm(EntityManager $em)
    {
        $this->em = $em;
    }
}

Step 3: Create your ServiceProvider

This provider will help us create our validator and inject the EntityManager

class UniqueValidatorServiceProvider implements ServiceProviderInterface
{
    public function register(Application $app)
    {
        $app['validator.unique'] = $app->share(function ($app) {
            $validator =  new UniqueValidator();
            $validator->setEm($app['orm.em']);

            return $validator;
        });
    }

    public function boot(Application $app) {}
}

Step 4: Register your validator

$app->register(new Silex\Provider\ValidatorServiceProvider(), array(
    'validator.validator_service_ids' => array(
        'validator.unique' => 'validator.unique',
    )
));
comments powered by Disqus