Меню администратора, или блоки в Zend Framework.

Продолжаю серию постов о Zend Framework.

В моем проекте передо мной встала задача. Мне нужно было сделать меню администратора, которое бы появлялось на странице при определенных событиях (например, после аутентификации).

Сначала я хотел решить эту задачу, определив базовый контроллер для всех контроллеров моего проекта. Но, я подумал, что это не лучший способ решения задачи, потому как я нашел более привлекательный метод - использовать плагин для фронт-контроллера. Такое решение мне показалось лучшим потому, что мы получаем менее связанный код. Чтобы убрать меню - нам придется всего лишь отключить плагин фронт-контроллера - это все. Нас опять выручают плагины!

Нам понадобится написать код плагина. Далее, я расскажу, как он работает. Итак, код:

class Project_Controller_Plugin_Toolbar extends Zend_Controller_Plugin_Abstract
{
    public function dispatchLoopStartup(Zend_Controller_Request_Abstract $request)
    {
        if (!$request->isXmlHttpRequest()) {
            $actionStack = Zend_Controller_Front::getInstance()
                ->getPlugin('Zend_Controller_Plugin_ActionStack');

            $menuAction = clone $request;
            $menuAction->setModuleName('application')
                       ->setActionName('index')
                       ->setControllerName('toolbar');

            $actionStack->pushStack($menuAction);
        }
    }
}

Теперь прокомментирую код.

Этот плагин срабатывает перед запуском цикла диспетчеризации, это обеспечивается определением метода dispatchLoopStartup(), в который передается объект текущего запроса. Видно, что логика метода завернуто в условие, которое определяет, что код не должен выполняться для AJAX запросов - нам же не нужно кашу к примеру, из JSON и нашего меню? :)

Дальше мы получаем стек плагин, управляющий стеком действий. Затем клонируем объект текущего запроса и устанавливаем при помощи аксессоров объекта свои значения контроллера, действия и модуля (так как мой проект имеет модульную структуру контроллеров).

В конце метода мы кладем в стек наш клонированный и настроенный объект запроса.

Итак, что получилось? Получилось, что мы создали новый объект запроса путем клонирования, которому установили значения модуля, контроллера и действия, а затем поместили его в стек действий. Плагин Zend_Controller_Plugin_ActionStack последовательно производит диспетчеризацию запросов из стека, после диспетчеризации основного действия (плагин делает это в хуке postDispatch()).

Важно! Не забудьте подключить к фронт-контроллеру плагин Zend_Controller_Plugin_ActionStack обслуживающий стек действий. Без него наш плагин Project_Controller_Plugin_Toolbar работать не будет.

$front->registerPlugin(new Zend_Controller_Plugin_ActionStack(), 97);

И, конечно, не забываем подключить и наш свеженаписанный плагин:

$front->registerPlugin(new Tanraya_Controller_Plugin_Toolbar(), 111);

А что же происходит в нашем контроллере ToolbarController? Там все просто - в методе indexAction() мы указываем, в какой сегмент макета выводить отрендеренный шаблон вида:

$this->_helper->viewRenderer->setResponseSegment('toolbar');

А в макете вывод сегмента выглядит так:

<?=$this->layout()->toolbar ?>

Ну вот - наше меню готово. У меня появились мысли, сделать универсальный механизм для работы с блоками, чтобы не писать отдельных плагинов для каждого блока на сайте. Я имею в виду те блоки, которые не кочуют из проекта в проект, как меню администратора, а используются только на конкретном сайте. Я пока не придумал, как реализовать такой механизм красиво, но зачатки мыслей уже есть и их нужно еще раз обдумать и реализовать. Как сделаю - напишу об этом отдельный пост.

Всем спасибо за внимание :)

Also interesting

Tags: , , ,

2 Responses to “Меню администратора, или блоки в Zend Framework.”

  1. IndecyImmenny says:

    Огромное спасибо! Очень помогла ваша информация!!!)))))))))))

  2. Atapin says:

    А чем Zend_Navigation не таков?

Leave a Reply