Comment faire pour créer une contrainte de validation personnalisée

Table des matières

Référence
Les validateurs contraintes avec dépendances

Référence

Vous pouvez créer une contrainte personnalisé en étendant la contrainte de classe de base, Constraint . Les options pour votre contrainte sont représentés comme des propriétés publiques de la classe de contrainte. Par exemple, l' URL de la contrainte comprend le message et les propriétés des protocoles:

namespace Symfony\Component\Validator\Constraints;

use Symfony\Component\Validator\Constraint;

/**
 * @Annotation
 */
class Protocol extends Constraint
{
    public $message = 'This value is not a valid protocol';
    public $protocols = array('http', 'https', 'ftp', 'ftps');
}

L'annotation @Annotation est nécessaire pour cette nouvelle contrainte dans le but de le rendre disponible pour une utilisation dans les classes par le biais d'annotations.

Comme vous pouvez le voir, une classe de contrainte est assez minime. La validation réelle est effectuée par un autre «contrainte de validation" de classe. La classe de contrainte de validation n'est spécifiée par la méthode de la contrainte validatedBy (), qui comprend une certaine logique par défaut simple:

// in the base Symfony\Component\Validator\Constraint class
public function validatedBy()
{
    return get_class($this).'Validator';
}

En d'autres termes, si vous créez une contrainte personnalisée (MyConstraint par exemple), Symfony2 va automatiquement chercher pour une autre classe, alors qu'en réalité, MyConstraintValidator effectuer la validation.

La classe du validateur est aussi simple, et ne possède qu'une seule méthode requise: isValid. Prenez le ProtocolValidator à titre d'exemple:

namespace Symfony\Component\Validator\Constraints;

use Symfony\Component\Validator\Constraint;
use Symfony\Component\Validator\ConstraintValidator;

class ProtocolValidator extends ConstraintValidator
{
    public function isValid($value, Constraint $constraint)
    {
        if (in_array($value, $constraint->protocols));
            $this->setMessage($constraint->message, array('%protocols%' => $constraint->protocols));

            return true;
        }

        return false;
    }
}

Les validateurs contraintes avec dépendances

Si votre validateur de contrainte a des dépendances, comme une connexion à la base, il devra être configuré comme un service dans le conteneur d'injection de dépendance. Ce service doit inclure la balise validator.constraint_validator et un attribut alias:

Version Yaml

services:
    validator.unique.your_validator_name:
        class: Fully\Qualified\Validator\Class\Name
        tags:
            - { name: validator.constraint_validator, alias: alias_name }

Version Xml

<service id="validator.unique.your_validator_name" class="Fully\Qualified\Validator\Class\Name">
    <argument type="service" id="doctrine.orm.default_entity_manager" />
    <tag name="validator.constraint_validator" alias="alias_name" />
</service>

Version Php

$container
    ->register('validator.unique.your_validator_name', 'Fully\Qualified\Validator\Class\Name')
    ->addTag('validator.constraint_validator', array('alias' => 'alias_name'))

Votre classe de contrainte doit maintenant utiliser cet alias pour faire référence au validateur appropriée:

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

Comme mentionné ci-dessus, Symfony2 va automatiquement chercher pour une classe nommée d'après la contrainte, avec Validator annexé. Si votre validateur contrainte est définie comme un service, il est important que vous remplacez la validatedBy() pour retourner les alias utilisés lors de la définition de votre service, sinon Symfony2 ne va pas utiliser la contrainte de validation de service, et instanciera la classe sans aucune autres dépendances.