Хуки и события

Хуки и события

Хуки — способ для плагинов вмешиваться в работу ядра и других плагинов, не меняя их код. Реализованы в стиле WordPress классом Celena\Core\Plugin\Hook. Есть два вида: actions (побочные эффекты) и filters (преобразование значения).

Контракт имени: <область>.<событие> в нижнем регистре, например news.published.

Actions — действия

Эффект без возврата значения. Подписчиков может быть несколько, порядок не важен.

use Celena\Core\Plugin\Hook;

// Подписаться:
Hook::on('news.published', function (array $news): void {
    // например, отправить уведомление
});

// Вызвать (это делает ядро/модуль):
Hook::action('news.published', $news);

Filters — фильтры

Преобразуют значение, передавая его по цепочке подписчиков.

// Подписаться (можно указать приоритет, меньше = раньше):
Hook::addFilter('news.title', fn (string $t) => trim($t), 10);

// Применить:
$title = Hook::filter('news.title', $news['title'], $news);

Встроенные хуки ядра

ХукТипАргументы
kernel.bootactionContainer $c
request.beforeactionRequest $req
response.before_sendfilterResponse $res, Request $req
user.registeredactionarray $user
user.login.successactionarray $user
user.login.failedactionstring $email, string $ip
news.publishedactionarray $news
news.titlefilterstring $title, array $news
template.render.beforeactionstring $template, array $vars
template.globalsfilterarray $vars
admin.sidebarfilterarray $items
admin.notificationsfilterarray $items
cache.clearedactionstring $type

Список расширяется по мере роста ядра.

Частые сценарии

Добавить пункт в меню админки

Hook::addFilter('admin.sidebar', function (array $items): array {
    $icon = new \Celena\Core\Template\Tags\IconTag();
    $items[] = [
        'svg'          => $icon(['name' => 'mail', 'size' => 22, 'class' => 'sb-ico']),
        'label'        => 'Заявки',
        'url'          => '/admin/forms',
        'slug'         => 'forms',
        'active_slugs' => ['forms', 'leads'],
        'children'     => [
            ['label' => 'Формы',      'url' => '/admin/forms', 'slug' => 'forms'],
            ['label' => 'Все заявки', 'url' => '/admin/leads', 'slug' => 'leads'],
        ],
    ];
    return $items;
});

Прокинуть переменную во все шаблоны

Hook::addFilter('template.globals', function (array $vars): array {
    $vars['my_flag'] = '1';   // доступно как {my_flag} в любом шаблоне
    return $vars;
}, 0);

Добавить уведомление в «колокольчик»

Hook::addFilter('admin.notifications', function (array $items): array {
    $items[] = ['title' => 'Новые заявки', 'text' => '3 шт.', 'url' => '/admin/forms', 'time' => ''];
    return $items;
});

Собственные хуки в плагине

Плагин может испускать свои события, чтобы другие расширения могли на них подписаться:

Hook::action('shop.order.created', $order);
$price = Hook::filter('shop.price', $price, $product);

Документируйте такие хуки в docs/hooks.md своего плагина — это контракт для интеграций.