22
juin
2009
3

Symfony : Gérer un formulaire dans un composant

Dans un projet Symfony, comment gérer la validation d’un formulaire lorsqu’il est dans un composant ? C’est la question que l’on m’a posé cette semaine la semaine dernière (le temps passe vite…).

Tout d’abord, qu’est-ce qu’un composant dans Symfony ? Il s’agit en quelque sorte d’une action qui est réutilisable entre les différents modules de l’application. A la différence des « partials », qui sont « que » des templates, les composants contiennent de la logique : le plus souvent, récupérer un ou plusieurs modèles.

Pour revenir à la question, le problème n’est pas de gérer la validation à proprement parler, Symfony va s’en occuper grâce au forms framework mais plutôt de savoir où envoyer le visiteur une fois le formulaire soumis et comment, à la fin, le rediriger sur la page initiale, celle où il a rempli le formulaire.

Une solution possible est de créer une action spécifique pour valider le formulaire et d’ajouter un champ caché « referer » contenant l’url de la page initiale. Dans le fonctionnement, c’est relativement simple, le formulaire du composant pointe vers l’action et lorsque les données saisies sont valides, l’utilisateur est redirigé vers le valeur du champ « referer ».

Pour les intéressés, vous trouverez ci-dessous le contenu des différents fichiers pour l’utilisation d’un formulaire en composant. C’est prévu pour fonctionner avec Symfony 1.2.

  1. Le formulaire (lib/form/TestForm.class.php)
    < ?php
    class TestForm extends sfForm
    {
    	public function configure()
    	{
    		$this->setWidgets(array(
    			'name'    => new sfWidgetFormInput(),
    			'referer' => new sfWidgetFormInputHidden(),
    		));
     
    		$this->setValidators(array(
    			'name'    => new sfValidatorString(),
    			'referer' => new sfValidatorString(array('required' => false)),
    		));
     
    		$this->widgetSchema->setNameFormat('test-form[%s]');
    	}
    }
  2. Le composant (apps/frontend/modules/mymodule/actions/components.class.php)
    < ?php
    class mymoduleComponents extends sfComponents
    {
    	public function executeTestForm(sfWebRequest $request)
    	{
    		$this->form = new TestForm(array(
    			'referer' => $request->getUri()
    		));
    	}
    }
  3. Le template du composant (apps/frontend/modules/mymodule/templates/_TestForm.php)
    <h2>My Form</h2>
    <form action="<?php echo url_for('test-form') ?>" method="post">
      <table>
        < ?php echo $form ?>
      </table>
      <input type="submit" value="Send" />
    </form>
  4. L’action (apps/frontend/modules/mymodule/actions/actions.class.php)
    < ?php
    class mymoduleActions extends sfActions
    {
    	public function executeTestForm(sfWebRequest $request)
    	{
    		$this->form = new TestForm(array(
    			'referer' => $request->getUri()
    		));
     
    		if ($request->isMethod('post'))
    		{
    			$this->form->bind($request->getParameter($this->form->getName()));
     
    			if ($this->form->isValid())
    			{
    				$this->redirect(
    					$this->form->getValue('referer') ? $this->form->getValue('referer') : 'homepage'
    				);
    			}
    		}
    	}
    }
  5. Le template de l’action (apps/frontend/modules/mymodule/templates/TestFormSuccess.php)
    < ?php include_partial('TestForm', array('form' => $form)) ?>
  6. La règle de routage (apps/frontend/config/routing.yml)
    test-form:
      url:    /test-form
      param:  { module: mymodule, action: TestForm }

Une fois tous les fichiers créés, il ne reste plus qu’à inclure le composant dans un template, par exemple apps/frontend/layout.php, en ajoutant ceci :

< ?php include_component('mymodule', 'TestForm') ?>

Ici, le formulaire ne sert absolument à rien, la valeur saisie n’est pas utilisée. Il s’agit juste d’un exemple pour montrer le principe. ;-)

Note : Attention Wordpress à ajouté un espace entre < et ?php

Vous avez apprécié ce billet ?
Abonnez-vous au flux RSS pour être informé des nouveaux billets.
3 commentaires :
  1. Thomas R. 22 juin, 2009

    Bonjour,

    Tu devrais passer la valeur du referer comme option, comme cela ton formulaire n’est pas lie au sfContext. C’est mieux pour les tests unitaires …

  2. Fabien 22 juin, 2009

    Bonjour,

    Merci ! J’ai modifié l’article en conséquence.

  3. Amo__ 29 juin, 2009

    Merci pour le post, c’est bon mangez-en !

Ajouter un commentaire
:D :) :o :eek: :( :lol: :wink: :arrow: :idea: :?: :!: :evil: :p