Documentation

Configuration

Présentation

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.

Dans le répertoire etc/, vous pourrez trouver deux fichiers servant à illustrer la configuration d'un projet Temma :

  • temma-mini.json : Fichier minimal contenant les directives de base.
  • temma-full.json : Fichier présentant toutes les options disponibles.

Fichier temma.json simple

Voici un exemple typique de fichier temma.json minimal :

{
    // Configuration de l'application
    "application": {
        "dataSources": {
            "db": "mysql://user:passwd@localhost/mybase"
        },
        "rootController": "HomepageController"
    },
    // Définition des niveaux de log
    "loglevels": "ERROR",
    // Définition des pages d'erreur
    "errorPages": "error404.html",
    // Données importées automatiquement comme variables de template
    "autoimport": {
        "googleId": "azeazeaez",
        "googleAnalyticsId": "azeazeazeaze"
    }
}

On peut y voir :

  • Ligne 5 : La définition du DSN qui permet de se connecter à la base de données.
  • Ligne 7 : Le nom du contrôleur racine, qui sera appelé quand quelqu'un se connectera sans spécifier de contrôleur.
  • Ligne 10 : Définition du seuil d'écriture des messages de log dans le fichier log/temma.log. Ici, avec le seuil "ERROR", seuls les messages avec les seuils ERROR et CRIT seront effectivement écrits dans le fichier de log.
  • Ligne 12 : Définition de la page à afficher si une erreur survient. La page en question doivent être situées dans le répertoire www/ du projet.
  • Les variables de template automatiquement importées.
    • Ligne 15 : Identifiant Google, disponible dans les templates avec {$conf.googleId} et dans le contrôleur avec $this['conf']['googleId'].
    • Ligne 16 : Identifiant Google Analytics, disponible dans les templates avec {$conf.googleAnalyticsId et dans le contrôleur avec $this['conf']['googleAnalyticsId'].

Fichier temma.json complet

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 MySQL
            //  (cf. objet \Temma\Base\Database).
            // Optionnel
            "db": "mysqli://user:passwd@localhost/mybase",

            // DSN de connexion à la base de données Redis
            //  (cf. objet \Temma\Base\NDatabase).
            // Optionnel
            "ndb": "redis://localhost:6379/0",

            // DSN de connexion au serveur de cache Memcached
            //  (cf. objet \Temma\Base\Cache).
            // Optionnel
            "cache": "memcache://localhost:11211"
        },

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

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

        // Source de données pour stocker les sessions.
        // Optionnel : Utilise le mécanisme de gestion des
        // sessions de PHP par défaut
        "sessionSource": "ndb",

        // Namespace par défaut des contrôleurs
        // Optionnel : par défaut les contrôleurs sont dans
        // le namespace global.
        "defaultNamespace": "\\MyApp\\Controllers",

        // 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": "Homepage",

        // Nom du contrôleur par défaut à utiliser si le contrôleur
        // demandé est inexistant.
        // Optionnel. Par défaut, génère une erreur 404 si on
        // demande un contrôleur qui n'existe pas.
        "defaultController": "NotFound",

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

        // Nom de la vue par défaut.
        // Optionnel. \Temma\Views\Smarty par défaut.
        "defaultView": "\\Temma\\Views\\Smarty",

        // Nom de l'objet qui sera utilisé comme
        // composant d'injection de dépendances
        "loader": "MyLoader",

        // Chemin vers le fichier de log.
        // Optionnel : Par défaut, les logs sont écrits dans
        // le fichier "log/temma.log".
        // Mettre une valeur fausse (null, false, chaîne vide ou le nombre zéro)
        // pour désactiver l'écriture dans le fichier de log.
        "logFile": "log/temma.log",

        // Nom de l'objet de gestion de log, ou liste de noms d'objets.
        // Optionnel : Aucun gestionnaire de log n'est activé par défaut.
        "logManager": [ "ElasticLogManager", "SentryLogManager" ]
    },
    // Définition des seuils de log
    "loglevels": {
        "Temma/Base": "ERROR",
        "Temma/Web": "WARN",
        "myapp": "DEBUG",
        "default": "NOTE"
    },
    // Routage : 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 exécutés avant le contrôleur
        "_pre": [
            "CheckRequest",
            "UserGrant"
        ],
        // - plugins exécutés après le contrôleur
        "_post": [ "AddCrossLinks" ],
        // Définition de plugins spécifiques au contrôleur Article
        "Article": {
            // plugins exécutés avant et après le contrôleur
            "_pre": [ "Something" ],
            "_post": [ "SomethingElse" ],
            // plugins spécifiques à l'action index
            "index": {
                "_pre": [ "Aaa" ],
                "_post": [ "Bbb" ]
            },
            // plugin exécuté avant l'action setData
            "setData": {
                "_pre": [ "CccPlugin" ]
            }
        },
        // Plugin 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": {
        "404":     "error404.html",
        "500":     "error500.html",
        "default": "error404.html"
    },
    // Liste de chemins d'inclusion
    "includePaths": [
        "/opt/some_library/lib",
        "/opt/other_lib"
    ],
    // Liste de chemins d'inclusions pour des préfixes de namespaces
    "namespacePaths": {
        "\\Acme\\Log":      "/path/to/acme-log/lib",
        "\\MyLib\\Feature": "/path/to/vendors/feature"
    },
    // 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

Comme vous pouvez le voir ci-dessus, les fichiers temma.json peuvent contenir des commentaires (sous la forme double-slashes, ou sous la forme /* … */).

application

La principale section du fichier est celle nommé application. Elle sert à définir les variables de configuration 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 (MySQL, Redis, Memcached).
  • enableSessions : Cette variable doit être mise à false dans le cas où on ne souhaite pas gérer les sessions. Cela peut être utile lorsqu'on ne veut pas suivre les visites des utilisateurs, comme par exemple pour une API.
  • sessionName : Nom du cookie qui contiendra l'identifiant de session.
  • defaultNamespace : Dans le cas où les fichiers PHP des contrôleurs ne sont pas enregistrés dans le répertoire controlers/, cette variable contient le namespace par défaut des contrôleurs.
    Par exemple, si cette variable contient la valeur \App\Ctrl, et qu'on se connecte à l'URL www.monsite.com/home, Temma va charger l'objet \App\Ctrl\Home.
  • rootController : Nom du contrôleur à exécuter quand une connexion a 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, même si le contrôleur demandé existe.
  • 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 explicitement demandée dans le contrôleur ou un plugin).
  • loader : Nom de l'objet qui sera utilisé comme le composant d'injection de dépendances.
  • logFile : Chemin vers le fichier de log. Mettre une valeur fausse (null, false, chaîne vide ou le nombre zéro) pour désactiver l'écriture dans le fichier de log (cela peut être utile si vous souhaitez passer uniquement par un log manager ; voir la directive suivante). Tout chemin ne commençant pas par un slash (/) sera relatif à la racine du projet.
  • logManager : Cette variable peut contenir le nom d'un objet de gestion du log, ou une liste de nom d'objets. Voir la documentation du log pour plus de détails.

DSN (Data Source Name)

Pour définir une connexion à une source de données, il faut écrire une chaîne de caractère qui contient tous les paramètres.

Plusieurs formats sont possible :

  • Variable d'environnement
    Il est possible d'indiquer le nom d'une variable d'environnement.
    env://VAR_NAME
    Il faut que cette variable soit correctement définie, et que son contenu soit un DSN deconnexion supporté par Temma (voir les cas ci-dessous).
  • Base de données relationnelle
    protocol://user:password@host[:port][/db_name]
    • protocol : Type de base de données, tel que défini par PDO (mysql, pgsql, cubrid, sybase, mssql, dblib, firebird, ibm, informix, sqlsrv, oci, odbc, 4D)
    • user : Nom de l'utilisateur pour se connecter au serveur
    • password : Mot de passe utilisé pour se connecter au serveur
    • host : Nom de la machine hôte hébergeant le serveur de base de données
    • port : Numéro de port de la connexion réseau (optionnel, utilise le numéro de port habituel par défaut)
    • db_name : Nom d'instance de base auquel se connecter (optionnel)
    Exemples :
    • mysql://db_user:db_password@localhost/app_db
    • pgsql://db_user:db_password@db_server.mydomain.com:3307/app_db
    Il est possible de se connecter à un serveur MySQL en utilisant des sockets Unix locales, plutôt que des sockets réseau : mysql://user:password@localhost/db_name#/var/run/mysqld/mysqld.sock
    Par rapport à une configuration MySQL classique, il faut ajouter un caractère dièse (#), suivi du chemin vers le fichier de la socket Unix. Le nom de machine hôte doit obligatoirement être localhost. Il ne peut pas y avoir de numéro de port.
    Exemple : mysql://db_user:db_password@localhost/app_db#/var/run/mysqld/mysqld.sock
  • Base de données relationnelle locale (SQLite)
    sqlite:/path/to/file.sq3
  • Base de données non relationnelle (Redis)
    redis://host[:port][/db_number]
    • host : Nom de la machine hôte hébergeant le serveur Redis
    • port : Numéro de port de la connexion réseau (optionnel, utilise le port 6379 par défaut)
    • db_number : Numéro de la base à laquelle se connecter (optionnel, utilise la base 0 par défaut)
    Exemples :
    • redis://localhost
    • redis://db_server.mydomain.com:6380/2
    Il est possible de se connecter à un serveur Redis en utilisant des sockets Unix locales, plutôt que des sockets réseau :
    redis-sock:///path/to/unix/socket[#base]
    Par rapport à une configuration Redis classique, il faut indiquer le chemin ver le fichier de la socket Unix, à la place du nom de serveur. Si un numéro de base est spécifié, il doit être indiqué à la fin, après un caractère dièse (#) ; sinon c'est la base 0 qui est utilisée par défaut.
    Exemples :
    • redis-sock:///var/run/redis/redis-server.sock
    • redis-sock:///var/run/redis/redis-server.sock#2
  • Serveur de cache (Memcached)
    memcache://host[:port]
    • host : Nom de la machine hôte hébergeant le serveur Memcached
    • port : Numéro de port de la connexion réseau (optionnel, utilise le port 11211 par défaut)
    Exemple : memcache://localhost
    Il est possible de configurer le client pour qu'il se connecte à plusieurs serveurs Memcached (la répartition des données sur plusieurs serveurs Memcached est gérée côté client). Pour cela, il faut indiquer les serveurs à la suite les uns des autres, séparés par un point-virgule (;) ; chaque serveur pouvant être accompagné d'un numéro de port spécifique.
    Exemple : memcache://localhost;serv1:11212;serv2

loglevels

La section loglevels sert à définir les différents niveaux de log. Vous trouverez des informations sur son utilisation dans la page de documentation consacrée au 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 (système de fichiers ou base de données).

Vous pouvez définir vos propres "classes" de log, en fonction de vos besoins applicatifs. En plus de cela, vous pouvez utiliser les classes suivantes :

  • Temma/Base : Logs concernant les objets de base de Temma (base de données, autoloader, sessions, etc.).
  • Temma/Web : Logs concernant les objets du framework lui-même.
  • default : Sert à définir le seuil par défaut, pour toutes les classes qui ne sont pas définies.

Si la directive loglevels ne contient pas un tableau associatif, mais simplement une chaîne de caractères représentant un seuil de log, celui-ci sera utilisé pour tous les messages, quel que soit leur "classe" spécifique.

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.

Pour ne pas définir toutes les pages d'erreur possible, vous pouvez utiliser la clé "default" pour définir la page par défaut.
Si vous voulez utiliser la même page, quelle que soit l'erreur, vous pouvez ne pas fournir un tableau associatif, mais juste une chaîne de caractères.

includePaths

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

À la base, Temma ajoute au chemin d'inclusion le répertoire lib/ du projet. Ainsi, si vous écrivez dans votre code : include('Toto.php');
C'est le fichier lib/Toto.php qui sera chargé.

Ou encore, grâce à l'autoloader, si vous écrivez : new \Aaa\Bbb();
PHP chargera le fichier lib/Aaa/Bbb.php automatiquement.

Mais si vous ajoutez la configuration suivante dans votre fichier temma.json :

{
    includePaths: [
        "/path/to/lib1",
        "/path2"
    ]
}

Si vous écrivez dans votre code require_once('titi.php');
PHP essaiera de charger successivement plusieurs chemins, jusqu'à trouver le fichier. Dans l'ordre, il essaiera :

  • /path/to/lib1/titi.php
  • /path2/titi.php
  • lib/titi.php

En utilisant l'autoloader, si vous écrivez new \Aa\Bb(); PHP essaiera les chemins suivants :

  • /path/to/lib1/Aa/Bb.php
  • /path2/Aa/Bb.php
  • lib/Aa/Bb.php

namespacePaths

Il peut arriver que vous ayez besoin de spécifier des chemins d'inclusion spécifiques pour certains préfixes de namespace. Imaginons que votre fichier temma.json contient la configuration suivante :

{
    namespacePaths: {
        "\\Acme\\Log": "/path/to/acme-log/lib",
        "\\Aa\\Bb": "/path/to/Bb"
    }
}

Si vous écrivez le code new \Acme\Log\Writer();
PHP tentera de charger le fichier /path/to/acme-log/lib/Writer.php

Par contre, si vous écrivez new \Aa\Bb\Cc();
PHP chargera le fichier /path/to/Bb/Cc.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 écrivant $this['variable'].
Elles peuvent aussi être crées (ou écrasées) en écrivant $this['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 via le composant d'injection de dépendances :
$this->_loader->config

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

Pour récupérer la variable senderName de la section x-email :
$data = $this->_loader->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->_loader->config->xtra('email', 'recipient', 'contact@host.domain');

Précédent : Installation
Suivant : Routage

Table des matières