Файл: system/core/eventsmanager.php
Строк: 207
<?php
/**
 * Класс управления событиями
 * @doc https://docs.instantcms.ru/dev/controllers/hooks
 */
class cmsEventsManager {
    /**
     * Список всех слушателей и событий
     * @var array
     */
    private static $structure = null;
    /**
     * Оповещает слушателей о произошедшем событии
     * Входящие данные $data передаются каждому слушателю по очереди,
     * на выходе возвращается измененный слушателями параметр $data
     *
     * @param mixed $event_name Название события/массив событий
     * @param mixed $data Параметр события
     * @param mixed $default_return Значение, возвращаемое по умолчанию если у события нет слушателей
     * @param object $_request Объект запроса
     * @return array Обработанный массив данных
     */
    public static function hook($event_name, $data = false, $default_return = null, $_request = false) {
        // Используйте массив событий, если они с разным названиями,
        // но с одинаковыми параметрами
        if (is_array($event_name)) {
            foreach ($event_name as $_event_name) {
                $data = self::hook($_event_name, $data, $default_return, $_request);
            }
            return $data;
        }
        //получаем все активные контроллеры, привязанные к указанному событию
        $listeners = self::getEventListeners($event_name);
        //если активных контроллеров нет, возвращаем данные без изменений
        if (!$listeners) {
            cmsDebugging::pointProcess('events_empty', [
                'data' => 'hook => ' . $event_name,
                'context' => [
                    'target' => null,
                    'subject' => $event_name
                ]
            ], 1);
            return is_null($default_return) ? $data : $default_return;
        }
        //перебираем контроллеры и вызываем каждый из них, передавая $data
        foreach ($listeners as $listener) {
            $request = ($_request === false) ? new cmsRequest([], cmsRequest::CTX_INTERNAL) : $_request;
            $controller = cmsCore::getController($listener, $request);
            if ($controller->mb_installed && !$controller->isControllerInstalled($listener)) {
                unset($controller);
                continue;
            }
            cmsDebugging::pointStart('events');
            $data = $controller->runHook($event_name, [$data]);
            cmsDebugging::pointProcess('events', [
                'data' => 'hook :: ' . $listener . ' => ' . $event_name,
                'context' => [
                    'target' => $listener,
                    'subject' => $event_name
                ]
            ], 1);
            unset($controller);
        }
        return $data;
    }
    /**
     * Оповещает слушателей о произошедшем событии
     * Входящие данные $data передаются каждому слушателю в изначальном виде,
     * на выходе возвращается массив с ответами от каждого слушателя
     *
     * @param string $event_name Название события
     * @param mixed $data Параметр события
     * @param mixed $default_return Значение, возвращаемое по умолчанию если у события нет слушателей
     * @param object $_request Объект запроса
     * @return array Обработанный массив данных
     */
    public static function hookAll($event_name, $data = false, $default_return = null, $_request = false) {
        //получаем все активные контроллеры, привязанные к указанному событию
        $listeners = self::getEventListeners($event_name);
        //если активных контроллеров нет, возвращаем данные без изменений
        if (!$listeners) {
            cmsDebugging::pointProcess('events_empty', [
                'data' => 'hookAll => ' . $event_name,
                'context' => [
                    'target' => null,
                    'subject' => $event_name
                ]
            ], 1);
            return is_null($default_return) ? false : $default_return;
        }
        $results = [];
        //перебираем контроллеры и вызываем каждый из них, передавая $data
        foreach ($listeners as $listener) {
            $request = ($_request === false) ? new cmsRequest([], cmsRequest::CTX_INTERNAL) : $_request;
            $controller = cmsCore::getController($listener, $request);
            if ($controller->mb_installed && !$controller->isControllerInstalled($listener)) {
                unset($controller);
                continue;
            }
            cmsDebugging::pointStart('events');
            $result = $controller->runHook($event_name, [$data]);
            if ($result !== false) {
                $results[$listener] = $result;
            }
            cmsDebugging::pointProcess('events', [
                'data' => 'hookAll :: ' . $listener . ' => ' . $event_name,
                'context' => [
                    'target' => $listener,
                    'subject' => $event_name
                ]
            ], 1);
            unset($controller);
        }
        return $results;
    }
    /**
     * Возвращает список всех слушателей указанного события
     * @param string $event_name Название события
     * @return array Список слушателей
     */
    public static function getEventListeners($event_name) {
        $listeners = [];
        if (self::$structure === null) {
            self::$structure = self::getAllListeners();
        }
        if (isset(self::$structure[$event_name])) {
            $listeners = self::$structure[$event_name];
        }
        return $listeners;
    }
    /**
     * Возвращает список всех слушателей для всех событий
     * @return array
     */
    public static function getAllListeners() {
        $cache     = cmsCache::getInstance();
        $cache_key = 'events';
        if (false !== ($structure = $cache->get($cache_key))) {
            return $structure;
        }
        $manifests = cmsCore::getControllersManifests(cmsConfig::get('manifest_from_files'));
        if (!$manifests) {
            return [];
        }
        $structure = [];
        foreach ($manifests as $controller_name => $hooks) {
            if (!cmsController::enabled($controller_name)) {
                continue;
            }
            foreach ($hooks as $ordering => $event_name) {
                $structure[$event_name][$ordering] = $controller_name;
            }
        }
        foreach ($structure as $event_name => $controllers) {
            ksort($structure[$event_name]);
        }
        $cache->set($cache_key, $structure, 86400);
        return $structure;
    }
}