Attributs
1Présentation
Temma propose des attributs PHP dont l'utilisation est complètement optionnelle, et qui permettent de contrôler l'accès aux contrôleurs et aux actions.
Ces attributs sont cumulables, il est possible de mettre plusieurs attributs différents (et parfois plusieurs fois le même attribut, avec des paramètres différents) sur le même contrôleur ou la même action.
De plus, vous avez la possibilité de créer vos propres attributs, qui pourront gérer les accès aux contrôleurs et aux actions.
Attributs proposés par Temma
Temma fournit plusieurs attributs, dont la documentation est accessible dans la section "Helpers" :
- Auth : Pour restreindre les accès aux utilisateurs authentifiés.
- Check : Pour valider les données en entrée (paramètres GET/POST, payload, fichiers).
- View : Pour gérer la vue des contrôleurs et des actions.
- Template : Pour définir le chemin vers le fichier de template.
- Method : Pour gérer les méthodes HTTP autorisées.
- Referer : Pour filtrer les accès par HTTP REFERER.
- Redirect : Pour rediriger les requêtes automatiquement.
2Écrire vos propres attributs
Vous pouvez créer des attributs qui pourront gérer de manière fine les accès aux contrôleurs et aux actions.
Dans Temma, les attributs sont actifs : le framework qui réagit à leur présence ; il exécute les
attributs, en leur mettant une API à disposition, et ce sont les attributs qui manipulent le comportement
du framework.
Comparativement à d'autres frameworks, cela rend Temma plus simple. On peut ajouter de nouveaux attributs
sans avoir besoin de faire évoluer le cœur du framework.
2.1Principe
Vos attributs doivent dériver de l'objet \Temma\Web\Attribute, et ne peuvent être appliqués que sur les contrôleurs et les actions.
Un attribut doit avoir un constructeur, qui peut recevoir les paramètres dont l'attribut a besoin.
Le constructeur ne doit faire aucun traitement et se contenter d'enregistrer les paramètres reçus.
Le traitement effectif de l'attribut doit s'exécuter dans une méthode apply(),
qui reçoit en pramètre un objet immplémentant l'interface Reflector,
indiquant le contexte dans lequel l'attribut s'exécute : cela peut être un objet de type
ReflectionClass
(au niveau d'un contrôleur) ou ReflectionMethod
(au niveau d'une action).
Par héritage, vos attributs ont accès à des fonctionnalités relativement similaires à celles des contrôleurs :
-
L'accès aux variables de templates par la notion à crochet.
Par exemple :- $this['var'] = 'value'; pour définir une variable
- $var = $this['var']; pour lire la valeur d'une variable.
-
L'accès aux sources de données sous forme de propriétés directes de l'objet.
Par exemple : $this->db pour accéder à une base de données nommée db. -
Les méthodes $this->_httpCode() et $this->_httpError()
pour définir le code HTTP de retour, ou le code d'erreur HTTP.
Les méthodes $this->_getHttpCode() et $this->_getHttpError() pour récupérer le code HTTP préalablement défini. - Les méthodes $this->_redirect() et $this->_redirect301() pour définir des ordres de redirection.
- Les méthodes $this->_view() pour définir la vue, $this->_template() pour définir le template, et $this->_templatePrefix() pour définir le préfixe de template.
De plus, des propriétés permettent d'accéder aux objets internes de Temma :
- $this->_loader : instance du composant d'injection de dépendances.
- $this->_session : instance de l'objet de gestion de la session.
- $this->_config : instance de l'objet d'accès à la configuration.
- $this->_request : instance de l'objet de gestion de la requête.
- $this->_response : instance de l'objet de gestion de la réponse.
Tous ces éléments permettent de manipuler l'exécution comme pour les plugins.
2.2Flux d'exécution
Pour modifier le flux d'exécution, un attribut doit lever une exception spécifique :
- \Temma\Exceptions\FlowHalt : Arrête le flux d'exécution. Aucun autre plugin ou contrôleur ne sera exécuté, et le framework passe directement au traitement de la vue ou de la redirection.
- \Temma\Exceptions\FlowRestart : Relance le traitement de la phase (pré-plugins, contrôleur ou post-plugins) en cours.
- \Temma\Exceptions\FlowReboot : Relance toute la chaîne de traitements (pré-plugins + contrôleur + post-plugins).
- \Temma\Exceptions\FlowQuit : Arrête l'exécution du framework. Aucun autre plugin ou contrôleur ne sera exécuté. La vue ne sera pas exécutée et les demandes de redirection ne sont pas prises en compte.
2.3Exemple
Voici l'exemple d'un attribut nommé MyLog, qui écrit dans un fichier juste avant qu'un contrôleur soit instancié ou qu'une action soit exécutée. Sont écrits le nom de l'objet ou de la méthode, avec le nom du fichier et le numéro de ligne.
<?php
use \Temma\Base\Log as TµLog;
/**
* Attribut utilisé pour écrire dans un log le flux d'exécution des
* contrôleurs et des actions.
*/
#[\Attribute(\Attribute::TARGET_CLASS | \Attribute::TARGET_METHOD)]
class MyLog extends \Temma\Web\Attribute {
/**
* Constructeur.
* @param string $message (optionnel) Message à ajouter à la ligne de log.
*/
public function __construct(private ?string $message=null) {
}
/**
* Traitement de l'attribut.
* @param \Reflector $context Contexte de l'élément (classe ou méthode).
*/
public function apply(\Reflector $context) : void {
// récupération des informations
$name = $context->getName();
$file = $context->getFileName();
$line = $context->getStartLine();
// Détermine le type de contexte
if ($context instanceof \ReflectionClass) {
$type = 'Contrôler';
// $name contient déjà le nom complet de l'objet
} elseif ($context instanceof \ReflectionMethod) {
$type = 'Action';
// $name contient le nom de la méthode, on y ajoute
// le nom de la classe
$name = $context->getDeclaringClass()->getName() . '::' . $name;
} else {
return;
}
// construction de la chaîne de log
$logString = "[$type] $name ($file:$line)";
if ($this->message)
$logString .= ' : ' . $this->message;
// écriture du log
TµLog::l($logString);
}
}
- Ligne 9 : L'objet est déclaré comme étant un attribut qui peut être appliqué sur des classes et des méthodes.
- Ligne 10 : Définition de l'objet, qui hérite de \Temma\Web\Attributes.
- Ligne 15 : Constructeur de l'attribut, qui reçoit un paramètre qui est promu en propriété privée.
- Ligne 22 : Méthode d'exécution, qui reçoit le contexte d'exécution en paramètre.
- Lignes 23 à 39 : Récupération des informations nécessaires à la constitution du texte à loguer.
- Lignes 41 à 44 : Construction du texte à loguer.
- Ligne 47 : Écriture de la chaîne en utilisant l'objet \Temma\Base\Log.
Et voici un exemple d'utilisation de cet attribut :
<?php
/** Contrôleur. */
#[MyLog]
class Article extends \Temma\Web\Controller {
/** Action affichant la liste des articles. */
#[MyLog('Liste des articles')]
public function liste() {
// ...
}
/**
* Action affichant un article.
* @param int $id Identifiant de l'article.
*/
#[MyLog('Affichage article')]
pulic function voir(int $id) {
// ...
}
}
-
Ligne 4 : On applique l'attribut MyLog sur le contrôleur.
Cela ajoutera au log la ligne [Contrôleur] Article (Article.php:4) -
Ligne 7 : On applique l'attribut sur l'action liste().
Cela ajoutera au log la ligne [Action] Article::liste (Article.php:7) : Liste des articles -
Ligne 16 : On applique l'attribut sur l'action voir().
Cela ajoutera au log la ligne [Action] Article::voir (Article.php:16) : Affichage article