maximaster / tools.events
该库在满足一定结构的情况下,提供自动加载事件处理器的帮助。
Requires
- php: >=5.3.0
README
该库提供自动加载1С-Битри克斯事件处理器的功能。
所有比特里克斯事件都绑定到模块,但Higload块创建的事件除外,它们与任何模块都不相关。每个模块都与创建该模块的供应商有关。对于内置模块,供应商是比特里克斯。
首先需要确定所有事件处理器将存储在哪个目录中。例如,可以是 /local/EventHandlers 目录。类名、其命名空间和目录的命名原则应符合 PSR-4 标准,这意味着对于 EventHandlers 目录,需要定义一个命名空间对应关系,例如 Maximaster\EventHandlers。在搜索事件处理器时,将供应商和模块名称转换为小写,并使用模块的不同写法,这允许将主模块标记为 Main 而不是 main。如果供应商或模块名称中包含下划线 "_",则该符号必须在命名空间中存在。例如,供应商 maxi_master 可以记录为 Maxi_Master,但不能为 MaxiMaster。
要将此目录注册为处理器存储库,需要编写类似以下内容
//Создаем инстанс нашего загрузчика $eventListener = new \Maximaster\Tools\Events\Listener(); //Добавляем соответствие между пространством имен и директорией, в которой будет производиться поиск обработчиков //с этим пространством имен $eventListener->addNamespace('Maximaster\\EventHandlers', $_SERVER['DOCUMENT_ROOT']. '/local/EventHandlers'); //Вызываем метод регистрации, который соберет все классы и вызовет для всех функцию AddEventHandler $eventListener->register();
之后,为每个事件创建一个包含该事件处理器的类。此类应位于包含供应商、模块和事件类型的命名空间中。例如,如果您需要创建主模块的 OnPageStart 事件处理器,则需要创建一个完整的类名(包含命名空间),以 Bitrix\Main\OnPageStart 结尾,而该类的路径应为 /local/EventHandlers/Bitrix/Main/OnPageStart.php。在这种情况下,该类的完整名称(包含命名空间)将是 \Maximaster\EventHandlers\Bitrix\Main\OnPageStart。在这里,Bitrix 是供应商,Main 是模块,OnPageStart 是事件名称。
如果命名空间中不存在供应商名称,则认为供应商是比特里克斯。上述示例等同于类名 \Maximaster\EventHandlers\Main\OnPageStart。
如果命名空间中不存在模块名称,则在将处理器绑定到事件时不会使用模块,也就是说,基本上将调用 AddEventHandler 函数,其中第一个参数将传递空字符串。
此类的每个方法都将作为与该类相关联的事件处理器。方法名称无关紧要。要更改同一类中方法的调用顺序,需要添加 phpDoc 块,其中使用 @eventSort 参数使用数值。仅处理第一个 @eventSort 值。以下示例
namespace Maximaster\EventHandlers\Bitrix\Main; use Maximaster\Tools\Events\BaseEvent; class OnPageStart extends BaseEvent { /** * @eventSort 100 */ public static function myEventHandler() { //код первого обработчика } /** * @eventSort 200 */ public static function myEventHandler2() { //код второго обработчика } }
库中存在 Maximaster\Tools\Events\BaseEvent 的基本事件处理器类。此类还可以管理处理器的调用顺序。要更改调用顺序,需要从包含处理器的类继承 BaseEvent 类,并定义 protected static 属性 $sort,其中包含 '方法名称' => '排序顺序' 的对应关系。请注意,此功能已被标记为过时,将在下一个主要版本中删除。以下示例
namespace Maximaster\EventHandlers\Bitrix\Main; use Maximaster\Tools\Events\BaseEvent; class OnPageStart extends BaseEvent { protected static $sort = array( 'myEventHandler' => 100, 'myEventHandler2' => 200, ); public static function myEventHandler() { //код первого обработчика } public static function myEventHandler2() { //код второго обработчика } }
此外,该类允许不同的事件处理器之间交换数据。例如,如果您想将 OnPageStart 事件的数据传递到 OnEndEpilog 事件,您需要在其中一个类中使用 setData() 方法保存这些数据,并在另一个类中使用 getData() 方法获取这些数据。
class OnPageStart extends BaseEvent { public static function myEventHandler() { self::setData('uniqueDataKey', 'dataValue'); } } //....... class OnEndEpilog extends BaseEvent { public static function anotherEventHandler() { $data = self::getData('uniqueDataKey'); } }
有时会出现这样的情况,需要将一个处理器绑定到多个不同的事件。例如,常常会遇到相同代码被用于添加和更新信息块元素的情况。为了解决这个问题,需要使用phpDoc的@eventlink块。在其值中,需要指定将调用当前方法的事件,除了通过命名空间定义的事件之外。可以绑定多个不同的事件。例如
/** * @eventLink OnAfterIblockElementUpdate * @eventLink OnAfterIblockElementDelete * @eventLink OnPageStart */ public static function OnAfterIblockElementAdd() { //Здесь код, который будет обрабатывать и обновление, добавление элемента инфоблока }
随着d7的出现,出现了一种新的事件绑定系统。该模块能够处理旧事件和新事件。为了注册不同版本的事件,可以使用以下方法之一
- 指定docblock
@eventVersion
- 在注册命名空间时指定参数
$version
,使用方法\Maximaster\Tools\Events\Listener::addNamespace
示例
/** * @eventVersion 2 * Данный обработчик будет зарегистрирован как новый, */ public function saveOrder(Bitrix\Main\Event $event) { }
$eventListener = new \Maximaster\Tools\Events\Listener(); // Все обработчики событий, находящиеся в директоири BitrixD7 будут зарегистрированы как новые $eventListener->addNamespace( '\\Maximaster\\EventHandlers\\BitrixD7', __DIR__ . '/../classes/Maximaster/EventHandlers/BitrixD7', false, 2 ); // А в директории Bitrix - как старые $eventListener->addNamespace( '\\Maximaster\\EventHandlers\\Bitrix', __DIR__ . '/../classes/Maximaster/EventHandlers/Bitrix', false, 1 );