Symfony 2.1, el libro oficial

11.5. Aplicando las restricciones sobre propiedades y getters

Las restricciones se pueden aplicar a una propiedad de una clase (por ejemplo, name) o a un método getter público (por ejemplo getFullName()). El primero es el más común y fácil de usar, pero el segundo te permite especificar reglas de validación más complejas.

11.5.1.  Propiedades

La validación de propiedades de clase es la técnica de validación más básica. Symfony2 te permite validar propiedades privadas, protegidas o públicas. El siguiente ejemplo muestra cómo configurar que la propiedad $firstName de una clase Author tenga al menos 3 caracteres de longitud.

# src/Acme/BlogBundle/Resources/config/validation.yml
Acme\BlogBundle\Entity\Author:
    properties:
        firstName:
            - NotBlank: ~
            - Length:
                min: 3
// Acme/BlogBundle/Entity/Author.php

// ...
use Symfony\Component\Validator\Constraints as Assert;

class Autor
{
    /**
     * @Assert\NotBlank()
     * @Assert\Length(min = "3")
     */
    private $firstName;
}
<!-- src/Acme/BlogBundle/Resources/config/validation.xml -->
<class name="Acme\BlogBundle\Entity\Author">
    <property name="firstName">
        <constraint name="NotBlank" />
        <constraint name="Length">
            <option name="min">3</option>
        </constraint>
    </property>
</class>
// src/Acme/BlogBundle/Entity/Author.php

// ...
use Symfony\Component\Validator\Mapping\ClassMetadata;
use Symfony\Component\Validator\Constraints\NotBlank;
use Symfony\Component\Validator\Constraints\Length;

class Autor
{
    private $firstName;

    public static function loadValidatorMetadata(ClassMetadata $metadata)
    {
        $metadata->addPropertyConstraint('firstName', new NotBlank());
        $metadata->addPropertyConstraint(
            'firstName',
            new Length(array("min" => 3)));
    }
}

11.5.2. Métodos getter

Las restricciones también se pueden aplicar al valor devuelto por un método. Symfony2 te permite añadir una restricción a cualquier método público cuyo nombre comience con get o is. En esta capítulo se utiliza la palabra getter para referirse a ambos tipos de métodos.

La ventaja de esta técnica es que te permite validar el objeto de forma dinámica. Por ejemplo, supongamos que por razones de seguridad quieres asegurarte de que un campo de contraseña no coincide con el nombre del usuario. Puedes hacerlo creando un método isPasswordLegal y añadiéndole una restricción que obligue a que el valor devuelto sea true:

# src/Acme/BlogBundle/Resources/config/validation.yml
Acme\BlogBundle\Entity\Author:
    getters:
        passwordLegal:
            - "True": { message: "The password cannot match your first name" }
// src/Acme/BlogBundle/Entity/Author.php

// ...
use Symfony\Component\Validator\Constraints as Assert;

class Autor
{
    /**
     * @Assert\True(message = "The password cannot match your first name")
     */
    public function isPasswordLegal()
    {
        // devuelve 'true' o 'false'
    }
}
<!-- src/Acme/BlogBundle/Resources/config/validation.xml -->
<class name="Acme\BlogBundle\Entity\Author">
    <getter property="passwordLegal">
        <constraint name="True">
            <option name="message">The password cannot match your first name</option>
        </constraint>
    </getter>
</class>
// src/Acme/BlogBundle/Entity/Author.php

// ...
use Symfony\Component\Validator\Mapping\ClassMetadata;
use Symfony\Component\Validator\Constraints\True;

class Autor
{
    public static function loadValidatorMetadata(ClassMetadata $metadata)
    {
        $metadata->addGetterConstraint('passwordLegal', new True(array(
            'message' => 'The password cannot match your first name',
        )));
    }
}

Ahora, crea el método isPasswordLegal() e incluye la lógica que necesites:

public function isPasswordLegal()
{
    return ($this->firstName != $this->password);
}

Nota Si te fijas detenidamente, verás que el prefijo del getter (get o is) se omite en todas las formas de definir la restricción (YAML, XML y PHP sin anotaciones). Esto te permite mover más adelante la restricción a una propiedad con el mismo nombre (o viceversa) sin cambiar la lógica de validación.

11.5.3.  Clases

Algunas restricciones se aplican a toda la clase que se va a validar. Por ejemplo, la restricción Callback es una restricción que se aplica a la clase en sí misma: Cuando se valide esa clase, los métodos especificados por esta restricción se ejecutan para que cada uno pueda proporcionar una validación más personalizada.