- Accueil
- Programmation Web S5
- Objectifs de la séance
- Préambule
- Mise en place d'une application
Symfony
7.1 - Gestion des versions avec Git
GitHub Copilot
- Création du projet dans
PhpStorm
- Qualité de code et automatisation
- Consignes de codage et de nommage
- Documentation du projet
- Standards de codage PHP avec
PHP CS Fixer
- Qualité de code avec
PHPStan
- Standards de codage Twig avec
Twig CS Fixer
- Mise en place de scripts
Composer
- Automatisation des contrôles de qualité de code avec
GrumPHP
- Installation / configuration des greffons
PhpStorm
- Conteneurisation des services de base de données
- Les annonces dans l'application
- Création d'une entité «
Advertisement
» - Génération de données factices
- Création de la base de données
- Visualisation des annonces
- Désactivation de
Symfony UX Turbo
- Utilisation de
Bootstrap
CDN dans l'interface utilisateur - Formulaire d'édition / création d'une annonce
- Automatisation des dates de création et de mise à jour
- Utilisation du formulaire d'édition / création d'une annonce
- Suppression d'une annonce
- Création d'une entité «
- Catégories d'annonces
- Considérations sur les performances
- Mise en place de tests
- Intégration continue
- Amélioration de l'interface et de l'expérience utilisateur
Objectifs de la séance ¶
- Prendre en main
Symfony
dans sa version 7.1 - Consolider les objectifs du TP de découverte de
Symfony 5
- Utiliser le routage
- Développer des « templates »
Twig
- Écrire des tests fonctionnels
- Utiliser l'ORM
Doctrine
- Gérer des relations entre entités
- Générer des données factices (« fixtures ») avec «
Foundry
» - Utiliser le composant
Form
- Utiliser le composant
Security
- Développer en respectant les bonnes pratiques de
Symfony
- Mettre en place des outils de qualité de code
- Automatiser l'utilisation des outils de qualité de code
- Conteneuriser certains services avec
Docker
Préambule ¶
L'objectif de ce TP est de consolider vos acquis en développement d'applications Symfony
(découverte de Symfony 5
puis API Platform
), mais également de vous faire découvrir de nouvelles possibilités. Le sujet vous donnera des consignes et des pointeurs vers de la documentation et des ressources, vous mettant ainsi dans une situation de réalisation professionnelle. L'accent sera une nouvelle fois mis sur les bonnes pratiques de Symfony
, la qualité de développement et l'automatisation.
Le fil conducteur sera un site de petites annonces, dont les fonctionnalités évolueront au fil de vos nouveaux apprentissages.
Mise en place d'une application Symfony
7.1
¶
Vous allez créer des applications Symfony
de façon conventionnelle, en utilisant l'outil « symfony
» en ligne de commande (« Symfony CLI »). Une nouvelle application Symfony
nécessite un peu plus de 80 Mo de sources PHP pour fonctionner (environ 10.000 fichiers dans un peu moins de 2.000 répertoires !). Ces données seront rapidement agrémentées de plusieurs dizaines de mégaoctets de cache générés par Symfony
.
Vous allez installer Symfony
à l'aide de l'outil « symfony
» en ligne de commande (« Symfony CLI ») et pour cela, vous allez devoir l'installer. Cet outil utilise Composer
dont vous devrez vous assurer du bon fonctionnement.
Quelques considérations liées à la configuration système de l'IUT ¶
Remarque importante
Si vous travaillez sur votre ordinateur personnel, sur Linux ou sur Windows, vous pouvez placer le répertoire « symfony-for-sale
» du projet où bon vous semble. La partie qui suit concerne uniquement le travail sur les ordinateurs de l'IUT. Cela ne vous empêche pas d'en prendre connaissance.
Votre répertoire d'accueil « $HOME
» se trouve sur un emplacement réseau NFS
, ce qui vous permet de retrouver vos fichiers quel que soit le PC du département sur lequel vous vous connectez. Symfony
utilise le sous-répertoire « var
» du projet pour la gestion de son cache, des traces d'exécution et des données de session. Ces tâches génèrent de nombreuses entrées-sorties sur le système de fichiers, particulièrement inadaptées aux systèmes de fichiers en réseau. Il en va de même pour PhpStorm
qui surveille les modifications de tous les fichiers de votre projet et ne peut pas fonctionner normalement lorsque ces fichiers sont sur un partage NFS
. Afin d'améliorer les performances de votre application et d'éviter de saturer le serveur de fichiers du département informatique, vous allez travailler dans le répertoire « /working/votre_login
» de la machine sur laquelle vous êtes connecté.
En fin de séance ¶
En fin de séance, vous devez impérativement synchroniser votre dépôt distant (en ligne de commande ou avec PhpStorm
)
git commitpuis
git pushfaute de quoi vous perdrez votre travail entre chaque séance !
Pensez également à supprimer votre répertoire de travail /working/votre_login/symfony-for-sale
pour éviter la saturation du disque local :
rm -Rf /working/votre_login/symfony-for-sale
En début de séance ¶
Lorsque vous reprenez le travail la séance suivante, vous avez trois choix possibles, qui dépendent de la façon dont vous avez travaillé :
- Mettre à jour votre dépôt local
cd /working/votre_login/symfony-for-sale
git pull
- Effacer votre dépôt local et repartir de zéro
cd /working/votre_login
rm -Rf /working/votre_login/symfony-for-sale
git clone https://iut-info.univ-reims.fr/gitlab/votre_login/symfony-for-sale.git
cd /working/votre_login/symfony-for-sale
- Réinitialiser votre dépôt local selon le dépôt distant
cd /working/votre_login/symfony-for-sale
git fetch
git reset --hard origin/main
Ensuite, dans le répertoire de votre projet, vous devez (ré)installer les composants nécessaires à son fonctionnement :
composer install
Vous devrez également reconfigurer votre accès base de données en redéfinissant le fichier « .env.local
»
Installation / mise à jour de l'exécutable « symfony
» et de Composer
¶
Travail à réaliser
- Vérifiez que l'outil «
symfony
» en ligne de commande (« Symfony CLI ») est installé et à jour en reprenant la procédure d'installation vu l'an passé - Contrôlez la compatibilité du système avec la commande :
symfony check:requirements --verbose
- Vérifiez que «
Composer
» est installé et à jour en reprenant la procédure d'installation vu l'an passé - Vérifiez que
Composer
fonctionne correctement :composer about
- Mettez à jour
Composer
:composer self-update
Création du projet Symfony
¶
Vous allez pouvoir créer un projet Symfony
à l'aide de l'outil « symfony
» en ligne de commande (« Symfony CLI »).
Travail à réaliser
- Vérifiez que vous êtes bien dans le répertoire «
/working/votre_login
» (ou n'importe quel répertoire de votre choix si vous êtes sur votre ordinateur personnel) - Lancez la création d'un nouveau projet
Symfony
version «7.1.*
» :symfony --version 7.1 --webapp new symfony-for-sale
Vérification du bon fonctionnement de l'application ¶
Si vous avez réalisé toutes les étapes précédentes sans encombre, votre application doit fonctionner. Vous allez donc le vérifier. Vous allez utiliser l'environnement de développement de Symfony
qui est celui qui est activé par défaut en mode développement.
Travail à réaliser
- Placez-vous dans le répertoire de votre application
- Dans le terminal, lancez le serveur Web local avec la commande suivante :
symfony serve
Le serveur Web fonctionnera tant que vous n'aurez pas terminé l'exécution de l'outil ligne de commande «symfony
» avec «CTRL+C
».Remarque importanteSi le serveur local ne fonctionne pas correctement en
HTTPS
, installez un certificat local. - Lancez votre navigateur web et saisissez l'URL suivante :
https://127.0.0.1:8000
- Vérifiez que le serveur Web local répond correctement
- Terminez l'exécution de l'outil ligne de commande «
symfony
» avec «CTRL+C
»
Gestion des versions avec Git ¶
Afin de fiabiliser votre méthode de développement, vous allez utiliser Git
pour gérer le suivi des versions de votre application Symfony
.
Dépôt local ¶
Vous allez configurer votre dépôt Git
local.
Travail à réaliser
- Assurez-vous d'être dans le répertoire du projet
symfony-for-sale
- Constatez que le dépôt
Git
local a été initialisé par l'outil «symfony
» en ligne de commande (« Symfony CLI »)git log
GitHub Copilot
¶
Une partie du code que vous produisez est prévisible, au moins en partie. C'est pourquoi GitHub
a développé un outil d'assistance à la saisie de code, GitHub Copilot
, qui s'appuie sur l'intelligence artificielle et l'apprentissage automatique pour vous aider à écrire du code. Cet outil est utilisé en entreprise pour augmenter la productivité des développeurs. Il nous semble donc intéressant de vous le présenter, tout en vous sensibilisant à son utilisation éclairée et raisonnée.
Information
Certaines informations sont nécessaires au bon déroulement de votre inscription au « GitHub Student Developer Pack ». Lisez l'intégralité des consignes fournies dans le sujet avant de vous lancer dans la création de votre compte GitHub
et de vous inscrire au « GitHub Student Developer Pack ».
Travail à réaliser
- Si vous n'en possédez pas déjà un, créez un compte sur
GitHub
, de préférence avec votre mail universitaire - Inscrivez-vous au « GitHub Student Developer Pack » : https://education.github.com/pack
- Si votre mail universitaire n'est pas connu de
GitHub
, vous devez le renseigner, car il est nécessaire pour être reconnu comme étudiant - Fournissez une photo de votre carte d'étudiant ou de votre certificat de scolarité Information
Vous devez impérativement fournir une photo de votre carte d'étudiant ou de votre certificat de scolarité. Vous pouvez utiliser votre smartphone pour obtenir un fichier image au format
JPEG
. Les captures d'écran du certificat de scolarité seront rejetées. - Constatez l'état de votre demande qui devrait être approuvée :
- Patientez quelques jours avant de profiter de votre accès à
GitHub Copilot
! - Après 3 ou 4 jours d'attente, vos avantages sont disponibles :
- Accédez à vos paramètres de compte concernant
GitHub Copilot
- Activez
GitHub Copilot
en cliquant sur le bouton « Start free trial » : - Vous devriez voir apparaître un message donnant accès à la version gratuite de
GitHub Copilot
: - Cliquez sur le bouton « Get access to GitHub Copilot »
- Choisissez ensuite vos préférences de
GitHub Copilot
:
Création du projet dans PhpStorm
¶
La gestion d'une application Symfony
nécessitant de modifier de nombreux fichiers dans une arborescence complexe, vous utiliserez PhpStorm
pour l'édition de texte. Des greffons apportent le support de Symfony
, Composer
, des fichiers YAML
, Twig
, … Certains sont préinstallés dans la configuration générale.
Vous allez créer un nouveau projet PHP
à partir de PhpStorm
pour gérer votre application Web.
Remarque importante
PhpStorm
est un outil puissant parmi d'autres développés par JetBrains. Leur utilisation dans le cadre professionnel impose de s'acquitter d'une licence annuelle. Cependant, dans la cadre universitaire, vous pouvez disposer d'une licence gratuite pour les étudiants. Ceci vous permet d'utiliser les outils sur votre ordinateur personnel, tant que vous êtes étudiant. L'utilisation de PhpStorm
au sein du département ne nécessite pas de démarche particulière puisque nous avons un serveur de licences JetBrains.
Je vous invite néanmoins à demander une licence et à travailler sur votre ordinateur personnel en dehors des séances de TP.
Travail à réaliser
- Dans votre terminal et dans le répertoire du projet, lancez la commande
phpstorm . &
Remarque importanteLa création du projet
PhpStorm
induit la création du répertoire «.idea
» dans le répertoire de votre projetSymfony
. En temps normal, en particulier lors d'un développement collaboratif comme la SAÉ de S3, il est impensable d'inclure le répertoire «.idea
» au dépôtGit
. En effet, chaque modification de la configuration dePhpStorm
faite par l'un des développeurs va engendrer la modification de la configuration de tous les autres développeurs une fois que la modification se retrouvera dans la branche principale.Néanmoins, à cause de la configuration particulière au sein du département informatique qui vous oblige à travailler dans le répertoire local «
/working/votre_login
» sur des ordinateurs différents, et parce que vous êtes l'unique développeur de votre projet, il est légitime d'inclure le répertoire de configuration dePhpStorm
, «.idea
», afin que vous n'ayez pas à reconfigurer votre environnement lorsque vous clonerez votre dépôt en début de séance.
Qualité de code et automatisation ¶
Consignes de codage et de nommage ¶
Le code de l'écosystème Symfony
est intégralement en anglais. Tous les composants que vous allez utiliser possèdent donc des noms anglais. Afin de maintenir une bonne lisibilité de votre code, vous allez respecter les règles de nommage en langue anglaise pour les noms de classes, de propriétés, de méthodes, de variables, de fonctions, de fichiers, … Ceci vaudra également pour les commentaires ainsi que les messages de commit. Les instructions et informations notables consignées dans le fichier « README.md
» pourront être en français. L'interface utilisateur de l'application sera également en français.
Documentation du projet ¶
Tout projet de développement doit fournir les clés pour l'installation, la configuration et le démarrage par un nouveau développeur. Cet effort de documentation peut également s'avérer bénéfique pour le créateur du projet qui peut oublier certains points essentiels de configuration au fil du temps. Ainsi, vous allez rédiger le mode d'emploi de votre projet dans un fichier « REAMDE.md
» et le tenir à jour au fil du développement.
Travail à réaliser
- Créez le fichier «
README.md
» à l'aide dePhpStorm
(qui vous propose de l'ajouter à l'indexGit
) - Complétez les informations suivantes :
- un titre de niveau 1 contenant le titre explicite du projet
- un titre de niveau 2 « Auteur(s) » vous permettant de préciser votre nom et votre prénom (ainsi que ceux de votre binôme, le cas échéant)
- un titre de niveau 2 « Installation / Configuration » précisant les points essentiels permettant d'installer, de configurer et de lancer le projet
- Validez votre travail dans
Git
Standards de codage PHP avec PHP CS Fixer
¶
Travail à réaliser
- Installez
PHP CS Fixer
sans oublier l'option «--dev
» - Configurez
PHP CS Fixer
pour utiliser 4 cœurs en parallèle - Configurez
PHP CS Fixer
dansPhpStorm
Qualité de code avec PHPStan
¶
Travail à réaliser
- Installez
PHPStan
sans oublier l'option «--dev
» - Ajoutez les extensions
PHPStan
pourSymfony
et pourDoctrine
, toujours sans oublier l'option «--dev
» - Configurez
PHPStan
dansPhpStorm
Standards de codage Twig avec Twig CS Fixer
¶
Travail à réaliser
- Installez
Twig CS Fixer
sans oublier l'option «--dev
»
Mise en place de scripts Composer
¶
Les dépendances de votre projet Symfony
sont gérées par Composer
. Profitons-en pour mettre en place quelques scripts Composer
qui faciliteront la gestion quotidienne du projet.
Travail à réaliser
- Ajoutez un script «
start
» qui lance le serveur web de test («symfony serve
») sans restriction de durée d'exécution - Ajoutez un script «
test:csfixer
» qui lance la commande de vérification du style de codePHP
parPHP CS Fixer
- Ajoutez un script «
fix:csfixer
» qui lance la commande de correction du style de codePHP
parPHP CS Fixer
- Ajoutez un script «
test:phpstan
» qui lance la commande de vérification du codePHP
parPHPStan
- Ajoutez un script «
test:twig
» qui lance la commande de vérification du style de codeTwig
parTwig CS Fixer
- Ajoutez un script «
fix:twig
» qui lance la commande de correction du style de codeTwig
parTwig CS Fixer
- Ajoutez un script «
test:yaml
» qui lance la commande de la consoleSymfony
permettant la vérification des fichiersYAML
contenus dans le répertoire «config
»InformationLancez la commande suivante pour découvrir les divers « linters » fournis par la console :
php bin/console lint help
- Ajoutez un script «
test
» qui lance tous les scripts de test - Ajoutez un script «
fix
» qui lance tous les scripts de correction de style de code - Documentez vos scripts dans le fichier «
composer.json
» - Documentez vos scripts dans le fichier «
README.md
»
Automatisation des contrôles de qualité de code avec GrumPHP
¶
Travail à réaliser
- Installez
GrumPHP
, sans oublier l'option «--dev
», et NE demandez PAS la génération du fichier de configuration (bug constaté)InformationLorsque
Composer
demande si vous souhaitez exécuter les scripts de post-installation, répondez «y
» :phpro/grumphp contains a Composer plugin which is currently not in your allow-plugins config. See https://getcomposer.org/allow-plugins Do you trust "phpro/grumphp" to execute code and wish to enable it now? (writes "allow-plugins" to composer.json) [y,n,d,?] y
- Créez un fichier de configuration de
GrumPHP
contenant :grumphp: tasks: { composer: null }
- Donnez au fichier de configuration une forme plus usuelle au niveau du tableau associatif «
tasks
»grumphp: tasks: composer: null
- Tentez de valider votre travail dans
Git
Remarque importanteSelon la façon dont votre environnement
Linux
est configuré, et si vous utilisezGit
à traversPhpStorm
, il se peut que vous rencontriez l'erreur suivante lors des tâchesGrumPHP
:The executable for "composer" could not be found.
Ceci est lié aux variables d'environnement accessibles par
PhpStorm
, en particulier «$PATH
», selon que vous le lancez par le menu de votre gestionnaire de fenêtres ou en ligne de commande. Pour résoudre ce problème, référez-vous au point « Exécution deComposer
à traversPhpStorm
» du guide « Installation et configuration dePhpStorm
». - Vous constatez que
GrumPHP
empêche la validation de votre travail : la tâche «composer
» échoue- ajoutez les éléments nécessaires au fichier «
composer.json
» selon les indications deGrumPHP
- cherchez l'option de «
composer update
» permettant de mettre à jour uniquement le fichier «composer.lock
» - mettez à jour uniquement le fichier «
composer.lock
»
- ajoutez les éléments nécessaires au fichier «
- Configurez
GrumPHP
:Remarque importanteAjoutez au fichier de configuration uniquement ce qui est demandé.
- désactivez le «
fixer
» intégré (voir la documentation des paramètres deGrumPHP
) - ajoutez la tâche «
git_blacklist
» et interdisez les expressions «dump(
», «var_dump(
», «print_r(
», «die(
», «exit(
» et «exit;
» - lisez la spécification «
Commits Conventionnels
» - ajoutez la tâche «
git_commit_message
» avec les options suivantes :- le sujet du commit ne commence pas forcément par une majuscule
- les types de commit se limitent à
«
build
», «ci
», «chore
», «docs
», «feat
», «fix
», «perf
», «refactor
», «revert
», «style
» et «test
» - les portées des commits (« scopes ») sont libres
- ajoutez la tâche «
composer_script
» pour déclencher le scriptComposer
«test:yaml
» - ajoutez la tâche «
composer_script
» pour déclencher le scriptComposer
«test:twig
»InformationVous ne pouvez pas ajouter directement deux tâches
GrumPHP
portant le même nom. Vous devez donc ajouter une tâche «composer_script
» pour chaque scriptComposer
que vous souhaitez exécuter selon la méthode définie dans la documentation. - ajoutez la tâche «
phpcsfixer
»InformationN'oubliez pas l'option «
config
» de cette tâche. - ajoutez la tâche «
phpstan
»
- désactivez le «
Installation / configuration des greffons PhpStorm
¶
Vous allez maintenant installer les greffons nécessaires à la gestion de votre projet Symfony
.
Travail à réaliser
- Installez les greffons suivants :
- Activez le support de
Symfony
pour le projet - Configurez le greffon
GitHub Copilot
dont l'icône doit apparaître dans la barre d'état en bas de la fenêtre dePhpStorm
Conteneurisation des services de base de données ¶
Les projets Symfony
générés avec l'outil ligne de commande « symfony
» contiennent un fichier « compose.yaml
» et un fichier « compose.override.yaml
». Les images utilisées par défaut sont celles de PostgreSQL
dans sa variante alpine
et de Mailpit.
Nous allons dans un premier temps nous concentrer sur la base de données pour changer l'image PostgreSQL
utilisée et ajouter une image dérivée de Adminer
permettant la connexion automatique à l'interface.
Travail à réaliser
- Modifiez le fichier «
compose.yaml
» pour utiliser l'imagePostgreSQL
classique en remplacement de celle basée suralpine
- Modifier le nom du volume de données de la base de données pour qu'il soit «
votre_login_database_data
» - Modifiez le fichier «
compose.override.yaml
» pour :- exposer le port du service de base de données
- ajouter l'image «
butopea/adminer
» en tant que service - configurer les variables d'environnement du service «
adminer
» pour que l'interface soit disponible sur le port «7080
» et que la connexion à la base de données soit automatiqueInformationNe touchez ni à configuration du conteneur
PostgreSQL
, ni au «DATABASE_URL
» par défaut du fichier «.env
». Modifiez uniquement les variables d'environnement du service «adminer
» pour les faire correspondre au reste de la configuration.
- Lancez vos conteneurs
- Vérifiez le bon fonctionnement de la base de données avec :
bin/console doctrine:query:sql "SELECT 1"
- Vérifiez le bon fonctionnement de l'interface
Adminer
en vous connectant à l'interface Web sur le port «7080
»
Les annonces dans l'application ¶
La base de l'application s'appuie sur les annonces d'objets à vendre. Vous mettrez en place une entité Advertisement
pour gérer ces annonces. Après avoir généré des données factices (« fixtures »), les premières fonctionnalités de l'application seront l'affichage de la liste des annonces et la consultation d'une annonce. Viendront ensuite la création, la modification et la suppression d'une annonce. Vous automatiserez la gestion des dates de création et de mise à jour de ces annonces. Les aspects de présentation seront facilités par l'utilisation de Bootstrap
.
Création d'une entité « Advertisement
»
¶
Afin de respecter le codage en langue anglaise, l'entité correspondant à une annonce sera nommée « Advertisement
».
Travail à réaliser
- Utilisez la commande du «
MakerBundle
»Symfony
pour générer l'entité «Advertisement
» avec les propriétés suivantes :- «
title
» de typestring(100)
, non null - «
description
» de typetext
, non null - «
price
» de typeint
, non null - «
createdAt
» de typedatetime_immutable
, non null - «
updatedAt
» de typedatetime_immutable
- «
location
» de typestring(100)
, non null
- «
- Créez une migration
Génération de données factices ¶
Afin de pouvoir tester votre application, vous allez proposer des données factices correspondant aux annonces. Pour cela, vous utiliserez le « DoctrineFixturesBundle
» ainsi que le paquet « Foundry
».
Travail à réaliser
- Installez le «
DoctrineFixturesBundle
» - Installez le paquet «
Foundry
» - Créez un modèle d'annonces avec «
Foundry
» - Configurez le modèle pour qu'il génère des annonces factices :
- avec un titre de maximum 100 caractères
- avec une description de maximum 500 caractères
- avec un prix entre 0 et 1500 €
- avec une localisation correspondant à une ville française
- créées entre maintenant et il y a 2 mois
- sans date de mise à jour
- Créez une classe de données factices «
AdvertisementFixtures
» - Modifiez «
AdvertisementFixtures
» pour créer 500 annonces aléatoires
Création de la base de données ¶
La création de la base de données en mode développement est une opération classique qui doit être facilement accessible. Vous devez disposer d'un script Composer
.
Travail à réaliser
- Ajoutez un script
Composer
«db
» permettant de :- forcer la suppression de la base de données, si elle existe
- créer la base de données
- appliquer les migrations
- charger les données factices
- Donnez une description de votre script dans le fichier «
composer.json
» - Documentez votre script dans le fichier «
README.md
» - Utilisez le service «
Adminer
» pour vérifier que les données factices ont bien été insérées dans la base de données
Visualisation des annonces ¶
Les annonces étant désormais créées en base de données, il est temps de les afficher. Dans un premier temps, vous proposerez une liste des annonces. Dans un second temps, vous proposerez une page de détail pour chaque annonce.
Travail à réaliser
- Utilisez la commande du «
MakerBundle
»Symfony
pour générer un contrôleur «AdvertisementController
» - Proposez la liste des annonces triées par ordre inverse de création dans l'action «
index()
»- Ajoutez une méthode «
findAllOrderedByDate()
» dans le dépôt «AdvertisementRepository
» - Utilisez la précédente méthode pour obtenir la liste des annonces et la transmettre à la vue qui se chargera de construire une liste
HTML
avec titre et date de création de chaque annonce
- Ajoutez une méthode «
- Proposez le détail d'une annonce dans l'action «
show()
»- Ajoutez une validation du paramètre de la route
- Utilisez un convertisseur d'attribut de requête pour obtenir l'annonce à partir de son identifiant
- Transmettez l'annonce à la vue qui se chargera de construire une présentation
HTML
simple des données
- Ajoutez un lien vers la page de détail de chaque annonce dans la liste des annonces
Désactivation de Symfony UX Turbo
¶
Depuis la version 7 de Symfony
, Symfony UX Turbo
est activé par défaut. Ce « bundle », faisant partie de l'initiative Symfony UX
, apporte le support de Hotwire Turbo
qui amène une expérience utilisateur de type application web monopage (SPA en anglais) sans avoir à écrire de Javascript
. Vous allez le désactiver pour éviter les problèmes de compatibilité avec Bootstrap
ainsi que des comportements de l'application, induits par la magie de Symfony UX Turbo
, qui perturberaient votre compréhension du fonctionnement de Symfony
.
Travail à réaliser
- Localisez le fichier contenant la liste des contrôleurs
Stimulus
installés - Désactivez le contrôleur
Stimulus
«@symfony/ux-turbo
»
Utilisation de Bootstrap
CDN dans l'interface utilisateur
¶
Vous allez maintenant améliorer la présentation de votre application en y incorporant Bootstrap
. Votre tâche sera facilitée par les composants HTML
et les classes CSS
proposés. Vous utiliserez ces composants pour améliorer l'interface utilisateur (UI) et l'expérience utilisateur (UX) de votre projet.
Dans un premier temps, vous intégrerez Bootstrap
à votre projet via un CDN. Par la suite, vous installerez Bootstrap
via AssetMapper
. Ceci vous permettra une intégration complète à votre projet et autorisera la personnalisation de Bootstrap
.
Travail à réaliser
- Générez un contrôleur «
HomeController
» qui permet de rediriger les requêtes de la page d'accueil vers la liste des annonces - Modifiez le « template » de base de votre projet
- Ajoutez les liens vers les fichiers
Bootstrap
- Définissez le « viewport »
- Ajoutez la langue par défaut
- Ajoutez les liens vers les fichiers
- Structurez le « template » de base de votre projet en utilisant les classes de «
Bootstrap
» :- Bloquez la largeur maximale du contenu principal
- Ajoutez une barre de navigation en haut de la page
- Donnez du style aux listes d'annonces
- Donnez du style aux annonces
- Modifiez la configuration de
Twig
pour appliquer le thèmeBootstrap
aux formulaires
Formulaire d'édition / création d'une annonce ¶
Le même formulaire doit permettre d'effectuer la saisie d'une nouvelle annonce ou l'édition d'une annonce existante.
Travail à réaliser
- Utilisez la commande du «
MakerBundle
»Symfony
pour générer une classe de formulaire «AdvertisementType
» pour l'entité «Advertisement
» - Supprimez les champs de saisie de date de création et de modification qui seront gérés automatiquement
- Précisez les types de champs de saisie restants
- Ajoutez des contraintes de validation sur l'entité «
Advertisement
» :- «
title
» est non vide et contient entre 10 et 100 caractères - «
description
» est non vide et contient entre 20 et 1000 caractères - «
price
» est positif ou nul («≥ 0
» mais pas «null
») - «
location
» est non vide et contient entre 2 et 100 caractères
- «
- A l'aide de l'option «
attr
» des champs de la classe de formulaire, précisez les attributsHTML
améliorant l'ergonomie de la saisie :- «
title
» contient entre 10 et 100 caractères - «
description
» contient entre 20 et 1000 caractères - «
price
» est positif ou nul - «
location
» contient entre 2 et 100 caractères
- «
Automatisation des dates de création et de mise à jour ¶
Un certain nombre de tâches de gestion de données se retrouvent dans de nombreux projets. C'est le cas des champs de date de création ou de mise à jour. Aussi, « StofDoctrineExtensionsBundle
», une extension de Doctrine
, propose un ensemble de fonctionnalités qui peuvent être activées pour automatiser ces tâches ainsi que d'autres dans le même esprit. La mécanique repose sur l'utilisation d'attributs PHP
8 associés aux propriétés des entités.
Dans le cas des annonces, la date de création doit être automatiquement renseignée lors de la création d'une annonce. De même, la date de mise à jour doit être automatiquement renseignée lors de la modification d'une annonce.
Travail à réaliser
- Installez l'extension «
StofDoctrineExtensionsBundle
»Remarque importanteExécutez bien la recette associée :
Symfony operations: 1 recipe (e371a4c7f75ca061c8026ed12542ac5b) - WARNING stof/doctrine-extensions-bundle (>=1.2): From github.com/symfony/recipes-contrib:main The recipe for this package comes from the "contrib" repository, which is open to community contributions. Review the recipe at https://github.com/symfony/recipes-contrib/tree/main/stof/doctrine-extensions-bundle/1.2 Do you want to execute this recipe? [y] Yes [n] No [a] Yes for all packages, only for the current installation session [p] Yes permanently, never ask again for this project (defaults to n): y
- Activez l'extension «
Timestampable
» - Utilisez les attributs
PHP
8 pour automatiser les dates de création et de mise à jour :- La date de création doit être automatiquement renseignée lors de la création d'une annonce
- La date de mise à jour doit être automatiquement renseignée lors de la modification des propriétés «
title
», «description
», «price
» ou «location
» d'une annonce
Utilisation du formulaire d'édition / création d'une annonce ¶
Le formulaire de saisie d'une nouvelle annonce ou d'édition d'une annonce existante étant créé, il convient à présent de l'utiliser. Pour cela, vous créerez deux nouvelles actions dans le contrôleur « AdvertisementController
» pour afficher le formulaire de saisie et enregistrer une nouvelle annonce ainsi que pour afficher le formulaire d'édition et modifier une annonce existante.
Travail à réaliser
- Créez un modèle «
advertisement/_form.html.twig
» qui affiche le formulaire de saisie d'une annonce et le bouton de soumission, selon les bonnes pratiques concernant les formulaires - Ajoutez une action «
new()
» (URL «/advertisement/new
») dans le contrôleur «AdvertisementController
», qui utilise «advertisement/_form.html.twig
» pour afficher le formulaire de saisie d'une nouvelle annonce - Ajoutez une action «
edit()
» (URL «/advertisement/12/edit
») dans le contrôleur «AdvertisementController
», qui utilise «advertisement/_form.html.twig
» pour afficher le formulaire d'édition d'une annonce existante - Rendez les actions fonctionnelles afin qu'elles puissent créer une nouvelle annonce ou enregistrer les modifications apportées à une annonce existante
Suppression d'une annonce ¶
L'action de suppression manque pour compléter le CRUD des annonces.
Travail à réaliser
- Ajoutez une action «
delete()
» (URL «/advertisement/12
») dans le contrôleur «AdvertisementController
», vide pour l'instant, accessible uniquement via la méthodeHTTP
POST
Remarque importanteLa suppression d'une annonce doit être réalisée en
POST
pour éviter les suppressions accidentelles. L'URL
de l'action est de la même forme que celle de l'affichage d'une annonce : «/advertisement/12
». La seule façon de distinguer les deux routes est la méthodeHTTP
utilisée. Pensez à limiter chaque route aux méthodesHTTP
qu'elle utilise. - Créez un « template » partiel pour le bouton de suppression d'une annonce Information
Le « template » partiel sera inclus dans chaque vue où un bouton de suppression d'une annonce est nécessaire. Il est constitué d'un formulaire
HTML
enPOST
contenant uniquement un bouton d'envoi. Afin d'éviter les suppressions intempestives, une confirmation réalisée enJavaScript
sera associée à l'événement de soumission du formulaire :<form … onsubmit="return confirm('Message de confirmation de suppression');">
- Implémentez la logique de suppression d'une annonce dans l'action «
delete()
» - Protégez la suppression de l'annonce des attaques « CSRF » en ajoutant un jeton « CSRF » au formulaire de suppression
- Contrôlez la présence du jeton « CSRF » dans l'action associée à la suppression
- Dans la vue des détails d'une annonce, ajoutez un bouton d'édition ainsi que le formulaire de suppression
Catégories d'annonces ¶
Les annonces seront plus faciles à trouver si elles sont rangées par catégorie.
Information
Vous veillerez à structurer correctement les informations présentées dans les vues et à fournir une interface utilisateur agréable en profitant de Bootstrap 5
.
Création de l'entité « Category
»
¶
Vous allez tout d'abord générer l'entité « Category
».
Travail à réaliser
- Utilisez la commande du «
MakerBundle
»Symfony
pour générer l'entité «Category
» avec les propriétés suivantes :- «
name
» de typestring(50)
, non null
- «
- Vérifiez le code généré
Relations entre les entités « Advertisement
» et « Category
»
¶
L'entité « Advertisement
» doit être liée à l'entité « Category
» afin de pouvoir associer une annonce à une catégorie. Une annonce appartient forcément à une catégorie et une catégorie peut contenir plusieurs annonces.
Travail à réaliser
- Utilisez la commande du «
MakerBundle
»Symfony
pour modifier l'entité «Advertisement
» :- ajoutez une relation «
category
» obligatoire vers l'entité «Category
» - ajoutez la relation inverse «
advertisements
» dans l'entité «Category
»
- ajoutez une relation «
- Créez une migration
Données factices ¶
Afin d'apporter un peu de lisibilité au jeu de données d'essai, vous allez construire la collection de catégories à partir d'un fichier contenant une liste réelle.
Travail à réaliser
- Récupérez le fichier «
category.txt
» et placez-le dans le répertoire «data
» du projet - Générez une classe de « fixtures » pour l'entité «
Category
» - Générez une «
Factory
» pour l'entité «Category
» - Importez les données du fichier dans la base de données en utilisant la «
Factory
» et la classe de « fixtures »InformationLe fichier contenant les données est localisé dans le répertoire «
data
» du projet. La classe de « fixtures », qui se trouve dans un autre répertoire, doit l'ouvrir et le lire. Il est donc nécessaire de préciser le chemin absolu du fichier. Pour cela, vous utiliserez les fonctionnalités d'« autowiring » deSymfony
, plus particulièrement le branchement manuel de paramètre pour accéder à la valeur du chemin du projet et contruire le chemin vers le fichier d'intérêt. - Modifiez la «
Factory
» de l'entité «Advertisement
» pour qu'elle associe chaque nouvelle annonce à une nouvelle catégorie - Rétablissez l'ordre logique de génération des « fixtures » pour que les catégories soient créées avant les annonces
- Vérifiez le bon chargement des données avec le service
Docker
Adminer
Données factices, introduction de « Story
»
¶
Les jeux de données d'essai peuvent devenir complexes à construire et sont alors difficilement réutilisables. Foundry
propose le concept de « Story
» qui permet de définir un ensemble de données cohérentes et réutilisables.
Travail à réaliser
- Lisez le chapitre de la documentation de
Foundry
consacré aux «Stories
» - Générez une «
Story
» pour l'entité «Category
» - Importez les données du fichier «
category.txt
» dans un tableauPHP
- Extrayez la première catégorie de votre import pour créer un «
State
» que vous nommerez «category_without_advertisement
» - Utilisez le reste du tableau de noms de catégories pour construire un «
Pool
» que vous nommerez «categories
» - Modifiez la classe de « fixtures » associée à l'entité «
Category
» afin qu'elle utilise la «Story
» pour générer toutes les catégories - Modifiez la classe de « fixtures » associée à l'entité «
Advertisement
» afin qu'elle utilise la «Story
» pour générer des annonces dont la catégorie sera tirée au hasard dans le «Pool
» «categories
» - Améliorez les performances de la génération du jeu d'essai en utilisant la fonction «
flush_after()
» pour toutes les « fixtures » des catégoriesInformationDepuis la version 2 de
Foundry
, l'utilisation deflush_after()
conjointement avec desPool
issus desStory
conduit à un comportement anormal.
Liste des annonces par catégorie ¶
Les utilisateurs doivent pouvoir visualiser les annonces par catégorie. Vous allez donc proposer la liste des catégories ainsi que la liste des annonces pour chaque catégorie.
Travail à réaliser
- Utilisez la commande du «
MakerBundle
»Symfony
pour générer un contrôleur «CategoryController
» - Utilisez la route par défaut du contrôleur pour afficher la liste des catégories triées par ordre alphabétique
- Définissez une route «
show
» pour afficher la liste des annonces d'une catégorieInformationPuisque vous avez déjà proposé une vue d'une liste d'annonces, il serait judicieux de mettre le code en commun dans un fragment de « template » qui sera nommé selon les bonnes pratiques. Ce dernier sera inclus ou intégré selon votre choix, et comprendra le titre «
h1
» qui pourra être personnalisé. - Ajoutez un lien sur chaque catégorie de la liste pour afficher les annonces de la catégorie
Affichage de la catégorie d'une annonce ¶
L'ergonomie de l'interface utilisateur sera améliorée si chaque annonce affiche la catégorie à laquelle elle est associée, aussi bien dans la vue détaillée de l'annonce que dans les listes d'annonces.
Travail à réaliser
- Ajoutez le nom de la catégorie dans la vue détaillée d'une annonce
- Ajoutez le nom de la catégorie dans la liste des annonces
- Ajoutez un lien sur la catégorie pour afficher les annonces de la catégorie
- Ajoutez une entrée dans la barre de navigation pour afficher la liste des catégories
Formulaire de saisie d'une annonce ¶
L'annonce possède une relation vers la catégorie. Il convient donc de proposer un champ de saisie permettant de sélectionner la catégorie de l'annonce.
Travail à réaliser
- Lisez la documentation de
Symfony
sur les champs de formulaires associés aux entités - Ajoutez un champ de saisie de catégorie dans le formulaire de saisie d'une annonce
- Affichez le nouveau champ de saisie dans la vue
- Dans la vue, pensez à ajouter une entrée dans la liste déroulante pour forcer le choix d'une catégorie
Considérations sur les performances ¶
L'ORM Doctrine
facilite la tâche du développeur en proposant une interface PHP
pour la gestion des données. Cependant, cette interface a un coût en termes de performance et il est nécessaire d'analyser les requêtes pour voir s'il est possible d'optimiser les performances de l'application. Dans le cas présent, la relation entre les annonces et les catégories implique d'effectuer, sur une collection d'annonces, une nouvelle requête en base de données pour récupérer la catégorie de chacune des annonces.
Catégorie de l'annonce dans la liste des annonces ¶
Vous allez analyser puis optimiser le requêtage des annonces au sein des listes.
Travail à réaliser
- Affichez la liste des annonces dans votre navigateur
- Observez les requêtes effectuées dans la partie
Doctrine
du «Profiler
» accessible par la barre de débogage (« Web Debug Toolbar ») - Expliquez pourquoi une requête est effectuée pour chaque catégorie
- Proposez une solution pour optimiser le requêtage au niveau du «
Repository
»InformationLe nom de la méthode du «
Repository
» doit refléter votre démarche d'optimisation. Vous devez donc le compléter avec un suffixe qui indique les entités supplémentaires sélectionnées. - Vérifiez que votre solution diminue le nombre de requêtes effectuées
Taille de la liste des annonces ¶
Du point de vue des performances, mais également de l'expérience utilisateur, les listes de grande taille doivent être paginées. C'est une problématique courante, dont la solution peut être trouvée dans un « bundle ». Concrètement, d'un point de vue base de données, il s'agit de limiter le nombre de résultats retournés par une requête. Cependant, il est nécessaire de connaître le nombre total de résultats pour pouvoir proposer une pagination. C'est pourquoi, il est nécessaire d'effectuer deux requêtes : une pour récupérer les résultats et une pour récupérer le nombre total de résultats.
Travail à réaliser
- Lisez les explications de la limitation de sélection de résultats dans la documentation « PHP MySQL Limit Data Selections » de
W3Schools
- Parcourez rapidement la documentation de «
KnpPaginatorBundle
» - Installez «
KnpPaginatorBundle
» dans votre projet - Utilisez «
KnpPaginatorBundle
» pour paginer la liste de toutes les annoncesInformationPour réaliser la pagination, vous devez utiliser un paramètre d'
URL
pour désigner la page demandée. La méthode classique pour récupérer ce paramètre est d'ajouter l'objetRequest
en argument de la méthode du contrôleur. Il est désormais possible d'utiliser le mappage automatique de la requêteHTTP
en utilisant l'attributPHP
«#[MapQueryParameter]
». Ceci offre une meilleure lisibilité du code et permet également d'appliquer des filtres de validation. - Modifiez le fichier de configuration de «
KnpPaginatorBundle
» pour appliquer le thèmeBootstrap 5
à la paginationInformationDans la documentation, le nom et le chemin du fichier de configuration
YAML
ne sont pas indiqués. Les fichiers de configuration des packages installés dans le projet se trouvent dans «config/packages
». A moins que ce soit un package du frameworkSymfony
, le fichier de configuration est nommé de la même manière que la première clé du fichierYAML
suivie de l'extension «.yaml
».Remarque importanteSi le thème
Bootstrap 5
ne s'applique pas, effacez le cache de l'application. - Observez la probable absence de répercussions sur les requêtes effectuées (absence de «
LIMIT
» dans les requêtes)Information«
KnpPaginatorBundle
» permet de paginer de nombreuses formes de collections. Si vous appliquez la pagination à la liste des annonces sous forme de résultat de requête, vous paginez un tableau de toutes les annonces. «KnpPaginatorBundle
» doit avoir accès à la requête pour pouvoir la modifier. C'est pourquoi, il est nécessaire de modifier votre approche en paginant une requête et non une collection issue d'un résultat de requête. - Modifiez le code de la méthode pour qu'elle retourne la requête et non son résultat
- Modifiez le nom de la méthode «
findAllOrderedByDate…()
» du «Repository
» en «queryAllOrderedByDate…()
» pour refléter le changement d'approche - Vérifiez que la pagination fonctionne correctement et que les requêtes sont optimisées (présence de «
LIMIT
») - Procédez de la même manière pour la liste des annonces d'une catégorie
- Modifiez la valeur par défaut du nombre d'annonces par page pour afficher 15 annonces par page
Pagination de la liste des catégories ¶
Afin d'uniformiser l'application, vous allez paginer la liste des catégories.
Travail à réaliser
- Modifiez tout le code nécessaire pour paginer la liste des catégories
- Vérifiez que la pagination fonctionne correctement et que les requêtes sont optimisées (présence de «
LIMIT
») - Vérifiez que la valeur par défaut du nombre de catégories par page est correcte
Catégorie dans les détails de l'annonce ¶
La récupération de l'annonce lors de son affichage détaillé peut bénéficier d'une requête optimisée. En effet, la relation entre l'annonce et la catégorie est connue lors de la récupération de l'annonce. Il est donc possible de récupérer la catégorie en même temps que l'annonce, en utilisant une jointure.
Travail à réaliser
- Lisez la documentation « Automatically Fetching Objects (EntityValueResolver) », en particulier le point sur l'utilisation d'une expression avec l'attribut
PHP
«MapEntity
» - Définissez une méthode dans le «
Repository
» pour répondre à la problématique - Associez la méthode du «
Repository
» à l'action «show()
» à l'aide de l'attributPHP
«MapEntity
» - Vérifiez les requêtes effectuées lors de l'affichage détaillé d'une annonce
- Associez la méthode du «
Repository
» à l'action «edit()
» à l'aide de l'attributPHP
«MapEntity
» - Vérifiez les requêtes effectuées lors de l'édition d'une annonce
Mise en place de tests ¶
Un projet informatique qui inclut des tests présente de nombreux avantages, directement liés à la détection précoce des problèmes :
- amélioration de la qualité du code
- non régression lors des évolutions
- possibilité de développement itératif par intégration continue et déploiement continu
- facilitation de la collaboration entre développeurs en contenant les effets de bord des modifications de chacun
- fiabilisation des mises à jour des composants (serveur, langage de programmation, « frameworks », « toolkits », …)
Les projets Web demandent un effort particulier sur les tests fonctionnels ou d'acceptation. Symfony s'appuie sur PHPUnit
pour proposer des tests unitaires, d'intégration et fonctionnels. Les tests fonctionnels (« Application Tests ») sont particulièrement adaptés aux projets Web, car ils permettent de tester l'application dans son ensemble, en simulant un navigateur qui va émettre une requête HTTP
vers l'application pour provoquer une réponse qui sera récupérée, analysée et testée.
Sur le même principe, Codeception
propose un module Symfony
. Nous utiliserons Codeception pour la lisibilité apportée par la syntaxe de ses tests.
Installation/configuration de Codeception
¶
Vous allez dans un premier temps installer Codeception
et les modules nécessaires.
Travail à réaliser
- Installez
Codeception
, sans oublier que c'est une dépendance de développementInformationAjoutez l'option «
--no-interaction
» pour éviter d'avoir à répondre à des questions et surtout pour empêcher la génération des suites de tests par défaut. - Installez en une seule commande les modules «
Asserts
», «Symfony
» et «Doctrine
» deCodeception
- Constatez l'échec de l'installation Information
La lecture attentive des messages d'erreur vous indique qu'il faut mettre à jour
PHPUnit
vers la version 10. - Modifiez la version de
PHPUnit
dans le fichier «composer.json
» pour qu'elle soit compatible avecCodeception
, en spécifiant une sous-version 10.5 - Lancez la mise à jour de
PHPUnit
ainsi que de tous les paquets dépendants avec l'option «-w
» ou «--with-dependencies
»composer update -w phpunit/phpunit
- Constatez la réussite de la mise à jour de
PHPUnit
, ainsi que d'une vingtaine de paquets - Relancez l'installation des modules de
Codeception
- Lisez le guide de démarrage rapide de
Codeception
- Consultez les options d'amorçage (« bootstrap ») de
Codeception
- Amorcez
Codeception
dans votre projet en précisant le namespace «App\Tests
» et en ne générant pas les suites par défautInformationEn ligne de commande, si vous souhaitez passer un paramètre contenant le caractère «
\
», vous devez le doubler puisque le shell utilise ce même caractère «\
» pour échapper les caractères. Ainsi, le namespace «App\Tests
» devient «App\\Tests
» dans les paramètres de la ligne de commande. - Chargez les paramètres de configuration dans la configuration générale de
Codeception
depuis les fichiers «.env
» et «.env.test
» - Configurez l'environnement de test de
Symfony
pour qu'il utilise une base de données «SQLite
» (trouvez le «DATABASE_URL
» adéquat dans le fichier «.env
») - Excluez les sources générées par
Codeception
(«tests/Support/_generated
») de l'analyse de code dePHP CS Fixer
- Excluez les sources générées par
Codeception
(«tests/Support/_generated
») de l'analyse de code dePHPStan
InformationCodeception
fonctionne en partie en générant du codePHP
dans le répertoire «tests/Support/_generated
». Ce code est nécessaire au fonctionnement deCodeception
, ainsi qu'à l'analyse statique de code effectuée parPHPStan
, manuellement ou à traversGrumPHP
. Vous serez donc peut-être amené à forcer la génération pour pouvoir effectuer un « commit ». Il peut également être nécessaire d'effacer le cache de résultats dePHPStan
pour que certaines modifications soient prises en compte. - Créez un script
Composer
nommé «test:codeception
» qui :- nettoie les fichiers générés par
Codeception
- détruit la base de données dans l'environnement de test
- crée la base de données dans l'environnement de test
- crée le schéma de la base de données dans l'environnement de test
- exécute les tests de
Codeception
InformationLe nom du script
Composer
«test:codeception
» peut sembler très long. Cependant, il est important de le nommer de manière explicite pour que chacun comprenne immédiatement son rôle. De plus, il est possible de raccourcir ce nom à l'utilisation en utilisant la commandeComposer
tant qu'il n'y a pas d'ambiguïté avec d'autres scripts. Ansi, la commandeComposer
permettant d'exécuter ce script peut être réduite àcomposer test:co
Ceci est naturellement valable pour tous les scriptsComposer
que vous créez, ainsi que les commandes classiques comme «install
». - nettoie les fichiers générés par
- Décrivez ce script dans «
composer.json
» et dans la documentation de votre projet - Complétez le script
Composer
nommé «test
» afin qu'il exécute les testsCodeception
à la suite des scripts de tests que vous avez créés jusqu'à présent
Quelques ajustements des outils de qualité de code ¶
La configuration des outils de qualité de code mis en place précédemment peut être affinée. PHPStan
sera plus adapté par l'intégration des extensions « PHPStan Extension Installer
» puis « PHPStan Symfony Framework extensions and rules
» et « Doctrine extensions for PHPStan
». Dans un souci d'organisation du projet, les fichiers de cache peuvent être relocalisés dans le répertoire « var
» de l'application. Pour finir, certains script Composer
peuvent être modifiés pour améliorer la lisibilité ou la robustesse des tests.
Travail à réaliser
- Installez l'extension «
PHPStan Extension Installer
» dePHPStan
, sans oublier d'exécuter les recettes de configuration - Installez les extensions de
PHPStan
pourSymfony
etDoctrine
- Modifiez la configuration des outils de qualité de code pour que le cache soit dans le répertoire «
var
» de l'application :- fichier de cache de
PHP CS Fixer
- fichier de cache de
Twig CS Fixer
- répertoire temporaire de
PHPStan
- répertoire de cache de
PHPUnit
- fichier de cache de
- Modifiez le script
Composer
«test:csfixer
» pour masquer la barre de progression dePHP CS Fixer
- Modifiez le script
Composer
«test:phpstan
» pour générer les classesActor
deCodeception
avant d'exécuterPHPStan
Suite de tests de « Application
»
¶
Votre première suite de tests regroupera tous les tests fonctionnels de l'application. Vous utiliserez ensuite des espaces de noms pour organiser les diverses catégories de tests.
Travail à réaliser
- Générez une suite de tests «
Application
» - Activez et configurez les modules «
Asserts
», «Symfony
» et «Doctrine
» pour la suite de tests «Application
»
« Cest » pour la liste des annonces ¶
Vos premières réalisations ont concerné la liste des annonces. Ce sera donc la première fonctionnalité que vous testerez
Travail à réaliser
- Générez un « Cest » «
Advertisement\List
» qui regroupera les tests fonctionnels de la liste des annonces - Si ce n'est pas encore fait, et afin d'écrire des tests valides pour des visiteurs français, configurez la traduction de
Symfony
pour la langue française - En utilisant vos
Factory
pour générer les données factices, effectuez les tests suivants, et corrigez votre code si nécessaire :- La liste des annonces est correctement affichée si elle est vide
- Une liste de 20 annonces s'affiche correctement, pagination comprise
« Cest » pour le CRUD des annonces ¶
Les annonces peuvent être créées, visualisées, modifiées et effacées (« CRUD »). Ces actions doivent naturellement être présentes et testées.
Travail à réaliser
- Générez un « Cest » «
Advertisement\CRUD
» qui regroupera les tests fonctionnels concernant les annonces - En utilisant vos «
Factory
» pour générer les données factices, effectuez les tests suivants, et corrigez ou complétez votre code si nécessaire :- La création d'une annonce à partir du formulaire de création fonctionne correctement et implique donc la présence des données en base de données
- L'affichage d'une annonce comporte bien ses caractéristiques
- La modification d'une annonce à partir du formulaire d'édition fonctionne correctement et implique donc la mise à jour des données en base de données
- la suppression d'une annonce fonctionne correctement et implique donc la suppression des données en base de données
InformationLes object créés par
Foundry
sont des instances de «PersistentProxyObjectFactory
» qui se comportent comme vos entités. Si vous désirez accéder à l'objet réel correspondant à votre entité, vous devez utiliser la méthode «_real()
».
« Smoke testing », test de fumée ¶
L'objectif des tests est de détecter précocement les problèmes de l'application. Le premier niveau de vérification consiste donc à vérifier que les URL de l'application répondent correctement. Chaque URL sera alors contrôlée a minima, en attendant que des tests détaillés soient écrits pour vérifier tous les aspects de la fonctionnalité implémentée. C'est ce que l'on appelle le « smoke testing ». Ces tests devront être exécutés avant tous les autres tests, ce qui va demander une utilisation particulière de Codeception
faisant appel aux groupes.
Travail à réaliser
- Générez un « Cest » «
Availability
» qui regroupera les tests de fumée - Créez un test «
pageIsAvailable
» qui vérifie que l'URL passée en paramètre est disponibleInformationRéfléchissez aux « fixtures » dans ce contexte.
- Créez un «
dataProvider
» qui fournit les URL à tester - Associez le «
dataProvider
» au test «pageIsAvailable
» - Exécutez le test «
pageIsAvailable
» pour toutes les URL connues de l'application - Lisez la documentation de
Codeception
sur les groupes - Créez un groupe «
available
» qui regroupe tous les tests de fumée - Lisez l'auto-documentation de la commande «
run
» de «vendor/bin/codecept
» - Modifiez le script
Composer
«test:codeception
» pour qu'il exécute, dans l'ordre :- les tests de fumée (ceux du groupe «
available
») - les tests de l'application (tous sauf ceux du groupe «
available
»)
- les tests de fumée (ceux du groupe «
Intégration continue ¶
L'intégration continue demande l'automatisation des tests pour détecter au plus tôt les erreurs afin d'éviter les régressions. Vous avez déjà mis en place des outils de qualité de code automatisés sur le poste de travail du développeur avec PHP CS Fixer
, PHPStan
, Twig CS Fixer
et GrumPHP
. Vous disposez également d'une batterie de tests fonctionnels. Il est temps de les automatiser dans le processus d'intégration continue.
Vous allez installer et configurer GitLab Runner
sur une machine virtuelle Ubuntu
dans la ferme OpenNebula
du département informatique. Le « runner » sera ensuite associé à votre dépôt GitLab
pour que les tests soient exécutés automatiquement à chaque « push
».
Configuration du « runner » dans une machine virtuelle ¶
Vous allez tout d'abord déployer une machine virtuelle Ubuntu
dans la ferme OpenNebula
du département informatique. La machine virtuelle Ubuntu
sera ensuite configurée pour pouvoir exécuter les tests de l'application. Elle doit donc disposer de PHP
, de Composer
et de Node.js
. Vous allez ensuite installer et configurer un « GitLab Runner
» pour exécuter les tests à chaque « push
».
Travail à réaliser
- Consultez le support de cours de Floran Brutel et Nicolas Hart sur l'intégration continue
- Suivez le guide de déploiement d'une machine virtuelle
Ubuntu
surOpenNebula
avec les paramètres suivants :- « template » «
Ubuntu Minimal 22.04
» 1024MB
de mémoire vive10GB
de disque dur
- « template » «
- Connectez-vous en
ssh
à la machine virtuelle et vérifiez qu'elle fonctionne correctement - Vérifiez que vous avez bien suivi les consignes en affichant la version du système d'exploitation :
lsb_release -a No LSB modules are available. Distributor ID: Ubuntu Description: Ubuntu 22.04.3 LTS Release: 22.04 Codename: jammy
- Effectuez les actions suivantes permettant de contourner de possibles désagréments ayant été constatés :
- Ajoutez «
localhost.localdomain
» dans «/etc/hosts
» en passant la commande :sed -i "s:^127.0.0.1 localhost$:127.0.0.1 localhost.localdomain localhost:" /etc/hosts
- Mettez à jour les dépôts :
apt update
- Ajoutez un éditeur de texte, «
vim
» ou «nano
» (Ubuntu Minimal
ne contient pas d'éditeur de texte) :apt install nano
- Ajoutez les outils de gestion des dépôts «
software-properties-common
» :apt install software-properties-common
- Limitez l'attente de la configuration réseau à 5 secondes en éditant le service «
systemd-networkd-wait-online.service
» avec la commande :systemctl edit --full systemd-networkd-wait-online.service
puis en ajoutant l'option «--timeout=5
» à la fin de la ligne commençant par «ExecStart=
»InformationMettez bien un espace entre la fin de la commande et l'option que vous ajoutez.
- Mettez à jour le système :
apt upgrade
InformationLors de la mise à jour du système, vous serez invité à confirmer la mise à jour du fichier «
/etc/ssh/sshd_config
». Conservez le fichier installé.Lors des installations à vernir, vous serez invité à redémarrer les services. Il n'est pas utile de le faire, vous redémarrerez la machine virtuelle à la fin de la configuration.
- Ajoutez «
- Ajoutez le dépôt des versions supportées de
PHP
«ppa:ondrej/php
» - Installez «
php8.3-cli
» avec les extensions «sqlite3
», «curl
», «intl
», «mbstring
», «xml
» et «zip
» - Ajoutez le dépôt officiel de
Gitlab Runner
- Installez «
gitlab-runner
» - Installez
Composer
dans «/usr/local/bin
» - Créez un « runner »
Linux
pour votre dépôtGitLab
avec les « tags » «php8.3
» et «composer
» - Enregistrez le « runner » avec la commande proposée et fournissez interactivement les informations nécessaires :
- le jeton d'enregistrement de votre dépôt
GitLab
(déjà renseigné via les options de la commande) - l'URL du serveur
GitLab
(déjà pré-renseigné via les options de la commande) - le nom du « runner » : «
symfony-for-sale
» - l'« executor » du « runner » : «
shell
»
- le jeton d'enregistrement de votre dépôt
- Désactivez les « runners d'instance » (« instance runners » en anglais) de votre dépôt
GitLab
- Redémarrez la machine virtuelle et vérifiez que le « runner » est bien actif dans votre dépôt
GitLab
Intégration continue dans le projet ¶
Vous allez pouvoir définir les tâches d'intégration continue pour votre projet. Afin de limiter le temps d'exécution et les ressources OpenNebula
consommées, vous définirez une seule tâche d'intégration continue qui installera les composants nécessaires au projet et exécutera les tests.
Travail à réaliser
- Créez le fichier «
.gitlab-ci.yml
» à la racine du projet - Définissez une tâche «
test
» qui :- nécessite les « tags » «
php8.3
» et «composer
» - installe les dépendances du projet
- exécute les tests
- conserve les artefacts des échecs des tests de
Codeception
InformationVous pouvez peaufiner la définition des artéfacts de
Codeception
en excluant le fichier «.gitignore
» contenu dans le répertoire concerné.
- nécessite les « tags » «
- Poussez le fichier «
.gitlab-ci.yml
» dans votre dépôtGitLab
- Vérifiez que le « pipepline » d'intégration continue est bien exécuté et se termine avec succès
Amélioration de l'interface et de l'expérience utilisateur ¶
L'accueil de l'application affiche toujours la page de test de Symfony
dans l'environnement de développement et une erreur HTTP
404 en production. Il faut donc effectuer une redirection vers la liste des annonces. Il manque également une fonctionnalité de rechercher des annonces.
Redirection depuis l'accueil de l'application ¶
Vous allez simplement rediriger le visiteur vers la liste des annonces depuis l'accueil de l'application.
Travail à réaliser
- Générez un nouveau contrôleur «
HomeController
» - Dans l'action «
index
» de ce contrôleur, redirigez le visiteur vers la liste des annonces - Supprimez la vue inutile associée à l'action «
index
» - Testez la fonctionnalité dans «
Application\HomeCest
»
Recherche des annonces par titre ou description ¶
Il est temps d'ajouter une barre de recherche.
Travail à réaliser
- Ajoutez un formulaire comportant un champ de recherche dans la barre de navigation
- Définissez la route correspondant à la liste des annonces comme action associée à la recherche
- Modifiez la methode de «
AdvertisementRepository
» afin qu'elle :- admette un paramètre correspondant à la chaîne de recherche
- effectue une recherche insensible à la casse sur le titre et la description des annonces Information
Inutile de complexifier la requête si la chaîne de recherche est vide.
- retourne la requête des annonces correspondant à la recherche
- Récupérez la valeur de la chaîne de recherche dans l'action affichant la liste des annonces
- Donnez cette valeur à la méthode de recherche de «
AdvertisementRepository
» - Reportez la valeur de la chaîne de recherche dans le champ de recherche du formulaire
- Ajustez le titre de la page («
title
» et «h1
») en fonction de la présence ou non d'une chaîne de recherche - Testez la fonctionnalité dans «
Application\Advertisement\SearchCest
»
Création d'une extension Twig
pour l'affichage des dates
¶
Ceci est une question complémentaire, qui n'est pas obligatoire. Les détails sont donnés au sein de l'ensemble des questions complémentaires.