8 - Création de formulaires (Symfony 7)

Temps de lecture : 25 minutes environ.

Dans cet article, nous allons vous guider à travers le processus de création de formulaires sous Symfony, en utilisant le projet OpenBlog comme exemple. Nous allons aborder l'ajout de mots-clés, de catégories, ainsi que la création d'articles de blog, le tout en exploitant les fonctionnalités offertes par Symfony pour gérer les relations entre les entités, la validation des formulaires, et l'intégration des formulaires dans les vues Twig.

Prérequis

Avant de commencer, assurez-vous d'avoir un environnement Symfony fonctionnel, avec le projet OpenBlog configuré. Vous pouvez accéder au code source complet ici.

Création d'un Formulaire pour les Mots-Clés

Commençons par créer un formulaire permettant d'ajouter des mots-clés dans notre base de données. Nous allons générer un contrôleur et un formulaire à l'aide de la console Symfony.

Génération du Contrôleur et du Formulaire

Utilisez la commande suivante pour créer un contrôleur dans un sous-dossier Admin :

symfony console make:controller Admin/KeywordController

Ensuite, générez un formulaire pour les mots-clés :

symfony console make:form AddKeywordFormType

Ce formulaire est lié à l'entité Keyword qui contient les champs name et slug. Le slug sera généré automatiquement à partir du nom du mot-clé.

Implémentation du Contrôleur

Voici un extrait de code pour le contrôleur KeywordController :

<?php

namespace App\Controller\Admin;

use App\Entity\Keywords;
use App\Form\AddKeywordFormType;
use Doctrine\ORM\EntityManagerInterface;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Annotation\Route;
use Symfony\Component\String\Slugger\SluggerInterface;

#[Route('/admin/keywords', name: 'app_admin_keywords_')]
class KeywordsController extends AbstractController
{
#[Route('/', name: 'index')]
public function index(): Response
{
return $this->render('admin/keywords/index.html.twig', [
'controller_name' => 'KeywordsController',
]);
}

#[Route('/ajouter', name: 'add')]
public function addKeyword(
Request $request,
SluggerInterface $slugger,
EntityManagerInterface $em
): Response
{
// On initialise un mot clé
$keyword = new Keywords();

// On initialise le formulaire
$keywordForm = $this->createForm(AddKeywordFormType::class, $keyword);

// On traite le formulaire
$keywordForm->handleRequest($request);

// On vérifie si le formulaire est envoyé et valide
if($keywordForm->isSubmitted() && $keywordForm->isValid()){
// On crée le slug
$slug = strtolower($slugger->slug($keyword->getName()));

// On attribue le slug à notre mot clé
$keyword->setSlug($slug);

// On enregistre le mot clé en base de données
$em->persist($keyword);
$em->flush();

$this->addFlash('success', 'Le mot-clé a été créé');
return $this->redirectToRoute('app_admin_keywords_index');
}

// On affiche la vue
return $this->render('admin/keywords/add.html.twig', [
'keywordForm' => $keywordForm->createView(),
]);
}
}

Ce code initialise un mot-clé vide, puis crée et gère le formulaire. Si le formulaire est soumis et valide, le slug est généré, et le mot-clé est enregistré dans la base de données.

Gestion des Catégories avec Relations Parentales

La gestion des catégories implique une relation potentielle entre une catégorie et une autre (parent/enfant). Nous allons aborder la création d'un formulaire permettant cette gestion.

Création du Formulaire pour les Catégories

Utilisez les commandes suivantes pour générer un contrôleur et un formulaire pour les catégories :

symfony console make:controller Admin/CategoryController
symfony console make:form AddCategoryFormType

Dans le formulaire, nous devons permettre la sélection d'une catégorie parente. Voici comment nous pouvons configurer le CategoryFormType :

<?php

namespace App\Form;

use App\Entity\Categories;
use App\Repository\CategoriesRepository;
use Symfony\Bridge\Doctrine\Form\Type\EntityType;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\Extension\Core\Type\TextType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolver;

class AddCategoriesFormType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options): void
{
$builder
->add('name', TextType::class, [
'label' => 'Nom de la catégorie'
])
->add('parent', EntityType::class, [
'class' => Categories::class,
'choice_label' => 'name',
'placeholder' => '-- Pas de parent --',
'required' => false,
'query_builder' => function(CategoriesRepository $cr){
return $cr->createQueryBuilder('c')
->orderBy('c.name', 'ASC');
}
])
;
}

public function configureOptions(OptionsResolver $resolver): void
{
$resolver->setDefaults([
'data_class' => Categories::class,
]);
}
}

Implémentation du Contrôleur pour les Catégories

Le contrôleur CategoryController suit une logique similaire à celle du KeywordController, en prenant en compte la relation parent/enfant.

<?php

namespace App\Controller\Admin;

use App\Entity\Categories;
use App\Form\AddCategoriesFormType;
use Doctrine\ORM\EntityManagerInterface;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Annotation\Route;
use Symfony\Component\String\Slugger\SluggerInterface;

#[Route('/admin/categories', name: 'app_admin_categories_')]
class CategoriesController extends AbstractController
{
#[Route('/', name: 'index')]
public function index(): Response
{
return $this->render('admin/categories/index.html.twig', [
'controller_name' => 'CategoriesController',
]);
}

#[Route('/ajouter', name: 'add')]
public function addCategory(
Request $request,
SluggerInterface $slugger,
EntityManagerInterface $em
): Response
{
// On initialise une catégorie
$category = new Categories();

// On initialise le formulaire
$categoryForm = $this->createForm(AddCategoriesFormType::class, $category);

// On traite le formulaire
$categoryForm->handleRequest($request);

// On vérifie si le formulaire est envoyé et valide
if($categoryForm->isSubmitted() && $categoryForm->isValid()){
// On génère le slug
$slug = strtolower($slugger->slug($category->getName()));

// On ajoute le slug à la catégorie
$category->setSlug($slug);

// On enregistre la catégorie en base de données
$em->persist($category);
$em->flush();

$this->addFlash('success', 'La catégorie a été créée');
return $this->redirectToRoute('app_admin_categories_index');
}

// On affiche la vue
return $this->render('admin/categories/add.html.twig', [
'categoryForm' => $categoryForm->createView(),
]);
}
}

3. Création d'Articles de Blog

Enfin, nous allons créer un formulaire pour ajouter des articles de blog, incluant la gestion des catégories et des mots-clés associés.

Génération du Formulaire pour les Articles

Générez le formulaire et le contrôleur pour les articles avec les commandes suivantes :

symfony console make:controller Profile/PostController
symfony console make:form AddPostFormType

Le formulaire pour les articles inclut des champs pour le titre, le contenu, l'image vedette, les catégories et les mots-clés. Voici un exemple de configuration de ce formulaire :

<?php

namespace App\Form;

use App\Entity\Categories;
use App\Entity\Keywords;
use App\Entity\Posts;
use App\Entity\Users;
use Symfony\Bridge\Doctrine\Form\Type\EntityType;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\Extension\Core\Type\FileType;
use Symfony\Component\Form\Extension\Core\Type\TextareaType;
use Symfony\Component\Form\Extension\Core\Type\TextType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolver;

class AddPostFormType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options): void
{
$builder
->add('title', TextType::class, [
'label' => 'Titre de l\'article'
])
->add('content', TextareaType::class, [
'label' => 'Contenu de l\'article'
])
->add('featuredImage', FileType::class, [
'label' => 'Image de l\'article',
'mapped' => false
])
->add('categories', EntityType::class, [
'class' => Categories::class,
'choice_label' => 'name',
'multiple' => true,
'expanded' => true
])
->add('keywords', EntityType::class, [
'class' => Keywords::class,
'choice_label' => 'name',
'multiple' => true,
'expanded' => true
])
;
}

public function configureOptions(OptionsResolver $resolver): void
{
$resolver->setDefaults([
'data_class' => Posts::class,
]);
}
}

Gestion des Images et Relations dans le Contrôleur

Dans le contrôleur, nous devons gérer le téléchargement de l'image, ce sera fait dans une prochaine partie

<?php

namespace App\Controller\Profile;

use App\Entity\Posts;
use App\Form\AddPostFormType;
use App\Repository\UsersRepository;
use Doctrine\ORM\EntityManagerInterface;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Annotation\Route;
use Symfony\Component\String\Slugger\SluggerInterface;

#[Route('/profil/articles', name: 'app_profile_posts_')]
class PostsController extends AbstractController
{
#[Route('/', name: 'index')]
public function index(): Response
{
return $this->render('profile/posts/index.html.twig', [
'controller_name' => 'PostsController',
]);
}

#[Route('/ajouter', name: 'add')]
public function addArticle(
Request $request,
SluggerInterface $slugger,
EntityManagerInterface $em,
UsersRepository $usersRepository
): Response
{
$post = new Posts();

$form = $this->createForm(AddPostFormType::class, $post);

$form->handleRequest($request);

if($form->isSubmitted() && $form->isValid()){
$post->setSlug(strtolower($slugger->slug($post->getTitle())));

$post->setUsers($usersRepository->find(1));

$post->setFeaturedImage('default.webp');

$em->persist($post);
$em->flush();

$this->addFlash('success', 'L\'article a été créé');
return $this->redirectToRoute('app_profile_posts_index');
}

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

Conclusion

Avec ces formulaires, vous avez maintenant une base solide pour gérer l'ajout de contenus dynamiques dans votre blog Symfony. Que ce soit pour des mots-clés, des catégories ou des articles, ces concepts peuvent être étendus pour inclure des fonctionnalités plus avancées, telles que la gestion des utilisateurs, des permissions, et bien plus encore.

N'hésitez pas à explorer et à adapter ces exemples pour répondre à vos besoins spécifiques, et si vous avez des questions, la communauté est là pour vous aider.

Obtenir de l'aide

Pour obtenir de l'aide, vous pouvez accéder au serveur Discord pour une entraide par chat.

8 - Création de formulaires (Symfony 7)
Article publié le

Catégories : Symfony formulaire Symfony 7

Mots-clés : Symfony Formulaires entity Symfony 7

Partager : Partager sur Facebook Partager sur Twitter Partager sur LinkedIn