# 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_ADMIN associé. 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_USER associé. 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ôle ROLE_USER associé. À la différence des routes Pro, 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.).