Consultez la FAQ sur le ZF avant de poster une question
Vous n'êtes pas identifié.
Pages: 1
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.
$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 :
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:
$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) :
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
PS: J'utilise Zend_Framework 1.9.2
Dernière modification par _Raynor_ (16-09-2009 11:24:15)
Hors ligne
Petite mise à jour :
J'ai également tenté de définir manuellement le message sur mon validator :
$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
La solution à ton problème est la suivante :
$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)
Hors ligne
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
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
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
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
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 :
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 :
$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
Pages: 1