Accueil » Symfony 6 CRUD

Symfony 6 CRUD

Dans cette procédure, je vais vous expliquer comment créer un CRUD à l’aide du Framework PHP Symfony 6.
La création d’un CRUD permet de gérer énormément de cas d’utilisation dans vos applications.

Logo Symfony

Prérequis :

Création du projet CRUD avec Symfony 6 :

Pour débuter ce projet, nous allons d’abord créer un nouveau projet, puis nous allons créer une entité Article et ensuite nous allons importer Bootstrap.

Création du projet :

Pour débuter, nous allons créer une nouvelle application à l’aide de la commande suivante :

symfony new projet_crud --webapp

Puis nous allons nous rendre dans le dossier notre application :

cd projet_crud

Ensuite nous allons personnaliser notre connexion à la base de données en modifiant le fichier .env :

DATABASE_URL="mysql://nom_utilisateur:mot_de_passe@127.0.0.1:3306/nom_bdd?serverVersion=version_mariadb&charset=utf8mb4"
  
avec mes valeurs 
  
DATABASE_URL="mysql://symfony:password@127.0.0.1:3306/projet_crud?serverVersion=mariadb-10.5.15&charset=utf8mb4"

Ensuite on vérifie que la liaison avec la base de données soit correct en créant la nouvelle base de donnée à l’aide de Doctrine :

symfony console d:d:c

Si le retour de la commande affiche le même contenu que si dessous, c’est que votre liaison fonctionne :

Symfony CRUD - Création de la base de données

Création de l’entité Article :

Pour créer l’entité article, si vous avez besoin de plus de détails, je vous invite à suivre cette procédure : Symfony 6 Créer une entité

Pour créer l’entité Article nous allons saisir la commande suivant :

symfony console make:entity Article

Article(id, date_publication, titre, contenu)

  • id: int
  • date_publication : Date
  • titre : String (50)
  • contenu : Text

Ensuite il faut répondre au questionnaire du script comme ci-dessous :

 created: src/Entity/Article.php
 created: src/Repository/ArticleRepository.php
 
 Entity generated! Now let's add some fields!
 You can always add more fields later manually or by re-running this command.

 New property name (press <return> to stop adding fields):
 > date_publication

 Field type (enter ? to see all types) [string]:
 > date

 Can this field be null in the database (nullable) (yes/no) [no]:
 > 

 updated: src/Entity/Article.php

 Add another property? Enter the property name (or press <return> to stop adding fields):
 > titre

 Field type (enter ? to see all types) [string]:
 > string

 Field length [255]:
 > 50

 Can this field be null in the database (nullable) (yes/no) [no]:
 > no

 updated: src/Entity/Article.php

 Add another property? Enter the property name (or press <return> to stop adding fields):
 > contenu

 Field type (enter ? to see all types) [string]:
 > text

 Can this field be null in the database (nullable) (yes/no) [no]:
 > no

 updated: src/Entity/Article.php

 Add another property? Enter the property name (or press <return> to stop adding fields):
 > 


           
  Success! 
           

 Next: When you're ready, create a migration with php bin/console make:migration

Ensuite nous pouvons faire la migration de doctrine :

symfony console make:migration

Puis on migre les données :

symfony console d:m:m

Import de Bootstrap dans nôtre projet CRUD Symfony 6 :

Nous allons utiliser le framework CSS Bootstrap afin de créer plus rapidement l’interface utilisateur. Ce procéder nous permettra de mieux approfondir la partie technique.

Pour avoir plus de détails sur cette partie, je vous invite à voir cet article : Importer Bootstrap dans Symfony 6.

Pour commencer, nous allons importer Webpack à l’aide de composer :

composer require symfony/webpack-encore-bundle

Puis nous installons les dépendances de Webpack avec Npm :

npm install

Modifier le fichier base.html.twig dans le dossier templates/ :

<!DOCTYPE html>
<html>
    <head>
        <meta charset="UTF-8">
        <title>{% block title %}Welcome!{% endblock %}</title>
        <!-- CSS only -->
        <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.2.0-beta1/dist/css/bootstrap.min.css" rel="stylesheet">
        {% block stylesheets %}{{ encore_entry_link_tags('app') }}{% endblock %}
    </head>
    <body>
        <div class="container mt-4">
            {% block body %}{% endblock %}
            {% block javascripts %}{{ encore_entry_script_tags('app') }}{% endblock %}
        </div>
    </body>
    <!-- JavaScript Bundle with Popper -->
    <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.2.0-beta1/dist/js/bootstrap.bundle.min.js"></script>
</html>

Ensuite on vérifie la compilation du projet avec la commande suivante :

npm run build

Si vous souhaitez utiliser du Scss ou utilisez Bootstrap sans CDN, je vous invite à regarder la procédure suivante : Importer Bootstrap dans Symfony 6

Création du CRUD avec Symfony 6 :

Pour commencer le crud il faut saisir la commande suivante :

symfony console make:crud

Ensuite remplissez le formulaire demander par la CLI :

 The class name of the entity to create CRUD (e.g. VictoriousPizza):
 > Article

 Choose a name for your controller class (e.g. ArticleController) [ArticleController]:
 > ArticleController

 Do you want to generate tests for the controller?. [Experimental] (yes/no) [no]:
 > no

 created: src/Controller/ArticleController.php
 created: src/Form/ArticleType.php
 created: templates/article/_delete_form.html.twig
 created: templates/article/_form.html.twig
 created: templates/article/edit.html.twig
 created: templates/article/index.html.twig
 created: templates/article/new.html.twig
 created: templates/article/show.html.twig

           
  Success! 
           

 Next: Check your new CRUD by going to /article/

Pour adapter nos formulaire à Bootstrap nous allons ajouter un paramètre dans le fichier config/packages/twig.yaml :

twig:
    form_themes: ['bootstrap_5_layout.html.twig']

Pusi ensuite vous pouvez personnaliser l’affichage des formulaires, voici un exemple :

  • _delete_form.html.twig
<form method="post" action="{{ path('app_article_delete', {'id': article.id}) }}" onsubmit="return confirm('Êtes-vous sur de vouloir supprimer cet article ?');" class="d-inline-block">
    <input type="hidden" name="_token" value="{{ csrf_token('delete' ~ article.id) }}">
    <button class="btn btn-danger">Supprimer</button>
</form>
  • _form.html.twig
{{ form_start(form) }}
    {{ form_widget(form) }}
    <button class="btn btn-success">{{ button_label|default('Enregistrer') }}</button>
{{ form_end(form) }}
  • edit.html.twig
{% extends 'base.html.twig' %}

{% block title %}Modification d'Article{% endblock %}

{% block body %}
    <h1>Modification d'Article</h1>

    {{ include('article/_form.html.twig', {'button_label': 'Modifier'}) }}

    <a href="{{ path('app_article_index') }}" class="btn btn-primary">Retour à la liste</a>

    {{ include('article/_delete_form.html.twig') }}
{% endblock %}
  • index.html.twig
{% extends 'base.html.twig' %}

{% block title %}Article index{% endblock %}

{% block body %}
    <h1>Article index</h1>

    <table class="table">
        <thead>
            <tr>
                <th>Id</th>
                <th>Date_publication</th>
                <th>Titre</th>
                <th>Contenu</th>
                <th>actions</th>
            </tr>
        </thead>
        <tbody>
        {% for article in articles %}
            <tr>
                <td>{{ article.id }}</td>
                <td>{{ article.datePublication ? article.datePublication|date('Y-m-d') : '' }}</td>
                <td>{{ article.titre }}</td>
                <td>{{ article.contenu }}</td>
                <td>
                    <a href="{{ path('app_article_show', {'id': article.id}) }}" class="btn btn-primary">Voir</a>
                    <a href="{{ path('app_article_edit', {'id': article.id}) }}" class="btn btn-success">Editer</a>
                </td>
            </tr>
        {% else %}
            <tr>
                <td colspan="5">Aucun résultat</td>
            </tr>
        {% endfor %}
        </tbody>
    </table>

    <a href="{{ path('app_article_new') }}" class="btn btn-primary">Créer un nouvel article</a>
{% endblock %}
  • new.html.twig
{% extends 'base.html.twig' %}

{% block title %}Nouvel Article{% endblock %}

{% block body %}
    <h1>Créer un nouvel Article</h1>

    <div class="form mb-2">
        {{ include('article/_form.html.twig') }}
    </div>

    <a href="{{ path('app_article_index') }}" class="btn btn-primary">Retour à la liste</a>
{% endblock %}
  • show.html.twig
{% extends 'base.html.twig' %}

{% block title %}Article{% endblock %}

{% block body %}
    <h1>Article</h1>

    <table class="table table-dark">
        <tbody>
            <tr>
                <th>Id</th>
                <td>{{ article.id }}</td>
            </tr>
            <tr>
                <th>Date_publication</th>
                <td>{{ article.datePublication ? article.datePublication|date('Y-m-d') : '' }}</td>
            </tr>
            <tr>
                <th>Titre</th>
                <td>{{ article.titre }}</td>
            </tr>
            <tr>
                <th>Contenu</th>
                <td>{{ article.contenu }}</td>
            </tr>
        </tbody>
    </table>

    <a href="{{ path('app_article_index') }}" class="btn btn-primary">Retour à la liste</a>

    <a href="{{ path('app_article_edit', {'id': article.id}) }}" class="btn btn-success">Editer</a>

    {{ include('article/_delete_form.html.twig') }}
{% endblock %}

Sources :

https://symfony.com/doc/current/index.html

Susceptible de vous intéresser :