Events: события

В ТАО реализована система событий (модуль Events), описывающая стандартный механизм событий в ООП. Что позволяет достаточно быстро внедрять дополнительный функционал в существующий код.

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

Генерация событий

Генерация события производится с использованием метода Events::call().

Events::call('name.of.event', $arg1, $arg2);

где,

  • name.of.event - имя события, строковое значение.
  • $arg1, $arg2 - аргументы, которые будут переданы в обработчик.

При формировании имен событий, для поддержания единообразия, желательно придерживаться сложившегося правила именования событий во фреймворке. А именно, если событие будет генерироваться в рамках компонента, то в имени указывается ключевое слово component и имя компонента, далее идет название модуля (где будет генерироваться событие), название действия. Если событие относится к библиотеке, то в имени должно быть указано ключевое слово CMS .

Например,

component.comments.before.add - компонент Комментарии, вызов события, позволяющего произвести какие-то действия до записи комментария в базу

cms.actions.dispatch - библиотечное событие. Вызывается перед началом диспетчеризации запроса.

Обработка событий

Как правило, в проектах редко возникает необходимость генерировать события. Основное место генерации в ядре фреймворка, в CMS, в библиотечных компонентах. На проектах часто осуществляется только обработка событий. Для этого применяется метод Events::add_listener(), с помощью которого можно подписаться на то или иное событие и повесить на него обработчик.

Events::add_listener('name.of.event', 'my_listener'); //подписываемся на событие name.of.event и вешаем на него функцию my_listener

function my_listener($arg1,$arg2)
{
	// ... здесь какой-то код
}

На одно событие можно повесить и несколько обработчиков - просто вызвав несколько раз Events::add_listener. Второй параметр - это callback, поэтому мы можем использовать в качестве обработчиков методы классов, а начиная с PHP 5.3 - и безымянные функции.

// безымянная функция в качестве аргумента
Events::add_listener('name.of.event', function($arg1, $arg2) {
	// ... здесь какой-то код
});

Есть возможность указать в качестве обработчика функцию из еще не загруженного модуля.

// метод класса в качестве аргумента
Events::add_listener('name.of.event', 'App.MyModule::listener');

В этом случае при вызове события модуль App.MyModule будет автоматически подгружен, и в нем будет вызван статический метод listener().

Отдельный вопрос - где располагать описание обработчиков. С технической стороны нет ограничений, соответственно вызов можно организовать в любом месте кода. Здесь важно придерживаться здравого смысла.

1. Регистрация события и реализация метода (функции), который будет вызван при наступлении события в одном месте.

Например, для вывода дополнительного поля в админке для списка записей, необходимо подписаться на событие nodus.admin.items.on_row. Для этого в описании дататайпа подпишемся на данное событие и здесь же, в классе дататайпа, опишем метод, реализующий вывод поля в списке.

// Nodus/app/Datatype/Cat/Type.php

Events::add_listener(
	'nodus.admin.items.on_row',
	'Component.Nodus.App.Datatype.Cat.Type::on_row'
);
class Component_Nodus_App_Datatype_Cat_Type extends Component_Nodus_Datatype implements Core_ModuleInterface
{
	...
	public static function on_row($row, $controller)
	{
		if ($row->datatype()->mnemocode() == 'cat') {
			$term = Component_Nodus::taxonomy_term($row->color);
			if ($term){
				$row->color = $term->field('title');
			}
			else{
				$row->color = '';
				}
		}
	}
}

2. Вынесение регистрации события в конфигурационные настройки компонента.

Все события внутри компонента можно вынести и зарегистрировать в конфигурационных настройках (/ComponentName/config/component.php). Для этого зарезервирована специальная настройка events.

// Nodus/config/component.php

return array(
	...
	'events' => array(
		'nodus.admin.items.on_row' => array(
			Component_Nodus::datatype('cat'), 'on_row'
		),
	),
);

3. Если событий много, правильнее будет, вообще вынести их в отдельный класс со всем описанием функций-обработчиков. Например, в папку app/lib/ проекта.

// app/lib/Events.php

class App_Events implements Core_ModuleInterface
{
	public static function initialize()
	{
		Events::add_listener('nodus.admin.items.on_row',
			array(Component_Nodus::datatype('cat'), 'on_row')

		);
	}
}

После этого не забываем подключить в index.php.

...
Core::load('App.Events');
...
CMS::Run();

Справочник событий ТАО

СобытиеПередаваемые аргументыОписание
cms.actions.dispatch($uri)
../tao/lib/CMS/Handlers.php
$uri - REQUEST_URIВызывается в методе run() перед началом диспетчеризации запроса. Обратившись к WS::env()->request, можно подменить что-либо в запросе, выполнить какие-либо действия, а также вернуть объект Net_HTTP_Response - в этом случае диспетчеризация даже не начнется, а будет использован возвращенный отклик.
cms.fields.{form_name}.{field_name}.after($parms)

cms.fields.admin.{$form_name}.{$field_name}.after($parms)

../tao/views/fields/layout-table.phtml
$parms - массив с дополнительной информацией о форме, поле, редактируемой сущности, исполняемом шаблонеВызывается в шаблоне layout-table после отрисовки поля средствами CMS.Fields. В качестве аргумента передается массив с дополнительной информацией.
Применяется в случае, если нужно дополнить отображение поля. Например, подключить дополнительный скрипт или CSS, вывести рядом с полем дополнительную информацию или контролы. Для администратора такое же событие вызывается с именем: cms.fields.admin.{$form_name}.{$field_name}.after.
cms.fspages.dirs($dirs)
../tao/lib/CMS/FSPages.php
$parms - массив с дополнительной информацией о форме, поле, редактируемой сущности, исполняемом шаблонеВызывается в шаблоне layout-table после отрисовки поля средствами CMS.Fields. В качестве аргумента передается массив с дополнительной информацией.
Применяется в случае, если нужно дополнить отображение поля. Например, подключить дополнительный скрипт или CSS, вывести рядом с полем дополнительную информацию или контролы. Для администратора такое же событие вызывается с именем: cms.fields.admin.{$form_name}.{$field_name}.after.
cms.fspages.realm($realm)
../tao/lib/CMS/Controller/FSPages.php
$realm - имя областиСобытие генерируется механизмом статических страниц (CMS.FSPages) в методе route() для уточнения списка каталогов, в которых ищутся шаблоны. При необходимости в список можно добавить свой каталог.
cms.initialize.ready
../tao/lib/CMS.php
Вызывается в конце инициализации метода initialize() при загрузке модуля CMS.
cms.initialize.start
../tao/lib/CMS.php
Вызывается в конце инициализации метода initialize() при загрузке модуля CMS.
cms.run
../tao/lib/CMS.php
Вызывается в методе before_run() после инициализации всех компонентов - в начале работы CMS::run().
cms.vars.change($var)

cms.vars.change.{$var_name}($var)

../tao/lib/CMS/Fields/Types/Image.php
$var - объект настройки перед сохранением
$var_name - мнемокод настройки
Вызывается непосредственно перед сохранением отдельной настройки (CMS.Vars) в методе save_var(). Позволяет обработать данные прежде, чем они будут сохранены, сбросить кеш, сгенерировать еще что-то и т.п. Для обработки данных какой-то конкретной настройки необходимо вешать обработчик на событие вида cms.vars.change.{$var_name}.
admin.change
../tao/lib/CMS/Fields/Types/Image.php
Вызывается в методе '''action_list()''' после определенных действий с записями (изменение, добавление, удаление, массовое изменение). Для методов action_add(), action_edit(), action_delete() в событие admin.change($item) в качестве аргумента передается объект записи в базу данных.
cms.table.access($action, $item)
../tao/lib/CMS/Controller/Table.php
$action - выполняемое действие (edit, add, delete и др.)
$item - объект записи в таблице
Вызывается событие в методе access() для проверки доступа к какой-либо операции над объектом записи. Данное событие является общим для всех действий. Если необходимо вызвать событие для конкретной операции, то доступны события cms.tables.access.edit, cms.table.access.delete, cms.table.access.add и др.
При определении своего метода типа '''action_имя_действия''' будет работать событие вида cms.table.access.имя_действия.
cms.table.tabs($tab, $data, $action, $item)
../tao/lib/CMS/Controller/Table.php
$tab - имя вкладки
$data - настройки вкладки из массива $form_tabs
$action - выполняемое действие (edit, add, delete и др.)
$item - объект записи в таблице
Событие вызывается в методе access_tab() и связано с проверкой доступа на отображение вкладки формы редактирования.
cms.add_component($name, $mapper, $layout)
../tao/lib/CMS/Controller/Table.php
$name - имя компонента
$mapper - экземпляр роутера
$layout - шаблон обрамления
Вызывается при регистрации компонента в методе add_component() и позволяет внедрить требуемый функционал сразу после регистрации компонента в системе.
cms.add_component_object($obj, $mapper, $layout)
../tao/lib/CMS.php
$obj - объект компонента
$mapper - экземпляр роутера
$layout - шаблон обрамления
Вызывается в методе add_component_object(). Позволяет внедрить требуемый функционал сразу после регистрации компонента в системе.
cms.admin.layout.body.begin

cms.admin.layout.body.end

../tao/views/layouts/admin.phtml
Вызываются в шаблоне админки соответственно в начале (сразу после тега BODY) и в конце тела шаблона (перед закрытием BODY), позволяя добавить что-либо.
core.find_all_modules($result)
../tao/lib/CMS.php
$result - массив со списком имен компонентов и путей к ним. Ключом выступают имена модулей, а значением физические пути к нимСобытие вызывается в методе find_all_modules() и позволяет внедрить какой-либо функционал перед тем, как будет возвращен массив значений.
cms.load_components
../tao/lib/CMS.php
Событие вызывается в методе load_components() после загрузки всех подключенных компонентов.
cms.navigation.add($title, $item, $url)
../tao/lib/CMS/Navigation.php
$title - заголовок объекта записи (заголовок ссылки)
$item - объект записи (пункт меню)
$url - адрес ссылки
Событие вызывается в методе read_item(), в момент построения навигации. Позволяет подменить звено навигационного дерева «на лету» или вставить новое, или произвести необходимые изменения в объекте записи, добавить или удалить вложенную ссылку ($item['sub']). Параметры передаются по ссылке, поэтому если изменить непосредственно переменную $url, то ссылка поменяется.
ws.response($response)
../tao/lib/WS.php
$response - сформированный объект отклика вэб-приложенияВызывается в методе формирования отклика вэб-приложения process_response() в момент, когда объект отклика уже сформирован и готов к отправке. В событие передается объект отклика, который можно доработать.
cms.fields.{$form_name}.{$name}.caption($caption, $rcaption)

cms.fields.{$form_name}.caption($caption, $rcaption)

../tao/lib/CMS/Fields.php
$caption - заголовок поля
$rcaption - заголовок поля (с правой стороны)
Вызывается в методе перед отрисовкой поля формы layout_preprocess(). Может использоваться как для конкретного поля конкретной формы, так и для всех полей конкретной формы.
cms.fields.upload($name, $data, $file, $new)

cms.fields.{$name}.upload($data, $file, $new)

../tao/lib/CMS/Fields.php
$name - имя поля
$data - массив настроек поля
$file - массив из $_FILES
$new - путь к файлу под которым он будет сохранен
Вызывается событие при закачивании файла в методе upload_file() для таких полей как image, attaches, gallery. Событие сработает в ситуации, когда метод вернет данные, отличные от null или true. В этот момент закачивание будет прервано.
cms.fields.{$form->name}.validation.js($validation_js)
../tao/views/fields/layout-table.phtml
$validation_js - скрипт валидации полей
{$form->name} - имя формы
Вызывается в шаблоне формы перед запуском стандартного скрипта валидации полей. Подписавшись на событие, можно подменить скрипт на кастомизированный. И таким образом, например, добавить валидацию по дополнительным полям.
cache.delete($key)
../tao/lib/Cache/Backend/Dummy.php
key - ключВызывается при удалении кэша по ключу в методе delete().
cache.flush
../tao/lib/Cache/Backend/Dummy.php
Не имеет аргументовВызывается при инвалидизации кеша в методе flush().
cache.has($key)
../tao/lib/Cache/Backend/Dummy.php
$key - ключВызывается в методе has().
cms.insertions.gallery.config($config)
../tao/views/insertions/gallery.phtml
$config - массив настроекСобытие вызывается в шаблоне вставки галереи. Позволяет изменить установленные или добавить новые настройки вывода изображений.
db.schema.execute($data)
db.schema.execute($data['name'], $data)

../tao/lib/DB/Schema.php
$data - массив DB.Schema
$data['name'] - имя таблицы
Вызывается при обработке DB.Schema в методе execute() перед изменением данных. Позволяет добавить поля, столбцы в таблицу, внести какие-то изменения. Для конкретной таблицы необходимо передать ее имя в качестве аргумента($data['name']).
db.schema.after_execute($data)
db.schema.after_execute($data['name'], $data)

../tao/lib/DB/Schema.php
$data - массив DB.Schema
$data['name'] - имя таблицы
Вызывается при обработке DB.Schema в методе execute() после изменения данных. Позволяет добавить поля, столбцы в таблицу, внести какие-то изменения. Для конкретной таблицы необходимо передать ее имя в качестве аргумента($data['name']).
templates.assets.postprocess($path, $data, $content)
../tao/lib/Templates/HTML/Assets.php
$path - путь к формируемому файлу
$data - массив параметров
$content - содержимое файла
Событие вызывается при подключении css- или js-файла в методе postprocess(). Позволяет добавить какую-либо обработку после того, как список сформирован.
templates.assets.preprocess($path, $data, $content)
../tao/lib/Templates/HTML/Assets.php
$path - путь к формируемому файлу
$data - массив параметров
$content - содержимое файла
Событие вызывается при подключении css- или js-файла в методе preprocess(). Позволяет добавить какую-либо обработку перед формированием списка файлов.
templates.partial($__name, $__params)
../tao/lib/Templates/HTML.php
$__name - имя шаблона
$__params - массив параметров шаблона
Вызывается при формировании шаблона.
cms.insertions.calendar.setup($router,$orm,$cache)
cms.insertions.calendar.{$component}.setup($router,$orm,$cache)
../tao/views/insertions/calendar.phtml
$router
$orm
$cache
$component - произвольный идентификатор для именования процесса обработки
Вызывается перед отрисовкой календаря. Позволяет добавить необходимый функционал.
cms.calendar.is_holiday($d,$holiday)../tao/views/insertions/calendar.phtml$d
$holiday
Вызывается перед отрисовкой каледаря. Позволяет назначить определенные дни выходными.

Метки: events
28.04.2016
Все статьи