Zend FR

Consultez la FAQ sur le ZF avant de poster une question

Vous n'êtes pas identifié.

#1 15-09-2009 22:32:34

_Raynor_
Membre
Date d'inscription: 11-09-2008
Messages: 28

[Zend_Form][1.9.2] Messages spécifiques pour une instance de Validator

Bonjour/Bonsoir,

Cela fait quelques temps que j'utilise les Zend_Form et je suis enfin passé à la vitesse supérieure avec les validators (Zend_Validate).
J'instancie mes Zend_Validate que j'ajoute/affecte à mes Zend_Form_Element.

Code:

$validators = array(
    new Zend_Validate_Alnum(),
    new Zend_Validate_StringLength(5, 10),
);

//...

$formElement = new Zend_Form_Element_Text('champ', 'Le champ');
$formElement->addValidators($validators);

Ce qui fonctionne plutôt bien.

Ensuite, vu que les messages d'erreurs (résultat de la validation des valeurs des formulaires) sont en anglais et que j'aimerais bien les avoir en français, j'ai créé un Zend_Translate d'adapter Array et l'ait déclaré comme translator par défaut de mes Zend_Form :

Code:

Zend_Form::setDefaultTranslator(
    new Zend_Translate(
        'Array',
        array(
            Zend_Validate_Float::NOT_FLOAT => '"%value%" ne semble pas être un nombre réel',
            //...
            Zend_Validate_Alpha::NOT_ALPHA => '"%value%" ne contient pas uniquement des caractères alphabétiques',
        ),
        'fr'
    )
);
//Note: Utiliser Zend_Validate_Abstract::setDefaultTranslator() serait peut-être plus juste ? Plus global ?

Là où ça se corse c'est que, pour certains validators, je souhaiterais un autre message d'erreur que la bête traduction par défaut. Notamment pour les Zend_Validate_Db.

J'ai donc modifié mes instanciation et affectation des Zend_Validate:

Code:

$dbValidator = new Zend_Validate_Db_NoRecordExists('ma_table', 'champ');
$dbValidator->setTranslator(
    new Zend_Translate(
        'Array',
        array(
            Zend_Validate_Db_Abstract::ERROR_RECORD_FOUND    => 'Un autre enregistrement porte ce nom là.'
        ),
        'fr'
    )
);
$validators = array(
    new Zend_Validate_Alnum(),
    new Zend_Validate_StringLength(5, 10),
    $dbValidator,
);

//...

$formElement = new Zend_Form_Element_Text('champ', 'Le champ');
$formElement->addValidators($validators);

Or cela ne fonctionne pas, c'est toujours mon Zend_Translate de défaut (celui attribué par Zend_Form::setDefaultTranslator()) qui est utilisé.

En consultant un peu toutes les classes incriminées (Zend_Form, Zend_Form_Element et Zend_Validate) je remarque que Zend_Form_Element::isValid() refile son propre Zend_Translate au Zend_Validate courant, écrasant celui déjà défini (fichier "Zend/Form/Element.php", ligne 1292) :

Code:

public function isValid($value, $context = null)
    [...]
        $this->_messages = array();
        $this->_errors   = array();
        $result          = true;
        $translator      = $this->getTranslator();
        $isArray         = $this->isArray();
        foreach ($this->getValidators() as $key => $validator) {
            if (method_exists($validator, 'setTranslator')) { // Vérifie que le Validator supporte les Translator
                $validator->setTranslator($translator); // Lui refile le sien
            }
    [...]

Quid alors du translator déjà défini pour ce validator ??

Merci pour vos lumières smile


PS: J'utilise Zend_Framework 1.9.2

Dernière modification par _Raynor_ (16-09-2009 11:24:15)

Hors ligne

 

#2 16-09-2009 14:02:44

_Raynor_
Membre
Date d'inscription: 11-09-2008
Messages: 28

Re: [Zend_Form][1.9.2] Messages spécifiques pour une instance de Validator

Petite mise à jour :

J'ai également tenté de définir manuellement le message sur mon validator :

Code:

$dbValidator = new Zend_Validate_Db_NoRecordExists('ma_table', 'champ');
$dbValidator->setMessage(
    'Un autre enregistrement porte ce nom là.',
    Zend_Validate_Db_Abstract::ERROR_RECORD_FOUND
);

Ce dernier est bien pris en compte (c'est ce "messageTemplate" qui est utilisé comme base) mais, ayant la même "$messageKey", il est tout de même traduit par mon Zend_Translate de défaut.

Comment peut-on faire pour définir un message spécifique pour un Validator donné ?

Dernière modification par _Raynor_ (16-09-2009 14:03:23)

Hors ligne

 

#3 16-09-2009 15:09:28

tonton flubb
Membre
Date d'inscription: 11-10-2008
Messages: 48
Site web

Re: [Zend_Form][1.9.2] Messages spécifiques pour une instance de Validator

La solution à ton problème est la suivante :

Code:

$formElement->addValidator('Db_NoRecordExists');
$formElement->addErrorMessage('Un autre enregistrement porte ce nom là.', Zend_Validate_Db_Abstract::ERROR_RECORD_FOUND);

Je te redirige vers le post d'une de mes questions sur le même sujet ici

Dernière modification par tonton flubb (16-09-2009 15:09:49)


Florent - Développeur Web

Hors ligne

 

#4 16-09-2009 15:20:44

_Raynor_
Membre
Date d'inscription: 11-09-2008
Messages: 28

Re: [Zend_Form][1.9.2] Messages spécifiques pour une instance de Validator

Merci pour cette réponse.

Mais je m'étonne que Zend_Form_Element::addErrorMessage() n'attende qu'un seul paramètre : une chaîne.
De plus, que faire lorsqu'un Form_Element a plusieurs validators (chacun pouvant générer une erreur, et donc un message d'erreur) ?

Dernière modification par _Raynor_ (16-09-2009 15:23:09)

Hors ligne

 

#5 16-09-2009 15:50:18

_Raynor_
Membre
Date d'inscription: 11-09-2008
Messages: 28

Re: [Zend_Form][1.9.2] Messages spécifiques pour une instance de Validator

Petit retour.

Avoir des errorMessages dans le Zend_Form_Element (ajoutées dans Zend_Form_Element::$_errorMessages via les méthodes addErrorMessage() et setErrorMessages()) fait que Zend_Form_Element::isValid() n'utilise pas les messages du validator mais celui ou ceux que j'ai donné.
Si j'ai deux validators sur mon Zend_Form_Element et que j'ajoute donc les deux messages "spécifiques" comme tu me l'as conseillé : les deux messages seront retournés/affichés quelque soit le validator ayant détecté l'erreur : ça n'est clairement pas la solution.

Hors ligne

 

#6 01-10-2009 17:27:44

mdelanno
Membre
Lieu: Nord
Date d'inscription: 26-08-2007
Messages: 90
Site web

Re: [Zend_Form][1.9.2] Messages spécifiques pour une instance de Validator

Chez moi, setMessage fonctionne. Je n'utilise pas Zend_Form::setDefaultTranslator, mais je place mon instance de Zend_Translate dans le registre avec la clé Zend_Translate.

Hors ligne

 

#7 01-10-2009 19:05:33

_Raynor_
Membre
Date d'inscription: 11-09-2008
Messages: 28

Re: [Zend_Form][1.9.2] Messages spécifiques pour une instance de Validator

Utiliser Zend_Form::setDefaultTranslator() ou Zend_Registry::set('Zend_Translate', ...) est équivalent vu que Zend_Form::getDefaultTranslator() retourne soit ton Zend_Translate définit par Zend_Form::setDefaultTranslator(), soit celui de Zend_Registry (Zend_Registry::get('Zend_Translate')).

Quand tu dis que Zend_Validate_Abstract::setMessage(texteErreur, codeErreur) fonctionne, c'est à dire ?
En regardant le code de Zend_Validate_Abstract::_createMessage() on voit que si ton Zend_Translate possède une traduction pour ton codeErreur (ou ton texteErreur d'ailleurs) et bien ton texteErreur est remplacé par la traduction : Il est donc impossible d'avoir un message spécifique pour un objet Zend_Validate donné.

Hors ligne

 

#8 23-10-2010 13:20:12

Denis. Beurive
Membre
Date d'inscription: 06-06-2009
Messages: 35

Re: [Zend_Form][1.9.2] Messages spécifiques pour une instance de Validator

Salut,

J'ai eu le même problème. La solution consiste à assigner un message d'erreur spécifique au validateur, et non pas à l'élément.

Exemple de code qui fonctionne bien :

Code:

class My_Forms_Register
{
    private $__form = null; 
    
    public function __call($inName, $inArguments)
    {
        $this->__form->$inName($inArguments);
    }
    
    
    public function __construct()
    {
        // API: http://framework.zend.com/apidoc/core/Zend_Form/Element/Zend_Form_Element.html
        // Il est possible de désactiver l'utilisation des décorateurs par défauts: http://framework.zend.com/manual/fr/zend.form.elements.html
        // Pour cela il faut passer le tableau suivant en deuxième argument du constructeur: array('disableLoadDefaultDecorators' => true)
        //
        // Pour la liste de tous les validateurs standards: http://framework.zend.com/manual/fr/zend.validate.set.html  
        
        $translate = Zend_Registry::get('translator')->getCurrentTranslator();
        
        $email1    = new Zend_Form_Element_Text('email1');
        $email2    = new Zend_Form_Element_Text('email2');
        $login     = new Zend_Form_Element_Text('login');
        $submit    = new Zend_Form_Element_Submit('submit');
        $password1 = new Zend_Form_Element_Password('password1');
        $password2 = new Zend_Form_Element_Password('password2');
        
        $validatorEmailIdentical = new Zend_Validate_Identical();
        $validatorEmailIdentical->setToken('email1')
                                ->setMessage('Les deux adresses emails que vous avez renseignées ne sont pas identiques.');
        
        $validatorPasswordIdentical = new Zend_Validate_Identical();
        $validatorPasswordIdentical->setToken('password1')
                                   ->setMessage('Les deux mots de passe que vous avez renseignés ne sont pas identiques.');
        
        $email1->setLabel("Veuillez indiquer votre adresse email.")
               ->setRequired(true)
               ->addValidator('emailAddress');
        $email2->setLabel("Veuillez confirmer votre adresse email.")
               ->setRequired(true)
               ->addValidator($validatorEmailIdentical, false);
        $password1->setLabel("Veuillez choisir un mot de passe.")
                  ->setRequired(true);
        $password2->setLabel("Veuillez retaper votre mot de passe.")
                  ->setRequired(true)
                  ->addValidator($validatorPasswordIdentical, false);
        $login->setLabel("Veuillez choisir un nom d'utilisateur.")
              ->setRequired(true)
              ->addValidator('login');
        
        // Note: Le framework ZEND fournit des décorateurs par défaut, qui sont assignés à l'élément dès sa création.
        // o Il est possible de retirer tous les décorateurs associés à un élément.
        // o Il est possible de retirer seulement une partie des décorateurs associés à un élément.
        // o Il est possible de remplacer tout, ou seulement une partie, des décorateurs associés à un élément.
        //
        // Très bonne explication: http://framework.zend.com/manual/fr/zend.form.elements.html
        
        $this->__form = new Zend_Form();
        $this->__form->setAction('/user/register')
                     ->setTranslator($translate)
                     ->addElementPrefixPath('My_Validators', 'My/Validators/', 'validate')
                     ->setMethod('post')
                     ->setAttrib('id', 'register')
                     ->addElement($login)
                     ->addElement($email1)
                     ->addElement($email2)
                     ->addElement($password1)
                     ->addElement($password2)
                     ->addElement($submit);
    }
    
    public function getForm() { return $this->__form; }
}

Le point important :

Code:

        $validatorEmailIdentical = new Zend_Validate_Identical();
        $validatorEmailIdentical->setToken('email1')
                                ->setMessage('Les deux adresses emails que vous avez renseignées ne sont pas identiques.');
        
        $validatorPasswordIdentical = new Zend_Validate_Identical();
        $validatorPasswordIdentical->setToken('password1')
                                   ->setMessage('Les deux mots de passe que vous avez renseignés ne sont pas identiques.');

A+

Hors ligne

 

Pied de page des forums

Propulsé par PunBB
© Copyright 2002–2005 Rickard Andersson
Traduction par punbb.fr

Graphisme réalisé par l'agence Rodolphe Eveilleau
Développement par Kitpages