Группы плагинов и события
Группа плагина определяет, когда Joomla его загружает и какие события он обычно обрабатывает. Плагин content из прошлого урока работает только там, где выводится или сохраняется содержимое. Для других задач выбирают другую группу — структура файлов при этом остаётся той же.
Группы
| Группа | Папка | Для чего |
|---|---|---|
content | plugins/content | Подготовка, сохранение и удаление содержимого |
system | plugins/system | Этапы обработки любого запроса |
user | plugins/user | Вход, выход, регистрация, сохранение пользователя |
authentication | plugins/authentication | Способы проверки имени и пароля |
editors-xtd | plugins/editors-xtd | Кнопки под редактором |
webservices | plugins/webservices | Маршруты API |
console | plugins/console | Команды консоли |
task | plugins/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.
События запроса
Системные события идут в таком порядке:
| Событие | Когда происходит |
|---|---|
onAfterInitialise | Joomla загружена, запрос ещё не разобран |
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. Сначала проверьте клиент и адрес, и только потом делайте работу.