Étude de l'architecture globale du projet

La contribution au logiciel Framadate constitue pour moi un grand premier pas dans l'open-source. En effet, je n'ai jamais eu l'occasion de m'intégrer au sein d'un projet informatique déjà conséquent voire déjà commencé. J'ai été particulièrement surprise et désorientée par le fait que le projet ne comportait pas une sorte de “mode-d'emploi”, un guide pour comprendre comment il est organisé. Cette étude a donc pour but de combler ce manque en partageant ce que je comprend au fil du projet. Elle sera sans le moindre doute non exhaustive, sûrement partiellement inexacte ou trop simplifiée, mais j'espère produire une esquisse qui pourra servir aux futurs contributeurs, et être complétée et corrigée par eux.

La première chose que j'ai pu remarqué et qu'il est important de saisir, c'est que le projet s'articule en plusieurs couches séparant l'utilisateur de la base de données. On représentera pour l'instant le projet de la manière simpliste suivante : La couche “Les objets” (au sens de l'orienté objet : il s'agit d'instance de Classes, nous y reviendrons) permettent de sécuriser l'accès en lecture et en écriture depuis l'interface sur la BDD. On va donc séparer les fichiers du code en plusieurs catégories que l'on va étudier une à une :

  1. La base de données
    1. Les classes Migration (définies dans des fichiers .php situés dans /framadate/app/classes/Framadate/Migration)
  2. Les classes objets (définies dans des fichiers .php)
    1. Les classes Particulières (situées dans /framadate/app/classes/Framadate)
    2. Les classes Repositories (situées dans /framadate/app/classes/Framadate/Repositories)
    3. Les classes Services (situées dans /framadate/app/classes/Framadate/Services)
  3. Les fichiers de manipulation des classes objets (les fichiers .php dans /framadate)
  4. L'interface (les fichiers template .tpl situés dans /framadate/tpl)

La base de données de Framadate est générée “en différentiel” : à partir de la base de données d'origine, on peut exécuter plusieurs scripts PHP qui vont la modifier pour atteindre sa forme finale, il n'y a pas un unique script générant directement la base finale (cf la section suivante : Modifier la base de donnée existante).

La BDD est composée de plusieurs tables dont :

  • La table poll(id, admin_id, title, description, admin_name, admin_mail, end_date, format, editable, receiveNewVotes, receiveNewComments, hidden, password_hash, results_publicly_visible, ValueMax)
  • La table vote(poll_id, name, choices, uniqId)

(TODO : ajout des autres tables au fur et à mesure de l'avancement du projet)

Modifier la base de données existante : les classes Migration

Pour modifier la base de donnée, on a précédemment dit qu'il fallait exécuter un nouveau script de modification : c'est l'objectif des classes Migration qui constituent des implémentations de l'interface Migration (décrite dans Migration.php).
Une implémentation d'une interface ? Quésako ?
Cette notion ressemble à l'héritage mais attention : une interface est techniquement une classe complètement abstraite (elle ne possède aucun attribut et n'implémente aucune méthode, elle possède seulement des méthodes abstraites qui se doivent d'être définies dans les implémentations), son rôle est de décrire le comportement d'un objet. Ici, les méthodes (abstraites) de Migration sont :

  • description()
  • preCondition(\PDO $pdo)
  • execute(\PDO $pdo)

Ainsi on trouve dans le répertoire /framadate/app/classes/Framadate/Migration un ensemble de classes qui permettent de modifier l'état d'origine de la base de données. Ces modifications sont effectuées via l'exécution du fichier /framadate/admin/migration.php.
(pour plus d'info techniques sur la modification de la BDD, se référer au wiki du semestre précédent :
https://wiki.picasoft.net/doku.php?id=txs:framadate:base_de_donnees)

Présentation

On est en droit de se demander quel est l'intérêt d'intercaler entre notre BDD et notre interface des objets intermédiaires alors que, les étudiants ayant suivi NF92 pourront en témoigner, il est tout à fait possible de réaliser un site internet avec un peu de SQL, une bonne dose d'HTML et une touche de php “classique”. C'est sûrement vrai, mais l'approche orientée objet offre ici de nombreux avantages dont je vais citer quelques exemples (se référer à n'importe quelle présentation de l'approche orientée objet pour une liste plus exhaustive).
La programmation orientée objet permet ici :

  • Une stabilité des développements : l'impact des modifications est restreint au cours du temps et aux seuls objets qu'elles concernent
  • Une réutilisation et une extension des codes existants
  • Une diminution de la complexité d'un problème en le découpant en parties plus simples
  • Un découpage en classes qui se délèguent mutuellement un ensemble de service


Au sein de notre projet, les différentes classes vont notamment permettre de simplifier, modulariser et sécuriser les accès (en lecture et en écriture) à la BDD. Comme il est d'usage de le faire en conception orientée objet, j'utiliserais la stylistique UML pour présenter les classes du projet.
(Si la conception orientée-objet t'est complètement inconnue, je t'invite à consulter mon Guide de survie à destination des débutants en orienté-objet)

Les classes Particulières

Ces classes permettent d'abstraire des objets très précis du projet. Leur définition se trouve dans le répertoire /framadate/app/classes/Framadate.

  • Form (abstrait un formulaire)
  • Choice (abstrait un choix)
  • FramaDB (abstrait une connexion à la base de données)

Les UMLs de ces classes sont disponibles ici : particular_classes.png

Les classes Repositories

Ces classes, dont on trouve la définition dans le répertoire /framadate/app/classes/Framadate/Repositories, permettent d'abstraire la base de données et s'organisent de la manière suivante : Il faut voir ces classes comme des dépôts (Repository est l'anglais de Dépôt) de données sur lesquels nous allons pouvoir agir (consultation, modification, suppression) : un objet RepositoryFactory est composé d'un objet PollRepository (qui gère les sondages), d'un objet VoteRepository (qui gère les votes), d'un objet CommentRepository (qui gère les commentaires) et enfin d'un objet SlotRepository (rôle encore à définir) (on constate l'aspect très modulaire caractéristique de la POO : chaque classe gère une partie seulement du problème).
Il est à noter que, par leur caractère static, ces classes n'existeront qu'en une instance à un instant donné de l'exécution du code, c'est à dire qu'on ne pourra avoir deux dépôts (de sondages, de votes,…) différents en même temps.
D'autres part, ces classes possèdent de nombreuses méthodes qui simplifient et sécurisent l'accès (en lecture et en écriture) à la BDD, c'est par ces méthodes (et elles seules) que la BDD pourra être modifiée.
Les UMLs détaillés de ces classes sont disponibles ici : repo_detail.png

Les classes Services

Voici la liste de l'ensemble des classes dont on peut trouver la définition dans le répertoire framadate/app/classes./Framadate/Services.

  • PollService
  • AdminPollService
  • InputService, InstallService, LogService, MailService, NotificationService, PurgerService, SecurityService, SessionService, SuperAdminService (classes dont nous n'allons pas parlé dans l'immédiat)

Nous avons déjà vu que les classes Repositories permettent d'intéragir indirectement avec la base de données, quel est donc l'intérêt des classes PollService et AdminPollService ? Et bien, les classes Repositories permettent d'effectuer n'importe quelle modification sur la base de données, il n'est pas souhaitable de laisser autant de liberté. Ainsi on intercale un nouveau niveau d'objet : les classes PollService et AdminPollService qui permettent de n'effectuer que les modifications qui ont du sens.
Les UMLs détaillés de des classes PollService et AdminPollService sont disponibles ici : services.png

Les fichiers .php dans /framadate (create_poll.php, create_classic_poll.php, create_date_poll.php, find_polls.php, studs.php, adminstuds.php,…) permettent de manipuler les différentes classes objets du projet et d'appeler les fichiers template pour l'interface.

Il est à noter que jusqu'ici, nous n'avons pas croiser la route du moindre fichier qui code un titre, un bouton ou un champ de texte pour créer une page web : ces fichiers se situent en fait dans le dossier /framadate/tpl.

Un fichier .tpl, mais qu'est ce que c'est ?
Excellente question, moi même j'ignorais complètement l'existence de cette extension de fichiers. Mais si j'ai bien compris : l'idée ici est de séparer le code PHP (qui permet la manipulation de données) du code de présentation des pages (HTML en l'occurence). Ce code de présentation est alors appelé template, ce sont les fameux fichiers .tpl.

Cette séparation est gérée dans le projet via Smarty : l'idée est d'envoyer à une variable réservée $smarty les informations changeantes au fil des exécutions et nécessaires au correct affichage de la page, et ensuite il suffit de demander (de manière sympathique) à $smarty de se charger de l'affichage en lui renseignant le .tpl à utiliser.
(TODO: insérer un exemple de code)

(pour plus d'informations sur Smarty : http://eric-pommereau.developpez.com/tutoriels/initiation-smarty/?page=page_1#LI-E)

Ces fichiers permettent de gérer l'aspect dynamique des pages HTML (ce que les fichiers .tpl ne permettent pas), par exemple : les menus déroulant lorsque l'on clique sur une option, les champs supplémentaires qui apparaissent lorsque l'on coche une option,… Ces fichiers se situent dans le dossier /framadate/js.