7.6. Wtyczki

7.6.1. Wprowadzenie

Architektura kontrolera zawiera także system wtyczek, który pozwala programiście na wykonanie własnego kodu, gdy następują określone zdarzenia w trakcie trwania procesu kontrolera. Kontroler frontowy używa agenta wtyczek jako rejeestru dla wtyczek programisty, a agent wtyczek jest odpowiedzialny za to, że metody zdarzeń są wywoływane dla każdej wtyczki zarejestrowanej w kontrolerze frontowym.

Metody zdarzeń są zdefiniowane w klasie abstrakcyjnej Zend_Controller_Plugin_Abstract, z której dziedziczy każda klasa wtyczki:

  • routeStartup() jest wywoływana zanim Zend_Controller_Front zacznie określać parametry żądania na podstawie tras.

  • routeShutdown() jest wywoływana gdy Zend_Controller_Router kończy pracę, gdy Zend_Controller_Front wychodzi z routera.

  • dispatchLoopStartup() jest wywoływana zanim Zend_Controller_Front wejdzie w pętlę uruchomieniową.

  • preDispatch() jest wywoływana przed uruchomieniem akcji przez Zend_Controller_Dispatcher. Pozwala to na uzyskanie funkcjonalności proxy lub filtra. Przez nadpisanie żądania i zresetowanie flagi uruchomienia (poprzez Zend_Controller_Request_Abstract::setDispatched(false)), obecna akcja może zostać ominięta.

  • postDispatch() jest wywoływana po uruchomieniu akcji przez Zend_Controller_Dispatcher. Pozwala to na uzyskanie funkcjonalności proxy lub filtra. Przez nadpisanie żądania i zresetowanie flagi uruchomienia (poprzez Zend_Controller_Request_Abstract::setDispatched(false)), może zostać określona nowa akcja do uruchomienia.

  • dispatchLoopShutdown() jest wywoływana gdy Zend_Controller_Front zakończy pętlę uruchomieniową.

7.6.2. Pisanie wtyczek

W celu napisania klasy wtyczki, w prosty sposób rozszerz klasę abstrakcyjną Zend_Controller_Plugin_Abstract:

<?php
require_once 'Zend/Controller/Plugin/Abstract.php';

class MyPlugin extends Zend_Controller_Plugin_Abstract
{
    // ...
}

Żadna z metod klasy Zend_Controller_Plugin_Abstract nie jest abstrakcyjna, co oznacza, że nie jest konieczne implementowanie wszystkich dostępnych metod zdarzeń opisanych powyżej. Autor wtyczki może zaimplementować tylko te metody zdarzeń, które są mu rzeczywiście potrzebne.

Zend_Controller_Plugin_Abstract udostępnia także obiekty żądania i odpowiedzi wtyczkom kontrolera za pomocą metod getRequest() oraz getResponse(), odpowiednio.

7.6.3. Użycie wtyczek

Klasy wtyczek są rejestrowane za pomocą metody Zend_Controller_Front::registerPlugin(), aż do momentu uruchomienia. Poniższy kod pokazuje w jaki sposób wtyczka może być użyta przez kontroler:

<?php
require_once 'Zend/Controller/Front.php';
require_once 'Zend/Controller/Router.php';
require_once 'Zend/Controller/Plugin/Abstract.php';

class MyPlugin extends Zend_Controller_Plugin_Abstract
{
    public function routeStartup()
    {
        $this->getResponse()->appendBody('<p>routeStartup() called</p>');
    }

    public function routeShutdown($request)
    {
        $this->getResponse()->appendBody('<p>routeShutdown() called</p>');
    }

    public function dispatchLoopStartup($request)
    {
        $this->getResponse()->appendBody('<p>dispatchLoopStartup() called</p>');
    }

    public function preDispatch($request)
    {
        $this->getResponse()->appendBody('<p>preDispatch() called</p>');
    }

    public function postDispatch($request)
    {
        $this->getResponse()->appendBody('<p>postDispatch() called</p>');
    }

    public function dispatchLoopShutdown()
    {
        $this->getResponse()->appendBody('<p>dispatchLoopShutdown() called</p>');
    }
}

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

echo $response;