# Plugins

## Introduction

L'architecture MVC de Zend Framework propose l'injection de plugins de code, qui vont intervenir à différents niveaux dans le processus complet. Le contrôleur frontal enregistre des plugins, et utilise un gestionnaire de plugins ("plugin broker"), qui va se charger de faire intervenir chaque plugin, à chacun des instants clés à votre disposition.

Les instants clés sont des méthodes événementielles définies dans la classe abstraite Zend_Controller_Plugin_Abstract, dont tous les plugins doivent hériter :

- routeStartup() est appelée avant que Zend_Controller_Front n'appelle le routeur pour évaluer ses routes et remplir la requête.

- routeShutdown() est appelée après que le routeur aie fini de router la requête.

- dispatchLoopStartup() est appelée juste avant que Zend_Controller_Front n'entre en boucle de distribution.

- preDispatch() est appelée avant qu'une action ne soit distribuée par le distributeur. Cette méthode permet un filtrage ou un proxy. En jouant sur la requête à ce niveau là, vous êtes capable de changer le processus, et en vous aidant de Zend_Controller_Request_Abstract::setDispatched(true)), vous supprimez l'ordre de distribution de celle-ci.

- postDispatch() est appelée après qu'une action n'ait été distribuée par le distributeur. Cette méthode permet un filtrage ou un proxy. En jouant sur la requête à ce niveau là, vous êtes capable de changer le processus, et en vous aidant de Zend_Controller_Request_Abstract::setDispatched(false)), vous ordonnez une redistribution de celle-ci.

- dispatchLoopShutdown() est appelée par Zend_Controller_Front lorsque celui-ci sort de la boucle de distribution.

## Écrire des plugins

Tous les plugins doivent hériter de Zend_Controller_Plugin_Abstract:

    class MyPlugin extends Zend_Controller_Plugin_Abstract
    {
        // ...
    }

Comme aucune des méthodes de Zend_Controller_Plugin_Abstract n'est abstraite, vous n'êtes pas obligé dans vos plugins de toutes les définir. Vous agissez aux endroits que vous voulez.

Zend_Controller_Plugin_Abstract vous donne aussi accès aux objets de réponse et de requête, dans vos plugins.getRequest() et getResponse() sont là pour ça. Cependant, l'objet de requête est de toute façon passé en paramètre à vos méthodes. Veillez à le récupérer dans la définition de vos méthodes sinon une erreur `E_STRICT` sera levée.

## Utilisation des plugins

Les plugins sont enregistrés avec Zend_Controller_Front::registerPlugin(), et peuvent l'être n'importe quand. Voici un exemple :

    class MyPlugin extends Zend_Controller_Plugin_Abstract
    {
        public function routeStartup(
                    Zend_Controller_Request_Abstract $request)
        {
            $this->getResponse()
                 ->appendBody("<p>routeStartup() appelée</p>\n");
        }

        public function routeShutdown(
                    Zend_Controller_Request_Abstract $request)
        {
            $this->getResponse()
                 ->appendBody("<p>routeShutdown() appelée</p>\n");
        }

        public function dispatchLoopStartup(
                    Zend_Controller_Request_Abstract $request)
        {
            $this->getResponse()
                 ->appendBody("<p>dispatchLoopStartup() appelée</p>\n");
        }

        public function preDispatch(
                    Zend_Controller_Request_Abstract $request)
        {
            $this->getResponse()
                 ->appendBody("<p>preDispatch() appelée</p>\n");
        }

        public function postDispatch(
                    Zend_Controller_Request_Abstract $request)
        {
            $this->getResponse()
                 ->appendBody("<p>postDispatch() appelée</p>\n");
        }

        public function dispatchLoopShutdown()
        {
            $this->getResponse()
                 ->appendBody("<p>dispatchLoopShutdown() appelée</p>\n");
        }
    }

    $front = Zend_Controller_Front::getInstance();
    $front->setControllerDirectory('/path/to/controllers')
          ->setRouter(new Zend_Controller_Router_Rewrite())
          ->registerPlugin(new MyPlugin());
    $front->dispatch();

Si aucune autre action ne génère une sortie (typiquement, un rendu de vue), alors le résultat suivant devrait s'afficher :

    <p>routeStartup() appelée</p>

    <p>routeShutdown() appelée</p>

    <p>dispatchLoopStartup() appelée</p>

    <p>preDispatch() appelée</p>

    <p>postDispatch() appelée</p>

    <p>dispatchLoopShutdown() appelée</p>

Enregistrez vos plugins où vous voulez dans votre code, mais faites attention de ne pas leur faire sauter de méthodes, selon l'endroit où vous les enregistrez.

## Récupération et manipulations des plugins

Il peut arriver que vous ayez besoin de récupérer des plugins, ou d'en supprimer. Les méthodes suivantes vous seront alors utiles :

- getPlugin($class) vous retourne l'objet de plugin correspondant à la chaîne passée en paramètre. Si il n'y a pas de correspondance, `FALSE` est retourné. Un tableau est retourné s'il y a plusieurs plugins de cette classe.

- getPlugins() retourne toute la pile de plugins.

- unregisterPlugin($plugin) supprime un plugin du processus. Passez un nom de classe, et tous les plugins de cette classe seront alors enlevés de la pile. Vous pouvez aussi passer un objet.

## Plugins inclus dans Zend Framework

Zend Framework possède des plugins dans sa distribution :