L3 Info : PHP et Applications Web
 
◃  Ch. 11 Some old Stuff (chapitre non maintenu)  ▹
 

Gestions de Formulaires

  • À l'image de Doctrine, Symfony met à disposition un environnement permettant de générer et traiter des formulaires.
  • Création de formulaires symfony
    • Les formulaires sont associés à des entités (comme Doctrine !)
    • Des classes décrivent les types d'input des formulaires :
      use Symfony\Component\Form\Extension\Core\Type\TextType;
      use Symfony\Component\Form\Extension\Core\Type\IntegerType;
      // ...
      Liste détaillée des types.
    • La classe FormBuilder permet de construire un formulaire :
          /**
           * @Route("livresf/form1/")
           */
          public function form1Action(Request $request) {
              /* Dans ce controller, on génère un formulaire permettant de saisir les informations d'une instance de livreSF. */
              $livresf = new LivreSF();
              $livresf->setLivTitre("Le cerveau solitaire");
              $livresf->setLivNum(90);
      
              $form = $this->createFormBuilder($livresf);
    • Il faut créer les inputs pour le numéro et le titre :
              $form->add('livtitre',TextType::class, array('attr' => array('maxlength' => 22)));
              $form->add('livnum', IntegerType::class);
    • Il faut générer le bouton d'envoi et préciser la méthode de transmission :
      
              $form->add('save', SubmitType::class, array('label' => 'Create livresf'));
              $form->setMethod("GET");
    • Le formulaire est prêt ! :
      
              $form->getForm();
    • Pour afficher le formulaire on passe par un template twig
      
              return $this->render("default/new.html.twig", array('form' => $form->createView()));
              }
    • Par défaut, l'attribut action du formulaire est associé à la route courante
    • Exemple complet (noter l'enchainement des méthodes de FormBuilder) :
          /**
           * @Route("livresf/form1/")
           */
          public function form1Action(Request $request) {
              $livresf = new LivreSF();
              $livresf->setLivTitre("Le cerveau solitaire");
              $livresf->setLivNum(90);
      
              $form = $this->createFormBuilder($livresf)
                  ->add('livtitre',TextType::class, array('attr' => array('maxlength' => 22)))
                  ->add('livnum', IntegerType::class)
                  ->add('save', SubmitType::class, array('label' => 'Create livresf'))
                  ->setMethod("GET")
                  ->getForm();
      
              return $this->render("default/new.html.twig", array('form' => $form->createView()));
          }
      
  • Affichage d'un formulaire avec twig :
    {# app/Resources/views/default/new.html.twig #}
    {{ form_start(form) }}
    {{ form_widget(form) }}
    {{ form_end(form) }}
    
  • Pour plus de possibilités avec les formulaires dans twig.
  • Gestion des attributs action et method des formulaires
    • La méthode par défaut est POST, donc dans ce cas pas besoin de setMethod("POST") !
          /**
           * @Route("livresf/form2/")
           */
          public function form2Action(Request $request) {
              $livresf = new LivreSF();
      
              $form = $this->createFormBuilder($livresf)
                  ->add('livtitre',TextType::class, array('attr' => array('maxlength' => 22)))
                  ->add('livnum', IntegerType::class)
                  ->add('save', SubmitType::class, array('label' => 'Create livresf'))
                  //->setMethod("POST") inutile car méthode par défaut
                  ->getForm();
      
              return $this->render("default/new.html.twig", array('form' => $form->createView()));
          }
      
    • Jusqu'ici les requêtes HTTP ne sont définies que via les routes et les réponses via la classe Response :
      use Symfony\Component\Routing\Annotation\Route;
      use Symfony\Component\HttpFoundation\Response;
      
    • La classe Request permet de configurer et réaliser une requête HTTP :
      use Symfony\Component\HttpFoundation\Request;
                      
    • Une instance de Request est passée en paramètre de l'action :
          public function form3Action(Request $request) {
    • Le controller récupère la gestion des données transmises par le formulaire :
              $form->handleRequest($request);
    • On précise comment gérer les données :
      
              if ($form->isSubmitted() && $form->isValid()) {
                  $livresf = $form->getData();
                          /* on fait ce qu'on veut de $livresf*/
    • On redirige si nécessaire l'utilisateur vers une route appropriée :
      
                  return $this->redirectToRoute('accueil');
                          }
    • Exemple complet :
          /**
           * @Route("livresf/form3/")
           */
          public function form3Action(Request $request) {
              $livresf = new LivreSF();
      
              $form = $this->createFormBuilder($livresf)
                  ->add('livtitre',TextType::class)
                  ->add('livnum', IntegerType::class)
                  ->add('save', SubmitType::class, array('label' => 'Create livresf'))
                  ->getForm();
      
              $form->handleRequest($request);
              if ($form->isSubmitted() && $form->isValid()) {
                  $livresf = $form->getData();
                  $entityManager = $this->getDoctrine()->getManager();
                  $entityManager->persist($livresf);
                  $entityManager->flush();
                  return $this->redirectToRoute('accueil');
              }
      
              return $this->render('default/new.html.twig', array(
                  'form' => $form->createView(),
              ));
          }
      
  • Validation de Formulaires
    • Le controller précédent permet de saisir une chaîne constituée d'espaces pour le titre, et dans ce cas :
      message d'erreur symfony
    • Des annotations dans le code des entités permettent de valider finement les informations issues des formulaires :
      /* (...) *.
      use Symfony\Component\Validator\Constraints as Assert;
      
      /* (...) *.
      class LivreSF
      {
          /**
           * @ORM\Column(type="string", length=100)
           * @Assert\NotBlank()
           */
          private $liv_titre;
      /* (...) *.
      
      Bloque le traitement du formulaire et place un message dans la page :
      message de validation symfony
    • Liste des contraintes annotables
    • On peut également créer des méthodes dans l'entité afin de mettre en oeuvre des validations complexes :
          /**
           * @Assert\IsTrue(message="Le titre du livre ne peut pas être 'Le Masque SF'")
           */
          public function isLivTitreOk()
          {
              return $this->liv_titre != "Le Masque SF";
          }