Creating a custom validation constraint in conjunction with Annotations

Posted on 9th March, 2011 | Tagged:

Today I needed to create a custom validator for Symfony 2, I began by reading and following the instructions in the documentation here.

However at time of writing this documentation is outdated and what is more we use annotations to define validation, and this introduces extra steps.

So here I will try and explain the extra steps I had to take to get this working.

Extra Step 1

You will need to declare a targets method in your Constraint class as follows:

<?php

namespace Ylly\Extension\ArticleBundle\Validator\Constraints;

use Symfony\Component\Validator\Constraint;

class ArticleTitleSlug extends Constraint
{
    public $message = 'This title already exists, please use another';

    public function validatedBy()
    {
        return 'article_title_slug';
    }

    public function targets()
    {
        return self::PROPERTY_CONSTRAINT;

    }
}

Extra Step 2

Because we are using Annotations to declare validation rules it is necessary to define an alias for the namespace where your validation classes can be found.

When you write @validation:NotBlank on an entity you are actually telling Symfony to use the class Symfony\Component\Validator\Constraints\NotBlank, as @validation is actually a namespace alias.

As our validation class is located in Ylly\ArticleBundle\Validator\Constraints we need to declare a new alias pointing to this namespace, we can do this using the Dependency Injection Container

// Ylly/ArticleBundle/DependencyInjection/ArticleExtension.php
public function load(array $configs, ContainerBuilder $container)
{
    $namespaces = $container->getParameter('validator.annotations.namespaces');
    $namespaces['articleValidation'] = 'Ylly\\Extension\\ArticleBundle\\Validator\Constraints\\';
    $container->setParameter('validator.annotations.namespaces', $namespaces);
}

Note that we use the PHP interface for defining the DIC.

Now we can add the validation constraint to our entity

/**
 * @articleValidation:ArticleTitleSlug()
 * @validation:NotBlank()
 */
protected $title;

And if the class doesnt exist...

The most difficult aspect of working with annotations that I have experienced it that if the class doesnt exist, e.g. if you have a typo in your declaration, the annotation reader doesnt throw an error. This is because the annotation reader parses all annotations (including JavaDoc) and if there is no class (for example for @param, @var or @return) it just ignores the annotation.

So if your validator is not working, check your namespaces and class definitions!

Comments

Thx a lot!

Posted by Markus Öhler, 11th Mar 2011
You saved me at least a few hours of searching around to get my custom validators working.

Post new comment


type "i hate spam" in UPPER CASE

Tags

10 Latest Items