Documentation du framework

Présentation du projet UTM

le framework PHP5 orienté objet développé par dizagn est basé sur des concepts et des patterns simples et à nos yeux essentiels : tel que DRY, KISS afin de garder la simplicité de maintenance dans un minimum de composants, ou encore MVC pour assurer une séparation entre la logique métier de votre application , l'accès aux données, et la présentation de votre rendu. Ceci en fournissant les fonctionnalitées modernes d'un framework, tel qu'un système avancé de gestion de plugins.


Il est léger, compact, rapide à prendre en main et suffisament modulaire pour s'adapter à tous types de projets. De nombreux plugins sont disponibles et sa structure ouverte vous permet de facilement intégrer des librairies externes.
Il existe plusieurs particularités qui caractérisent volontairement ce framework. Il est fourni en standard sans système de mapping pour votre SGBD (ORM), ni mécanisme de template pour les vues.
Tous ces éléments sous fournis sous la forme de plugins, ou de librairies PHP standards (Doctrine, Propel, DB_DataObject de PEAR, Smarty, PHPSavant, etc.) que vous ajouter selon vos besoins.

Premiers pas avec le framework

L'organisation des fichiers dans le framework

on retrouve à la racine du site les 4 principaux répertoires:

  • application : Contient les fichiers que vous allez développer (controlleurs, modèles, vues, etc.). Ils seront disposés par défaut de la façon suivante dans à minima 5 dossiers. En effet certains plugins peuvent ajoutés leurs propres dossiers à cet endroit (Session, cache, temp, etc.)
    • Component : Contient les controlleurs, vues, et eventuellement vos templates selon le moteur que vous utilisez
    • Config : Contient les fichiers de configuration de l'application. On en trouve 2 par défaut : config.ini qui contient vos parametres applicatifs, et utm.ini la configuration du framework. Les plugins viennent parfois avec leurs configurations, pour pouvez les laisser dans ce dossier ils seront alors chargés automatiquement par le framework, ou les intégrer dans le fichier config.ini pour optimiser le chargement des fichiers
    • lib : En mettant vos librairies externes dans ce dossier, elles seront chargées automatiquement tant qu'elles respectent la règle suivante : le fichier à inclure doit s'appeler comme la classe à instancier (ex: fichier phpMailer.php -> class phpMailer())
    • model : Contient les fichiers modèles. C'est ici que se retrouvent tous les objets metiers, et les objets de données
    • plugin : Emplacement réservés aux fichiers plugins
  • bin : Contient les utilitaires en ligne de commande fournis avec le framework (Shell, vidage du cache, etc.), ils doivent être lancés en ligne de commande.
  • utm : Contient les fichiers coeur du framework que vous n'aurez à priori jamais à toucher.
  • www : Contient les éléments à publier à travers l'url comme les images, les feuilles de styles, les javascripts, etc..
Ceci est la configuration par defaut. Vous pouvez cependant réorganiser comme vous le souhaitez ces dossiers en modifiant le fichier de configuration "config/utm.ini"

Nomenclature des fichiers et nommage de classes

La plupart des fichiers du framework sont chargés automatiquement grâce à la fonction autoload. Pour cela le fichier doit porter le même nom que la classe à instancier. Les fichiers suivants sont concernés par cette caractéristique : les plugins, les librairies, les modèles. Vous pouvez toujours inclure vos fichiers à la main au cas ou vous ne souhaiteriez pas modifer, ou renommer vos fichiers.

Principe de fonctionnement

Les fichiers index.php

Il y a deux fichiers index.php. l'un situé dans le dossier "www/index.php" qui contient le demarrage du framework et l'autre qui contient une redirection vers le premier fichier index.php. Il s'agit d'une bonne pratique visant a empecher l'utilisateur web a remonter dans les dossier parent. L'ideal etant de poser un alias vers le fichier www/index.php. Pour ceci il faut voir la documentation correspondante a votre seveur web. Nous ne verrons que le fichier situé dans www/index.php car c'est lui qui nous interesse.

Les URLs

Certains éléments constituants la requete sont des mots clés permettant au framework de connaitre les composants à charger (Ex: contolleurs et vues). Les mots clés par defaut sont : ctrl pour les controlleurs, act pour determiner l'action à executer sur le controlleur et mod pour les modules permettant d'ajouter un niveau supplémentaire dans la hierarchie des controlleurs.
Ces mots clés sont configurables dans le fichier de configuration du framework "utm.ini".
Voir les paramètres module, controller, action dans la section [request]
La valeur par defaut des composants de la requete tel que "ctrl" et "act" est elle aussi définie dans le fichier de config
Voir le paramètre "default" dans la section [core].

Exemple 1: On appele l'action "list" sur le controlleur "product"

Exemple 2: on appele l'action "delete" sur le controlleur "product" situé dans le module "admin" avec un parametre supplémentaire id=12

Grandes étapes de l'éxécution du framework

Voici les grandes étapes de l'execution du framework. la plupart se trouve dans le méthode run() du fichier core.php

  1. Instanciation du framework
    Le framework commence par charger les configurations présentes dans le répertoire de configuration, puis il définit les chemins d'inclusion
    Référence : instance() dans core.php
  2. Initialisation des plugins
    On enregistre les plugins, et on récupere les evenements qu'il faudra écouter ainsi que toutes les nouvelles méthodes ajoutées au framework
    Référence : initPlugin() dans corePlugin.php
  3. Evenement onStart()
  4. Analyse de la requête
    On parse la requete et on définit les membres de l'objet request.
    Référence : setRequest() dans coreRequest.php
  5. Evenement onPostRequest()
  6. Execution du controlleur
    Le framework a reussi a déterminer le controlleur, et l'execute.
  7. Rendu de la vue
    Le framework détermine si une vue existe, et récupere le rendu de la vue.
  8. Evenement onEcho()
  9. Affichage du rendu
    On fait le echo de la variable contenant le rendu de la vue
    Référence : run() dans core.php
  10. Evenement onFinish()

Configuration du framework

Fichier de configuration du framework : utm.ini

Fichier de configuration de l'applicatif web : config.ini

Dans ce fichier vous pouvez ajouter autant d'entrées que vous le désirez. Attention tout de même a ne pas surcharger celles d'un plugin par exemple

Les controlleurs

Création d'un controlleur

Tous les controleurs de l'application doivent étendre la classe "coreController" afin de profiter des fonctionnalités du framework, et posséder également une methode "execute".
Dans cette implémentation du MVC le controlleur est obligatoire.
Le controleur peut redirigé vers un autre controleur(redirect) ou appelé un autre controleur (forward).

Les super-controlleurs

On s'apercoit que dans certains cas les controlleurs contiennent peu de choses, il est alors fastidieux et inutile d'en créer autant. La notion de supercontroller est là pour vous permettre de réduire le nombre de fichier et de gagner du temps de developpement pour un nouveau controleur.
Le principe consiste à remplacer la methode obligatoire execute d'un controlleur par le nom de l'action demandée, dans une classe dont la syntaxe comporte uniquement le nom du controlleur et eventuellement d'un module.
Attention le nom de l'action ne peut etre un mot clé réservé de PHP comme default par exemple

Les vues

Toutes les vues doivent étendre la classe coreView et posséder une methode "render". C'est la vue qui a la charge d'afficher son contenu avec eventuellement un systeme de template ou de layout, ces éléments sont fournis par les plugins et librairies correspondantes. Dans un cas par défaut la vue se contente de retourner la chaine à afficher, et c'est le framework qui est en charge d'afficher le contenu.

Les modèles

Création d'un modèle

Les modèles peuvent étendre la classe coreModel afin de profiter des fonctionnalités du framework. Ils peuvent également étendre un plugin ou une classe tel que db, pdo, mdb2. Cependant si cette classe n'etend pas coreModel, ou corePLugin pour perdrez certaines fonctionnalités comme par exemple la possibilité de lancer vos propres evenements ou d'utiliser les methodes mise à disposition par un plugin.

Utilisation d'un modèle

la classe coreModel definit la methode factory permettant de renvoyer une instance de l'objet model passé en parametre. On peut ensuite utiliser les methodes du modèle sur l'objet fraichement instancié.Lors de la ré-utilisation d'un modele dans une autre classe durant la même execution, le modele n'est pas instancier mais pris directement dans le cache présent dans le registre

Les plugins et les evenements

Principe de fonctionnement des plugins

Les plugins permettent deux choses :

  1. Ajouter des fonctionnalités aux controleurs, aux vues, aux modeles, et aux autres plugins.
  2. Réagir à des evenements.

Enregistrement d'un plugin

Les plugins pour fonctionner doivent être enregistrés dans le fichier index.php juste après la création de l'instance du framework grace à la methode "registerPlugin", cette methode recoit en parametre le nom de la classe du plugin ou un tableau de plugins. Ensuite vous n'avez plus qu'a placer vos fichiers dans le dossier des plugins (Généralement : application/plugin/). Chaque plugin peut étendre la classe corePlugin pour profiter des fonctionnalités du framework. Dans certains cas les plugins étendent des objet PHP (DOM, PDO, mysqli, etc.)


Attention : L'ordre dans lequel vous enregistrez les plugins a une importance. Surtout si il réagisse à un evenement.

Dans la page d'index vous devez enregistrer les plugins de la facon suivante pour qu'il soit pris en compte par le framework. le fichier du plugin doit etre placé dans le dossier : "/application/plugin" et le fichier de configuration du plugin si il existe dans "/application/config"


Ajout de fonctionnalités

Les plugins permettent d'ajouter des nouvelles fonctionnalités au framework et les mettre à disposition des composants que vous créez (Controleur, vue, modele, plugin) comme si il s'agissait d'une methode de cette classe.

Utilisation du plugin

Utilisation de notre nouvelle methode dans une vue. Pour éviter des créer des conflits entre plusieurs plugins qui porteraient des méthodes du meme nom, vous pouvez utiliser 2 syntaxes pour appeler les méthodes de vos plugins : $this->methode() ou $this->plugin->methode().

Les evenements

Les événements sont des actions déclenchés par le framework ou par l'utilisateur. Les plugins peuvent être à l'écoute de ces événements, simplement en implémentant une methode portant le nom de l'événement. Ils se déclenchent selon l'ordre dans lequel ils ont été enregsitrés dans le fichier index.php.


Les 6 événements standards

  • onStart
    Il se déclenche lorsque le framework se lance, juste apres le chargement de la configuration. A ce moment la requete n'est pas encore transformé en objet request.
  • onPostRequest
    A ce moment là, la requete est disponible, la configuration est chargée. Nous sommes juste avant l'execution du controlleur.
  • onExecute
    Se déclenche à l'execution du controlleur, avant n'importe quelle autre ligne de code présente dans le controlleur.
  • onEcho
    Lorsqu'un contenu est retourné par la vue, cet événement se déclenche juste avant le echo.
  • onFinish
    juste apres le rendu finale pour finir l'éxécution du framework cet événement est émis.
  • onError
    Cet événement est différent des autres, en effet il n'est pas dépendant de l'execution du framework mais de l'apparition d'une erreur.

Ajouter ses propres evenements

Vous pouvez créer vos propres événements grace à la methode statique "emit" présente dans la classe "corePlugin".
Il vous suffit ensuite de définir la méthode dans le plugin comme pour n'importe quel autre evenement. Cet evenement peut etre emis a partir d'un controleur d'une vue, d'un modele, d'un plugin ou de tout autre composant au cours de l'execution du framework. Par convention les evenements du framework commence par "on", mais ceci n'a rien d'obligatoire.

Le gestionnaire d'erreur

Le framework vient avec un gestionnaire d'erreur, implémenté nativement dans le coeur. Il permet d'intercepter quasiment toutes les erreurs produites par l'application. Seules les erreurs fatales de PHP ne peuvent etre attrapées.
Vous pouvez décider de désactiver les messages d'erreurs en modifiant la valeur du paramètre "display" de la section "error".

Interception des erreurs

lorsqu'une erreur se produit, le framework l'affiche ou pas selon la configuration choisie. Cependant il émet systématiquement un évènement onError. Cet évènement peut ensuite etre récupéré grace à la methode statique getError() de la classe coreError. 2 formats sont possibles "html" ou "text"

Le registre et le cache

Le registre : présentation de la classe coreRegistry

Le coeur du framework pour fonctionner utilise un registre afin d'échanger des objets entre les diverses instances des composants. Vous pouvez utiliser ce registre grace aux accesseurs "set()" et get"()" dont vous disposez dans la classe coreRegistry.
Ce registre est composé de différents espace de noms qui fonctionnent comme des compartiments afin d'isoler les objets, tableau et autres données que vous pourriez etre amené à stocker dedans. Ces espaces de noms sont définis dans le fichier de configuration du framework utm.ini par exemple : "ns_plugin" pour les instances des plugins, "ns_model" pour les instances des modèles et ns_general pour les valeurs non spécifiées.

Gestion du cache grace au registre

Avant d'instancier un plugin ou un modèle, le framework verifie toujours si il n'est pas déjà présent dans le registre. On peut demander lors de l'instanciation par exemple d'un modele à ne pas allez le chercher dans le cache en l'indiquant à la methode factory de la classe "coreModel". Ceci afin d'economiser le cout de l'instanciation de l'objet et de l'autoload du fichier .

L'objet request

Dès le début de son execution, le framework va décomposer en plusieurs éléments la partie "querystring" de la requete HTTP qu'il vient de recevoir afin de définir un objet request. Cet objet est accessible pour tous les composants du framework. Il possede également des methodes permettant de récuperer des informations sur la requete en cours.

Récupérer l'instance depuis n'importe quel composant

L'instance du framework est accessible par le coeur du framework, grace à l'objet core. Il suffit d'appeler la méthode getRequest sur cet objet Attention l'objet request n'est défini qu'apres l'événement "onPostRequest", avant il ne contient que les valeurs par défaut du fichier de config

Methodes utiles

Certaines methodes appartenant à cet objet permettent de récupérer facilement des éléments de la requete, sous la forme d'une string ou d'un tableau de valeurs.