7.10. Плагины

7.10.1. Введение

Архитектура контроллеров включает в себя систему плагинов, которая позволяет добавлять свой код, который будет вызываться при определенных событиях в процессе жизни контроллера. Фронт-контроллер использует брокер плагинов (plugin broker, можно также перевести как "посредник" - прим. перев.) для регистрации пользовательских плагинов, он обеспечивает вызов методов событий в каждом плагине, зарегистрированном через фронт-контроллер.

Методы событий определены в абстрактном классе Zend_Controller_Plugin_Abstract, от которого должны наследовать все пользовательские плагины:

  • routeStartup() вызывается до того, как Zend_Controller_Front начнет сопоставление запроса с маршрутами.

  • routeShutdown() вызывается после того, как Zend_Controller_Router завершит свою работу во фронт-контроллере.

  • dispatchLoopStartup() вызывается до того, как Zend_Controller_Front войдет в цикл диспетчеризации.

  • preDispatch() вызывается до того, как диспетчером будет запущено действие. Этот обратный вызов позволяет реализовать поведение посредника или фильтра. Через изменение запроса и сброс его флага диспетчеризации (методом Zend_Controller_Request_Abstract::setDispatched(false)) текущее действие может быть пропущено.

  • postDispatch() вызывается после того, как действие было вызвано диспетчером. Этот обратный вызов позволяет реализовать поведение фильтра или посредника. Через изменение запроса и сброс его флага диспетчеризации (методом Zend_Controller_Request_Abstract::setDispatched(false)) может быть определено новое действие для диспетчеризации.

  • dispatchLoopShutdown() вызывается до того, как Zend_Controller_Front выйдет из цикла диспетчеризации.

7.10.2. Написание плагинов

Для того, чтобы написать класс плагина, просто включите абстрактный класс Zend_Controller_Plugin_Abstract и создайте его подкласс:

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

class MyPlugin extends Zend_Controller_Plugin_Abstract
{
    // ...
}

Ни один из методов класса Zend_Controller_Plugin_Abstract не является абстрактным, поэтому классы плагинов не обязательно должны реализовать все из перечисленных выше методов. Разработчики плагинов могут реализовать только те методы, которые соответствуют их нуждам.

Zend_Controller_Plugin_Abstract также делает объекты запроса и ответа доступными плагинам контроллеров через методы getRequest() и getResponse() соответственно.

7.10.3. Использование плагинов

Классы плагинов регистрируются через Zend_Controller_Front::registerPlugin() до начала диспетчеризации. Следующий пример демонстрирует использование плагина:

<?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;