1 / 44

symfony

symfony. Formulaires. Helper formulaire. Éviter les <?php echo dans les balises input, etc … <?php echo form_tag('test/save') ?>  <form method="post" action="/path/to/save"> <?php echo form_tag('test/save', array( 'method’ => ‘get’, ‘multipart’ => ‘true’,

melchior
Download Presentation

symfony

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. symfony Formulaires

  2. Helper formulaire • Éviter les <?php echo dans les balises input, etc … <?php echo form_tag('test/save') ?>  <form method="post" action="/path/to/save"> <?php echo form_tag('test/save', array( 'method’ => ‘get’, ‘multipart’ => ‘true’, ‘class’ => ‘simpleForm‘ ) ?> <form method="get" enctype="multipart/form-data" class="simpleForm"action="/path/to/save"> • Fermé par </form>

  3. Helper champs de formulairetexte • tout les champs et contrôles ont un attribut id déduit de l'attribut name <?php echo input_tag('nom', default') ?>  <input type="text" name="nom" id="nom" value="default" /> <?php echo textarea_tag('nom', 'default', array( 'size’ => ’10x20‘ ) ) ?>  <textarea name="nom" id="nom" cols="10" rows="20"> default </textarea>

  4. Helper champs de formulairechoix <?php echo checkbox_tag('celibataire', 1, true) ?> <?php echo checkbox_tag('permisdeconduire', 'B', false) ?> • <input type="checkbox" name="celibataire" id="celibataire" value="1"checked="checked" /><input type="checkbox" name="permisdeconduire" id="permisdeconduire"value="B" /> <?php echo radiobutton_tag('status[]', 'value1', true) ?> <?php echo radiobutton_tag('status[]', 'value2', false) ?> • <input type="radio" name="status[]" id="status_value1" value="value1"checked="checked" /><input type="radio" name="status[]" id="status_value2" value="value2" />

  5. Helper champs de formulairesélection – syntaxe la plus élégante <?php echo select_tag('payment', options_for_select( array( 'Visa' => 'Visa', 'Eurocard' => 'Eurocard', 'Mastercard' => 'Mastercard‘ ), array('Visa', 'Mastercard') ), array('multiple' => true) ) ?>  <select name="payment" id="payment" multiple="multiple"> <option value="Visa" selected="selected">Visa</option> <option value="Eurocard">Eurocard</option> <option value="Mastercard">Mastercard</option></select>

  6. Helper champs de formulaireautres <?php echo input_file_tag('nom') ?>  <input type="file" name="nom" id="nom" value="" /> <?php echo input_password_tag('nom', 'valeur') ?>  <input type="password" name="nom" id="nom" value="valeur" /> <?php echo input_hidden_tag('nom', 'valeur') ?>  <input type="hidden" name="nom" id="nom" value="valeur" />

  7. Helper champs de formulairesoumission <?php echo submit_tag('Sauvegarder') ?>  <input type="submit" name="submit" value="Sauvegarder" /> <?php echo submit_image_tag('submit_img') ?>  <input type="image" name="submit" src="/images/submit_img.png" /> • helper submit_image_tag() même syntaxe helper image_tag().

  8. Gestion de la soumission mymodule/templates/editAuthorSuccess.php Bonne pratique : utiliser la même action pour afficher et gérer le formulaire. <?php echo form_tag('mymodule/editAuthor') ?> </form> mymodule/actions/actions.class.php public function executeEditAuthor() { if ($this->getRequest()->getMethod() != sfRequest::POST) { // Affichage du Formulaire return sfView::SUCCESS; } else { // Management de la soumission du formulaire $name = $this->getRequestParameter('name'); ... $this->redirect('mymodule/anotheraction'); } }

  9. Gadget date poor   <?php echo input_date_tag('datedenaissance', '2005-05-01‘)?> <?php echo select_day_tag('day', 1, array('include_custom’ => ‘Choose a day‘)) ?> • <select name="day" id="day"> <option value="">Choose a day</option> <option value="1" selected="selected">01</option> <option value="2">02</option> ... <option value="31">31</option> </select> <?php echo select_month_tag('month', 1, 'include_custom=Choose a month use_short_month=true') ?> <?php echo select_year_tag('year', 2007, 'include_custom=Choose a year year_end=2010') ?>

  10. Gadget date rich  <?php echo input_date_tag('datedenaissance', '2005-05-03', array('rich’ => ’true') ?>

  11. Gadget date valeur par défaut • dates reconnues par la fonction PHP strtotime() <?php echo input_date_tag('test', '2006-04-01', 'rich=true') ?> <?php echo input_date_tag('test', 1143884373, 'rich=true') ?> <?php echo input_date_tag('test', 'now', 'rich=true') ?> <?php echo input_date_tag('test', '23 October 2005', 'rich=true') ?> <?php echo input_date_tag('test', 'next tuesday', 'rich=true') ?> <?php echo input_date_tag('test', '1 week 2 days 4 hours 2 seconds', 'rich=true') ?> • Aucune valeur par défaut <?php echo input_date_tag('test', ‘ ', 'rich=true') ?> • Les Formats de date autre qu’anglais ne fonctionnent pas (14/12/2008)

  12. Rich text TinyMce • http://tinymce.moxiecode.com/ • tinymce/jscripts/tiny_mce/ => web/js/ • settings.yml all: .settings: rich_text_js_dir: js/tiny_mce • <?php echo textarea_tag('name', 'default content', Array( 'rich’ => true, ‘size’ => ‘10x20’, ‘tinymce_options’ => ‘language:"fr",theme_advanced_buttons2:"separator"‘ ) ) ?>

  13. Rich text Fck • http://fckeditor.com/ • fkceditor/ => web/js/ • Myproject/apps/myapp/config/settings.yml all: .settings: rich_text_fck_js_dir: js/fckeditor • <?php echo textarea_tag('name', 'default content', Array( 'rich’ => ‘fck, ‘size’ => ‘10x20’, ) ) ?>

  14. Sélecteur de Pays et de Langage <?php echo select_country_tag('pays', 'AL') ?>  <select name="pays" id="pays"> <option value="AF">Afghanistan</option> <option value="AL" selected="selected">Albania</option> <option value="DZ">Algeria</option> <option value="AS">American Samoa</option> … <?php echo select_language_tag('langue', 'en') ?>  <select name="langue" id="langue"> <option value="elx">Elamite</option> <option value="en" selected="selected">English</option> <option value="enm">English, Middle (1100-1500)</option> <option value="ang">English, Old (ca.450-1100)</option> <option value="myv">Erzya</option> <option value="eo">Esperanto</option> …

  15. Helper formulaire pour objet <?php echo input_tag('telephone', $customer->getTelephone()) ?> <?php echo object_input_tag($client, 'getTelephone') ?> <input type="text" name="telephone" id="telephone" value="0123456789" />

  16. Helper formulaire pour objet • object_input_tag($object, $method, $options) • object_input_date_tag($object, $method, $options) • object_input_hidden_tag($object, $method, $options) • object_textarea_tag($object, $method, $options) • object_checkbox_tag($object, $method, $options) • object_select_tag($object, $method, $options) • object_select_country_tag($object, $method, $options) • object_select_language_tag($object, $method, $options) • object_password_tag() n’existe pas car ce n’est pas une bonne idée d’initialiser un mot de passe avec quelque chose de saisi par l’utilisateur

  17. Peupler une liste déroulante avec des objets <?php echo options_for_select(array( '1' => 'Steve', '2' => 'Bob', '3' => 'Albert', '4' => 'Ian', '5' => 'Buck' ), 4) ?>  <option value="1">Steve</option> <option value="2">Bob</option> <option value="3">Albert</option> <option value="4" selected="selected">Ian</option> <option value="5">Buck</option>

  18. Code contrôleur typique • Dans l’action $options = array(); foreach ($authors as $author) { $options[$author->getId()] = $author->getName(); } $this->options = $options;   • Dans le template <?php echo options_for_select($options, 4) ?> • MIEUX! <?php echo objects_for_select($authors, 'getId', 'getName', 4) ?>

  19. Peupler une liste déroulante à base d’une clé étrangère <?php echo select_tag('author_id', objects_for_select( AuthorPeer::doSelect(new Criteria()), 'getId', '__toString', $article->getAuthorId() )) ?> • MIEUX! <?php echo object_select_tag($article, 'getAuthorId') ?> • Le helper devine à partir de la méthode passée en paramètre • le nom de la classe peer associée AuthorPeer • le nom de la méthode peer à utiliser doSelect(new Criteria) • La méthode à utiliser sur chaque objet de la liste __toString() si elle existe ou la clé primaire sinon

  20. Peupler une liste déroulante à base d’une clé étrangère – version explicite • Spécifier la classe peer utilisée pour retrouver les valeurs <?php echo object_select_tag($article, 'getAuthorId', 'related_class=Foobar')?> • Spécifier la méthode peer utilisée pour retrouver les valeurs <?php echo object_select_tag($article, 'getAuthorId','peer_method=getMostFamousAuthors') ?> • Ajouter un item blanc en début de liste <?php echo object_select_tag($article, 'getAuthorId', 'include_blank=true') ?> • Ajouter un item personnalisé en début de liste <?php echo object_select_tag($article, 'getAuthorId', 'include_custom=Choose an author') ?> • Les options de ce helper sont combinables en utilisant un tableau d’options

  21. Validation de formulaire • Formulaire typique <?php echo form_tag('contact/send') ?> Name: <?php echo input_tag('name') ?><br /> Email: <?php echo input_tag('email') ?><br /> Age: <?php echo input_tag('age') ?><br /> Message: <?php echo textarea_tag('message') ?><br /> <?php echo submit_tag() ?> </form> • name est obligatoire et est un texte entre 2 et 100 caractères. • email est obligatoire et est un texte entre 2 et 100 caractères, et doit être valide • age est obligatoire et doit être un entier entre 0 et 120 • message est obligatoire

  22. Les validateurs • Symfony met à disposition des validateurs usuels • Un validateur possède une méthode execute() • Prend une valeur de champ en paramètre • Retourne vrai si la valeur est valide, false sinon • Emploi de sfStringValidator pour les deux premiers champs • Il vérifie que la taille d’un string est compris dans l’intervalle défini lors de l’appel de la méthode initialize()

  23. modules/contact/action/actions.class.php public function validateSend() { $name = $this->getRequestParameter('name');   if (!$name) { $this->getRequest()->setError('name', 'The name field cannot be left blank');   return false; } characters $myValidator = new sfStringValidator(); $myValidator->initialize($this->getContext(), array( 'min' => 2, 'min_error' => 'This name is too short (2 characters minimum)', 'max' => 100, 'max_error' => 'This name is too long. (100 characters maximum)', )); if (!$myValidator->execute($name, $error)) { return false; }   return true; }

  24. Processus de validation • Si l’utilisateur rentre une valeur incorrecte • la méthode execute de sfStringValidator retournera false • L’action validateSend échouera • La méthode handleErrorSend sera appelée au lieu de la méthode executeSend() • La classe sfRequest met à disposition une méthode setError(), et une méthode hasError() pour afficher des messages d’erreurs précis • C’est le rôle que jouent les paramètres • min_error • max_error

  25. Fichier de validation • modules/contact/validate/send.yml fields name: required: msg: The name field cannot be left blank sfStringValidator: min: 2 min_error: This name is too short (2 characters minimum) max: 100 max_error: This name is too long. (100 characters maximum) • Toutes les validations sont effectuées • Tous les messages d’erreur seront affichés • La validation globale échoue si au moins une validation de champs échoue • La méthode validateXXX() sera ensuite exécutée si elle existe • Les fichiers de validations sont stockés dans le répertoire validate/ du module et sont nommés nomAction.yml

  26. Réafficher le formulaire • En cas déchec • handleErrorSend() est exécutée si elle existe • Sinon le template sendError.php est affiché • Habituellement si la validation echoue on souhaite réafficher le formulaire • Redéfinir handleErrorSend() en la redirigeant vers l’affichage du formulaire

  27. modules/contact/actions/actions.class.php class ContactActions extends sfActions { public function handleErrorSend() { $this->forward('contact', ‘displayForm'); }   public function executeSend() { // traitement du formulaire } }   • Si c’est la même action qui affiche le formulaire et qui le traite handleErrorSend() n’a qu’à renvoyer sfView::SUCCESS pour réafficher sendSuccess.php

  28. Code typique de gestion d’un formulaire avec symfony class ContactActions extends sfActions { public function executeSend() { if ($this->getRequest()->getMethod() != sfRequest::POST) { // Prepare data for the template, should be shared return sfView::SUCCESS; } else { // traite le formulaire $this->redirect('mymodule/anotheraction'); } } public function handleErrorSend() { // Prepare data for the template, should be shared return sfView::SUCCESS; } }

  29. Afficher les message d’erreurs dans les formulaires <?php if ($sf_request->hasErrors()): ?> <p>valeurs incorrectes:</p> <ul> <?php foreach($sf_request->getErrors() as $name => $error): ?> <li><?php echo $name ?>: <?php echo $error ?></li> <?php endforeach; ?> </ul> <?php endif; ?>

  30. Afficher les message d’erreurs au niveau des champs <?php echo form_tag('contact/send') ?> <?php if ($sf_request->hasError('name')): ?> <?php echo $sf_request->getError('name') ?> <br /> <?php endif; ?> Name: <?php echo input_tag('name') ?><br /> <?php echo submit_tag() ?> </form> Ou via les helpers Validation <?php use_helper('Validation') ?> <?php echo form_tag('contact/send') ?> <?php echo form_error('name') ?><br /> Name: <?php echo input_tag('name') ?><br /> <?php echo submit_tag() ?> </form>

  31. Repeupler le formulaire • Peut se faire via $sf_params • Simple forward donc la requête est toujours accessible <?php echo input_tag('name', $sf_params->get('name')) ?> • Sinon laisser faire symfony • validate/send.yml fillin: enabled: true param: name: test # nom du forumlaire s’il y en a plusieurs skip_fields: [email] # champs exclus exclude_types: [hidden, password] # types de champs exclus check_types: [text, checkbox, radio, select, hidden] # champs à repeupler content_type: html # html, xml ou xhtml

  32. Transformation des données repeuplées • Pour transformer les données réaffichées • Entities, escaping etc … • validate/send.yml fillin: enabled: true param: name: test converters: # Converters to apply htmlentities: [first_name, comments] htmlspecialchars: [comments]

  33. Les validateurs symfony • sfStringValidator applique des contraintes sur les chaînes de carctères sfStringValidator: values: [foo, bar] values_error: The only accepted values are foo and bar insensitive: false # If true, comparison with values is case insensitive min: 2 min_error: Please enter at least 2 characters max: 100 max_error: Please enter less than 100 characters • sfEmailValidator vérifie la validité d’un adresse email sfEmailValidator: strict: true # name@domaine.ext est valide, sinon RFC822 email_error: This email address is invalid

  34. Les validateurs symfony II • sfNumberValidator vérifie qu’une entrée est bien un nombre et lui applique des contraintes de taille sfNumberValidator: nan_error: Please enter an integer min: 0 min_error: The value must be at least zero max: 100 max_error: The value must be less than or equal to 100 • sfUrlValidator vérifie la validité d’une url sfUrlValidator: url_error: This URL is invalid

  35. Les validateurs symfony III • sfRegexValidator vérifie qu’une entrée est conforme ou non à un masque d’expression régulière compatible perl sfRegexValidator: match: No # spécifie que l’entrée doit vérifier le masque (ne doit pas sinon) match_error: Posts containing more than one URL are considered as spam pattern: /http.*http/si • sfCompareValidator vérifie que deux entrées sont égales fields: password1: required: msg: Please enter a password password2: required: msg: Please retype the password sfCompareValidator: check: password1 compare_error: The two passwords do not match

  36. Les validateurs symfony IV • sfPropelUniqueValidator vérifie qu’une entrée n’existe pas déjà en bas de données (pratique pour le identifiant unique) fields: nickname: sfPropelUniqueValidator: class: User column: login unique_error: This login already exists. Please choose another one. • sfCallbackValidator vérifie que deux entrées sont égales fields: account_number: sfCallbackValidator: callback: is_numeric invalid_error: Please enter a number. credit_card_number: sfCallbackValidator: callback: [myTools, validateCreditCard] # doit renvoyer true ou false invalid_error: Please enter a valid credit card number.

  37. Les validateurs symfony V • sfFileValidator vérifie qu’un fichier uploadé a le bon type mime et la bonne taille fields: image: file: True required: msg: Please upload an image file sfFileValidator: mime_types: - 'image/jpeg' - 'image/png' - 'image/x-png' - 'image/pjpeg' mime_types_error: Only PNG and JPEG images are allowed max_size: 512000 max_size_error: Max size is 512Kb .

  38. DRY – les validateurs nommés validators: myStringValidator: class: sfStringValidator param: min: 2 min_error: This field is too short (2 characters minimum) max: 100 max_error: This field is too long (100 characters maximum) fields: name: required: msg: The name field cannot be left blank myStringValidator: email: required: msg: The email field cannot be left blank myStringValidator: sfEmailValidator: email_error: This email address is invalid

  39. Restriction de validation à la méthode POST ou GET • La validation est appelé par défaut pour la méthode POST • redéfinissable globalement ou champs par champs methods: [post] fields: email: methods: [post, get] # redéfinit la conf globale required: msg: The email field cannot be left blank sfEmailValidator: email_error: This email address is invalid

  40. Validateur personnalisé • Tout validateur hérite de sfValidator • Stocké dans un des répertoires lib/ • La méthode execute() prend la valeur à valider et le message d’erreur en paramètre • La méthode initalize() recoit le singletion context, et les paramètres du fichier YAML en paramètre • Elle doit commencer par appeler la méthode initalize de la classe dont elle dérive (sfValidator) • Elle définit les paramètres si le ichier YAML n’existe pas • Tout validateur peut accéder aux paramètres via $this->getParameterHolder()

  41. Validateur personnalisécode class sfSpamValidator extends sfValidator { public function execute (&$value, &$error) { $re = '/'.implode('.*', array_fill(0, $this->getParameter('max_url') + 1, 'http')).'/is';   if (preg_match($re, $value)) { $error = $this->getParameter('spam_error'); return false; }   return true; }   public function initialize ($context, $parameters = null) { parent::initialize($context);   $this->setParameter('max_url', 2); $this->setParameter('spam_error', 'This is spam'); $this->getParameterHolder()->add($parameters);   return true; } }  

  42. Validateur personnaliséutilisation • validate/send.yml message: required: msg: The message field cannot be left blank sfSpamValidator: max_url: 3 spam_error: Leave this site immediately, you filthy spammer!

  43. Utilisation de la syntaxe tableau dans les formulaires • PHP permet d’utiliser la syntaxe tableau dans les formulaires <label for="story_title">Title:</label> <input type="text" name="story[title]" id="story_title" value="default" /> • Incidence sur le fichier de validation fields: story{title}: required: Yes

  44. Exécution d’un validateur sur un champs vide • Exemple du changement de mot de passe fields: password1: password2: sfCompareValidator: check: password1 compare_error: passwords mismatch Valide un mot de passe blanc!! fields: password1: group: group_password password2: group: group_password sfCompareValidator: check: password1 compare_error: passwords mismatch Les tests agissant sur un groupe ne s’applique que si un des champs membre n’est pas vide

More Related