В посте Заменяем устаревший метод CMSApplicationInterface::triggerEvent в Joomla 5.1.4 я вскольз упоминал собственные классы событий. Теперь я хочу рассказать о них подробнее.
Создание класса начинается с пространства имён, имени класса и родителя
Имя и пространство имён класса зависит от контекста. Например, я пишу компонент импорта для JoomShopping:
-
Компонент:
com_jsimport
-
Модель:
PriceModel
-
Метод:
importExcel
-
Событие:
onJSImportPriceBeforeImportExcel
(о именах для событий читайте в статье: Как событие Joomla назовёшь, так оно и триггернётся?).
Пространство имён
Event\Model\Price
— Событие относится к модели, но в компоненте есть и другие модели, у которых тоже есть метод importExcel
. Поэтому включим имя модели Price
в namespace.
Имя класса
А класс назовём BeforeImportExcelEvent
аналогично другим классам из ядра Joomla. В компоненте могут классы событий с такие же именем, но другим namespase.
Родительский класс
Очевидный родитель для нашего класса — Joomla\CMS\Event\AbstractEvent
, который является родителем и для Joomla\CMS\Event\GenericEvent
используемого по-умолчанию.
И так, наш класс готов к использованию, но у него нет никаких преимуществ.
Недостатки стандартного класса события
Объект события в первую очередь предназначен для передачи данных в обработчик события и получения из него результатов. В классе \Joomla\CMS\Event\GenericEvent
вам доступны методы getArgument
и setArgument
с помощью которых вы можете работать с аргументами по имени.
<?php public function onJSImportPriceBeforeImportExcel(Event $event): void { $data = $event->getArgument('data'); }
Недостаток такого подхода в том, что метод getArgument
возвращает mixed
то есть там может быть что угодно, ваша IDE не знает что в переменной, и не ожидаемый тип данных может вызвать ошибку.
Можно дописать @var
-комментарий и проверку типа для каждого аргумента:
<?php public function onJSImportPriceBeforeImportExcel(Event $event): void { /** @var array $data */ $data = $event->getArgument('data'); if (!is_array($data)) { throw new Exception('Data must be array'); } }
Но вам придётся делать это в каждом событии каждого плагина, что делает код более громоздким.
Преимущества собственного класса
Геттеры и сетеры для аргументов
В своём классе вы можете определить сеттеры и геттеры для аргументов и методы setArgument
и getArgument
родительского класса Joomla\CMS\Event\AbstractEvent
будут их использовать.
on
+ Set/Get
+ Имя аргумента с большой буквы
.
В моём случае onSetData($value)
и onGetData($value)
.
setArgument
передаст значение сеттеру и установит полученный от него результат .
getArgument
передаст значение геттеру и вернёт полученный от него результат.
Собственные методы
Так же для удобства написания плагинов вы можете добавить в класс события собственный метод для получения данных: getData(): array
указав ему тип возвращаемого значения. Таким образом, код для получения валидных данных в плагине сократится до одной строки, и IDE будет видеть тип данных.
<?php public function onJSImportPriceBeforeImportExcel(BeforeImportExcelEvent $event): void { $data = $event->getData(); }
А вот код нашего класса:
<?php namespace Joomla\Component\Jsimport\Event\Model\Price; use Joomla\CMS\Event\AbstractEvent; use function defined; // phpcs:disable PSR1.Files.SideEffects defined('_JEXEC') or die; // phpcs:enable PSR1.Files.SideEffects /** * @since 1.0.0 */ class BeforeImportExcelEvent extends AbstractEvent { /** * Setter for the data argument. * * @param array $value The value to set * * @return array * * @since 1.0.0 */ protected function onSetData(array $value): array { if (!count($value)) { throw new Exception('Data must be not empty array'); } return $value; } /** * Getter for the data. * * @return array * * @since 1.0.0 */ public function onGetData(array $value): array { return $value; } /** * @return array * * @since 1.0.0 */ public function getData(): array { return $this->arguments['data']; } }
В Joomla 5.2.0 для событий есть и другие родительские классы, интерфейсы и трейты, о них напишу в следующей статье.
Продолжение: Пишем класс для «Result»-события Joomla
ссылка на оригинал статьи https://habr.com/ru/articles/853180/
Добавить комментарий