Помощники действий
Введение
Помощники действий (action helpers) дают разработчикам возможность
добавлять функционал во время выполнения или по требованию в любые
контроллеры действий, которые наследуют от
Zend_Controller_Action.
Помощники действий помогают снизить необходимость в наследовании от
абстрактного контроллера действий при добавлении общего
функционала в контроллер действий.
Есть несколько вариантов использования помощников действий.
Помощники действий используют брокерскую систему (brokerage system),
подобную той, которая используется в
Zend_View_Helper и
Zend_Controller_Plugin.
Помощники действий (как и Zend_View_Helper) могут быть
загружены и вызваны по требованию, либо инстанцироваться во время
запроса (начальной загрузки) или создания контроллера действий
(init()). Для того, чтобы лучше разобраться с этим, см. ниже раздел
по использованию.
Инициализация помощника
Помощник может быть инициализирован несколькими различными
способами, выбор способа зависит от ваших нужд и от
функционала, предоставляемого этим помощником.
Брокер помощников хранится как член $_helper класса
Zend_Controller_Action; используйте брокер для
получения или вызова помощников. Методы для этого включают в себя:
-
Явное использование метода getHelper() . Просто
передайте ему имя, и будет возвращен объект помощника:
span style="color: #ff0000;">'FlashMessenger''We did something in the last request');
-
Используйте функционал "волшебного" метода
__get() брокера помощников - извлекайте
помощника так же, как если бы он был свойством этого брокера:
span style="color: #ff0000;">'We did something in the last request');
-
И наконец, большинство помощников действий реализует метод
direct() , который будет вызывать особый,
используемый по умолчанию метод в помощнике. Например, в
случае FlashMessenger будет вызван метод
addMessage() :
span style="color: #ff0000;">'We did something in the last request');
Note:
Все примеры выше функционально эквивалентны.
Вы можете также явно инстанцировать помощников. Вы можете захотеть
сделать это, если используете помощника вне контроллера действий,
или если хотите передавать помощника брокеру для использования в
любых действиях. Инстанцирование производится так же, как и для
любого другого класса PHP.
Брокер помощников
Zend_Controller_Action_HelperBroker управляет
регистрацией объектов помощников и путей к помощникам, а также
извлечением помощников по требованию.
Для того, чтобы зарегистрировать помощника через брокер, используйте
addHelper :
Само собой, инстанцирование и передача помощников брокеру отнимают
некоторое время и ресурсы, поэтому существуют два метода для
некоторой автоматизации: addPrefix() и
addPath() .
-
addPrefix() принимает префикс класса и
использует его для определения пути, по которому определен
класс помощника. Подразумевается, что префикс следует
соглашениям по именованию классов Zend Framework-а.
// Добавление помощников, начинающихся
// с My_Action_Helpers в My/Action/Helpers/
'My_Action_Helpers');
-
addPath() принимает директорию в качестве
первого аргумента и префикс класса в качестве второго (по
умолчанию это 'Zend_Controller_Action_Helper'). Это
позволяет поставить в соответствие определенным
директориям собственные префиксы классов.
// Добавление помощников, начинающихся с Helper в Plugins/Helpers/
'./Plugins/Helpers',
'Helper');
Поскольку эти методы статические, то они могут вызываться из любого
места в цепочке контроллеров для динамического добавления
помощников при необходимости.
Внутри себя брокер помощников использует экземпляр PluginLoader
для поддержки путей. Вы можете извлечь PluginLoader, используя
статический метод getPluginLoader() , или
добавить свой экземпляр PluginLoader, используя
setPluginLoader() .
Для определения того, есть ли помощник в брокере, используйте
hasHelper($name) , где $name - короткое
имя помощника без префикса:
// Проверка, зарегистрирован ли помощник 'redirector' в брокере:
'redirector''Redirector helper registered';
}
Есть также два статических метода для извлечения помощников из
брокера помощников: getExistingHelper() и
getStaticHelper() . getExistingHelper()
будет извлекать помощника только если он был ранее вызван или явно
зарегистрирован через брокер помощников, иначе бросается исключение.
getStaticHelper() делает то же самое, что и
getExistingHelper() , за тем исключением, что будет
пытаться инстанцировать помощника, если он еще не был
зарегистрирован в стеке помощников. getStaticHelper()
является хорошим выбором, если нужно извлечь помощника для конфигурирования.
Оба метода принимают единственный аргумент, $name,
который является коротким именем помощника (без префикса).
// Проверка, зарегистрирован ли помощник 'redirector' в брокере,
// и его извлечение:
'redirector''redirector');
}
// Или просто извлеките его, не заботясь о том,
// был ли он ранее зарегистрирован:
'redirector');
}
Наконец, для удаления зарегистрированного помощника из брокера
используйте removeHelper($name) , где $name
- короткое имя помощника без префикса:
// Удаление помощника 'redirector' из брокера, помещенное
// в условную конструкцию
'redirector''redirector')
}
Встроенные помощники действий
Zend Framework уже содержит в себе набор помощников действий:
AutoComplete автоматизирует ответы для автозавершения
ввода с использованием AJAX; ContextSwitch и
AjaxContext для обслуживания альтернативных форматов
ответов для ваших действий; FlashMessenger для
управления сессионными сообщениями; Json для
кодирования и отправки ответов JSON; Redirector ,
предоставляющий различные реализации перенаправления из вашего
приложения на внутренние и внешние страницы; и
ViewRenderer , автоматизирующий процесс настройки
объекта вида в контроллерах и рендеринга видов.
ActionStack
Помощник ActionStack позволяет добавлять в стек запросы к плагину
фронт-контроллера, именуемуму
ActionStack.
Это позволяет создать очередь из задач, планируемых к выполнению в ходе данного запроса.
Помощник ActionStack позволяет добавлять задачи как путем указания
новых объектов запроса, так и набора действие - контроллер - модуль.
Note: Вызов помощника ActionStack инициализирует плагин ActionStack
Вызов помощника ActionStack неявно регистрирует плагин
ActionStack, следовательно, нет необходимости
явным образом регистрировать плагин ActionStack
для использования данной функциональности.
Example #1 Добавление задачи с указанием имен действия, контроллера и модуля
Зачастую, проще всего указать имена действия, контроллера и модуля
(и прочие параметры запроса) таким же образом, как и при вызове
Zend_Controller_Action::_forward():
span style="color: #808080; font-style: italic;">// Добавить две задачи в стек
// Добавить вызов к /foo/baz/bar/baz
// (FooController::bazAction() со следующими переменными в запросе: bar = baz)
'baz',
'foo',
'default''bar' => 'baz'));
// Добавить вызов к /bar/bat
// (BarController::batAction())
'bat', 'bar');
}
}
Example #2 Добавление задачи с использованием нового объекта запроса
Иногда появляется необходимость работать с запросом как с объектом
(в лучших традициях ООП). В таком случае объект запроса
можно передать помощнику ActionStack при его вызове.
span style="color: #808080; font-style: italic;">// Добавить две задачи в стек
// Добавить вызов к /foo/baz/bar/baz
// (FooController::bazAction() со следующими
// переменными в запросе: bar = baz)
$request = clone $this->getRequest();
// Использовать текущие контроллер и модуль;
// установить новое действие - baz
$request->setActionName('baz''bar' => 'baz'// Добавить вызов к /bar/bat
// (BarController::batAction())
$request = clone $this->getRequest();
// Использовать текущий модуль; установить новый контроллер - bar
// и действие - bat
$request->setActionName('bat')
->setControllerName('bar'
AutoComplete
Многие JavaScript-библиотеки для AJAX предоставляют функционал для
автодополнения, с его помощью отображается список
возможных соответствий в то время, пока пользователь набирает текст.
Помощник AutoComplete предназначен для облегчения возврата
допустимых ответов для функционала такого рода.
Поскольку не все JavaScript-библиотеки реализуют автодополнение
одинаково, то помощник AutoComplete предоставляет в
абстрактном классе некоторый базовый функционал, необходимый для
большинства библиотек, и конкретные реализации для отдельных библиотек.
Возвращаемые данные в
основном - JSON-массивы строк, JSON-массивы массивов (в которых каждый
массив-член является ассоциативным массивом метаданных, используемых при
создании списка), либо HTML.
Базовое использование одинаково для всех реализаций:
span style="color: #808080; font-style: italic;">// Выполнение некоторой логики...
// Кодирование и отправка ответа:
// То же самое явным образом:
// Или просто подготовьте ответ для автодополнения:
По умолчанию этот помощник делает следующее:
Отключает макеты и ViewRenderer.
Устанавливает необходимые заголовки ответа.
Устанавливает тело ответа с закодированными данными в нужном
формате для автодополнения.
Отправляет ответ.
Доступные методы помощника включают в себя:
disableLayouts() может использоваться для
отключения макетов и ViewRenderer. Обычно он вызывается в
prepareAutoCompletion() .
encodeJson($data, $keepLayouts = false) будет
кодировать данные в формат JSON, при этом можно опционально
включать или отключать макеты. Обычно этот метод вызывается в
prepareAutoCompletion() .
prepareAutoCompletion($data, $keepLayouts = false)
используется для подготовки ответа в формате, необходимом для
конкретной реализации, при этом можно опционально включать или
отключать макеты. Возвращаемое значение может варьироваться в
зависимости от используемой реализации.
sendAutoCompletion($data, $keepLayouts = false)
используется для отправки данных в формате, необходимом для
конкретной реализации. Он вызывает
prepareAutoCompletion() и затем отправляет ответ.
direct($data, $sendNow = true, $keepLayouts =
false)
используется, когда помощник вызывается как метод брокера
помощников. Флаг $sendNow используется для
определения того, какой метод вызывать -
sendAutoCompletion() или
prepareAutoCompletion() . По умолчанию ответ
отправляется сразу.
В настоящее время AutoComplete поддерживает AJAX-библиотеки
Dojo и Scriptaculous.
Автодополнение c Dojo
В Dojo нет собственно виджета для автодополнения, но есть два
виджета, которые могут производить автодополнение: ComboBox и
FilteringSelect. В обоих случаях они требуют использования хранилища
данных, который реализует QueryReadStore, читайте документацию по
» dojo.data для получения более подробной информации по этой теме.
В Zend Framework вы можете передавать простой индексный массив для
помощника AutoCompleteDojo, и он будет возвращен в формате,
пригодном для использования с хранилищем в Dojo:
// в контроллере действий:
Example #3 Автодополнение с Dojo и Zend MVC
Автодополнение с Dojo через Zend MVC требует реализации
нескольких вещей:
генерация объекта формы для того ComboBox, для которого нужно
реализовать автодополнение, действие контроллера для
обслуживания автодополнения, создание своего QueryReadStore для
связи с этим действием и генерация javascript-кода для
инициализации автодополнения.
Для начала рассмотрим, что нужно сделать по части
javascript. Dojo представляет собой полный фреймворк для
создания объектно-ориентированного кода на языке JavaScript,
почти так же, как Zend Framework на языке PHP. Он позволяет
создавать псевдопространства имен, используя для этого иерархию
директорий. Создадим директорию 'custom' на том же уровне,
что и директория Dojo. В этой директории создадим файл
TestNameReadStore.js со следующим содержимым:
span style="color: #3366CC;">"custom.TestNameReadStore""custom.TestNameReadStore""fetch", arguments);
}
});
Этот класс просто наследует от класса QueryReadStore фреймворка
Dojo, который сам по себе является абстрактным. Мы просто
определяем метод, по которому производится запрос, и присваиваем
его элементу 'test'.
Далее создадим элемент формы, для которого хотим реализовать
автодополнение:
span style="color: #ff0000;">'get''/test/process''test''type' => 'text', 'options''filters''StringTrim'),
'dojoType''dijit.form.ComboBox'),
'store' => 'testStore',
'autoComplete' => 'false',
'hasDownArrow' => 'true',
'label' => 'Your input:',
)),
'go''type' => 'submit',
'options''label' => 'Go!'
Здесь мы просто создаем форму с методами 'test' и 'go'. Метод
'test' добавляет несколько специальных, специфических для Dojo
атрибутов: dojoType, store, autoComplete и hasDownArrow. Через
'dojoType' мы указываем, что создается ComboBox, он связан
с хранилищем данных (ключ 'store') 'testStore'. Устанавливая
'autoComplete' в false, мы говорим Dojo, чтобы он не выбирал
автоматически первое соответствие, а вместо этого показывал
список соответсвий. Наконец, 'hasDownArrow' создает стрелку
наподобие той, что присутствует в выпадающем списке, чтобы можно
было выводить и убирать список соответствий.
Добавим метод для отображения формы и действие для обработки
автодополнения:
span style="color: #808080; font-style: italic;">// ...
/**
* Страница с формой
*/'ajax''format''index''index''test', ''
В методе autocompleteAction() мы делаем несколько
вещей. Сначала мы проверяем, был ли произведен POST-запрос и
имеет ли параметр 'format' значение 'ajax', это помогает
отсечь большинство ложных запросов. Далее мы получаем
параметр 'test' и сравниваем его с нашими данными (здесь я
намеренно опустил реализацию метода getData() ,
источники данных могут быть любыми). В конце выполнения
передаем найденные соответствия помощнику AutoCompletion.
Теперь на очереди написание скрипта вида для страницы с формой.
В нем нужно установить хранилище данных, вывести
форму и подключить все необходимые библиотеки
Dojo, включая наше хранилище данных. Ниже приведен
скрипт вида с комментариями:
span style="color: #808080; font-style: italic;">// установка хранилища данных: ?>
"custom.TestNameReadStore" jsId="testStore"
url="<?php echo $this->baseUrl() ?>/unit-test/autocomplete/format/ajax"
requestMethod="get"// рендеринг формы: ?>
// подключение CSS для Dojo в HTML-заголовке: ?>
"<?php echo $this->baseUrl()
?>/javascript/dijit/themes/tundra/tundra.css";
@import "<?php echo $this->baseUrl() ?>/javascript/dojo/resources/dojo.css"// подключение javascript в HTML-заголовке, включая все
// необходимые библиотеки для Dojo: ?>
'/javascript/dojo/dojo.js',
'text/javascript''djConfig' => 'parseOnLoad: true'"custom","../custom""dojo.parser""dojox.data.QueryReadStore""dijit.form.ComboBox""custom.TestNameReadStore"
Обратите внимание на вызовы помощников видов, таких, как
headStyle м headScript, - это метки заполнения, которые могут
затем рендериться в HTML-заголовке скрипта макета.
Теперь у нас есть всё для того, чтобы автодополнение с Dojo заработало.
Автодополнение с Scriptaculous
» Scriptaculous
ожидает HTML-ответ в определенном формате.
С этой библиотекой используется помощник
'AutoCompleteScriptaculous'.
Просто передавайте ему массив данных, и он создает ответ HTML,
совместимый с Ajax.Autocompleter.
ContextSwitch и AjaxContext
Помощник действий ContextSwitch предназначен для облегчения
возврата ответов в различных форматах.
Помощник AjaxContext является специализированной версией
ContextSwitch , которая облегчает возврат ответа на запросы,
произведенные посредством XmlHttpRequest.
Для того, чтобы включить использование какого-либо из этих помощников,
нужно указать в своем контроллере, какие действия могут отвечать в каком
контексте. Если входящий запрос означает допустимый контекст для данного
действия, то помощник производит следующие действия:
Выключает макеты, если они включены.
Устанавливает альтернативный суффикс вида, это позволяет эффективно
разделять скрипты видов для различных контекстов.
Отправляет HTTP-заголовки ответа, требуемые в данном контексте.
Опционально вызывает предопределенные функции обратного вызова для
установки контекста и/или пост-обработки.
В качестве примера рассмотрим следующий контроллер:
span style="color: #808080; font-style: italic;">/**
* Начальная страница, производится переход к listAction()
*/'list');
}
/**
* Выводит список новостей
*//**
* Просмотр одной новости
*/
Предположим, нам нужно, чтобы действие listAction() было
доступно и в формате XML. Вместо того, чтобы создавать новое действие,
мы можем указать, что действие listAction() может
возвращать и ответ в формате XML:
span style="color: #ff0000;">'contextSwitch''list', 'xml')
->initContext();
}
// ...
}
Этим будет:
Установлен заголовок ответа 'Content-Type' со значением
'text/xml'.
Изменено значение суффикса вида на 'xml.phtml' (или
'xml.[your suffix]', если вы используете другой суффикс вида).
Теперь нужно создать новый скрипт вида - 'news/list.xml.phtml',
в котором формируется код XML.
Для определения того, нужно ли переключение контекста,
помощник проверяет метку в объекте запроса. По умолчанию он
проверяет параметр 'format', но это поведение может быть изменено.
Это значит, что в большинстве случаев для того, чтобы инициировать
переключение контекста, достаточно добавить параметр 'format' в
запрос одним из двух способов:
Через параметр URL: /news/list/format/xml
(напоминаем, используемый по умолчанию механизм маршрутизации
разрешает добавление произвольных пар ключ/значение после
имени действия в URL)
Через параметр GET: /news/list?format=xml
ContextSwitch позволяет задавать любой контекст, включая
используемый суффикс вида, отправляемые заголовки ответа и функции
обратного вызова для инициализации и пост-обработки.
Доступные по умолчанию контексты
По умолчанию через помощник ContextSwitch используются
два контекста: json и xml.
-
JSON. Контекст JSON устанавливает
заголовок ответа 'Content-Type' в значение
'application/json' и суффикс скрипта вида в значение
'json.phtml'.
Но по умолчанию использование скриптов вида не обязательно.
Контекст просто сериализует все переменные вида и сразу
возвращает ответ в формате JSON.
Это поведение может быть отменено путем отключения
автоматической сериализации JSON:
-
XML. Контекст XML устанавливает
заголовок ответа 'Content-Type' в значение 'text/xml' и
суффикс скрипта вида в значение 'xml.phtml'. Для этого
контекста нужно создавать скрипты вида.
Создание своего контекста
Иногда доступных по умолчанию контекстов может быть недостаточно.
Например, нужно возвращать данные в формате YAML, сериализованный
PHP, ленты RSS, ATOM и т.д. ContextSwitch позволяет
добавлять новые контексты.
Наиболее простым способом добавления нового контекста является
использование метода addContext() . Этот метод
принимает два аргумента - имя контекста и массив спецификации.
Массив должен включать в себя один или более элементов
из следующих:
-
suffix: суффикс, который должен
добавляться перед суффиксом, зарегистрированным во
ViewRenderer.
-
headers: массив пар
заголовок/значение, которые требуется отправлять в
ответе.
-
callbacks: массив, который содержит
ключи 'init' и 'post' (один из них или оба).
Ключи должны указывать на действующие функции обратного вызова,
которые могут использоваться для инициализации и пост-обработки
контекста.
Вызов функции инициализации производится сразу после
того, как контекст определен помощником
ContextSwitch . Вы можете использовать его для
выполнения произвольной логики. Например, контекст JSON
использует функцию обратного вызова для отключения
ViewRenderer, если включена автоматическая сериализация
JSON.
Вызов функции пост-обработки производится во время
операции postDispatch() и может использоваться для
выполнения произвольной логики. Например, контекст JSON
использует функцию обратного вызова для определения того,
включена ли автоматическая сериализация JSON; если включена, то
помощник сериализует переменные вида в JSON и отправляет ответ,
иначе включается ViewRenderer.
Для взаимодействия с контекстом есть несколько методов:
addContext($context, array $spec) : добавляет новый
контекст. Бросает исключение, если контекст уже существует.
setContext($context, array $spec) : добавляет новый
контекст или переопределяет существующий. Использует ту же
спецификацию, что и addContext() .
addContexts(array $contexts) : добавляет несколько
контекстов одновременно. Массив $contexts должен
содержать пары контекст/спецификация. Если какой-либо из
контекстов уже существует, то бросается исключение.
setContexts(array $contexts) : добавляет новые
контексты и переопределяет существующие. Использует ту же
спецификацию, что и addContexts() .
hasContext($context) : если контекст с этим именем
уже существует, то метод возвращает true, иначе false.
getContext($context) : возвращает контекст по его
имени в виде массива, следующего спецификации, используемой
в addContext() .
getContexts() : возвращает все контексты в виде
массива пар контекст/спецификация.
removeContext($context) : удаляет контекст
по его имени. Возвращает true в случае успеха, false - если
контекст не найден.
clearContexts() : удаляет все контексты.
Установка контекстов для действий
Есть два способа установки доступных для действий контекстов.
Вы можете либо вручную создавать массивы в своем контроллере, либо
использовать несколько методов в ContextSwitch для
"сборки" таких массивов.
addActionContext() является основным методом для
добавления связей действие/контекст. Он принимает два аргумента:
действие, к которому добавляется контекст, и имя контекста (либо
массив контекстов). Для примера рассмотрим следующий класс
контроллера:
Предположим, что мы хотим добавить контекст XML к действию 'list',
а к действию 'comments' - контексты XML и JSON. В этом случае мы
можем добавить следующий код в метод init() :
span style="color: #ff0000;">'list', 'xml')
->addActionContext('comments''xml', 'json'))
->initContext();
}
}
Мы можем также просто определить свойство $contexts
в контроллере:
span style="color: #ff0000;">'list''xml'),
'comments''xml', 'json'
Этот способ менее трудоемкий, но заключает в себе больше
потенциальных ошибок.
Следующие методы могут использоваться для построения связей
действие/контекст:
-
addActionContext($action, $context) : помечает
один или более контекстов как доступные для действия
$action. Если связи уже существуют, то производится
добавление к ним. $context может быть как
одним контекстом, так и массивом контекстов.
Если $context имеет значение TRUE,
то все доступные в ContextSwitch контексты
помечаются как доступные для действия.
Пустое значение аргумента $context отключит
все контексты для данного действия.
setActionContext($action, $context) : помечает
один или более контекстов как доступные для действия
$action. Если связи уже существуют, то метод заменяет их
указанными.
$context может быть как одним контекстом, так и
массивом контекстов.
addActionContexts(array $contexts) : добавляет
одновременно несколько пар действие/контекст.
$contexts должен быть ассоциативным массивом
пар действие/контекст. Использует метод
addActionContext() , это означает, что если
связи для данного действия уже существуют, то указанные в
$contexts связи добавляются к ним.
setActionContexts(array $contexts) : действует
аналогично addActionContexts() , но
переопределяет пары действие/контекст, если они уже
существуют.
hasActionContext($action, $context) :
используется для определения того, имеет ли действие $action
данный контекст.
getActionContexts($action = null) : возвращает
все контексты для действия $action или все пары
действие/контекст.
removeActionContext($action, $context) :
удаляет один или более контекстов из действия $action.
$context может быть как
одним контекстом, так и массивом контекстов.
clearActionContexts($action = null) : удаляет
все контексты из действия $action или из всех
действий с контекстами.
Инициализация переключения контекста
Для того, чтобы инициализировать переключение контекста, необходимо
вызвать метод initContext() в контроллере действий:
В некоторых случаях может потребоваться принудительное использование
контекста - например, использовать только контекст XML, если
переключение контекста включено. Вы можете осуществить это
передачей контекста методу initContext() :
span style="color: #ff0000;">'xml');
Дополнительный функционал
Для управления помощником ContextSwitch могут
использоваться различные методы. Эти методы включают в себя:
-
setAutoJsonSerialization($flag) : По умолчанию
контекст JSON будет сериализовать все переменные вида
согласно нотации JSON и возвращать их в качестве ответа.
Если вы хотите самостоятельно формировать ответ, то должны
отключить автоматическую сериализацию через данный метод;
это нужно делать до вызова initContext() .
Вы можете получить значение этого флага через метод
getAutoJsonSerialization() .
-
setSuffix($context, $suffix,
$prependViewRendererSuffix) : Используя этот
метод, вы можете задать другой суффикс для использования в
контексте $context. Третий аргумент используется для
указания того, добавлять ли или нет суффикс из
помощника ViewRenderer к новому суффиксу; этот флаг
установлен по умолчанию.
Передача пустого значения в качестве суффикса приведет к
тому, что будет использоваться только суффикс из
ViewRenderer.
-
addHeader($context, $header, $content) :
Добавляет заголовок ответа для контекста $context.
$header является именем заголовка, а
$content - значением для этого заголовка.
Любой контекст может иметь несколько заголовков.
addHeader() добавляет дополнительные
заголовки в стек заголовков для данного контекста.
Если переданный заголовок уже существует для данного
контекста, то бросается исключение.
-
setHeader($context, $header, $content) :
setHeader() действует аналогично
addHeader() за исключением того, что позволяет
переопределять существующие для данного контекста заголовки.
-
addHeaders($context, array $headers) :
Добавляет несколько заголовков к контексту $context.
Использует addHeader() , поэтому
если заголовок уже существует, то бросается исключение.
$headers является массивом пар
заголовок/значение.
-
setHeaders($context, array $headers.) :
действует аналогично addHeaders() за
исключением того, что использует setHeader() ,
что позволяет перезаписывать существующие заголовки.
-
getHeader($context, $header) : возвращает
значение заголовка для данного контекста. Если заголовок
не найден, то возвращается null.
-
removeHeader($context, $header) : удаляет
один заголовок для данного контекста.
-
clearHeaders($context) : удаляет все
заголовки для данного контекста.
-
setCallback($context, $trigger, $callback) :
устанавливает функцию обратного вызова для триггера $trigger
и контекста $context. Триггерами могут быть 'init' или
'post' (выбор триггера определяет, когда будет вызвана
функция - во время инициализации контекста или операции
postDispatch() ). $callback должен
быть действующей PHP-функцией обратного вызова.
-
setCallbacks($context, array $callbacks) :
устанавливает несколько функций обратного вызова для
данного контекста. $callbacks должен быть
массивом пар триггер/функция обратного вызова. В
действительности можно зарегистрировать максимум две
функции обратного вызова, одна для инициализации, другая для
пост-обработки.
-
getCallback($context, $trigger) : возвращает
функцию обратного вызова для триггера $trigger и контекста
$context.
-
getCallbacks($context) : возвращает все функции
обратного вызова в виде массива пар триггер/функция
обратного вызова.
-
removeCallback($context, $trigger) : удаляет
функцию обратного вызова для триггера $trigger и контекста
$context.
-
clearCallbacks($context) : удаляет все функции
обратного вызова для данного контекста.
-
setContextParam($name) : устанавливает параметр
запроса, используемый для переключения контекста. По
умолчанию установлено значение 'format', но его можно
изменить с помощью данного аксессора.
getContextParam() может использоваться для
получения текущего значения.
-
setAutoDisableLayout($flag) : По умолчанию
макеты отключаются, когда производится переключение
контекста. Это потому, что макеты, как правило, используются
только с обычным выводом и их использование не имеет смысла
для альтернативного контекста. Тем не менее, если вы хотите
использовать макеты, то можете изменить это поведение,
передав значение FALSE методу
setAutoDisableLayout() . Вы должны делать это
до вызова initContext() .
Для получения значения этого флага используйте аксессор
getAutoDisableLayout() .
-
getCurrentContext() может использоваться
для определения того, какой контекст был установлен.
Возвращает null, если не было переключения контекста,
или метод был вызван до initContext() .
Функционал AjaxContext
Помощник AjaxContext наследует от
ContextSwitch , поэтому весь функционал, описанный
для ContextSwitch , доступен и для него. Но есть
несколько ключевых отличий.
Во-первых, он использует другое свойство контроллера для
определения контекстов, а именно $ajaxable. Поэтому вы
можете одновременно использовать различные контексты для AJAX и
обычных HTTP-запросов. Все методы
*ActionContext*() помощника AjaxContext
будут записывать в это свойство.
Во-вторых, он будет запускаться только тогда, когда производится
запрос XmlHttpRequest. Для определения того, был ли произведен
запрос XmlHttpRequest, используется метод
isXmlHttpRequest() объекта запроса.
Таким образом, если параметр контекста ('format') был передан в
запросе, но сам запрос был произведен не через
XmlHttpRequest, то не будет произведено переключение контекста.
И в-третьих, AjaxContext добавляет дополнительный
контекст - HTML. В этом контексте он устанавливает суффикс в
значение 'ajax.phtml' для отделения этого контекста от обычных
запросов. Дополнительные заголовки не возвращаются.
Example #4 Установка действий для ответов на AJAX-запросы
В следующем примере мы указываем, что действия 'view', 'form' и
'process' могут отвечать на AJAX-запросы. В действиях
'view' и 'form' мы будем возвращать куски HTML-кода для
обновления страницы, в действии 'process' - данные в формате
JSON.
span style="color: #ff0000;">'AjaxContext');
$ajaxContext->addActionContext('view', 'html')
->addActionContext('form', 'html')
->addActionContext('process', 'json'// Извлекает один комментарий для просмотра
// Если определен контекст AjaxContext, то используется
// скрипт вида comment/view.ajax.phtml
// Рендерит форму для добавления нового комментария
// Если определен контекст AjaxContext, то используется
// скрипт вида comment/form.ajax.phtml
// Обрабатывает новый комментарий
// Возвращает результат в формате JSON. Просто присвойте значения
// переменным вида и эти значения будет возвращены в формате JSON.
}
}
На клиентской стороне посредством AJAX-библиотеки производятся
запросы к конечным точкам '/comment/view',
'/comment/form', '/comment/process' и передается параметр
'format': '/comment/view/format/html',
'/comment/form/format/html', '/comment/process/format/json'
(можно также передавать параметр
через строку запроса, например: "?format=json").
Если ваша AJAX-библиотека передает заголовок 'X-Requested-With:
XmlHttpRequest', то эти действия будут возвращать ответ в
требуемом формате.
FlashMessenger
Введение
Помощник FlashMessenger позволяет передавать сообщения,
которые требуется отобразить пользователю при следующем запросе.
Это достигается путем сохранения сообщений в
Zend_Session_Namespace, откуда они могут быть получены при
последующих запросах. Если вы планируете использовать
Zend_Session или Zend_Session_Namespace,
имеет смысл инициализировать сессию еще в файле загрузки командой
Zend_Session::start(). (Подробнее о работе с сессиями в
документации к
Zend_Session)
Пример использования
Нижеприведенный пример иллюстрирует самое простое использование помощника
FlashMessenger. При вызове действия /some/my
добавляется сообщение "Запись сохранена!". При последующем вызове действия
/some/my-next-request это сообщение будет
получено из сессии (сразу после этого удалено) и отображено пользователю.
span style="color: #808080; font-style: italic;">/**
* FlashMessenger
*
* @var Zend_Controller_Action_Helper_FlashMessenger
*/'FlashMessenger'/**
* метод для получения экземпляра помощника
* Zend_Controller_Action_Helper_FlashMessenger
*/'Запись сохранена!'
JSON
Ответы в формате JSON становятся все более популярными
для работы с AJAX запросами, которые предполагают отправку
и получение массивов данных; JSON может быть немедленно
обработан на стороне клиента, что существенно ускоряет выполнение скриптов.
Помощник действий JSON выполняет несколько функций:
-
Отключает макеты, если они включены.
-
Альтернативно, можно передавать массив параметров, который будет использован
в качестве второго аргумента для Zend_Json::encode().
Передавая массив параметров, можно включить макеты и кодирование
с использованием Zend_Json_Expr.
span style="color: #ff0000;">'enableJsonExprFinder'
-
Отключает ViewRenderer, если он включен.
-
Присваивает заголовку ответа 'Content-Type' значение
'application/json'.
-
По умолчанию немедленно возвращает ответ, не дожидаясь завершения
выполнения действия.
Использование: помощник может быть вызван как метод брокера помощников действий
или посредством вызова одного из его методов encodeJson()
или sendJson():
span style="color: #808080; font-style: italic;">// выполнить некоторые действия...
// отправить ответ в формате JSON
// или...
// или получить ответ в формате json:
Note: Использование макетов
В случае необходимости использования макета для возвращения ответов
в формате JSON (например, для возвращения JSON
как части некоторого контекста), при вызове любого из методов помощника
JSON нужно передавать второй, необязательный, аргумент:
флаг для включения/отключения макетов. Передача булевого значения
TRUE оставит макеты включенными:
Альтернативно, в качестве второго аргумента можно передавать массив параметров,
среди которых и keepLayouts:
span style="color: #ff0000;">'keepLayouts'
Note: Включение кодирования с использованием Zend_Json_Expr
Метод Zend_Json::encode() позволяет кодировать "родные"
JSON выражения при помощи объектов класса
Zend_Json_Expr. По умолчанию эта возможность отключена.
Для того, чтоб ее включить, нужно передать параметр
enableJsonExprFinder со значением TRUE:
span style="color: #ff0000;">'enableJsonExprFinder'
Для использования описанной возможности необходимо передавать
массив в качестве второго аргумента. Кроме указанного параметра, в массив
можно включить и другие, к примеру keepLayouts.
Все параметры из этого массива будут переданы как аргумент при вызове
Zend_Json::encode().
span style="color: #ff0000;">'enableJsonExprFinder''keepLayouts'
Redirector
Введение
Помощник Redirector позволяет использовать объект
Redirector для удовлетворения нужд в перенаправлении на
новые URL. Он имеет многие преимущества по сравнению с методом
_redirect() , такие, как возможность предварительной
конфигурации поведения на стороне сайта в объекте Redirector или
использование встроенного интерфейса
gotoSimple($action, $controller, $module, $params) , подобного
интерфейсу Zend_Controller_Action::_forward() .
Redirector имеет набор методов, которые могут
использоваться для управления поведением при перенаправлении:
-
setCode() может использоваться для установки
кода ответа HTTP, используемого при перенаправлении.
-
setExit() может использоваться для установки
принудительного вызова exit() после
перенаправления. По умолчанию он установлен в true.
-
setGotoSimple() может использоваться для
установки URL, используемого по умолчанию, если методу
gotoSimple() не был передан URL. Использует
интерфейс
Zend_Controller_Action::_forward() :
setGotoSimple($action, $controller = null, $module = null, array
$params = array());
-
setGotoRoute() может использоваться для
установки URL, основываясь на зарегистрированном маршруте.
Ему должен передаваться массив пар ключ/значение и имя
маршрута, из них будет собран URL в соответствии с типом и
определением маршрута.
-
setGotoUrl() может использоваться для установки
URL, используемого по умолчанию, если методу
gotoUrl() не был передан URL. Принимает единственную строку URL в качестве аргумента.
-
setPrependBase() может использоваться для
добавления базового URL объекта запроса в начало URL,
заданного через методы setGotoUrl() ,
gotoUrl() , или
gotoUrlAndExit() .
-
setUseAbsoluteUri() может использоваться для
принуждения Redirector -а применять
абсолютные URI при произведении перенаправления. Когда эта
опция установлена, то используются значения
$_SERVER['HTTP_HOST'],
$_SERVER['SERVER_PORT'] и
$_SERVER['HTTPS'] для формирования полного URI
из URL, определенного одним из методов перенаправления. Эта
опция по умолчанию отключена, но может быть включена по
умолчанию в последующих релизах.
Кроме этого, в Redirector есть различные методы, выполняющие текущие
перенаправления:
-
gotoSimple() использует
setGotoSimple() (интерфейс, подобный
_forward() ) для построения
URL и перенаправления на него.
-
gotoRoute() использует
setGotoRoute() (сборка маршрута) для построения
URL и перенаправления на него.
-
gotoUrl() использует setGotoUrl()
(строка URL) для построения URL и перенаправления на него.
Наконец, можно в любое время получить текущий URL для
перенаправления, используя getRedirectUrl() .
Базовые примеры использования
Example #5 Опции настройки
В этом примере переопределяются несколько опций, включая
код статуса HTTP, используемого при перенаправлении
(303), и определение URL, используемое по умолчанию при
перенаправлении.
span style="color: #808080; font-style: italic;">/**
* Редиректор - определен для полноты кода
*
* @var Zend_Controller_Action_Helper_Redirector
*/'Redirector');
// Установка опций по умолчанию для редиректора
// Поскольку объект зарегистрирован в брокере помощников,
// то эти опции будут действительными для всех
// последующих действий
"this-action",
"some-controller"/* делаем что-то */
// Перенаправление на ранее зарегистрированный URL и
// принудительное завершение исполнения скрипта:
// никогда не будет достигнуто
}
}
Example #6 Использование по умолчанию
Этот пример предполагает, что используются значения по
умолчанию, это означает, что после любых перенаправлений будет
производиться выход exit() .
// АЛЬТЕРНАТИВНЫЙ ПРИМЕР
/**
* Редиректор - определен для полноты кода
*
* @var Zend_Controller_Action_Helper_Redirector
*/'Redirector'/* делаем что-то */'/my-controller/my-action/param1/test/param2/test2');
// это место никогда не будет достигнуто,
// т.к. по умолчанию производится переход и завершение выполнения
Example #7 Использование интерфейса _forward() для gotoSimple()
Метод gotoSimple() копирует интерфейс метода
Zend_Controller_Action::_forward() . Основное
отличие состоит в том, что он строит URL из переданных
параметров и использует формат
:module/:controller/:action/* маршрутизатора по
умолчанию. Затем он производит перенаправление вместо добавления
действия в цепочку.
span style="color: #808080; font-style: italic;">/**
* Редиректор - определен для полноты кода
*
* @var Zend_Controller_Action_Helper_Redirector
*/'Redirector'/* Делаем что-то */
// Перенаправление на действие 'my-action' контроллера 'my-controller'
// в текущем модуле с использованием параметров param1 => test и
// param2 => test2
'my-action',
'my-controller''param1' => 'test',
'param2' => 'test2'
)
);
}
}
Example #8 Использование маршрута с gotoRoute()
Следующий пример использует метод assemble()
маршрута для
создания URL, основанного на переданном ассоциативном массиве
параметров. Этот пример предполагает, что был зарегистрирован
следующий маршрут:
span style="color: #ff0000;">'blog/:year/:month/:day/:id''controller' => 'archive',
'module' => 'blog',
'action' => 'view')
);
$router->addRoute('blogArchive', $route);
При заданном массиве, в котором year (год), month (месяц), и day
(день) установлены в 2006, 4 и 24 соответственно, будет построен
URL /blog/2006/4/24/42 .
span style="color: #808080; font-style: italic;">/**
* Редиректор - определен для полноты кода
*
* @var Zend_Controller_Action_Helper_Redirector
*/'Redirector'/* делаем что-то */
// Перенаправление в архив блога. Строит URL
// /blog/2006/4/24/42
'year' => 2006,
'month' => 4,
'day' => 24,
'id' => 42),
'blogArchive'
);
}
}
ViewRenderer
Введение
Помощник ViewRenderer предназначен для решения
следующих задач:
-
Устранение необходимости инстанцирования объектов вида
внутри контроллеров; объекты вида будут автоматически
регистрироваться вместе с контроллером.
-
Автоматическая установка путей к скриптам вида, помощникам
и фильтрам, основанная на текущем модуле, и автоматическое
присоединение имени текущего модуля в качестве префикса имен
классов помощников и фильтров.
-
Создание глобально доступного объекта вида для всех
запускаемых контроллеров и действий.
-
Возможность устанавливать используемые по
умолчанию опции рендеринга для всех контроллеров.
-
Возможность автоматического рендеринга скрипта
вида, не требующего от разработчика каких-либо действий.
-
Возможность создавать собственные спецификации базового пути
вида и путей к скриптам видов.
Note:
Если вы вручную производите _forward() ,
перенаправление или render , то авторендеринг не
будет произведен, поскольку выполнение любых этих операций
говорит помощнику ViewRenderer , что вы определили
свой собственный вывод.
Note:
ViewRenderer включен по умолчанию. Вы можете
отключить его через параметр фронт-контроллера
noViewRenderer
($front->setParam('noViewRenderer', true)) или
посредством удаления помощника из стека брокера помощников
(Zend_Controller_Action_HelperBroker::removeHelper('viewRenderer') ).
Если вы хотите изменить настройки ViewRenderer до
начала диспетчеризации, то можете сделать это одним из двух
способов:
|
|