Почитать другие заметки или статьи

Сумбурность заголовка данной заметки может навести на мысль о том, что текст этот — перевод чужой статьи. На самом деле я просто попытался описать в одном предложении то, о чём пойдет речь ниже. А ниже ни много ни мало мы будем создавать события и подключать их в своем условном компоненте, который работает либо под Joomla 4, либо под Joomla 5.

Бардак и кровь

История с событиями в процессе эволюции Joomla с третьей версии на четвертую, а затем и на пятую попила немало крови порядочных разработчиков.

Весь код, который связан с событиями пришлось переписывать. Методы, используемые в Joomla 3, в последующих версиях удалены.

Да и сам способ подключения событий несколько отличается.

Впрочем, даже то, что предлагалось использовать в Joomla 4, в Joomla 5 уже объявлено устаревшим.

Любопытно было наблюдать код двух компонентов, которые много лет идут в стандартной сборке Joomla. Речь идет о компоненте «Контакты» (com_contact) и стандартном менеджере материалов (com_content).

Если последний выполнен по последнему слову техники, то в первом используются так называемые «устаревшие» (deprecated) методы.

И всё это в Joomla 5.0.2!!!

Чтобы вы не думали, что я вас обманываю, ниже скриншоты кода двух компонентов.

Смотрим на код компонента контакты, где вызываются события «onContentAfterTitle», «onContentBeforeDisplay» и «onContentAfterDisplay».

Как видим, метод «triggerEvent» в редакторе PHPStorm показан, как устаревший и, конечно же, использовать таковой в своем собственном компоненте не хочется, поскольку в относительно ближайшее время этот код придется переписывать.

Впрочем, всё в Joomla рано или поздно приходится переписывать.

Теперь посмотрим на похожий по предназначению код компонента «com_content»:

Как видим, отличия видны невооруженным взглядом. Что говорит не в пользу разработчиков самой CMS Joomla, ибо даже в рамках одной версии не всегда есть понимание: «А как, собственно говоря, писать правильно?».

Бесконечные метания и постоянное переделывание кода системы разработчиками Joomla однозначно нервируют создателей сторонних расширений.

Хватит слёз, ставим задачу

Предположим, у нас есть плагин. Да не простой, а с уникальным типом. Поскольку идея этой статьи появилась в процессе создания событий для моего компонента «J SMS Registration», то пусть тип этого плагина будет «jsmsregistration».

Сам плагин, как и положено, расположен в одноименном каталоге.

Итак, мы должны создать и вызвать события в компоненте. О том, как писать плагин, в рамках этой статьи я не буду.

К слову говоря, мой личный плагин назывался «jsjobsaddfields».

Скрывать не буду: встречаются в природе названия и получше.

Для себя события я разделил на три вида или типа или варианта. Кому, как угодно.

Первый:

Возвращает определенный контент. Используется в шаблонах вывода. Например, когда до или после какого то контента нужно вывести определенное содержимое.

Предположим, ваш компонент выводит форму из трех полей. Однако, с помощью плагинов вы хотели бы иметь возможность вставки новых полей или выпадающих списков.

Второй:

Событию передаются какие то данные, событие их обрабатывает и что-то с ними делает.

Например, передается объект пользователя, у которого в процессе срабатывания события должен поменяться email или имя или что угодно.

То есть, по сути событие необходимо для видоизменения каких либо данных.

Третий:

При срабатывании события ничего не возвращается. Например, при срабатывании события мы просто должны записать в одну из таблиц базы данных слово «Сайтогон».

Ниже я сразу покажу фрагмент кода для всех трех вариантов. С небольшими пояснениями.

use Joomla\CMS\Factory;
use Joomla\CMS\Plugin\PluginHelper;
use Joomla\Event\Event;

// Импортируем плагины с типом jsmsregistration
// А также подключаем в переменную $dispatcher диспетчер событий

PluginHelper::importPlugin('jsmsregistration');
$app = Factory::getApplication();
$dispatcher = $app->getDispatcher();

// ВАРИАНТ 1. ПОДКЛЮЧАЕМ СОБЫТИЕ, КОТОРОЕ БУДЕТ СРАБАТЫВАТЬ В ШАБЛОНЕ КОМПОНЕНТА.

// Данный объект будет содержать контент, возвращаемый событиями
$this->content = new \stdClass;

// Событие я назвал onRenderRegistrationFormField
// У вас будет свое уникальное название
// Для вызова события подключаем объект Event, которому можно передать параметры в виде массива

$event = new Event('onRenderRegistrationFormField', array());
$dispatcher->dispatch('onRenderRegistrationFormField', $event);

// Получаем данные, возвращаемые методом onRenderRegistrationFormField нашего события

$results = $event->getArgument('result');

// Если ничего не возвращается, то в переменную сохраняем пустой массив
// Иначе будет ошибка

if (!is_array($results)) {
    $results = array();
}

$this->content->beforeDisplayFormFields = trim(implode("\n", $results));

// Далее нам остается вывести переменную $this->content->beforeDisplayFormFields в нужном месте шаблона

// ВАРИАНТ 2. ПОДКЛЮЧАЕМ СОБЫТИЕ, ГДЕ МЫ ПЕРЕДАЕМ ССЫЛКУ НА ПЕРЕМЕННУЮ С ОБЪЕКТОМ.

// После срабатывания события onBeforeAddUser одноименный метод
// может поменять содержимое переменной $user


$event = new Event('onBeforeAddUser', array(&$user));
$dispatcher->dispatch('onBeforeAddUser', $event);

// ВАРИАНТ 3. ПОДКЛЮЧАЕМ СОБЫТИЕ, ГДЕ НИЧЕГО НЕ ВОЗВРАЩАЕМ И НЕ ОБРАБАТЫВАЕМ
// ОТПРАВЛЕННЫЕ ДАННЫЕ

$event = new Event('onBeforeRedirectFromFinalRegistration', array($user));
$dispatcher->dispatch('onBeforeRedirectFromFinalRegistration', $event);

Заключение

Возможно, кто то не до конца понял представленный выше код. А кто-то вообще ничего не понял.

Следует понимать, что представленная выше шпаргалка будет полезна, в первую очередь, тем, кто уже имеет опыт разработки. Например, мне.

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

https://vk.com/sitogon

С уважением, Владимир Егоров