Symfony
Symfony est un puissant framework PHP offrant des composants pour gérer les requêtes HTTP. Symfony simplifie le développement d'applications web robustes et flexibles.
Informations
Date de publication :
Date de modification :
Catégories : symfony, php, api, webpack, twig, doctrine, html, css, yaml
Auteur :
meezyr
Sommaire
- 1. Nouveau projet
- 2. Composants Symfony
- 3. Gestion des Routes et Requêtes HTTP
- 4. Contrôleurs
- 5. Twig
- 6. Services et Dépendances
- 7. Sessions, messages flash et Cookies
- 8. Doctrine ORM
- 9. Sécurité et Gestion des Utilisateurs
- 10. Événements et Écouteurs
- 11. Envoi de Courriels
- 12. JavaScript
- 13. Vérifications
- 14. Bundles & Frameworks

Symfony est un framework PHP puissant et flexible utilisé pour le développement d'applications web. Il facilite la création d'applications robustes, modulaires et extensibles en utilisant des composants réutilisables. Cette documentation explore certains des composants clés de Symfony et offre des conseils pour développer des applications web efficaces. Consultez la documentation officielle de Symfony pour plus de détails.
1. Nouveau projet
1.1 Installer le CLI
Avant de démarrer un projet, il faut intaller le CLI de Symfony, il y a 2 méthodes pour cela. La première méthode consiste à installer le CLI, pour cela il faut installer Scoop dans le powershell :
Set-ExecutionPolicy RemoteSigned -Scope CurrentUser
irm get.scoop.sh | iex
Puis il faut installer le CLI de Symfony :
scoop install symfony-cli
Pour plus d'informations sur Scoop, consultez la documentation.
1.2 Télécharger le CLI
La deuxième méthode consiste à télécharger le CLI pour un projet seulement, pour cela il faut télécharger le dossier symfony-cli_windows_386.zip sur le dépôt GitHub et mettre le fichier symfony.exe à la racine du projet.
1.3 Nouveau projet
Pour démarrer un nouveau projet Symfony, il faut ce placer dans le dossier où l'on souhaite avoir notre projet et créer le projet avec la commande suivante :
composer create-project symfony/skeleton my_project
Un fois cette commande faite, pour les autres commandes il faut ce placer dans le dossier racine du projet :
cd my_project
Pour créer une webapp dans un projet Symfony, il faut utiliser la commande suivante :
composer require webapp
1.4 Démarrer le projet
Pour démarrer le projet Symfony, il faut utiliser la commande suivante :
symfony server:start
// ou
.\symfony server:start
On peut retrouver notre projet à l'URL http://127.0.0.1:8000.
1.5 Vider le cache
Pour vider le cache de Symfony en mode dev, il faut utiliser la commande suivante :
php bin/console cache:clear
//ou
php bin/console c:c
En mode prod, il faut utiliser la même commande mais en étant en root. Dans le fichier .env, il faut avoir cela en prod :
APP_ENV=prod
APP_DEBUG=0
1.6 Créer la base de donnée
Pour créer un base de donnée sur Symfony, il faut d'abord configurer les identifiants dans le fichier .env ou .env.local :
DATABASE_URL="mysql://user:mdp@127.0.0.1:3306/basename?serverVersion=mariadb-10.5.4"
Puis pour intaller la base de donnée, utilisez la commande suivante :
php bin/console doctrine:database:create
1.7 Créer une entité
Pour créer une entité, il faut utiliser la commande suivante :
php bin/console make:entity
On peut dans l'entité permettre à un champs datetime de s'enregistrer à la date du jour et l'heure actuelle :
#[ORM\Column(type: 'datetime_immutable', options: ['default' => 'CURRENT_TIMESTAMP'])]
On peut mettre en place des validation pour les champs d'une entité, consultez la documentation officielle, pour cela :
composer require symfony/validator
Une fois les modifications faites sur une ou des entités, il faut utiliser ces commandes pour appliquer les modifications :
php bin/console make:migration
php bin/console doctrine:migrations:migrate
Pour effectuer une suppresion en cascade des données lié, ajoutez ceci dans l'entité :
#[ORM\JoinColumn(onDelete: 'CASCADE')]
Pour optimiser un projet Symfony (surtout en prod), on peut utiliser des traits ce qui permet de réutiliser des champs dans plusieurs entités. Pour en savoir plus, regarder cette vidéo.
Les DataFixtures permettent d'effectuer des testes avec des données, celui-ci importe de données en BDD via une commande symfony :
php bin/console make:fixtures
1.8 Créer un formulaire
La réalisation de formulaires est facile avec Symfony grâce au FormBuilder, consultez la documentation de officielle. Consultez également la liste de tous les types de champs dans un formulaire Symfony, grâce la documentation. Il faut avant tout utiliser cette commande :
composer require symfony/form
Puis pour créer un formulaire, il faut utiliser cette commande :
php bin/console make:form
Pour supprimer un champs d'un formtype dans un contrôleur, il faut utiliser ceci :
$form->remove('description');
1.9 Créer des utilisateurs
Pour créer une entité pour les utilisateurs dans Symfony c'est très simple, il faut utiliser ces commandes :
composer require symfony/security-bundle
composer require symfonycasts/verify-email-bundle
Puis, pour créer l'entité des utilisateurs, il faut utiliser cette commande :
php bin/console make:user
Pour générer la partie connexion à l'utilisateur, il faut utiliser cette commande :
php bin/console make:auth
Pour générer la partie inscription à l'utilisateur, il faut utiliser cette commande :
php bin/console make:registration-form
Pour générer manuellement un hash de mot de passe, il faut utiliser cette commande :
php bin/console security:hash-password
2. Composants Symfony
2.1 Serializer
Le composant Serializer de Symfony permet de transformer des entités dans un format spécifique (tel que JSON ou YAML) et de désérialiser depuis ces formats vers des entités PHP.
2.2 HttpClient, HttpKernel et HttpFoundation
Ces composants sont utilisés pour gérer les requêtes HTTP entrantes et les réponses HTTP sortantes dans l'application Symfony.
2.3 Bundle
Un bundle dans Symfony permet d'ajouter d'ajouter une fonctionnalité spécifique à l'application. Symfony utilise également le terme package pour décrire ces bundles. Voici quelques exemples de bundles à installer :
composer require maker
composer require symfony/orm-pack
composer require symfony/maker-bundle --dev
2.4 HttpFoundation
Le composant Symfony HttpFoundation permet de remplacer les variables globales par des objets, notamment par Request et Response. L'objet Response permet de créer, modifier et envoyer une réponse HTTP.
2.5 Attributes (Depuis PHP 8)
La fonctionnalité attributes de PHP 8 permet d'annoter les classes, méthodes, fonctions, paramètres, propriétés et constantes de classe.
2.6 Traduction
Pour traduire un message d'erreur, il faut utiliser le composant de traduction dans config/packages/translation.yaml :
composer require symfony/translation
framework:
default_locale: fr
translator:
default_path: '%kernel.project_dir%/translations'
fallbacks:
- en
Pour modifier les traductions des messages d'erreurs, cela ce passe dans le fichier translations/security.fr.yaml :
'Invalid credentials.': 'Vos identifiants sont incorrects'
2.7 RateLimiter
Pour limiter les tentatives de connexion, il faut utiliser le composant RateLimiter, dans config/packages/security.yaml :
composer require symfony/rate-limiter
firewalls:
#...
main:
#...
login_throttling:
max_attempts: 3
interval: '5 minutes'
2.8 Validation des Fichiers
Utilisez le composant Validator pour valider les fichiers téléchargés, tels que la taille et le type de fichier, il faut commencer par installer le composant Validator :
composer require validator
Puis dans le FormBuilder utilisez les contraintes :
'constraints' => [
new File([
'maxSize' => '1M',
'maxSizeMessage' => 'Le fichier {{ name }} fait {{ size }} {{ suffix }} et la limite est {{ limit }} {{ suffix }}.',
'mimeTypes' => [
'image/png'
],
'mimeTypesMessage' => 'Le type du fichier ({{ type }}) est invalide. Les types requis sont {{ types }}.',
])
]
3. Gestion des Routes et Requêtes HTTP
Voici une route sur Symfony :
#[Route(path: '/blog', name:'blog', methods: ['PUT', 'POST'], schemes: ['https'])]
3.1 Principaux Verbes HTTP
- GET : Récupérer une ressource à l'
URIspécifiée, les requêtesGETdoivent uniquement être utilisées pour obtenir des données (pageHTML). - POST : Envoyer une entité vers l'
URIspécifiée, le serveur enregistre les données envoyées dans une base de données. - PUT : Remplacer une entité par celle envoyée vers l'
URI, on l'utilise pour remplacer complètement une entité enregistrée dans une base de données. - PATCH : Modifier partiellement une entité avec les changements envoyés vers l'
URI, on l'utilise souvent pour modifier partiellement une entité enregistrée dans une base de données. - DELETE : Supprimer la ressource indiquée par l'
URI.
3.2 Routes Variables
Pour indiquer qu'une partie d'une route est variable et que c'est un paramètre, utilisez ceci :
#[Route(path: '/blog/{nom-de-parametre<regex>?valeur-par-defaut}', name: 'blog')] // Le code regex est à saisir (\d+ ou [a-zA-Z]+)
3.3 Priorité des Routes
Par défaut, toutes les routes ont une priorité de 0. Il suffit donc d'attribuer une priorité de 1 pour que la route soit prioritaire. Pour attribuer une priorité à une route :
#[Route(path: '/blog', name: 'blog', priority: 1)]
3.4 Redirection de Routes
Définissez l'option host pour que l'hôte soit pris en compte lorsqu'une requête est examinée par le Router :
#[Route(path: '/blog', name: 'blog', host: 'ultrage.meezyr.fr')]
Redirigez certaines routes vers de nouvelles routes en utilisant la configuration du fichier de routage. Notamment si vous modifiez votre architecture de routing mais que certains liens sont déjà utilisés ailleurs, par exemple dans config/routes.yaml :
homepage:
path: /homepage
controller: Symfony\Bundle\FrameworkBundle\Controller\RedirectController
defaults:
route: 'accueil'
keepQueryParams: true
title: 'Documentation Symfony'
permanent: true
3.5 Débogage des Routes
Utilisez la console Symfony pour déboguer les routes en utilisant les commandes suivantes :
symfony console debug:router
symfony console router:match /blog
4. Contrôleurs
Pour créer un contrôleur avec Symfony, il faut utiliser la commande suivante :
php bin/console make:controller nomDuController
Pour en savoir plus sur les contrôleurs, consultez la documentation officielle.
4.1 AbstractController
L'AbstractController possède en effet de nombreuses méthodes et permet de rediriger sur une autre route (redirectToRoute()) ou une autre URL (redirect()), de renvoyer un fichier (file()), d'envoyer un message flash (addFlash()), vérifier que l'accès est autorisé, rendre des vues, créer et rendre des formulaires, vérifier la validité d'un token CSRF, d'envoyer une réponse au format JSON...
4.2 Erreurs
La méthode qui permet de retourner une réponse HTTP avec le code de statut 404 pour Not Found (non trouvé) est :
throw $this->createNotFoundException('Rien à cette adresse');
4.3 Redirections
On peut rediriger vers la page précédente grâce à HTTP REFERER, pour cela utilisez le code :
$referer = $request->server->get('HTTP_REFERER');
return $referer ? $this->redirect($referer) : $this->redirectToRoute('home');
5. Twig
Consultez la documentation officielle de Twig.
5.1 Templates
templates/base.html.twig: Défini les éléments communs à toutes les pages et contient leheader, lefooter, l'élémentheadavec lesstyleset lesscriptsglobaux.templates/layout.html.twig: Hérite du templatebase.html.twiget définit la structure de la plupart des pages (sidebar, conteneur, colonnes...). Il n'est bien sûr pas obligatoire de l'utiliser pour toutes vos pages. Certaines parties de l'application peuvent mettre en place unlayoutspécifique (par exemple :templates/users/layout.html.twig).templates/_partials/_header.html.twig: Permet de séparer des parties de pages, afin d'être réutiliser à d'autres endroit par exemple. Pour cela il faut utiliser{% include "_partials/_header.html.twig" %}là où on souhaite intégrer le code.
5.2 Variable globale
La variable globale app en Twig contient de multiples propriétés :
- user : l'utilisateur connecté ou
null. - request : l'objet
Requestdu composantHttpFoundation. - session : la session de l'utilisateur ou
null. - flash : les messages flash de la session courante ou
null. - environment : l'environnement actuel (
dev,test,prod...). - debug : vaut
trueen mode debug. - token : contient le token de sécurité.
5.3 Intégration de Contrôleurs dans les Templates Twig
Pour incorporer des contrôleurs dans les templates Twig, utilisez ceci :
{{ render(controller('App\\Controller\\NewsController::lastNews')) }}
Pour utiliser cette fonctionnalité, il faut modifier le fichier config/packages/framework.yaml et il faut décommenter fragments.
5.4 Rendre un template directement
Pour rendre un template directement depuis une route, il suffit de définir le template à utiliser dans le fichier de configuration config/routes.yaml, comme ceci :
privacy:
path: /privacy
controller: Symfony\Bundle\FrameworkBundle\Controller\TemplateController
defaults:
template: 'static/privacy.html.twig'
5.5 Thèmes préconfigurés
Symfony met à disposition des thèmes préconfigurés pour fonctionner avec les principaux frameworks CSS comme Bootstrap, Tailwind ou Foundation, pour cela modifiez le fichier config/packages/twig.yaml :
twig:
form_themes: ['bootstrap_5_layout.html.twig']
Si vous souhaitez utiliser un thème spécifique pour l'un de vos formulaires, il suffit de faire, dans le template de votre formulaire :
{% form_theme form 'bootstrap_5_horizontal_layout.html.twig' %}
Pour modifier certaines variables de formulaire dans les thèmes, créez le fichier templates/form-theme.html.twig avec ceci au début :
{% use 'form_div_layout.html.twig' %}
Pour en savoir plus, consultez la documentation ou un exemple.
5.6 Détection des erreurs
Le linting est l'exécution d'un programme qui analyse le code pour détecter d'éventuelles erreurs, utilisez la commande :
symfony console lint:twig
Comme pour le Routing, Symfony propose un utilitaire pour vérifier toute la configuration de Twig et tous vos templates, utilisez la commande :
symfony console debug:twig
5.7 Autres
Pour interprèter du HTML avec Twig, il faut utiliser ceci :
{{ description|raw }}
Pour ajouter une class active à un élément HTML en Twig :
class="{{ app.request.pathinfo == path('home') ? 'active' : '' }}"
6. Services et Dépendances
6.1 Services
Les services dans Symfony sont des classes qui effectuent diverses tâches, comme l'envoi d'un e-mail, la journalisation (log), la manipulation d'une base de données... Afin d'obtenir tous les services disponibles dans le conteneur de service, faites la commande suivante :
symfony console debug:container
Pour voir tous les services disponibles pour l'injection de dépendances, faites la commande :
symfony console debug:autowiring
6.2 Création de services
Un service est simplement une classe qui a des méthodes qui réalisent des actions, on peut donc en créer comme ceci :
<?php
namespace App\Service;
class MonSuperService
{
public function neFaitRien(): void
{
}
}
6.3 Validation de Formulaire
Utilisez ValidatorInterface pour gérer soit même les erreurs de formulaire, sans les renvoyer à Twig pour l'affichage, pour cela utilisez ce code :
use Symfony\Component\Validator\Validator\ValidatorInterface;
public function todo(ValidatorInterface $validator)
{
$todo = new Todo();
$errors = $validator->validate($todo);
if (count($errors) > 0) {
dump($errors);
return new Response('Une erreur est survenue'));
}
}
6.4 Manipulation de fichiers
Le service Filesystem permet de manipuler des fichiers et des dossiers, pour cela utilisez le code suivant :
use Symfony\Component\Filesystem\Filesystem;
function __construct(private Filesystem $fs)
{
}
Pour créer par exemple un fichier de log, utilisez ce code :
$fs->appendToFile('log.txt', 'Hello world' . PHP_EOL);
6.5 Arguments
Il est possible de passer manuellement des arguments aux services pour les configurer, il faut modifier le fichier config/services.yaml :
App\Service\MyLog:
arguments:
$logFile: 'logs/logs.txt'
6.6 Changer la locale
Pour modifier la locale par défaut de votre application et afficher les dates en français, modifiez le fichier config/packages/framework.yaml comme ceci :
framework:
default_locale: fr
7. Sessions, messages flash et Cookies
7.1 Gestion des Sessions
Pour configurer les sessions, cela se trouve dans le fichier config/packages/framework.yaml :
session:
handler_id: session.handler.native_file
# Pour une semaine :
cookie_lifetime: 604800
gc_maxlifetime: 604800
sid_bits_per_character: 5
cookie_secure: true
cookie_samesite: lax
storage_factory_id: session.storage.factory.native
Pour stocker et récupérer une valeur dans une session, utilisez ce code :
use Symfony\Component\HttpFoundation\RequestStack;
public function index(RequestStack $requestStack): Response
{
$session = $requestStack->getSession();
$session->set('clé', 'valeur');
$session->get('clé');
}
Pour en savoir plus, consultez la documentation officielle.
7.2 Messages Flash
Utilisez les messages flash, ils sont conçus pour afficher des notifications aux utilisateur :
$this->addFlash( 'type', 'Le message' );
Pour en savoir plus, consultez la documentation officielle.
7.3 Gestion des Cookies
Pour définir des cookies, il suffit d'utiliser le code suivant :
use Symfony\Component\HttpFoundation\Cookie;
$response = $this->render('page1.html.twig', [
'myform' => $form->createView()
]);
$response->headers->setCookie(Cookie::create('clé', 'valeur'));
//ou
$cookie = Cookie::create('clé', 'valeur')
->withExpires(strtotime('Fri, 20-May-2023 15:25:52 GMT'))
->withDomain('.example.com')
->withSecure(true);
$response->headers->setCookie($cookie);
return $response;
Pour récupérer des cookies, il suffit d'utiliser le code suivant :
$request->cookies->get('clé');
8. Doctrine ORM
Doctrine est un ORM (Object-Relational Mapper) pour les projets PHP. Il est intégré par défaut dans Symfony pour la gestion des bases de données. Pour en savoir plus sur Doctrine, consultez la documentation officielle.
8.1 Persistance des Données
Utilisez le gestionnaire d'entité et les méthodes persist() et flush() pour persister des données. Pour éditer des entités, il suffit d'appeler flush() pour exécuter la requête SQL de modification. Il n'y a pas besoin d'utiliser persist() lors d'une édition car Doctrine suit automatiquement les changements des objets récupérés. Pour supprimer un objet c'est très simple, il faut le récupérer en utilisant le répertoire puis envoyer la requête de suppression avec le gestionnaire d'entité.
8.2 Récupération automatique d'entités
Pour récupérer les entités avec le convertisseur de paramètre automatique Doctrine, il suffit d'utiliser le code suivant :
#[Route('/user/{id}')]
public function show(User $user)
{
}
Pour spécifier quel est le paramètre de route correspondant à la clé primaire, il faut utiliser id :
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Entity;
#[Route('/user/{user_id}')]
#[Entity('user', options: ['id' => 'user_id'])]
public function show(User $user)
{
}
Pour spécifier un mapping autre que pour la clé primaire, il faut utiliser l'option mapping :
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Entity;
#[Route('/user/{user_email}')]
#[Entity('user', options: ['mapping': ['user_email' => 'email']])]
public function show(User $user)
{
}
8.3 QueryBuilder et DQL
Le QueryBuilder est une API de Doctrine qui permet de construire des requêtes DQL conditionnelles :
$query = $this->createQueryBuilder('t')
->where('t.priority > :priority')
->setParameter('priority', $priority)
->orderBy('t.priority', 'ASC')
->getQuery();
return $query->execute();
Le DQL (Doctrine Query Language) est le langage de requête de Doctrine :
$em = $this->getEntityManager();
$query = $em->createQuery('SELECT t FROM App\Entity\Todo t WHERE t.prority > :priority ORDER BY t.prority ASC')
->setParameter('prority', $priority);
return $query->getResult();
Pour en savoir plus sur QueryBuilder, consultez la documentation officielle.
9. Sécurité et Gestion des Utilisateurs
9.1 Modifier les Rôles utilisateur
Lorsqu'un utilisateur se connecte, vous pouvez lui attribuer d'autres rôles avec le setter setRoles(). Il est nécessaire que tous les rôles commencent par ROLE_.
9.2 Gestion des Rôles et des Permissions
- Utilisez les rôles comme
ROLE_USERetROLE_ADMIN. - Utilisez
denyAccessUnlessGranted()pour vérifier les autorisations. - Utilisez
#[IsGranted('ROLE_USER')]pour appliquer des autorisations aux méthodes du contrôleur (peut être utiliser sur la class d'un contrôleur). - Utilisez
IS_AUTHENTICATED_FULLYqui vérifie simplement que l'utilisateur est authentifié.
Si vous ne souhaitez pas rediriger l'utilisateur mais exécuter du code en fonction du rôle de l'utilisateur, il faut utiliser la méthode isGranted() :
if ($this->isGranted('ROLE_ADMIN')) {
// faire quelque chose
}
Vous devez vérifier que l'utilisateur est authentifié soit dans le contrôleur soit directement dans le template sinon vous aurez une erreur si la variable n'est pas définie :
{% if is_granted('ROLE_USER') %}
<p>Email : {{ app.user.email }}</p>
{% endif %}
Un utilisateur qui est authentifié par session "normal" (après connexion par mot de passe), aura l'attribut IS_AUTHENTICATED_FULLY jusqu'à expiration de la session. Un utilisateur dont la session est expirée et qui s'authentifie automatiquement avec le cookie REMEMBERME aura l'attribut IS_AUTHENTICATED_REMEMBERED.
9.3 Protection contre les Attaques CSRF
Les attaques Cross-Site Request Forgery (CSRF) sont un type d'attaques où le navigateur d'un utilisateur envoie une requête à un site Web tiers sans son consentement et sans qu'il le sache, pour cela dans le fichier config/packages/framework.yaml décommenter la ligne "csrf_protection : true".
9.4 Voter
Les Voters permettent de mettre en place à un endroit les logiques de permissions des utilisateurs et de les réutiliser dans toutes les parties de vos applications qui en ont besoin. Ils sont appelés à chaque fois que vous utilisez denyAccessUnlessGranted() ou isGranted() dans un contrôleur, ou lorsque vous utilisez la propriété access_control dans le fichier security.yaml :
symfony console make:voter
$this->denyAccessUnlessGranted('BLOG_EDIT', $blog);
Pour en savoir plus, consultez la documentation sur les droits d'accès.
10. Événements et Écouteurs
10.1 EventDispatcher
Le composant EventDispatcher de Symfony est le médiateur du pattern du médiateur, il joue aussi le rôle d'observable dans le pattern de l'observeur. Le pattern du médiateur est le fait qu'un seul objet est communiquant avec les autres objets participants. Les autres objets informent le médiateur de leurs changements et le médiateur va prévenir les autres objets de ces changements. Lorsqu'un événement est émis le Dispatcher va appeler tous les écouteurs qui se sont enregistrés pour l'événement.
10.2 EventListener
EventListener est un écouteur qui est simplement une classe avec des méthodes qui peuvent être exécutées lorsque certains événements surviennent. Dans le fichier config/services.yaml :
App\EventListener\LoginListener:
tags:
- { name: kernel.event_listener }
Dans le fichier src/EventListener/LoginListener.php :
<?php
namespace App\EventListener;
use Symfony\Component\Security\Http\Event\LoginSuccessEvent;
class LoginListener
{
function __invoke(LoginSuccessEvent $event)
{
$request = $event->getRequest();
$username = $event->getPassport()->getUser()->getName();
$request->getSession()->getFlashBag()->add('success', 'Bon retour parmi nous ' . $username);
}
}
Pour en savoir plus, consultez la documentation officielle.
10.3 EventSuscriber
EventSuscriber permet également d'écouter des événements, on peut en créer grâce à cette commande :
symfony console make:subscriber
Pour en savoir plus, consultez la documentation officielle.
10.4 Événements personnalisés
Pour créer des événements personnalisés, on utilise un événement qui est une classe qui doit étendre la classe native Event, comme dans le fichier src/Event/NewUserEvent.php :
use Symfony\Contracts\EventDispatcher\Event;
class UserRegisteredEvent extends Event
{
public const NAME = 'user.registered';
public function __construct(private string $email)
{
}
public function getEmail(): string
{
return $this->email;
}
}
On peut émettre un événement personnalisé grâce à la méthode dispatch() disponible sur l'EventDispatcher :
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
$dispatcher->dispatch(new UserRegisteredEvent($email), UserRegisteredEvent::NAME);
10.5 Lifecycle Events
Lifecycle events sont des événements du cycle de vie permettant d'exécuter du code à des moments clés de la persistance des entités, les événements disponibles sont :
- prePersist : est émis juste avant que l'entité soit persistée (donc pas lors des mises à jour, uniquement lors de la création).
- postPersist : est émis juste après que l'entité soit persistée (de même uniquement lors de la création). La clé primaire est disponible à ce moment.
- preFlush : est émis juste avant de
flushl'entité (donc de l'enregistrer dans la base de données). - preUpdate : est émis juste avant que l'entité soit mise à jour.
- postUpdate : est émis juste après que l'entité soit mise à jour.
- preRemove : est émis juste avant que l'entité soit supprimée.
- postRemove : est émis juste après que l'entité soit supprimée.
- postLoad : est émis juste après que l'entité soit chargée dans l'
EntityManager.
Exemple de Lifecycle events prepersist :
#[ORM\PrePersist]
public function setCreatedAt(): void
{
$this->createdAt = new \DateTimeImmutable();
}
10.6 Événements dans un formulaire
Pour utiliser un écouteur d'événements avec le composant Form, utilisez le code suivant :
$builder->add('password')->addEventListener(FormEvents::PRE_SET_DATA, function (FormEvent $event) {
$data = $event->getData();
$form = $event->getForm();
if ($data->getName() === 'Jean') {
$form->add('gender');
}
});
11. Envoi de Courriels
Utilisez le composant Mailer pour envoyer des courriels à partir de l'application Symfony. Pour en savoir plus, consultez la documentation. Pour installer Mailer sur Symfony, il faut utiliser cette commande :
composer require symfony/mailer
11.1 Configuration du Mailer
Configurez le composant Mailer dans le fichier .env en utilisant un serveur SMTP, par exemple Mailtrap :
MAILER_DSN=smtp://c9fb3db1854506:75b5f25e2191c6@smtp.mailtrap.io:2525?encryption=tls&auth_mode=login
11.2 Envoi de Courriels
Pour envoyer un mail avec Mailer, utilisez le code suivant :
use Symfony\Component\Mime\Email;
$email = new Email();
$email->to('Jean Dupont<jean@gmail.com>')
->subject('Bienvenue sur Dyma !')
->cc('jp@gmail.com,marie@gmail.com')
->text('Bienvenue chez nous, nous sommes très contents de votre arrivée !');
$mailer->send($email);
On peut tester l'envoi de mails en mode dev, via un faux serveur SMTP que propose l'outil Mailtrap.
11.3 From général
On peut déclarer un from général pour Mailer dans le fichier config/packages/mailer.yaml :
framework:
mailer:
dsn: '%env(MAILER_DSN)%'
headers:
from: Ultrage <ultrage@gmail.com>
11.4 Personnalisation de mails
On peut mettre du style dans les mails grâce à Twig :
composer req twig/extra-bundle twig/cssinliner-extra
$email->htmlTemplate('./email/welcome.html.twig')
->context(['username' => 'Jean']);
Utilisez le fichier templates/email/welcome.html.twig pour personnaliser l'affichage d'un mail et le CSS doit être dans le fichier public/css/welcome-email.css :
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
</head>
<body>
{% apply inline_css(source('@css/welcome-email.css')) %}
<h1>Bienvenue {{username}}</h1>
<p>Nous sommes heureux de vous compter parmi nous.</p>
{% endapply %}
</body>
</html>
Pour que cela fonctionne il faut que le fichier config/packages/twig.yaml soit paramétré comme ceci :
twig:
default_path: '%kernel.project_dir%/templates'
paths:
'%kernel.project_dir%/public/css': css
'%kernel.project_dir%/public/images': images
when@test:
twig:
strict_variables: true
Pour intégrer une image à un mail, utilisez le code suivant :
<img src="{{ email.image('@images/monimage.png') }}" alt="monimage">
Pour en savoir plus, consultez la documentation officielle.
11.5 Pièces jointe
Pour attacher des pièces jointe à un mail, il faut utiliser le code :
use Symfony\Component\Mime\Part\DataPart;
use Symfony\Component\Mime\Part\File;
$email->addPart(new DataPart(new File('/path/to/documents/terms-of-use.pdf')));
Il faut passer la propriété LOCK_DSN du fichier .env à :
LOCK_DSN=flock
12. JavaScript
12.1 Webpack Encore
Avec Webpack, on peut afficher un fichier JS ou/et CSS pour une page uniquement, pour cela dans le fichier webpack.config.js :
.addEntry('app', './assets/app.js')
.addEntry('panier', './assets/panier.js')
.addEntry('compte', './assets/compte.js')
Dans le template Twig, on peut utiliser le code suivant :
{% extends "base.html.twig" %}
{% block stylesheets %}
{{ parent() }}
{{ encore_entry_link_tags('panier') }}
{% endblock %}
{% block javascripts %}
{{ parent() }}
{{ encore_entry_script_tags('panier') }}
{% endblock %}
Consultez la documentation officielle de Symfony sur Webpack, sachant que Symfony utilise une version modifié de Webpack nommé Webpack Encore.
12.2 Intégration avec Vue.js
Grâce à Webpack Encore, on peut utiliser Vue.js directement dans Symfony, grâce à la commande suivant :
yarn add vue@next vue-loader@next @vue/compiler-sfc
13. Vérifications
Pour vérifier la configuration de votre système avant de lancer Symfony, utilisez la commande :
symfony check:requirements
14. Bundles & Frameworks
14.1 KnpTime
Le bundle KnpTime permet de transformer une date en un message lisible par un utilisateur. Par exemple, il y a x minutes ou x secondes ou x heures, grâce à ce code :
composer require knplabs/knp-time-bundle
{{ comment.createdAt | ago(locale="fr") }
14.2 API Platform
Le framework API Platform permet de créer des API très performantes avec Symfony, pour intaller API Platform il faut utiliser cette commande :
composer require api
Puis pour transformer une entité Symfony en API, il faut mettre ceci dans le fichier de l'entité :
use ApiPlatform\Metadata\ApiResource;
#[ApiResource]
Pour accéder à l'interface de API Platform, utilisez cette URL http://127.0.0.1:8000/api. Pour plus d'information sur la création d'API avec API Platform, consultez la documentation officielle de Symfony.
On peut accèder aux API de Symfony avec Postman qui permet d'intéragir avec les API, pour cela il faut modifier le fichier config/packages/api_platform.yaml :
patch_formats:
jsonld: ['application/ld+json']
jsonhal: ['application/hal+json']
jsonapi: ['application/vnd.api+json']
json: ['application/json']
xml: ['application/xml', 'text/xml']
yaml: ['application/x-yaml']
csv: ['text/csv']
html: ['text/html']
On peut voir la liste des opérations disponible sur la documentation de API Platform.
14.3 EasyAdmin
Le bundle EasyAdmin permet la création rapide et automatisé d'un backoffice permettant de gérer les donnée d'un projet.
14.4 Éditeurs de texte
Le bundle CKEditor permet l'édition avancé de texte dans un formulaire.
Le bundle TinyMCE permet également l'édition avancé de texte dans un formulaire.
14.5 StofDoctrineExtensions
Le bundle StofDoctrineExtensions permet la création de slugs dans une entité, pour en savoir plus sur l'utilisation de ce bundle, consultez cette documentation.
14.6 LiipImagine
Le bundle LiipImagine permet de recadrer des images.
14.7 LexikJWTAuthentication
Le bundle LexikJWTAuthentication permet de sécuriser une API grâce à l'utilisation de clés privé et public.