Programmation PHP/Symfony/Formulaire


PrincipeModifier

Le principe est d'ajouter des champs de formulaire en PHP, qui seront automatiquement convertis en code HTML correspondant.

En effet, comme vu dans le chapitre sur les formulaire PHP, en HTML on utilise habituellement la balise <form> pour afficher les champs à remplir par le visiteur. Puis sur validation on récupère leurs valeurs en PHP avec la superglobale $_REQUEST (ou ses composantes $_GET et $_POST). Or ce système ne fonctionne pas en $_POST dans Symfony : si on affiche un tel formulaire et qu'on le valide, $_POST est vide, et l'équivalent Symfony de $_REQUEST, $request->request[1] aussi.

Les formulaires doivent donc nécessairement être préparés en PHP.

InstallationModifier

Terminal

 

 composer require symfony/form

Pour ajouter des contrôles sur les champs[2] :

Terminal

 

 composer require symfony/validator


ContrôleurModifier

Injection du formulaire dans un TwigModifier

class HelloWorldController extends AbstractController
{
    /**
     * @Route("/helloWorld", name="helloWorld")
     *
     * @return Response
     */
    public function indexAction(Request $request)
    {
        $form = $this->createForm(HelloWorldForm::class);

        return $this->render('helloWorld.html.twig', [
            'form' => $form->createView(),
        ]);
    }
}

Le second paramètre de createForm() est facultatif est sert à préciser des valeurs initiales dans le formulaire qui seront injectées en Twig, mais elles peuvent aussi l'être via le fichier du formulaire dans les paramètres de chaque champ.

Traitement post-validationModifier

Dans la même méthode du contrôleur qui injecte le formulaire, il faut prévoir le traitement post-validation :

    $form->handleRequest($request);
    if ($form->isSubmitted() && $form->isValid()) {
        $email = $form->get('email')->getData();
        // ...
    }

Fichier du formulaireModifier

Dans SF4, l'espace de nom Symfony\Component\Form\Extension\Core\Type propose 35 types de champ, tels que :

  • email (avec validation en option de la présence d'arrobase ou de domaine).
  • submit (bouton).
  • date.

Exemple :

    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $builder
            ->add('email', 'text', [
                'required' => true,
        ]);
    }

Pour préremplir des valeurs dans les champs :

    $form->get('email')->setData($user->getEmail());

EntityTypeModifier

De plus, en installant Doctrine, il est possible d'ajouter un type de champ "entité" directement relié avec un champ de base de données[3].

  Il n'y a pas de type Checkbox ou Radiobox comme mais il faut jouer sur deux paramètres de EntityType ainsi :


Élément Expanded Multiple
Sélecteur false false
Sélecteur multiple false true
Boutons radio true false
Cases à cocher true true

Exemple :

    $builder->add('gender', EntityType::class, ['expanded' => true, 'multiple' => false]);

ContrôleModifier

Le validateur de formulaire d'entité peut utiliser les annotations des entités. Ex :

use Symfony\Component\Validator\Constraints as Assert;
...
@Assert\NotBlank

Sinon il permet aussi des contrôles plus personnalisés dans les types (qui étendent Symfony\Component\Form\AbstractType). Ex :

'constraints' => [
    new Assert\NotBlank(),
    new Assert\Callback([ProductChecker::class, 'check']),
],

Plusieurs types de données sont déjà définis, comme l'email ou l'URL[4]. Ex :

@Assert\Email()

Appel du formulaire Symfony dans la vueModifier

Les fonctions Twig permettant d'ajouter les éléments du formulaire sont :

  • form_start
  • form_errors
  • form_row
  • form_widget
  • form_label

Pour afficher tout le formulaire, dans l'ordre où les champs ont été définis en PHP :

    {{ form_start(form) }}
    {{ form_end(form) }}

Pour n'afficher qu'un seul champ :

{{ form_widget(form.choosen_credit_card) }}

Les même attributs qu'en PHP peuvent être définis en paramètre. Ex :

{{ form_widget(form.name, {'attr': {'class': 'address', 'placeholder': 'Entrer une adresse'} }) }}
{{ form_label(form.name, null, {'label_attr': {'class': 'address'}}) }}

Exemple complet :

{{ form_start(form) }}
    {{ form_errors(form) }}

    {{ form_label(form.name, 'Label du champ "name" écrasé ici') }}
    {{ form_row(form.name) }}
    {{ form_widget(form.message, {'attr': {'placeholder': 'Remplacez ce texte par votre message'} }) }}

    {{ form_rest(form) }}

    {{ form_row(form.submit, { 'label': 'Submit me' }) }}
{{ form_end(form) }}

RéférencesModifier