Quand une erreur survient, il faut afficher un message d'erreur le plus explicite possible. Avec Zend_Form, les messages d'erreur sont issus des validateurs.
Les messages sont par défaut en anglais. Il faut donc en proposer une version traduite.Zend_Form gère la traduction automatique, il suffit de créer une entrée Zend_Translate dans le registre :
<?php
// Création d'un objet locale qu'on place dans le registre
$locale = new Zend_Locale('fr_FR');
Zend_Registry::set('Zend_Locale', $locale);
// Création d'un objet Zend_Translate utilisant l'adaptateur GetText
$translate = new Zend_Translate('gettext', APPLICATION_PATH . '/languages/fr/zf.mo');
// On définit la locale que Zend_Translate doit utiliser
$translate->setLocale($locale);
// On place l'objet dans le registre avec la clé Zend_Translate pour que Zend_Form
// le trouve et l'utilise
Zend_Registry::set('Zend_Translate', $translate);
?>
On obtient ainsi un message traduit :
C'est mieux, mais il faut idéalement un message correspondant au contexte. Pour cela, il faut utiliser la méthode setMessage du validateur:
<?php
// On crée le validateur
$noRecordExistsVal = new Zend_Validate_Db_NoRecordExists(
'estimates',
'num'
);
// On définit le message associé à la constante ERROR_RECORD_FOUND
$noRecordExistsVal->setMessage(
'Ce numéro est déjà utilisé',
Zend_Validate_Db_Abstract::ERROR_RECORD_FOUND
);
// On ajoute l'élément au formulaire
$this->addElement(
'text',
'num',
array(
'label' => 'Numéro : ',
'required' => true,
'validators' => array($noRecordExistsVal)
)
);
?>
Vous pouvez obtenir le détail des différentes constantes en examinant le code source des composants Zend_Validate.
Si le champ doit être obligatoirement rempli, vous allez mettre l'option required à true. Zend_Form_Element va alors insérer automatiquement un validateur NotEmpty avant de procéder à la validation. Comme il est inséré au niveau de la méthode isValid, vous ne pouvez pas le récupérer avec la méthode getValidator après la création de l'objet.
La solution, c'est de créer explicitement le validateur NotEmpty :
<?php
$notEmptyVal = new Zend_Validate_NotEmpty();
$notEmptyVal->setMessage('Obligatoire', Zend_Validate_NotEmpty::IS_EMPTY);
// On ajoute l'élément au formulaire
$this->addElement(
'text',
'num',
array(
'label' => 'Numéro : ',
'required' => true,
'validators' => array($notEmptyVal, $noRecordExistsVal)
)
);
?>
Vous pouvez récupérer les messages à traduire avec la méthode getMessageTemplates. Cela vous permet de définir un message d'erreur générique pour tous les types d'erreurs qui peuvent se produire. Exemple avec Zend_Validate_EmailAddress.
<?php
// Création du validateur
$emailAddressVal = new Zend_Validate_EmailAddress();
// Récupération des messages
$msgTemplates = $emailAddressVal->getMessageTemplates();
// On remplace les différents messages d'erreur par un message simple
foreach($msgTemplates as $key => $msg) {
$emailAddressVal->setMessage('Cette adresse E-mail n\'est pas valide', $key);
}
?>
Attention cependant, certains validateurs comme Zend_Validate_Hostname peuvent renvoyer plusieurs messages.
Les messages peuvent contenir des variables qui seront automatiquement remplacées lors de la récupération du message. La variable %value%, toujours disponible, correspond à la valeur passée au validateur. Certains validateurs proposent des variables supplémentaires, par exemple %min% pour Zend_Validate_GreaterThan. Vous pouvez récupérer la liste des variables additionnelles avec la méthode getMessageVariables.
Commentaires
enzostar (non vérifié)
lun, 08/03/2010 - 16:39
Permalink
Bonjour il est noté "il
Bonjour il est noté "il suffit de créer une entrée Zend_Translate dans le registre":
où se trouve le registre ?
Maxence
mar, 16/03/2010 - 10:56
Permalink
Le registre, c'est
Le registre, c'est Zend_Registry. C'est une classe dotée de méthodes statiques qui permettent de placer et de récupérer des objets dans un espace accessible de façon globale. Une sorte de dictionnaire en quelque sorte qui se substitue aux variables globales.
Si tu veux en savoir plus sur ce motif de conception : http://www.phppatterns.com/docs/design/the_registry
$translate = new Zend_Translate(...);
Zend_Registry::set('Zend_Translate', $translate);
Thierry BENDA (non vérifié)
sam, 27/03/2010 - 07:42
Permalink
Bonjour Maxence, Suite à
Bonjour Maxence,
Suite à quelques essais sur la personnalisation des messages d'erreurs, je n'arrive pas à récupérer ceux-ci convenablement traduits avec substitution des variables.
Je n'arrive à récupérer que les messages par défaut convenablement traduits... ce qui n'est pas si mal.
Voici ma manière de faire, dans mon IdentificationController, section validation echouée du formulaire:
$translate = Zend_Registry::get('Zend_Translate');
//username messages
$username_messages = $form->getElement('username')->getMessages();
$this->view->username_label = ''.$translate->translate("identification_labelUsername").'';
$this->view->username_messages = '
';
//password messages
$password_messages = $form->getElement('password')->getMessages();
$this->view->password_label = ''.$translate->translate("identification_labelPassword").'';
$this->view->password_messages = '
';
Et dans la vue associée à mon formulaire, j'ai ceci:
<?php echo $this->translate("identification_title"); ?>
<?php echo $this->message; ?>
<?php echo $this->username_label.' '.$this->username_messages; ?>
<?php echo $this->password_label.' '.$this->password_messages; ?>
<?php echo $this->form; ?>
Pourrais-tu préciser comment tu récupères les différents messages d'erreurs personnalisés lors de la validation de ton formulaire ? Merci.
Te souhaitant une excellente journée.
Thierry.
Thierry BENDA (non vérifié)
sam, 27/03/2010 - 09:19
Permalink
En fait, ayant affecté une
En fait, ayant affecté une instance de mon objet responsable des traductions sur mon formulaire, il semblerait que les messages personnalisés des validateurs soient tout à fait ignorés au profit des traductions :P
Suite à la consultation de la documentation, les méthodes de l'api ne sont pas plus fonctionnelles. Par exemple, la méthode suivante:
$val->setErrorMessages(array($key=>$value));
//$key constante de classe du validateur que l'on veut personnaliser
//$val message personnalisé que l'on souhaite affecter à cette clef du validateur
Permet de définir des messages d'erreurs qui ne sont pas traduits par le formulaire lors de la validation... même en utilisant la méthode
$val->setTranslator($translator)
Bon, je vais bien finir par trouver une manière de faire fonctionnelle.
Ajouter un commentaire