Documentation : Configuration

Le fichier temma.json

La configuration d'un projet utilisant Temma se fait en modifiant le fichier temma.json qui est placé dans le répertoire etc/.

C'est un fichier au format JSON, qui comporte plusieurs sections faciles à éditer.

Voici un exemple typique de fichier temma.json minimal :

01 {
02     // configuration de l'application
03     "application": {
04         "dataSources": {
05             "_db":           "mysqli://user:passwd@localhost/mybase",
06             "_cache":        "memcache://localhost"
07         },
08         "sessionSource":     "_cache",
09         "rootController":    "HomepageController",
10         "defaultController": "MainController"
11     },
12     // définition des niveaux de log
13     "loglevels": {
14         "finebase": "ERROR",
15         "temma":    "WARN",
16         "myapp":    "DEBUG"
17     },
18     // définition des pages d'erreur
19     "errorPages": {
20         "500": "error500.html",
21         "default": "error404.html"
22   }
23 }
						

On peut y voir :

  • Ligne 5 : La définition du DSN qui permet de se connecter à la base de données.
  • Ligne 6 : La définition du DSN qui permet de se connecter au cache.
  • Ligne 8 : La source de données qui sera utilisée pour stocker les sessions. Si elle n'est pas indiquée, c'est le mécanisme de base de PHP qui sera utilisé.
  • Ligne 9 : Le nom du contrôleur racine, qui sera appelé quand quelqu'un se connectera sans spécifier de contrôleur.
  • Ligne 10 : Le nom du contrôleur par défaut, qui sera appelé lorsque le contrôleur demandé n'existe pas.
  • Les définition de niveaux de log, avec pour chacun le nom du module de log et le niveau de log minimal associé.
    • Ligne 14 : Les objets de la bibliothèque FineBase n'écrirons que leurs erreurs dans le fichier de log.
    • Ligne 15 : Le framework Temma écrira ses messages d'alerte et d'erreur dans le fichier de log.
    • Ligne 16 : Tous les message de log applicatif (vous pouvez adapter le nom "myapp" par un label représentant votre application) seront écrits dans le fichier de log, qu'il s'agisse de messages de débug ou de messages d'erreur critique.
  • Les définitions des pages à afficher si une erreur survient. Les pages en question doivent être situées dans le répertoire www/ du projet.
    • Ligne 20 : Si une erreur 500 survient, la page error500.html sera retournée.
    • Ligne 21 : Dans tous les autres cas d'erreur, c'est le contenu de la page error404.html qui sera renvoyé.

Voici un autre exemple, qui montre toutes les variables de configuration standard :

{
    // variables de définition générale de l'application
    "application": {
        // sources de données
        "dataSources": {
	    // DSN de connexion à la base de données (cf. objet FineDatabase).
	    // Optionnel
            "_db": "mysqli://user:passwd@localhost/mybase",

            // DSN de connexion à la base Redis
            // optionnel
            "_ndb": "redis://localhost:6379/0",

            // DSN de connexion au cache
            // optionnel
            "_cache": "memcache://localhost:11211"
        },

	// Indique qu'on souhaite ou non utiliser les sessions.
	// Optionnel : "true" par défaut. À utiliser pour désactiver les sessions au besoin.
	"enableSessions": true,

	// Nom du cookie de session.
	// Optionnel : "TemmaSession" par défaut.
	"sessionName": "TemmaSession",

        // source de données pour stocker les sessions.
        // Optionnel : le mécanisme de gestion des sessions de PHP est utilisé par défaut
        "sessionSource": "_cache",

	// Nom du contrôleur utilisé pour la racine du site.
	// Optionnel. Utilise le contrôleur défini par la variable defaultController par défaut.
	"rootController": "HomepageController",

	// Nom du contrôleur par défaut à utiliser si le contrôleur demandé est inexistant.
	// Optionnel mais recommandé : Utilise "\\Temma\\Controller" par défaut, qui
	// génère une erreur HTTP 404.
	"defaultController": "\\Temma\\Controller",

	// Nom du contrôleur à appeler systématiquement, même si celui demandé existe.
	// Optionnel.
	"proxyController": "MainController"

	// Nom de la vue par défaut.
	// Optionnel. TemmaSmartyView par défaut.
	"defaultView": "\\Temma\\Views\\SmartyView"
    },
    // Définition des seuils de log à utiliser en fonction des classes
    // de log correspondantes.
    "loglevels": {
	"finebase": "ERROR",
	"temma": "WARN",
	"myapp": "DEBUG"
    },
    // On indique des noms de contrôleurs "virtuels", en y associant un contrôleur
    // réel (ou virtuel, en cascade), qui prendra en charge les requêtes.
    "routes": {
	"sitemap.xml": "SitemapController",
	"sitemap.extended.xml": "sitemap.xml",
        "robert": "BobController"
    },
    // Gestion des plugins
    "plugins": {
	// Plugins exécutés pour tous les contrôleurs
	// - plugins appelés avant l'exécution de tous les contrôleurs
	"_pre": [
	    "CheckRequestPlugin",
	    "UserGrantPlugin"
	],
	// - plugins appelés après l'exécution de tous les contrôleurs
	"_post": [ "AddCrossLinksPlugin" ],
	// Définition de plugins pour le contrôleur BobController
	"BobControler": {
	    // plugins toujours appelés avant et après l'exécution du contrôleur
	    "_pre": [ "SomethingPlugin" ],
	    "_post": [ "SomethingElsePlugin" ],
	    // plugins spécifiques en fonction des actions du contrôleur
	    "index": {
		"_pre": [ "AaaPlugin" ],
		"_post": [ "BbbPlugin" ]
	    },
	    "setData": {
		"_pre": [ "CccPlugin" ]
	    }
	},
        // Définition de plugins pour le contrôleur BobController, mais
        // uniquement lorsqu'il est appelé par sa route "robert"
        "robert": {
            "_pre": [ "AnotherPlugin" ]
        }
    },
    // Définition des pages d'erreurs
    "errorPages": {
	"default": "path/to/page.html",
	"404": "path/to/page.html",
	"500": "path/to/page.html"
    },
    // Liste de chemins d'inclusion
    "includePaths": [
        "/opt/some_library/lib",
        "/opt/other_lib"
    ],
    // données importées automatiquement comme variables de template
    "autoimport": {
	"googleId": "azeazeaez",
	"googleAnalyticsId": "azeazeazeaze"
    },
    // configuration étendue
    "x-homepage": {
        "title":       "Titre du site",
        "description": "Description du site"
    },
    // une autre configuration étendue
    "x-email": {
        "senderAddress": "admin@localhost.localdomain",
        "senderName":    "Administrateur"
    }
}
						
Commentaires

Attention : Les exemples affichés ci-dessus comportent des commentaires, pour en faciliter la compréhension. Toutefois, PHP est incapable de lire des fichiers JSON comportant des commentaires. Pensez bien à les supprimer dans votre fichier temma.json définitif.

Les fichiers d'exemple temma-mini.json et temma-full.json fournis à l'installation de Temma ne contiennent pas de commentaire, pour en faciliter l'utilisation (vous pouvez sans problème renommer directement temma-mini.json en temma.json, par exemple).

application

La principale section du fichier est celle nommé application. Elle sert à définir les variables les plus importantes du projet.
Voici les différentes variables qu'elle peut contenir :

  • dataSources : Sert à définir les DSN (Database Source Name) de connexion à des sources de données.
  • enableSessions : Cette variable doit être mise à false dans le cas où on ne souhaite pas gérer les sessions.
  • sessionName : Nom du cookie qui contiendra l'identifiant de session.
  • rootController : Nom du contrôleur à exécuter quand une connexion à lieu sur la racine du site.
  • defaultController : Nom du contrôleur à exécuter quand est demandé un contrôleur qui n'existe pas.
  • proxyController : Nom du contrôleur à exécuter systématiquement.
  • defaultView : Nom de la vue par défaut, qui sera utilisée pour générer le flux de sortie, à moins qu'une autre vue ne soit demandée.
loglevels

La section loglevels sert à définir les différents niveaux de log.

Vous pouvez définir plusieurs "classes" de log, chacune avec un seuil d'affichage différent. Le seuil détermine les messages qui apparaîtront dans le fichier etc/temma.log. Lorsqu'un code tente d'écrire un message de log, le message en question n'apparaîtra que si son niveau de criticité est supérieur ou égale à celui du seuil correspondant.

Les différentes valeurs de seuil possibles sont :

  • DEBUG : message de débuggage (criticité la plus faible)
  • INFO : message d'information (niveau par défaut des messages dont le niveau n'est pas précisé)
  • NOTE : notification ; message normal mais significatif (seuil par défaut)
  • WARN : message d'alerte ; l'application ne fonctionne pas normalement mais elle peut continuer à fonctionner.
  • ERROR : message d'erreur ; l'application ne fonctionne pas normalement et elle doit s'arrêter.
  • CRIT : message d'erreur critique ; l'application risque d'endommager son environnement (filesystem ou base de données).
routes

Les routes permettent de définir des «contrôleurs virtuels», servant d'alias aux contrôleurs réels. C'est particulièrement utile pour permettre l'accès à des contrôleurs sous des noms de fichiers (tels que les classiques robots.txt et sitemap.xml). Cela permet aussi d'avoir un même contrôleur qui répond sur plusieurs URL différentes, en faisant éventuellement des traitements différents en fonction du nom de contrôleur demandé.

plugins

Les plugins servent à exécuter du code avant et/ou après l'exécution du contrôleur. Vous trouverez des informations détaillées sur la page de documentation dédiée.

La variable _pre permet de lister les plugins qui seront exécutés avant les contrôleurs.
La variable _post permet de lister les plugins qui seront exécutés après les contrôleurs.

Il est possible de lister les contrôleurs par leurs noms, en spécifiant pour chacun des directives _pre et post spécifiques. Il est aussi possible de spécifier des plugins pour une action particulière d'un contrôleur.

errorPages

Dans certains cas, votre site devra envoyer un code d'erreur HTTP. Et si une erreur a lieu dans votre code lui-même (à cause d'une requête SQL incorrecte, par exemple), c'est le framework qui décidera d'envoyer une erreur 500.

Il est possible d'afficher une page HTML statique différente pour chaque type d'erreur HTTP, et de définir une page par défaut pour tous les types d'erreur qui ne sont pas explicitement configurés.

Par défaut, Temma propose une page pour les erreurs 404 et une page pour les erreurs 500.

includePaths

Cette section sert à ajouter des chemins d'inclusion dans lesquels PHP est susceptible d'aller chercher les objets à inclure.

Par exemple, si vous ajoutez le chemin "/opt/mylib", puis que vous écrivez dans votre code :
include("Toto.php");
PHP regardera si le fichier /opt/mylib/Toto.php existe.

De la même manière, si vous faites une inclusion du genre :
require_once("toto/Titi.php");
PHP cherchera le fichier /opt/mylib/toto/Titi.php.

autoimport

Toutes les directives placées dans la section autoimport sont chargées automatiquement à l'intérieur de la variable de template $conf.

Les variables de template sont accessibles dans les contrôleurs en utilisant la méthode $this->get("variable").
Elles peuvent aussi être crées (ou écrasées) en utilisant la méthode $this->set("variable", $valeur).

Configuration étendue

Le fichier de configuration peut contenir des sections de configuration étendues. Leur but est de regrouper des variables de paramétrage supplémentaires, en les classant par fonctionnalité. Ainsi, un contrôleur ou un plugin peut facilement récupérer les valeurs qui l'intéressent, sans avoir besoin de connaître l'ensemble des variables de configuration existantes.

Pour récupérer une section entière de configuration étendue, il faut passer par l'objet de configuration qui est disponible sous l'attribut $this->_config.

Par exemple, pour récupérer l'ensemble de la configuration étendue x-homepage, il faut écrire :
$data = $this->_config->xtra("homepage");

Pour récupérer la variable senderName de la section x-email :
$data = $this->_config->xtra("email", "senderName");

Il est aussi possible de spécifier une valeur par défaut qui sera utilisée si la variable demandée n'existe pas :
$data = $this->_config->xtra("email", "recipient", "contact@localhost.localdomain");

Documentation : Log

Il est absolument nécessaire de pouvoir suivre l'exécution du code d'une application. Pendant le développement, ou quand on doit faire du débuggage, on veut savoir quelles sont les fonctions qui sont exécutées et dans quel ordre. Pour une application en production, on veut tracer toutes les erreurs, pour pouvoir les traiter spécifiquement.

Temma offre un mécanisme de logging basé sur l'objet FineLog.
Pour l'utiliser, il suffit d'appeler la méthode statique log, en lui fournissant 3 paramètres (les deux premiers sont optionnels) :

  • Une classe de log, c'est-à-dire un label qui permettra au système de connaître le seuil de criticité au-delà duquel le message apparaîtra.
  • Un niveau de criticité, qui sert à indiquer s'il s'agit d'un simple message de débuggage, ou d'une information remontant une erreur critique.
  • Le texte du message de log.

Voici la liste des niveaux de criticités gérés par FineLog :

  • DEBUG : message de débuggage (criticité la plus faible)
  • INFO : message d'information (niveau par défaut des messages dont la criticité n'est pas précisée)
  • NOTE : notification ; message normal mais significatif (seuil par défaut)
  • WARN : message d'alerte ; l'application ne fonctionne pas normalement mais elle peut continuer à fonctionner
  • ERROR : message d'erreur ; l'application ne fonctionne pas normalement et elle doit s'arrêter
  • CRIT : message d'erreur critique ; l'application risque d'endommager son environnement (criticité la plus élevée

Pour qu'un message soit écrit dans le fichier de log, il faut que son niveau de criticité soit supérieur ou égale au seuil prévu pour sa classe de log. Les classes de logs sont définies dans le fichiers de configuration temma.json (voir plus haut).
Un message de log dont le niveau de criticité n'est pas défini est vu comme un message d'information (INFO).
Si la classe d'un message n'est pas définie, on lui affecte une classe par défaut, dont le seuil d'apparition est NOTE.

Voici quelques exemples :

01 FineLog::log("Ceci est un message de log utilisant les seuils par défaut.");
02 FineLog::log(FineLog::NOTE, "Notice d'information, liée à la classe par défaut.");
03 FineLog::log("myapp", FineLog::DEBUG, "Ceci est un message de débug.");
04 FineLog::log("data", FineLog::INFO, "Message d'information");
						

Ligne 1 : Ce message a une criticité par défaut (INFO), et une classe par défaut (default, dont le seuil est NOTE). La criticité étant moins importante que le seuil, le message n'apparaîtra pas.
Ligne 2 : Ce message a la criticité NOTE, et une classe par défaut (default, dont le seuil est NOTE). La criticité étant égale au seuil, le message apparaîtra.
Ligne 3 : Ce message a la criticité DEBUG (la moins importante), et la classe myapp. Si le seuil de cette classe est défini à DEBUG, le message apparaîtra.
Ligne 4 : Ce message a la criticité INFO, et la classe data. Si le seuil de cette classe est défini à INFO ou à DEBUG, le message apparaîtra.

Espaces de nommage

La bibliothèque FineBase, au contraire de Temma, n'utilise pas les espaces de nommage, pour permettre son utilisation sur des installations de PHP inférieures à la version 5.3.

Si vous utilisez FineLog dans un objet qui fait partie d'un namespace, il ne faut pas oublier d'indiquer que FineLog est placé dans l'espace de nom global, en utilisant le caractère antislash ("\") :

\FineLog::log("myapp", \FineLog::DEBUG, "Ceci est un message de débug.");