Documentation

Plugins personnalisés

Présentation

Les plugins permettent de modulariser le développement d'applications web. Ils permettent notamment de factoriser des traitements qui doivent se faire systématiquement au début ou à la fin de tous les accès.

Cela peut être, par exemple, un plugin qui vérifie que certaines URLs ne sont accessible qu'aux utilisateurs authentifiés, et qui s'exécutera avant que les traitements n'atteignent les contrôleurs ; si l'utilisateur n'est pas authentifié, le plugin le redirigera vers la page d'authentification, et le contrôleur ne sera même pas exécuté.
Cela peut être un plugin qui s'exécute en fin de traitement, pour positionner des variables de template qui sont nécessaires pour toutes les pages.
Les possibilités sont infinies…

Les plugins peuvent même manipuler les données du framework, ce qui leur donne la possibilité de changer le contrôleur ou l'action qui va être exécuté, ainsi que les paramètres qui lui seront passés.

Développement

Voici un exemple de plugin :

class CheckPlugin extends \Temma\Web\Plugin {
    public function plugin() {
        // on affecte une variable de template
        $this['checked'] = true;
    }
}

Comme on peut le voir dans cet exemple, les plugins héritent de la classe parente \Temma\Web\Plugin, qui dérive elle-même de la classe \Temma\Web\Controller. Les plugins sont donc des contrôleurs avec juste une capacité supplémentaire.
Un plugin peut donc être utilisé par ailleurs comme un contrôleur, et un contrôleur peut aussi être utilisé comme un plugin.

Dans cet exemple, on a défini une méthode plugin(), qui sera exécutée lorsque le plugin sera appelé. C'est donc la configuration qui déterminera si l'objet est un pré-plugin ou un post-plugin.

Pour transmettre des données entre les plugins, ou entre les plugins et le contrôleur (et inversement), il faut utiliser les variables de template. Si un plugin positionne une variable de template, elle sera accessible par tous les plugins/contrôleur qui suivent dans la chaîne d'exécution.

Pour qu'un même objet (qu'il ne soit qu'un plugin, ou contrôleur+plugin) puisse être à la fois un pré-plugin et un post-plugin, en exécutant du code différent suivant le moment de son exécution, on peut définir des méthodes preplugin() et postplugin().

  • Lorsqu'un plugin est exécuté dans la chaîne d'actions PRÉ, Temma regarde d'abord s'il possède une méthode nommée preplugin(). Si c'est le cas, elle est exécutée ; sinon, on exécute la méthode plugin().
  • Lorsqu'un plugin est exécuté dans la chaîne d'actions POST, Temma regarde d'abord s'il possède une méthode nommée postplugin(). Si c'est le cas, elle est exécutée ; sinon on exécute la méthode plugin().

Voici un exemple de contrôleur qui est capable d'agir comme pré-plugin et comme post-plugin, en plus de posséder plusieurs actions :

class Page extends \Temma\Web\Plugin {
    protected $_temmaAutoDao = true;

    // pré-plugin de vérification d'URL
    public function preplugin() {
        if (!$this->_checkUrl()) {
            return $this->httpError(404);
        }
        $this['checked'] = true;
    }

    // post-plugin de retraitement de variables avant envoi au template
    public function postplugin() {
        $dirtyData = $this['dirtyData'];
        $cleanData = htmlspecialchars($dirtyData);
        $this['cleanData'] = $cleanData;
    }

    // action racine
    public function index() {
        $this['pages'] = $this->_dao->search();
    }

    // action supplémentaire
    public function show($id) {
        $this['page'] = $this->_dao->get($id);
    }

    // méthode privée
    private function _checkUrl() {
        // ...
        return (true);
    }
}

Manipulation des plugins et contrôleur

Les plugins et le contrôleur peuvent modifier dynamiquement les informations que le framework utilise pour déterminer quels sont les plugins/contrôleur à exécuter.

Modification des plugins

Dans une méthode de plugin ou une méthode de contrôleur (initialisation, action ou finalisation), il est possible de récupérer la liste complète des plugins, et de la mettre à jour.

Cela se fait en passant par l'objet $this->_loader->config, qui offre l'attribut plugins, accessible en lecture et en écriture. Cet attribut contient directement le tableau de plugins tel que défini dans le fichier temma.json (voir la documentation de la configuration).

Si vous modifiez la configuration des plugins, il vous faudra sûrement retourner un statut EXEC_RESTART ou EXEC_REBOOT, pour forcer Temma à réexécuter la chaîne des plugins.

Voici un exemple de pré-plugin qui inverse l'ordre des post-plugins.

class ReverseExamplePlugin extends \Temma\Web\Plugin {
    public function preplugin() {
        // récupération de la liste des plugins
        $plugins = $this->_loader->config->plugins;

        // inversion des post-plugins
        $plugins['_post'] = array_reverse($plugins['_post']);

        // mise-à-jour de la liste des plugins
        $this->_loader->config->plugins = $plugins;
    }
}
Modification du contrôleur

Dans une méthode de plugin ou une méthode de contrôleur (initialisation, action ou finalisation), il est possible d'accéder aux informations suivantes, et de les modifier :

  • Le nom du contrôleur à exécuter.
  • Le nom de l'action à exécuter.
  • Les paramètres fournis à l'action.

Toute ces informations sont accessibles par l'objet $this->_loader->request, qui propose les méthodes suivantes :

  • getController() : Retourne le nom du contrôleur qui va être exécuté. Identique à la variable de template $this['CONTROLLER'].
  • getAction() : Retourne le nom de l'action qui va être exécutée. Identique à la variable de template $this['ACTION'].
  • getNbrParams() : Retourne le nombre de paramètres.
  • getParams() : Retourne la liste des paramètres.
  • getParam(int $index, [$default]) : Retourne le paramètre dont l'index est fourni en paramètre. Une valeur par défaut peut être passée en second paramètre ; elle sera retournée si le paramètre demandé n'est pas défini.
  • setController(string $name) : Définit le nom du contrôleur à exécuter.
  • setAction(string $name) : Définit le nom de l'action à exécuter.
  • setParams(array $params) : Définit la liste des paramètres.
  • setParam(int $index, string $value) : Définit la valeur d'un paramètre dont l'index est fourni.

Attention : Si vous modifiez le contrôleur et/ou l'action avec les méthodes setController() et setAction(), pensez à mettre à jour les variables de template correspondantes $this['CONTROLLER'] et $this['ACTION'], ainsi que $this['URL'].


Voici un exemple de pré-plugin simpliste qui extrait la langue au début de l'URL.
Par exemple, pour une URL /fr/article/voir/123/mon-article, le plugin va mettre "fr" dans la variable de template $this['lang'], puis fera ce qu'il faut pour que Temma fasse comme si l'URL reçue avait été /article/voir/123/mon-article.

class LangExamplePlugin extends \Temma\Web\Plugin {
    public function preplugin() {
        // récupération de la langue
        $lang = $this['CONTROLLER'];
        // récupération du contrôleur
        $newController = $this['ACTION'];
        // récupération des paramètres
        $params = $this->_loader->request->getParams();
        // extraction de l'action et décalage des paramètres
        $newActions = array_shift($params);

        // mise-à-jour des données dans Temma
        $this->_loader->request->setController($newController);
        $this->_loader->request->setAction($newAction);
        $this->_loader->request->setParams($params);
        // mise-à-jour des variables de template
        $this['lang'] = $lang;
        $this['CONTROLLER'] = $newController;
        $this['ACTION'] = $newAction;
        $this['URL'] = substr($this['URL'], strlen($lang));
    }
}
Précédent : Plugins
Suivant : Plugin de cache

Table des matières