Opérations CRUD dans Symfony 2-3
Création d’une entité « Module » et mise en place du CRUD
-
Objectifs
- Comprendre comment créer des entités Symfony, telles que « Module », pour représenter les données de l’application.
- Apprendre à mettre en place les opérations CRUD (Create, Read, Update, Delete) pour interagir avec les données des entités.
- Explorer les techniques pour personnaliser les vues à l’aide de Twig, le moteur de template par défaut de Symfony.
-
Introduction
- Symfony est un framework PHP moderne qui simplifie le processus de développement d’applications web robustes.
- Dans ce tutoriel, nous allons apprendre à créer une entité « Module », en utilisant la commande make:entity de Symfony.
- Ensuite, nous mettrons en place les opérations CRUD pour cet entité afin de gérer efficacement les données.
-
Création de l’entité Module:
- Pour créer une entité « Module » avec Symfony en utilisant la commande make:entity, vous pouvez suivre ces étapes :
- Ouvrez votre terminal ou votre invite de commande.
- Utilisez la commande suivante pour générer l’entité Module:
symfony console make:entity Module
- Après avoir exécuté cette commande, vous serez guidé à travers un questionnaire interactif pour définir les propriétés de votre entité Module.
- Le questionnaire vous demandera de fournir les détails pour chaque champ de l’entité.
-
Création du CRUD avec Symfony
-
Commande à utiliser
- Pour commencer à mettre en place le CRUD (Create, Read, Update, Delete), il fautous pouvez saisir la commande suivante :
symfony console make:crud
-
Etapes de réalisation
- Après avoir exécuté la commande symfony console
make:crud
, voici les étapes : - Une fois la commande exécutée, Symfony vous demande le nom de la classe de l’entité pour laquelle vous souhaitez créer le CRUD. Dans cet exemple, le nom de l’entité est « Module ».
- Symfony vous demande de choisir un nom pour votre classe de contrôleur. Par défaut, il vous suggère « ModuleController », mais vous pouvez saisir un nom différent si vous le souhaitez. Par exemple, si vous créez un CRUD pour une entité « Matière », vous pourriez nommer votre contrôleur « MatiereController ».
- Symfony vous demande ensuite si vous souhaitez générer des tests pour le contrôleur. Cette fonctionnalité est expérimentale. Vous pouvez répondre « yes » si vous souhaitez générer des tests unitaires pour votre contrôleur, ou « no » si vous ne le souhaitez pas.
-
Les fichiers générés
- Après avoir répondu aux questions, Symfony génère les fichiers suivants :
- src/Controller/ModuleController.php : Le contrôleur contenant les actions pour le CRUD.
- src/Form/ModuleType.php : Le formulaire Symfony correspondant à l’entité « Module ».
- templates/module/_delete_form.html.twig : Le modèle Twig pour le formulaire de suppression.
- templates/module/_form.html.twig : Le modèle Twig pour le formulaire de création/modification.
- templates/module/edit.html.twig : Le modèle Twig pour la vue d’édition.
- templates/module/index.html.twig : Le modèle Twig pour la vue d’index (liste des entités).
- templates/module/new.html.twig : Le modèle Twig pour la vue de création.
- templates/module/show.html.twig : Le modèle Twig pour la vue de détails.
- Une fois ces fichiers générés, le message « Success! » indique que le CRUD a été créé avec succès. Vous pouvez maintenant vérifier votre nouveau CRUD en accédant à l’URL /module/ dans votre application Symfony.
-
Mettre à jour les modèles Twig
- Twig est le langage de création de modèles utilisé dans Symfony qui vous permet de créer des modèles concis et lisibles, et il est plus puissant à plusieurs égards que les modèles PHP.
- Nous utiliserons Bootstrap 5 pour ajouter des styles sur notre modèle.
- Ouvrez templates/base.html.twig et ajoutez les css et js de Bootstrap :
- Nous allons maintenant mettre à jour les modèles de brindilles générés lors de la création d’un contrôleur. Nous y ajouterons des styles car il s’agit d’un code déjà fonctionnel pour les opérations CRUD et nous créerons quelques ajustements.
- Nous mettrons à jour les fichiers dans ce dossier templates/module :
- _delete_form.html.twig : Ce fichier est utilisé pour afficher un formulaire de confirmation de suppression d’un élément. Il est généralement inclus dans une vue de détails (show.html.twig) ou dans une vue index (index.html.twig) pour chaque élément listé.
- Vous pouvez supprimer le templates/project /_delete_form.html.twig puisque nous allons déplacer son code sur le templates/project/index.html.twig .
- _form.html.twig : Ce fichier est utilisé pour afficher le formulaire d’édition ou de création d’un nouvel élément. Il est généralement inclus dans les vues edit.html.twig et nouveau.html.twig. Il contient les champs nécessaires pour l’édition ou la création d’un élément.
<div class="container"> <div class="row justify-content-center"> <div class="col-md-6"> {{ form_start(form) }} <div class="form-group"> {{ form_row(form.libelle, {'attr': {'class': 'form-control'}}) }} </div> <div class="form-group"> {{ form_row(form.duree, {'attr': {'class': 'form-control'}}) }} </div> <button class="btn {{ button_color|default('btn-outline-primary') }} mt-3">{{ button_label|default('Enregistrer le module') }}</button> {{ form_end(form) }} </div> </div> </div>
- edit.html.twig : Ce fichier est utilisé pour afficher le formulaire d’édition d’un élément existant. Il inclut généralement le fichier _form.html.twig pour afficher le formulaire complet.
{% extends 'base.html.twig' %} {% block title %}Editer Module{% endblock %} {% block body %} <div class="container"> <h2 class="text-center mt-5 mb-3">Editer Module</h2> <div class="card"> <div class="card-header"> <a class="btn btn-outline-info float-right" href="{{ path('app_module_index') }}"> Afficher liste des modules </a> </div> <div class="card-body"> {% include 'module/_form.html.twig' with {'button_label': 'Mèttre à jour le module', 'button_color': 'btn-outline-success'} %} </div> </div> </div> {% endblock %}
- index.html.twig : Ce fichier est utilisé pour afficher une liste d’éléments. Il peut inclure des liens vers les vues de détail (show.html.twig), de modification (edit.html.twig) et de suppression (_delete_form.html.twig).
{% extends 'base.html.twig' %} {% block title %}Module index{% endblock %} {% block body %} <div class="container"> <h2 class="text-center mt-5 mb-3">Liste des modules</h2> <div class="card"> <div class="card-header"> <a class="btn btn-outline-primary" href="{{ path('app_module_new') }}"> Créer un nouveau Module </a> </div> <div class="card-body"> <table class="table table-bordered"> <tr> <tr> <th>Id</th> <th>Libelle</th> <th>Duree</th> <th width="240px">Action</th> </tr> {% for module in modules %} <tr> <td>{{ module.id }}</td> <td>{{ module.libelle }}</td> <td>{{ module.duree }}</td> <td> <form method="post" action="{{ path('app_module_delete', {'id': module.id}) }}" onsubmit="return confirm('Are you sure you want to delete this item?');"> <a class="btn btn-outline-info" href="{{ path('app_module_show', {'id': module.id}) }}"> Show </a> <a class="btn btn-outline-success" href="{{ path('app_module_edit', {'id': module.id}) }}"> Edit </a> <input type="hidden" name="_token" value="{{ csrf_token('delete' ~ module.id) }}"> <button class="btn btn-outline-danger">Delete</button> </form> </td> </tr> {% endfor %} </table> </div> </div> </div> {% endblock %}
- new.html.twig : Ce fichier est utilisé pour afficher le formulaire de création d’un nouvel élément. Il inclut également le fichier _form.html.twig pour afficher le formulaire complet.
{% extends 'base.html.twig' %} {% block title %}New Project{% endblock %} {% block body %} <div class="container"> <h2 class="text-center mt-5 mb-3">Créer un nouveau Module</h2> <div class="card"> <div class="card-header"> <a class="btn btn-outline-info float-right" href="{{ path('app_module_index') }}"> Afficher liste des modules </a> </div> <div class="card-body"> {{ include('module/_form.html.twig') }} </div> </div> </div> {% endblock %}
- show.html.twig : Ce fichier est utilisé pour afficher les détails d’un élément spécifique. Il peut contenir des informations sur l’élément ainsi que des actions telles que l’édition, la suppression, etc.
{% extends 'base.html.twig' %} {% block title %}Project{% endblock %} {% block body %} <div class="container"> <h2 class="text-center mt-5 mb-3">Afficher liste des modules</h2> <div class="card"> <div class="card-header"> <a class="btn btn-outline-info float-right" href="{{ path('app_module_index') }}"> View All Projects </a> </div> <div class="card-body"> <b class="text-muted">ID:</b> <p>{{ module.id }}</p> <b class="text-muted">Libellé:</b> <p>{{ module.libelle }}</p> <b class="text-muted">Durée:</b> <p>{{ module.duree }}</p> </div> <div class="card-footer"> <div class="text-center"> <a href="{{ path('app_module_index') }}" class="btn btn-secondary me-2">Retour à la liste</a> <a href="{{ path('app_module_edit', {'id': module.id}) }}" class="btn btn-primary">Edit</a> </div> </div> </div> </div> {% endblock %}
-
Utiliser des icones pour vos boutons
PS D:\cours\symfony\exemple01\ex02_projet_symfony> symfony console make:crud
The class name of the entity to create CRUD (e.g. FiercePuppy):
> Module
Choose a name for your controller class (e.g. ModuleController) [ModuleController]:
>
Do you want to generate tests for the controller? [Experimental] (yes/no) [no]:
>
created: src/Controller/ModuleController.php
created: src/Form/ModuleType.php
created: templates/module/_delete_form.html.twig
created: templates/module/_form.html.twig
created: templates/module/edit.html.twig
created: templates/module/index.html.twig
created: templates/module/new.html.twig
created: templates/module/show.html.twig
Success!
Next: Check your new CRUD by going to /module/
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>{% block title %}Welcome!{% endblock %}</title>
<link rel="icon" href="data:image/svg+xml,<svg xmlns=%22http://www.w3.org/2000/svg%22 viewBox=%220 0 128 128%22><text y=%221.2em%22 font-size=%2296%22></text><text y=%221.3em%22 x=%220.2em%22 font-size=%2276%22 fill=%22%23fff%22>sf</text></svg>">
{% block stylesheets %}
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-EVSTQN3/azprG1Anm3QDgpJLIm9Nao0Yz1ztcQTwFspd3yD65VohhpuuCOmLASjC" crossorigin="anonymous">
{% endblock %}
{% block javascripts %}
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/js/bootstrap.bundle.min.js" integrity="sha384-MrcW6ZMFYlzcLA8Nl+NtUVF0sA7MsXsP1UyJoMp4YLEuNSfAP+JcXn/tWtIaxVXM" crossorigin="anonymous"></script>
{% endblock %}
</head>
<body>
{% block body %}{% endblock %}
</body>
</html>
{% extends 'base.html.twig' %}
{% block title %}Module index{% endblock %}
{% block body %}
<div class="container">
<div class="row justify-content-center">
<div class="col-md-8">
<h2 class="text-center mt-5 mb-3">Liste des modules</h2>
<div class="card">
<div class="card-header">
<a class="btn btn-outline-primary" href="{{ path('app_module_new') }}">
<i class="fas fa-plus"></i> <!-- Icône pour créer un nouveau module -->
</a>
</div>
<div class="card-body">
<table class="table table-bordered">
<thead>
<tr>
<th>Id</th>
<th>Libelle</th>
<th>Duree</th>
<th width="200px">Actions</th>
</tr>
</thead>
<tbody>
{% for module in modules %}
<tr>
<td>{{ module.id }}</td>
<td>{{ module.libelle }}</td>
<td>{{ module.duree }}</td>
<td>
<form method="post" action="{{ path('app_module_delete', {'id': module.id}) }}" onsubmit="return confirm('Are you sure you want to delete this item?');">
<a class="btn btn-outline-info" href="{{ path('app_module_show', {'id': module.id}) }}">
<i class="fas fa-eye"></i> <!-- Icône pour afficher -->
</a>
<a class="btn btn-outline-success" href="{{ path('app_module_edit', {'id': module.id}) }}">
<i class="fas fa-edit"></i> <!-- Icône pour éditer -->
</a>
<input type="hidden" name="_token" value="{{ csrf_token('delete' ~ module.id) }}">
<button class="btn btn-outline-danger" type="submit">
<i class="fas fa-trash-alt"></i> <!-- Icône pour supprimer -->
</button>
</form>
</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
</div>
</div>
</div>
</div>
{% endblock %}
Captures d’écran: