Сумбурность заголовка данной заметки может навести на мысль о том, что текст этот — перевод чужой статьи. На самом деле я просто попытался описать в одном предложении то, о чём пойдет речь ниже. А ниже ни много ни мало мы будем создавать события и подключать их в своем условном компоненте, который работает либо под 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 по ссылке ниже:
С уважением, Владимир Егоров