# Organisation du code
Les dossiers sont organisés de la manière proposée par défaut par Symfony.
La plupart des dossiers sont assez simples à décrire :
- bin: Contient les scripts de l'application. Ils ne sont jamais utilisés au runtime.
- config: Contient la configuration (en yaml) de l'application et des packages.
- docs: Contient la documentation du projet, rédigée en VuePress (opens new window).
- migrations: Contient les migrations de base de données générées par DoctrineMigrations (opens new window).
- templates: Contient un fichier par défaut. Probablement supprimable ?
- translations: Contient les traductions potentielles de l'application, pour l'instant vide. Probablement supprimable ?
- uploads: Contient les documents uploadés par les utilisateurs de l'application (images, etc).
- var: Dossier interne au fonctionnement de Symfony : cache, logs, sessions, ...
- vendor: Contient les packages communautaires de l'application. (une fois l'application lancée au moins une première fois)
- web: Seul dossier servi publiquement par Symfony. Nous sert principalement à resservir les documents uploadés par les utilisateurs.
- src: Contient le code de l'application. Voir ci-dessous pour plus d'informations.
Le dossier src contient le code de l'application Jindexe.
Le code est séparé dans des sous-dossiers, dont chacun a une spécificité.
# Classes
Le dossier Classes contient les classes (au sens POO) de l'application, mais qui ne se retrouvent pas en tant que schéma de base de données : il s'agit des classes utilisées pour les exceptions, les interfaces, etc.
TIP
Concernant les classes "schéma" pour la base de données, voir le dossier Entity
# Command
Le dossier Command contient les commandes custom pour le projet, appelées grâce à l'utilitaire
bin/console command:name --options
Les commandes sont elles-mêmes organisées en sous-dossier de fonctionnalités : Images, Payment, Posts, ... En revanche, le sous-dossier n'a aucune influence sur la manière d'appeler la commande grâce à l'utilitaire bin/console.
TIP
Pour en savoir plus sur les commandes, voir la documentation Symfony (opens new window).
# Controller
Il s'agit d'un des dossiers principaux de l'application.
Il contient l'intégralité du code déclarant les routes de l'application.
Il est lui-même scindé en plusieurs sous-dossiers, et le sous-dossier dans lequel est présent un Controller y applique de facto certaines règles d'accès :
- Admin: Les contrôleurs présents dans ce dossier ne sont accessibles qu'avec un utilisateur ayant le rôle
ROLE_ADMINassocié. Elles sont toutes accessibles sous/admin. - Pro: Les contrôleurs présents dans ce dossier ne sont accessibles qu'avec un utilisateur ayant le rôle
ROLE_USERassocié. Il s'agit des routes de gestion de fiches établissement en tant que professionel (gestion des informations, publications, etc.). Elles sont toutes accessibles sous/pro. - User: Tout comme pour les contrôleurs
Pro, les contrôleurs présents dans ce dossier ne sont accessibles qu'avec un utilisateur ayant le rôleROLE_USERassocié. À la différence des routesPro, elles concernent la gestion et les actions exécutables en tant qu'utilisateur de l'application : changement de mot de passe, commentaire, likes, ... Elles sont toutes accessibles sous/user. - Pub: Les contrôleurs présents dans ce dossier sont accessibles sans utilisateur connecté. Elles nécessitent en revanche l'emploi d'une clef API, tout comme toutes les autres routes. Elles sont toutes accessibles sous
/public. - Ext: Il s'agit des contrôleurs externes : ils sont accessibles sans utilisateur connecté, ET sans clef API. Ils permettent par exemple d'exposer les images de l'application, ou de permettre des endpoints à des webhooks ne permettant pas de configurer des headers HTTP. Les routes sont toutes accessibles sous
/ext.
WARNING
Le dossier Pub aurait dû s'appeler Public, cependant c'est un mot clef réservé de PHP, et l'application est instable avec ce nom.
TIP
Pour comprendre comment le branchage des routes, des droits associés & de la nommenclature de leur exposition, se référer aux fichiers config/packages/security.yaml et config/routes/annotations.yaml.
# DataFixtures
Contient les fixtures, les jeux de données permettant aux environnements de développement d'être rapidement montés.
Pour en savoir plus sur les fixtures, se référer à la documentation de DoctrineFixturesBundle (opens new window).
# Doctrine
Contient les fonctions custom Doctrine.
Pour en savoir plus, se référer à la documentation Doctrine sur le sujet (opens new window).
# DTO
Le dossier DTO (pour Data Transfer Object (opens new window)) contient les classes utilisées en tant qu'interface (au sens propre du terme, pas POO) dans la communication entre les différents Services et Managers de l'application, ainsi que pour mapper les données sérialisées / désérialisées des requêtes.
Par exemple, une session Stripe, n'existant pas sous forme de schéma de base de données, mais fonctionnant lors de la requête comme une classe sérialisée / désérialisée, et utilisée par les différents services de l'application, fait l'objet d'un DTO spécifique.
TIP
La différence entre les classes déclarées dans DTO et celles déclarées dans Classes est qu'un DTO a pour objectif unique le mapping de données au sein d'une classe. Elle n'a a priori pas de logique complexe associée et a pour seul objectif le transfert d'information entre différentes parties du projet, en lieu et place d'un tableau associatif PHP par exemple, et sa sérialisation & déserialisation (en JSON dans notre cas).
# Entity
Les classes présentes dans Entity sont des entités en terme Symfony, ou Models en terme plus généraux, c'est à dire des classes permettant à l'ORM de mapper les données en base de données sur des Objets (au sens POO), et vice-versa.
# Filters
Les Filters sont des classes permettant la généralisation des filtres de requête dans l'application.
Pour en savoir plus sur les filtres, voir le chapitre associé.
# Form
Le dossier Form contient les "formulaires" de l'application, c'est à dire la logique propre à comprendre les requêtes de création/modification d'entités, ou de manière générale à la digestion des requêtes POST/PUT/PATCH.
Pour en savoir plus, consulter la documentation Symfony à ce sujet (opens new window).
# Listener
Ce dossier contient le code réagissant à certains évènements au sein de l'application.
Ces évènements sont pour l'instant de deux ordres :
- Création/Modification de données en base de données (évènements Doctrine)
- Exceptions ayant remonté toute la pile d'exécution
# Repository
Les Repository sont utilisés par Doctrine pour permettre le requêtage des entités.
Chaque Entity est liée à un Repository. Il contient le DQL (language de requêtage Doctrine, très semblable au SQL, mais a pour avantage d'être agnostique de la base de données sous-jacente), et est donc très proche de la base de données.
# Manager
Afin de permettre un interfaçage plus élégant pour le reste de l'application, les Managers ont pour rôle de communiquer avec les Repositories.
Dans le cas où nous souhaiterions implémenter un système de caching (Redis par exemple) suite à de trop grosses contraintes pesant sur la base de données, les Managers seraient un excellent point d'entrée pour ce développement. Ils permettent de contrôler l'accès aux Repositories, et donc à la base de données.
De même qu'un Repository, un Manager est lié à une seule entité.
TIP
Ce système est encore un peu frais. Il n'est pas impossible que certains contrôleurs ou services fassent encore directement appel aux Repositories. Ne pas hésiter à implémenter l'appel via un Manager le cas échéant, à terme cela nous rendra service.
# Resources
Contient les templates d'email (et d'invoices, du temps où nous les générions - ce qui est désormais révolu) générés par l'API.
Pour en savoir plus, voir le chapitre associé
# Security
Contient l'intégralité du code custom permettant l'authentification des utilisateurs et la validation des clefs API présentées.
TIP
L'implémentation de ces systèmes dans Symfony est assez complexe, se référer aux cookbooks Symfony sur le sujet ainsi qu'à la documentation (opens new window).
# Serializer
Contient les classes de sérialization des entités de l'application dont la sérialization est suffisamment complexe pour le justifier.
La plupart des entités ont une sérialization simple s'appuyant sur des décorateurs (@JMS\Expose par exemple), cependant dans certains cas la sérialization des champs se complexifie : il faut donc déclarer un sérializer custom.
# Service
Les Services sont des objets (POO) interfaçant la connexion avec des outils externes (autres APIs, mailer, filesystem, ...), ou contenant de la logique complexe liée à plusieurs Managers.
WARNING
Il subsiste un AccountService qui n'a plus grand sens depuis la création des Managers. Il peut probablement être repensé sous forme de Manager (UserManager ?).
# Traits
Contient les traits PHP (opens new window) de l'application.
# Util
Contient les outils globaux à l'application, n'ayant aucune dépendance avec le reste de celle-ci.
TIP
Comme dans la plupart des applications, un dossier util ou tools devient assez vite un fourre-tout...
En vérité, il pourrait être repensé : les outils permettant de déduire le type MIME d'un fichier pourrait appartenir au FileService, pour la génération des strings aléatoires, un RandomService pourrait voir le jour...
# Voter
Les Voters ont pour rôle de déterminer si l'accès à une ressource est autorisée.
C'est à dire, par exemple, autoriser ou non une requête entrante de modification sur la publication d'id 42 en fonction du contexte d'exécution (utilisateur connecté ? A-t-il les droits pour accéder à cette publication (en est-il l'auteur) ? etc.).