Symfony 3, validateur personnalisé avec dépendance

L'auteur de ce sujet a trouvé une solution à son problème.
Auteur du sujet

Bonjour,

J'essaie d'implémenter une règle de validation personnalisée. La validation nécéssite un accès à la base de données, je définis donc mon validateur comme service dans le services.yml.

Quand je soumets le formulaire qui contient cette règle de validation, j'obtiens cette erreur:

1
Warning: Missing argument 1 for AppBundle\Validator\NotJunkEmailValidator::__construct(), called in C:\...\vendor\symfony\symfony\src\Symfony\Bundle\FrameworkBundle\Validator\ConstraintValidatorFactory.php on line 71 and defined

Les classes de contrainte et de validateur sont visiblement bien trouvées, mais le système d'injection de dépendances de symfony ne semble pas transmettre doctrine au constructeur. Je ne comprends pas pourquoi. Qu'ais-je fait de faux ou que me manque-t-il ? A toutes fins utiles j'ai vidé le cache dev mais ça n'a rien changé.

JE pense pourtant avoir suivi au plus près ce qui est indiqué dans le cookbook ici: http://symfony.com/doc/current/validation/custom_constraint.html

Mon code est ci-dessous. Merci pour vos réponses.

La déclaration du service:

1
2
3
4
5
#app/config/services.yml
    validator.junkEmail:
        class: AppBundle\Validator\NotJunkEmailValidator
        arguments: ['@doctrine']
        tags: [{ name: validator.constraint_validator }]

La classe de contrainte:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
<?php
// src/AppBundle/Validator/NotJunkEmail.php
namespace AppBundle\Validator;
use Symfony\Component\Validator\Constraint;

/**
*@Annotation
*/
class NotJunkEmail extends Constraint {
public $message = "JunkEmailNotAllowed";
public $entity;
public $field;
}

Le validateur:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
<?php
// src/AppBundle/Validator/NoJunkEmailValidator.php
namespace AppBundle\Validator;
use Symfony\Component\Validator\Constraint;
use Symfony\Component\Validator\ConstraintValidator;

class NotJunkEmailValidator extends ConstraintValidator {
private $doctrine;

public function __construct ($d) {
parent::__construct();
$this->doctrine=$d;
}

public function validate ($value, Constraint $constraint) {
//...
}

}

Extrait de l'entité utilisant ce validateur:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
<?php
use AppBundle\Validator as Validator;

//...

/**
*@ORM\Column(type="string")
*@Assert\NotBlank
*@Assert\Email
*@Validator\NotJunkEmail(entity=JunkEmailDomain::class, field="domain")
*/
public $email;

Ma plateforme avec 23 jeux de société classiques en 6 langues et 13000 joueurs: http://qcsalon.net/ | Apprenez à faire des sites web accessibles http://www.openweb.eu.org/

+0 -0

Salut !

Je ne sais pas trop si le service doctrine est public, peut-être que tu dois, pour tes propres services, utiliser doctrine.default ?

Édité par Ymox

Evitez qu'on vous dise de les lire : FAQ PHP et Symfony 2Tutoriel WAMP • Cliquez 👍 pour dire merci • Marquez vos sujets résolus

+0 -0
Auteur du sujet

Je ne sais pas trop si le service doctrine est public, peut-être que tu dois, pour tes propres services, utiliser doctrine.default ?

Je ne pense pas, je passe @doctrine comme paramètre à d'autres services et ça fonctionne.

Rajouts: Si je mets @doctrine.default , j'ai cette erreur:
The service "validator.junkemail" has a dependency on a non-existent service "doctrine.default".

A tout hasard j'ai essayé de mettre public: false, comme c'est le cas pour un autre service, mais ça ne change rien; je ne sais pas au juste ce que fait ce paramètre.

Édité par QuentinC

Ma plateforme avec 23 jeux de société classiques en 6 langues et 13000 joueurs: http://qcsalon.net/ | Apprenez à faire des sites web accessibles http://www.openweb.eu.org/

+0 -0
Auteur du sujet

Problème résolu en ajoutant un alias dans service.yml et en modifiant la méthode validatedBy.

Il semblerait que cette façon de faire soit héritée de Symfony 2 et devrait être dépréciée en version 3. Toujours est-il que ce n'est expliqué nulle part dans la doc…

Dans NotJunkEmail.php:

1
2
<?php
public function validatedBy () { return 'antijunkmail'; }

Et dans services.yml:

1
2
3
4
    validator.junkEmail:
        class: AppBundle\Validator\NotJunkEmailValidator
        arguments: ['@doctrine']
        tags: [{ name: validator.constraint_validator, alias: antijunkmail }]

Ma plateforme avec 23 jeux de société classiques en 6 langues et 13000 joueurs: http://qcsalon.net/ | Apprenez à faire des sites web accessibles http://www.openweb.eu.org/

+1 -0
Vous devez être connecté pour pouvoir poster un message.
Connexion

Pas encore inscrit ?

Créez un compte en une minute pour profiter pleinement de toutes les fonctionnalités de Zeste de Savoir. Ici, tout est gratuit et sans publicité.
Créer un compte