Encodera

Спасибо, что читаете!

Пожертвуйте сайту, мы стараемся ради вас.

Оглавление

Группы плагинов и события

Группа плагина определяет, когда Joomla его загружает и какие события он обычно обрабатывает. Плагин content из прошлого урока работает только там, где выводится или сохраняется содержимое. Для других задач выбирают другую группу — структура файлов при этом остаётся той же.

Группы

ГруппаПапкаДля чего
contentplugins/contentПодготовка, сохранение и удаление содержимого
systemplugins/systemЭтапы обработки любого запроса
userplugins/userВход, выход, регистрация, сохранение пользователя
authenticationplugins/authenticationСпособы проверки имени и пароля
editors-xtdplugins/editors-xtdКнопки под редактором
webservicesplugins/webservicesМаршруты API
consoleplugins/consoleКоманды консоли
taskplugins/taskЗадачи планировщика

Системный плагин

Плагины группы system загружаются при каждом запросе — и на сайте, и в панели. Создайте второй плагин по образцу первого:

plugins/system/hello/
├── hello.xml
├── services/provider.php
└── src/Extension/Hello.php

В манифесте замените group="content" на group="system", имя — на plg_system_hello, пространство имён — на My\Plugin\System\Hello. В провайдере — PluginHelper::getPlugin('system', 'hello') и новый класс. Сам класс:

// plugins/system/hello/src/Extension/Hello.php
namespace My\Plugin\System\Hello\Extension;
 
defined('_JEXEC') or die;
 
use Joomla\CMS\Plugin\CMSPlugin;
use Joomla\Event\Event;
use Joomla\Event\SubscriberInterface;
 
final class Hello extends CMSPlugin implements SubscriberInterface
{
    public static function getSubscribedEvents(): array
    {
        return [
            'onAfterInitialise' => 'addHeader',
        ];
    }
 
    public function addHeader(Event $event): void
    {
        $this->getApplication()->setHeader('X-Frame-Options', 'SAMEORIGIN', true);
    }
}

Установите плагин через «Поиск» и включите его. Откройте в браузере инструменты разработчика, вкладку «Сеть»: в заголовках ответа любой страницы появился X-Frame-Options.

События запроса

Системные события идут в таком порядке:

СобытиеКогда происходит
onAfterInitialiseJoomla загружена, запрос ещё не разобран
onAfterRouteОпределены компонент и страница
onAfterDispatchКомпонент отработал, содержимое готово
onBeforeRenderПеред сборкой страницы шаблоном
onBeforeCompileHeadПеред выводом тегов в head — последний шанс добавить стили и скрипты
onAfterRenderСтраница готова, её текст можно изменить целиком

Чтобы код работал только на сайте, проверяйте клиент: $this->getApplication()->isClient('site').

Плагин группы user

Так же создаётся плагин plugins/user/hello с пространством имён My\Plugin\User\Hello. Он приветствует пользователя после входа:

// plugins/user/hello/src/Extension/Hello.php
public static function getSubscribedEvents(): array
{
    return [
        'onUserAfterLogin' => 'greet',
    ];
}
 
public function greet(Event $event): void
{
    $options = $event->getArgument('options');
 
    $this->getApplication()->enqueueMessage('С возвращением, ' . $options['user']->name . '!');
}

Событие несёт массив options, в котором лежит вошедший пользователь. enqueueMessage() ставит сообщение в очередь — оно появится вверху следующей страницы. Войдите на сайт: над содержимым показано «С возвращением, Анна!».

События содержимого и пользователей

СобытиеКогда происходит
onContentPrepareТекст готовится к выводу
onContentBeforeSave, onContentAfterSaveДо и после сохранения записи
onContentAfterDeleteПосле удаления записи
onContentPrepareFormФорма подготовлена — в неё можно добавить поля
onUserAfterLogin, onUserLogoutВход и выход
onUserBeforeSave, onUserAfterSaveДо и после сохранения пользователя

Готовые примеры — в папках ядра: plugins/content, plugins/system, plugins/user.

Частая ошибка

В системный плагин кладут тяжёлую работу — запросы к базе или к внешнему сервису — без всяких условий. Такой код выполняется при каждом запросе, включая панель управления и API. Сначала проверьте клиент и адрес, и только потом делайте работу.

Спасибо, что читаете!

Пожертвуйте сайту, мы стараемся ради вас.