Skip to Content
SymfonyPartie 18 — Mini-jeux (exploration guidée)Terrain 9 — Formulaires & validation

Terrain 9 — Formulaires & validation

🔍 Renfort : Partie 9.

1. FormType de base ⭐⭐

🕹️ Mission : un ProviderType avec name (texte) et active (case), + bouton.

✅ Solution

$builder ->add('name', TextType::class) ->add('active', CheckboxType::class, ['required' => false]) ->add('submit', SubmitType::class);

2. Traiter la soumission ⭐⭐

🕹️ Mission : la condition standard pour traiter un formulaire.

✅ Solution

$form->handleRequest($request); if ($form->isSubmitted() && $form->isValid()) { /* ... */ }

3. Champ enum ⭐⭐

🕹️ Mission : un select à partir de BookingStatus.

✅ Solution

->add('status', EnumType::class, ['class' => BookingStatus::class])

4. Contraintes de base ⭐⭐

🕹️ Mission : sur un DTO, email requis+valide, plainPassword ≥ 8.

✅ Solution

#[Assert\NotBlank] #[Assert\Email] public string $email = ''; #[Assert\NotBlank] #[Assert\Length(min: 8)] public string $plainPassword = '';

5. DTO plutôt qu’entité ⭐⭐⭐

🕹️ Mission : pour un formulaire d’inscription exposant email/password/roles, pourquoi un DTO ?

✅ Solution

Éviter le mass assignment : lier à l’entité User laisserait modifier roles (élévation de privilèges). Un DTO cadre exactement les champs autorisés ; le service assigne les rôles côté serveur.

6. Unicité ⭐⭐⭐

🕹️ Mission : garantir un email unique. Une contrainte suffit-elle ?

✅ Solution

Non : #[UniqueEntity(fields: ['email'])] (message propre) + unique: true sur la colonne (index unique, garde-fou contre les courses).

7. Contrainte métier ⭐⭐⭐⭐

🕹️ Mission : interdire une réservation sur un créneau complet. Standard ou custom ?

✅ Solution

Custom : Constraint + ConstraintValidator injectable (reçoit SlotAvailabilityChecker), posée sur le DTO. Réutilisée par le formulaire et l’API.

8. Token CSRF manuel ⭐⭐⭐

🕹️ Mission : un formulaire de suppression rendu à la main est toujours invalide. Que manque-t-il ?

✅ Solution

form_rest(form) (rend le token CSRF caché) ; ou, pour un <form> à la main, un csrf_token(...) + isCsrfTokenValid() côté contrôleur.

9. CollectionType ⭐⭐⭐⭐

🕹️ Mission : des sous-formulaires Slot répétés ne persistent pas. Quelle option ?

✅ Solution

by_reference: false (pour appeler addSlot/removeSlot qui synchronisent la relation).

10. Upload sécurisé ⭐⭐⭐⭐

🕹️ Mission : trois règles de sécurité pour un upload de logo.

✅ Solution

Valider le MIME réel (#[Assert\Image], allowlist), régénérer un nom sûr/unique (jamais le nom client), stocker dans un emplacement non exécutable (ou S3).


Terrain suivant : Sécurité.