Après avoir mis en place notre site, il est souvent nécessaire de créer une interface d'administration, qui permettra de créer, modifier, et supprimer différents types de contenus.
ATTENTION : Ce tutoriel est adapté à la version 2 de EasyAdmin et n'est pas compatible avec la version 3 sortie en juin 2020.
ATTENTION : les fichiers correspondant à cet article sont disponibles à cette adresse sur Github.
Cette interface d'administration peut être créée de toute pièce ou peut être créée en utilisant un bundle disponible sur Symfony, appelé Easy Admin, que nous utiliserons ici.
Avant toute chose, nous aurons besoin d'installer différents outils qui nous permettront :
- De générer automatiquement les "slugs"
- De générer automatiquement les dates de création et mise à jour
- De créer des articles en utilisant un éditeur "Wysiwyg" qui permettra de mettre le texte en forme
- D'ajouter une image pour illustrer l'article
Création des slugs
Lors de l'ajout d'un article, nous allons générer une version simplifiée de son titre qui sera utilisée dans les routes pour générer des urls qui seront plus compréhensibles. Il s'agit d'un "slug". Le slug ne contient ni majuscules, ni accents, ni espaces ni caractères spéciaux.
Pour commencer nous allons installer les extensions Doctrine qui nous permettront d'effectuer cette tâche
composer require stof/doctrine-extensions-bundle
Une fois ces extensions installées, nous allons activer l'extension "Sluggable".
Celà se passe dans le fichier "config/packages/stof_doctrine_extensions.yaml", fichier à créer si il n'est pas présent
# Read the documentation: https://symfony.com/doc/current/bundles/StofDoctrineExtensionsBundle/index.html
# See the official DoctrineExtensions documentation for more details: https://github.com/Atlantic18/DoctrineExtensions/tree/master/doc/
stof_doctrine_extensions:
default_locale: fr_FR
orm:
default:
sluggable: true
Nous allons ensuite ajouter le "use" ci-dessous dans la ou les entités contenant des slugs
use Gedmo\Mapping\Annotation as Gedmo;
Enfin, dans ces mêmes entités, nous allons modifier l'annotation de la propriété "slug"
/**
* @Gedmo\Slug(fields={"titre"})
* @ORM\Column(length=128, unique=true)
*/
private $slug;
Il est également nécessaire de supprimer le "setter" setSlug.
Mise en place des dates de création et mise à jour
Lors de l'ajout d'un article, nous allons générer automatiquement la date de création et la date de mise à jour.
Pour commencer nous allons installer les extensions Doctrine qui nous permettront d'effectuer cette tâche (inutile si vous avez effectué la partie précédente)
composer require stof/doctrine-extensions-bundle
Une fois ces extensions installées, nous allons activer l'extension "Timestampable".
Celà se passe dans le fichier "config/packages/stof_doctrine_extensions.yaml", fichier à créer si vous n'avez pas effectué la partie précédente
# Read the documentation: https://symfony.com/doc/current/bundles/StofDoctrineExtensionsBundle/index.html
# See the official DoctrineExtensions documentation for more details: https://github.com/Atlantic18/DoctrineExtensions/tree/master/doc/
stof_doctrine_extensions:
default_locale: fr_FR
orm:
default:
timestampable: true
Nous allons ensuite ajouter le "use" ci-dessous dans la ou les entités contenant des dates
use Gedmo\Mapping\Annotation as Gedmo;
Enfin, dans ces mêmes entités, nous allons modifier l'annotation des propriétés de date
/**
* @var \DateTime $created_at
*
* @Gedmo\Timestampable(on="create")
* @ORM\Column(type="datetime")
*/
private $created_at;
/**
* @var \DateTime $updated_at
*
* @Gedmo\Timestampable(on="update")
* @ORM\Column(type="datetime")
*/
private $updated_at;
Il est également nécessaire de supprimer les "setters" setCreatedAt et setUpdatedAt si ils existent.
L'éditeur Wysiwig
Nous utiliserons un éditeur appelé CKEditor, disponible en téléchargement pour tout projet sur le site officiel, et adapté à Symfony par le groupe "Friends of Symfony", sous le nom FOSCkeditor.
Installer CKEditor
Pour procéder à l'installation de FOSCkeditor, nous allons utiliser le terminal et composer.
La 1ère commande à entrer dans le terminal va récupérer CKEditor et l'intégrer à Symfony et au dossier vendor.
composer require friendsofsymfony/ckeditor-bundle
Il faudra ensuite télécharger les ressources nécessaires au fonctionnement de CKEditor (HTML, CSS, Javascript) et les installer.
php bin/console ckeditor:install
Enfin, nous allons installer toutes les ressources nécessaires dans le dossier "public"
php bin/console assets:install public
Voilà CKEditor maintenant installé.
Configurer CKEditor
Une fois installé, CKEditor est configurable directement depuis le fichier "config/packages/fos_ckeditor.yaml" qui a été créé automatiquement
Par défaut, il contient les lignes suivantes
# Read the documentation: https://symfony.com/doc/current/bundles/FOSCKEditorBundle/index.html
twig:
form_themes:
- '@FOSCKEditor/Form/ckeditor_widget.html.twig'
Nous allons y ajouter les configurations qui nous intéressent, et principalement la liste des options qui seront proposées aux utilisateurs.
Dans l'exemple ci-dessous, nous créons une configuration appelée "main_config" en ajoutant quelques lignes dans le fichier
# Read the documentation: https://symfony.com/doc/current/bundles/FOSCKEditorBundle/index.html
twig:
form_themes:
- '@FOSCKEditor/Form/ckeditor_widget.html.twig'
fos_ck_editor:
configs:
main_config:
toolbar:
- { name: "styles", items: ['Bold', 'Italic', 'Underline', 'Strike', 'Blockquote', '-', 'Link', '-', 'RemoveFormat', '-', 'NumberedList', 'BulletedList', '-', 'Outdent', 'Indent', '-', '-', 'JustifyLeft', 'JustifyCenter', 'JustifyRight', 'JustifyBlock', '-', 'Image', 'Table', '-', 'Styles', 'Format','Font','FontSize', '-', 'TextColor', 'BGColor', 'Source'] }
L'upload d'images
Pour pouvoir envoyer l'image d'illustration lors de l'ajout d'un article, il va être nécessaire de modifier l'entité "Articles" afin de prendre en compte cette option. A ce stade, notre entité "Articles" contient une propriété de type texte pour stocker le nom du fichier.
Le bundle Vich Uploader va nous permettre de paramétrer l'envoi de fichiers de façon simple.
Installer Vich Uploader
Pour installer le bundle Vich Uploader, nous allons utiliser composer.
composer require vich/uploader-bundle
Après cette installation, nous allons configurer l'emplacement des fichiers après l'upload.
Cette configuration sera à effectuer dans plusieurs fichiers YAML.
Le premier d'entre eux, "services.yaml", contiendra le paramètre qui formalisera le chemin vers le dossier d'upload ainsi qu'un nom qui sera attribué à ce chemin, ici "featured_images". "app.path" permet de spécifier que notre valeur est un chemin.
parameters:
app.path.featured_images: /uploads/images/featured
Dans le deuxième fichier, "vich_uploader.yaml" nous allons configurer le "mapping", c'est à dire le lien entre le chemin et le nom attribué dans l'uploader. Les différentes valeurs se comprennent comme ceci :
- uri_prefix : préfixe de l'url, deviendra "/uploads/images/featured" dans notre exemple
- namer : permet de spécifier quel système de "nommage" nous souhaitons, ici, nommage unique, deux fichiers ne pourront pas avoir le même nom
- upload_destination : A quel endroit les images doivent-elles être stockées
vich_uploader:
db_driver: orm
mappings:
featured_images:
uri_prefix: '%app.path.featured_images%'
namer: Vich\UploaderBundle\Naming\UniqidNamer
upload_destination: '%kernel.project_dir%/public%app.path.featured_images%'
Enfin, nous allons mettre à jour notre entité pour que Vich Uploader fasse le lien entre la propriété "featured_image" et le fichier envoyé.
Les modifications à apporter dans l'entité "Articles" sont les suivantes
// Au début du fichier
use Symfony\Component\HttpFoundation\File\File;
use Vich\UploaderBundle\Mapping\Annotation as Vich;
// Juste au dessus de la classe Articles
/**
* @ORM\Entity(repositoryClass="App\Repository\ArticlesRepository")
* @Vich\Uploadable
*/
class Articles
// Près de la propriété $featured_image
/**
* @ORM\Column(type="string", length=255)
* @var string
*/
private $featured_image;
/**
* @Vich\UploadableField(mapping="featured_images", fileNameProperty="featured_image")
* @var File
*/
private $imageFile;
// Dans les Getters/setters
public function setImageFile(File $image = null)
{
$this->imageFile = $image;
if ($image) {
$this->updated_at = new \DateTime('now');
}
}
public function getImageFile()
{
return $this->imageFile;
}
public function getFeaturedImage()
{
return $this->featured_image;
}
public function setFeaturedImage($featured_image)
{
$this->featured_image = $featured_image;
return $this;
}
Voilà, le terrain est prêt pour créer l'interface d'administration.
L'interface d'administration
Installer Easy Admin
Nous allons maintenant passer à l'installation d'Easy Admin afin de mettre en place l'interface d'administration du site.
Comme pour les bundles précédents, nous allons utiliser composer
composer require admin
Configurer Easy Admin
Une fois installé, la configuration d'Easy Admin se déroule dans le fichier "config/packages/easy_admin.yaml".
Nous allons pouvoir définir de nombreuses propriétés générales ainsi que pour chacune de nos entités.
Les propriétés générales
Quelques propriétés nous permettent de définir le titre de l'administration, l'affichage de l'utilisateur, les menus situés à gauche, entre autres, très nombreuses. L'exemple ci-dessous en définit certaines.
easy_admin:
# On définit le nom de l'interface d'administration
site_name: 'Gestion de mon blog'
# On définit l'affichage de l'utilisateur
user:
display_name: true
display_avatar: false
design:
# Ces lignes sont utiles pour CKEditor
form_theme:
- "@EasyAdmin/form/bootstrap_4.html.twig"
- "@FOSCKEditor/Form/ckeditor_widget.html.twig"
# Ces lignes définiront notre menu
menu:
- { label: 'Articles' }
- { entity: 'Articles', label: 'Articles', icon: 'book' }
- { entity: 'Categories', label: 'Catégories', icon: 'tag' }
- { entity: 'MotsCles', label: 'Mots Clés', icon: 'tag' }
- { label: 'Utilisateurs' }
- { entity: 'Users', label: 'Utilisateurs', icon: 'user' }
formats:
# Ici on définit le format des dates
datetime: 'd/m/Y à H:i'
Les entités
Pour chacune des entités, nous pourrons définir quelles informations s'affichent dans la liste, lesquelles s'affichent dans le formulaire d'ajout, entre autres.
L'exemple ci-dessous correspond à la configuration de l'entité "Articles"
entities:
Articles:
# Correspond au fichier Articles.php
class: App\Entity\Articles
# On définit ci-dessous le contenu de la liste qui affichera les articles et les critères de tri
list:
fields:
- id
- titre
# Le champ ci-dessous affichera l'image de l'article
- { property: 'featured_image', label: 'Image', type: 'image', base_path: '%app.path.featured_images%' }
- { property: 'created_at', label: 'Créé' }
# Les catégories et les mots-clé sont listés ci-dessous
- { property: 'categories', label: 'Catégories', type: 'array'}
- { property: 'motsCles', label: 'Mots-Clés', type: 'array'}
sort: ['created_at', 'desc']
# On définit ci-dessous le contenu du formulaire d'ajout ou modification d'article
form:
fields:
- titre
# Affichage de l'éditeur Wysiwyg
- { property: 'contenu', type: 'fos_ckeditor', type_options: { config_name: 'main_config' }}
# Affichage du champ d'ajout d'image
- { property: 'imageFile', type: 'vich_image', label: 'Image' }
- users
# Les catégories et mots-clés peuvent s'afficher avec une sélection multiple
- { property: 'categories', label: 'Catégories', type: 'entity', type_options: { class: 'App\Entity\Categories', multiple: true,by_reference: false, attr: { data-widget: 'select2' }}}
- { property: 'motsCles', label: 'Mots Clés', type: 'entity', type_options: { class: 'App\Entity\MotsCles', multiple: true,by_reference: false, attr: { data-widget: 'select2' }}}
Les autres entités pourront être affichées de la même façon.
Pour l'entité Users, nous allons également pouvoir modifier le rôle de l'utilisateur.
La configuration de cette entité sera donc la suivante (avec rôles user et admin)
Users:
class: App\Entity\Users
label: 'Utilisateurs'
list:
fields:
- id
- { property: 'roles', label: 'Rôles', type: json_array}
form:
fields:
- { property: 'roles', label: 'Rôles', type: choice, type_options: {expanded: true, multiple: true, choices: {'Utilisateur':'ROLE_USER', 'Administrateur':'ROLE_ADMIN'}}}
Gérer les relations
Dans le cas d'entités avec relations, comme par exemple les entités "Articles" et "Categories", il est nécessaire de définir quelle valeur sera affichée pour les catégories lors de l'ajout ou la modification d'un article.
Nous allons afficher le nom de la catégorie, option la plus logique.
Afin de permettre cet affichage, il sera nécessaire d'implémenter la méthode magique "__toString" dans les entités qui le nécessitent, "Categories" dans cet exemple.
Nous ajouterons donc cette méthode comme ci-dessous
public function __toString()
{
return $this->nom;
}
Protéger notre administration
L'interface d'administration ne doit pas être accessible par tous les utilisateurs.
Afin de la protéger, nous allons demander l'authentification des utilisateurs avant de pouvoir y accéder, et vérifier qu'ils sont administrateurs.
Pour ce faire, rendez-vous à la fin de "config/packages/security.yaml" et retirez le # devant la ligne ci-dessous
- { path: ^/admin, roles: ROLE_ADMIN }
C'est tout, merci de votre fidélité.
Obtenir de l'aide
Pour obtenir de l'aide, vous pouvez accéder au serveur Discord pour une entraide par chat
Catégories : MVC Tutoriel Symfony Live-Coding
Mots-clés : Tutoriel Framework Base de données MVC Symfony Live-Coding administration livecoding easyadmin