maximaster/tools.events

该库在满足一定结构的情况下,提供自动加载事件处理器的帮助。

v1.2.1 2016-04-26 09:56 UTC

This package is auto-updated.

Last update: 2024-09-12 23:26:10 UTC


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