Le Bundle EasyAdmin 4 permet de créer un menu d’administration avec le Framework Symfony 6. Dans cette procédure, je vais vous montrer comment créer un menu d’administration à l’aide ce Bundle Symfony 6. Nous allons commencer par créer un nouveau projet avec de nouvelles entités et puis nous les intégrerons dans EasyAdmin.
Prérequis :
Création d’un menu d’administration sous Symfony 6 avec EasyAdmin 4 :
Avant de créer le menu d’administration, nous allons préparer le projet dans lequel nous allons créer ce menu d’administration.
Préparation de l’application Symfony :
Pour préparer le projet, nous allons créer le projet, puis le connecter à notre base de données et ensuite nous allons créer deux entités pour la présentation.
Création du projet et configuration de la base de données :
Pour débuter ce projet, nous allons créer un nouveau projet Symfony 6 à l’aide de la commande suivante :
symfony new projet_administration --webapp
Puis on rentre dans le dossier du projet :
cd projet_administration
Ensuite nous allons modifier le fichier .env pour changer les accès à la base de données. J’utilise dans le cadre de cette procédure MariaDB (Installer Mariadb sur Debian 11).
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_administration?serverVersion=mariadb-10.5.15&charset=utf8mb4"
Création de la base de données à l’aide de la CLI Symfony :
symfony console doctrine:database:create
Ou avec cette commande qui est plus courte :
symfony console d:d:c
Ensuite on importe Encore et Webpack :
composer require encore
composer require symfony/webpack-encore-bundle
Création de deux entités (Article et Catégories) dans l’application Symfony :
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é
On créer l’entité Categorie :
symfony console make:entity Categorie
# Ou
symfony console m:e Categorie
Categorie :
- id : int
- nom : String (255)
- active : Boolean
- dateModification : DateTimeImmutable
- dateCreation : DateTimeImmutable
Ensuite il faut répondre au questionnaire du script comme ci-dessous :
created: src/Entity/Categorie.php
created: src/Repository/CategorieRepository.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):
> nom
Field type (enter ? to see all types) [string]:
>
Field length [255]:
>
Can this field be null in the database (nullable) (yes/no) [no]:
>
updated: src/Entity/Categorie.php
Add another property? Enter the property name (or press <return> to stop adding fields):
> active
Field type (enter ? to see all types) [string]:
> boolean
Can this field be null in the database (nullable) (yes/no) [no]:
>
updated: src/Entity/Categorie.php
Add another property? Enter the property name (or press <return> to stop adding fields):
> dateModification
Field type (enter ? to see all types) [string]:
> datetime_immutable
Can this field be null in the database (nullable) (yes/no) [no]:
> yes
updated: src/Entity/Categorie.php
Add another property? Enter the property name (or press <return> to stop adding fields):
> dateCreation
Field type (enter ? to see all types) [string]:
> datetime_immutable
Can this field be null in the database (nullable) (yes/no) [no]:
>
updated: src/Entity/Categorie.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
Pour créer l’entité Article nous allons saisir la commande suivant :
symfony console make:entity Article
# Ou
symfony console m:e Article
Article :
- id: int
- titre : String (255)
- contenu : Text
- datePublication : DateTimeImmutable
- dateModification : DateTimeImmutable
- actif : Boolean
- categorie : relation (Many To One)
Ensuite il faut répondre au questionnaire du script comme ci-dessous :
MODIFIER QUESTIONNAIRE ENTITE ARTICLE
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):
> titre
Field type (enter ? to see all types) [string]:
>
Field length [255]:
>
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):
> contenu
Field type (enter ? to see all types) [string]:
> text
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):
> datePublication
Field type (enter ? to see all types) [string]:
> datetime_immutable
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):
> dateModification
Field type (enter ? to see all types) [string]:
> datetime_immutable
Can this field be null in the database (nullable) (yes/no) [no]:
> yes
updated: src/Entity/Article.php
New property name (press <return> to stop adding fields):
> actif
Field type (enter ? to see all types) [string]:
> boolean
Can this field be null in the database (nullable) (yes/no) [no]:
>
New property name (press <return> to stop adding fields):
> categorie
Field type (enter ? to see all types) [string]:
> relation
What class should this entity be related to?:
> Categorie
What type of relationship is this?
------------ ------------------------------------------------------------------------
Type Description
------------ ------------------------------------------------------------------------
ManyToOne Each Article relates to (has) one Categorie.
Each Categorie can relate to (can have) many Article objects
OneToMany Each Article can relate to (can have) many Categorie objects.
Each Categorie relates to (has) one Article
ManyToMany Each Article can relate to (can have) many Categorie objects.
Each Categorie can also relate to (can also have) many Article objects
OneToOne Each Article relates to (has) exactly one Categorie.
Each Categorie also relates to (has) exactly one Article.
------------ ------------------------------------------------------------------------
Relation type? [ManyToOne, OneToMany, ManyToMany, OneToOne]:
> ManyToOne
Is the Article.categorie property allowed to be null (nullable)? (yes/no) [yes]:
> no
Do you want to add a new property to Categorie so that you can access/update Article objects from it - e.g. $categorie->getArticles()? (yes/no) [yes]:
>
A new property will also be added to the Categorie class so that you can access the related Article objects from it.
New field name inside Categorie [articles]:
>
Do you want to activate orphanRemoval on your relationship?
A Article is "orphaned" when it is removed from its related Categorie.
e.g. $categorie->removeArticle($article)
NOTE: If a Article may *change* from one Categorie to another, answer "no".
Do you want to automatically delete orphaned App\Entity\Article objects (orphanRemoval)? (yes/no) [no]:
>
updated: src/Entity/Article.php
updated: src/Entity/Categorie.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
Une fois que les entitées ont étés créées, nous pouvons réalisé la migration vers la base de données :
symfony console make:migration
Puis on migre les données :
symfony console d:m:m
Mise en place du menu d’administration EasyAdmin Symfony :
Pour créer notre dashboard d’administration nous avons besoin d’importer le Bundle EasyAdmin :
composer require easycorp/easyadmin-bundle
Puis création de menu d’administration :
symfony console make:admin:dashboard
Which class name do you prefer for your Dashboard controller? [DashboardController]:
>
In which directory of your project do you want to generate "DashboardController"? [src/Controller/Admin/]:
>
[OK] Your dashboard class has been successfully generated.
Next steps:
* Configure your Dashboard at "src/Controller/Admin/DashboardController.php"
* Run "make:admin:crud" to generate CRUD controllers and link them from the Dashboard.
Ensuite si vous démarrer votre serveur Symfony 6 vous pouvez allez consulter la route /admin :
symfony serve
Puis nous pouvons créer le CRUD (Create, Read, Update, Delete) :
symfony console make:admin:crud
Ensuite un questionnaire nous demande quelle Entité le CRUD doit gérer :
Which Doctrine entity are you going to manage with this CRUD controller?:
[0] App\Entity\Article
[1] App\Entity\Categorie
> 0
Which directory do you want to generate the CRUD controller in? [src/Controller/Admin/]:
>
Namespace of the generated CRUD controller [App\Controller\Admin]:
>
[OK] Your CRUD controller class has been successfully
generated.
Next steps:
* Configure your controller at "src/Controller/Admin/ArticleCrudController.php"
* Read EasyAdmin docs: https://symfony.com/doc/master/bundles/EasyAdminBundle/index.html
Puis on refait la même étape pour créer le CRUD des catégories :
symfony console make:admin:crud
Which Doctrine entity are you going to manage with this CRUD controller?:
[0] App\Entity\Article
[1] App\Entity\Categorie
> 1
Which directory do you want to generate the CRUD controller in? [src/Controller/Admin/]:
>
Namespace of the generated CRUD controller [App\Controller\Admin]:
>
[OK] Your CRUD controller class has been successfully
generated.
Next steps:
* Configure your controller at "src/Controller/Admin/CategorieCrudController.php"
* Read EasyAdmin docs: https://symfony.com/doc/master/bundles/EasyAdminBundle/index.html
Ensuite on installe les librairies :
npm install
Puis ensuite on compile avec NPM :
npm run build
Ajout du CRUD dans l’affiche de l’administration dans le fichier src/Controller/Admin/DashboardController.php :
<?php
namespace App\Controller\Admin;
use App\Entity\Article;
use App\Entity\Categorie;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Annotation\Route;
use EasyCorp\Bundle\EasyAdminBundle\Config\Crud;
use EasyCorp\Bundle\EasyAdminBundle\Config\MenuItem;
use EasyCorp\Bundle\EasyAdminBundle\Config\Dashboard;
use EasyCorp\Bundle\EasyAdminBundle\Router\AdminUrlGenerator;
use EasyCorp\Bundle\EasyAdminBundle\Controller\AbstractDashboardController;
class DashboardController extends AbstractDashboardController
{
public function __construct(
private AdminUrlGenerator $adminUrlGenerator
)
{
}
#[Route('/admin', name: 'admin')]
public function index(): Response
{
$url = $this->adminUrlGenerator
->setController(ArticleCrudController::class)
->generateUrl();
return $this->redirect($url);
}
public function configureDashboard(): Dashboard
{
return Dashboard::new()
->setTitle('Projet Administration');
}
public function configureMenuItems(): iterable
{
yield MenuItem::section('Blog');
yield MenuItem::linkToDashboard('Dashboard', 'fa fa-home');
yield MenuItem::section('Articles');
yield MenuItem::subMenu('Actions', 'fas fa-bar')->setSubItems([
MenuItem::linkToCrud('Create Article', 'fas fa-plus-circle', Article::class)->setAction(Crud::PAGE_NEW),
MenuItem::linkToCrud('Show Articles', 'fas fa-eye', Article::class),
]);
yield MenuItem::section('Categories');
yield MenuItem::subMenu('Actions', 'fas fa-bar')->setSubItems([
MenuItem::linkToCrud('Create Categorie', 'fas fa-plus-circle', Categorie::class)->setAction(Crud::PAGE_NEW),
MenuItem::linkToCrud('Show Categories', 'fas fa-eye', Categorie::class),
]);
}
}
Modification des champs dans le CRUD des Categories et le fonctionnement (src/Controller/CategorieCrudController.php) :
<?php
namespace App\Controller\Admin;
use App\Entity\Categorie;
use Doctrine\ORM\EntityManagerInterface;
use EasyCorp\Bundle\EasyAdminBundle\Field\IdField;
use EasyCorp\Bundle\EasyAdminBundle\Field\TextField;
use EasyCorp\Bundle\EasyAdminBundle\Controller\AbstractCrudController;
use EasyCorp\Bundle\EasyAdminBundle\Field\BooleanField;
use EasyCorp\Bundle\EasyAdminBundle\Field\DateTimeField;
class CategorieCrudController extends AbstractCrudController
{
public static function getEntityFqcn(): string
{
return Categorie::class;
}
public function configureFields(string $pageName): iterable
{
return [
IdField::new('id')->hideOnForm(),
TextField::new('nom'),
BooleanField::new('active'),
DateTimeField::new('dateModification')->hideOnForm(),
DateTimeField::new('dateCreation')->hideOnForm(),
];
}
public function persistEntity(EntityManagerInterface $entityManager, $entityInstance): void
{
if (!$entityInstance instanceof Categorie) return;
$entityInstance->setDateCreation(new \DateTimeImmutable());
parent::persistEntity($entityManager, $entityInstance);
}
public function updateEntity(EntityManagerInterface $entityManager, $entityInstance):void
{
if (!$entityInstance instanceof Categorie) return;
$entityInstance->setDateModification(new \DateTimeImmutable());
parent::persistEntity($entityManager, $entityInstance);
}
}
On refait la même opération pour le CRUD Article (src/Controller/Admin/ArticleCrudController.php) :
<?php
namespace App\Controller\Admin;
use App\Entity\Article;
use Doctrine\ORM\EntityManagerInterface;
use EasyCorp\Bundle\EasyAdminBundle\Field\IdField;
use EasyCorp\Bundle\EasyAdminBundle\Field\TextField;
use EasyCorp\Bundle\EasyAdminBundle\Field\BooleanField;
use EasyCorp\Bundle\EasyAdminBundle\Field\DateTimeField;
use EasyCorp\Bundle\EasyAdminBundle\Controller\AbstractCrudController;
use EasyCorp\Bundle\EasyAdminBundle\Field\AssociationField;
class ArticleCrudController extends AbstractCrudController
{
public const ACTION_DUPLICATE = 'duplicate';
public static function getEntityFqcn(): string
{
return Article::class;
}
public function configureFields(string $pageName): iterable
{
return [
IdField::new('id')->hideOnForm(),
TextField::new('titre'),
TextField::new('contenu'),
BooleanField::new('actif'),
AssociationField::new('categorie'),
DateTimeField::new('dateModification')->hideOnForm(),
DateTimeField::new('datePublication')->hideOnForm(),
];
}
public function persistEntity(EntityManagerInterface $entityManager, $entityInstance): void
{
if (!$entityInstance instanceof Article) return;
$entityInstance->setDatePublication(new \DateTimeImmutable());
parent::persistEntity($entityManager, $entityInstance);
}
public function updateEntity(EntityManagerInterface $entityManager, $entityInstance):void
{
if (!$entityInstance instanceof Article) return;
$entityInstance->setDateModification(new \DateTimeImmutable());
parent::persistEntity($entityManager, $entityInstance);
}
}
Ensuite dans l’entité Categorie ajouter la méthode suivant (__toString) qui va permettre d’afficher le nom de la catégorie lors de la recherche d’une categorie pour un article :
public function __toString(): string
{
return $this->nom;
}
Enfin nous pouvons utilisé le crud depuis la route /admin :
Sources :
https://symfony.com/bundles/EasyAdminBundle/current/index.html