---
title: "Триггеры ядра Joomla при CRUD-операциях - WebTolk"
description: "Разработчикам при написании плагинов Joomla используют события-триггеры, в которые могут передаваться данные. Как найти нужное событие для своего плагина в Joomla подскажет эта статья. Список стандартных триггеров Joomla 5+. Получение аргументов события getArguments(), контекста getContext()."
url: "https://web-tolk.ru/blog/triggery-yadra-joomla-pri-crud-operatsiyakh"
date: "2025-01-20T05:38:48+00:00"
language: "ru-RU"
---

# Триггеры ядра Joomla при CRUD-операциях

 Автор: Сергей Толкачев Создано: 20 января 2025 Обновлено: 01 сентября 2025 Просмотров: 1048

**CRUD** - аббревиатура основных операций с данными: создание (**C**reate), чтение (**R**ead), изменение (**U**pdate) и удаление (**D**elete). Практически все действия на сайте как в админке, так и пользовательской части можно описать этими действиями. Разработчикам при создании функционала часто в какие-то моменты этих действий нужно проделать некие действия с участием данных или без них. Для этого в частности существует механизм вызова событий (Event Dispatching) и плагинов, которые на эти события "откликаются".

В названии событий есть определенная логика и здесь я упомяну статью [Виталия Некрасова на Хабре](https://habr.com/users/VitaliyNekrasov) [Как событие Joomla назовёшь, так оно и триггернётся?](https://habr.com/ru/articles/851886/).

Самый простой пример (один момент в процессе **Read** данных) - триггер onContentPrepare - вызывается перед отображением какого-либо контента "снаружи" сайта. Обычно плагины, срабатывающие на этом событии заменяют какие-нибудь шорт-коды на какое-нибудь содержимое.

## Карта событий плагинов в моделях Joomla

Обработка, проверка и сохранение данных в Joomla происходит с помощью моделей (MVC - Model), которые **обычно** расширяют родительскую `\Joomla\CMS\MVC\Model\AdminModel` (**libraries/src/MVC/Model/AdminModel.php**). Именно она описывает CRUD-процессы, а модели конкретных компонентов дополняют родительские методы. В AdminModel есть "карта событий" для плагинов, которая сопоставляет собственно момент времени с названием триггера, а так же говорит какую группу плагинов вызывать.

```
<?php
// Для наглядности вырезал всё лишнее

abstract class AdminModel extends FormModel
{

    public function __construct($config = [], ?MVCFactoryInterface $factory = null, ?FormFactoryInterface $formFactory = null)
    {
        parent::__construct($config, $factory, $formFactory);
        // ....
        // Указываем имя триггера
        if (isset($config['event_after_delete'])) {
            $this->event_after_delete = $config['event_after_delete'];
        } elseif (empty($this->event_after_delete)) {
            $this->event_after_delete = 'onContentAfterDelete';
        }
        // ....
        $config['events_map'] = $config['events_map'] ?? [];

        // Указываем какая группа плагинов, кроме системных
        // будет реагировать на триггер.
        $this->events_map = array_merge(
            [
                'delete'       => 'content',
                'save'         => 'content',
                'change_state' => 'content',
                'validate'     => 'content',
                'batch'        => 'content',
            ],
            $config['events_map']
        );

        // ....
    }
}
```

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

Имена триггеров Joomla по умолчанию, если не переопределены конкретным компонентом:

- **onContentBeforeDelete** - перед удалением сущности
- **onContentAfterDelete** - после удаления
- **onContentBeforeSave** - перед сохранением данных сущности
- **onContentAfterSave** - после сохранения
- **onContentBeforeChangeState** - перед изменением состояния (опубликовано, не опубликовано, в корзине...)
- **onContentChangeState** - после изменения состояния
- **onBeforeBatch** - перед пакетной обработкой нескольких сущностей

По умолчанию это триггеры, содержащие слово "Content" в названии. Но если мы посмотрим в конструкторы моделей некоторых компонентов ядра, то увидим, что они вызывают собственные более узко-специализированные триггеры. Например, компоненты модулей (com_modules) и шаблонов (com_templates) вызывают собственные события **onExtensionBeforeDelete**, **onExtensionAfterDelete**, **onExtensionBeforeSave**, **onExtensionAfterSave**и группа плагинов - **extension**. Или же модель `\Joomla\Component\Users\Administrator\Model\UserModel` (**administrator/components/com_users/src/Model/UserModel.php**) определяет события **onUserAfterDelete**, **onUserAfterSave**, **onUserBeforeDelete**, **onUserBeforeSave**в группе плагинов **user**.

Таким образом, работая с компонентами Joomla всегда можно посмотреть какое именно событие и какой именно группы плагинов можно использовать. Другое дело, что на практике нередко лень создавать несколько плагинов под разные случаи и множество событий помещают в один системный плагин, чтобы всё было в одном месте. Недостаток такого подхода в том, что системные плагины срабатывают на каждый чих в Joomla и поэтому велик риск сломать что-то абсолютно далёкое от зоны ответственности вашего плагина.

## Данные для использования при срабатывании плагина

Какие данные приходят и как с ними работать? Здесь предварительно упомяну ещё одну статью Виталия Некрасова - [Каждому событию Joomla — свой класс](https://habr.com/ru/articles/853180/). Также я кратко (но подробнее, чем тут) писал об этом в статье [Программное создание материалов с пользовательскими полями в Joomla 5+](https://web-tolk.ru/blog/index.php?option=com_content&view=article&id=96&catid=10&lang=ru-RU&Itemid=114). В Joomla 5 для разных типов событий стали создавать кастомные классы этих событий для того, чтобы можно было использовать методы работы с данными, характерными для этих только событий. Для контентных плагинов - `$event->getContext()` вместо получения `$event->getArgument(0);` или `$event->updateEventResult($data)` для `AjaxEvent` для и т.д.

### Получение данных события плагина Joomla

**Вариант 1. По числовому индексу аргумента.** Устаревший, но в Joomla 5 ещё работающий. Тут нужно знать порядок аргументов для данного события, исторически сложившийся в Joomla.

```
// public function onContentAfterDisplay($context, &$row, &$params, $page = 0)
$context = $event->getArgument(0);
```

**Вариант 2. По имени аргумента.**Для этого надо знать имя аргумента.

```
// Get the service container.
$container = $event->getArgument('container');
```

**Вариант 3. Методом getArguments().**

Здесь тоже нужно знать порядок аргументов. Но если вы его знаете, почему бы и нет? Этот способ можно использовать и тогда, когда компонент, с которым вы работаете не предоставляет собственные классы для событий.

```
/**
 * Пример из плагина для интернет-магазина JoomShopping
 * @var object $order  JoomShopping order object
 * @var object $cart   JoomShopping cart object
 */
[$order, $cart] = $event->getArguments();
```

**Вариант 4. Методами класса события (Joomla 5+).**

Метод класса события предлагает и геттеры и сеттеры - получение и сохранение данных.

```
public function onContentBeforeDisplay(BeforeDisplayEvent $event):void
{
    $context = $event->getContext();
    // Тут возвращаем результаты
    $event->addResult($this->showLikeButton($context, $event->getItem(), $event->getParams(), $event->getPage()));
}
```

#### Контекст вызова плагина Joomla

Событие одно, а компонентов - много. CRUD-ы разные. Чтобы плагин отличал их в событие передаётся контекст вызова. Обычно это строка вида <component_name>.<entity>. Например:

- com_menus.item при сохранении пункта меню
- com_contact.contact при сохранении контакта
- com_media.file при сохранении загруженного файла в медиа менеджере
- com_content.article при сохранении материала
- и т.д.

Проверяем нужный нам контекст и выполняем необходимую работу.

```
if($event->getContext() !== 'com_content.article')
{
    return;
}
// Тут работаем с данными
```

#### Получение данных

Обычно для этого используют метод getItem() класса плагина. Что именно за итем может оказаться - зависит от компонента и контекста. Это может оказаться объект Table удаляемого элемента, или объект материала (com_content), контакта (com_contact) или категории (com_categories).

В некоторых случаях метода getItem() не существует. Например, при вызове триггера onContentChangeState метода getItems() нет, но есть методы getPks() (получение списка id сущностей, которые удаляют в корзину или снимают с публикации) и getValue() - устанавливаемый статус. IDE подсказывает какие методы есть у класса события.

## Исключения из правил

Когда мы работаем с Joomla, то далеко не всегда встречаемся именно с компонентами ядра, но используем расширения сторонних разработчиков. Кто-то из них следует "Joomla way" и использует функционал ядра, а кто-то наоборот идёт своим путём и в таком случае нужно использовать те события для плагинов, которые предоставляет сам компонент, так как большая часть событий (или вообще все) ядра Joomla не будут работать. В качестве примера приведу компонент-интернет магазина JoomShopping, модели которого наследуют не штатную **AdminModel**, а абстрактную **BaseDatabaseModel**, которая находится выше по уровню иерархии и в ней не описаны стандартные CRUD-операции, а разработчики JoomShopping сделали их по-своему.

## Список всех событий ядра Joomla 4.2+

Его можно найти в трейте `\Joomla\CMS\Event\CoreEventAware` (**libraries/src/Event/CoreEventAware.php**). Если посмотреть на ползунок файла, то будет видно, что событий не мало. Просто информация по теме статьи, полезная тем, у кого ещё нет IDE для работы с Joomla.

![Joomla CMS Event CoreEventAware screenshot plugin triggers list](https://web-tolk.ru/blog/images/blog/triggery-yadra-joomla-pri-crud-operatsiyakh/Joomla-CMS-Event-CoreEventAware.webp)

## Об авторе

![Толкачев Сергей Юрьевич](https://web-tolk.ru/images/uslugi/sergey-tolkachyov-apr-2023.webp)

### Толкачев Сергей Юрьевич

Joomla-разработчик. [Контрибьютер ядра Joomla](https://github.com/joomla/joomla-cms/pulls?q=is%3Apr+author%3Asergeytolkachyov+). Один из ведущих Telegram-канала русскоязычного Joomla-сообщества [JoomlaFeed](https://t.me/joomlafeed), один из модераторов [чата русскоязычного Joomla-сообщества](https://t.me/joomlaru). Мои расширения в официальном маркетплейсе расширений Joomla - [Joomla Extensions Directory](https://extensions.joomla.org/profile/profile/details/528051/). Имею публикации в [официальном журнале международного Joomla-сообщества - Joomla Community Magazine](https://magazine.joomla.org/authors/sergeytolkachyov) и на [официальном сайте русскоязычного Joomla-сообщества](https://joomlaportal.ru/users/sergey-tolkachyov).

Муж. Отец 3 детей.

Россия, Саратов.

## JSON-LD Schema

```json
{
    "@context": "https://schema.org",
    "@type": "BreadcrumbList",
    "@id": "https://web-tolk.ru/#/schema/BreadcrumbList/17",
    "itemListElement": [
        {
            "@type": "ListItem",
            "position": 1,
            "item": {
                "@id": "https://web-tolk.ru/",
                "name": "Главная"
            }
        },
        {
            "@type": "ListItem",
            "position": 2,
            "item": {
                "@id": "https://web-tolk.ru/blog",
                "name": "Блог"
            }
        },
        {
            "@type": "ListItem",
            "position": 3,
            "item": {
                "name": "Триггеры ядра Joomla при CRUD-операциях"
            }
        }
    ]
}
```

```json
{
    "@context": "https://schema.org",
    "@graph": [
        {
            "@type": "Organization",
            "@id": "https://web-tolk.ru/#/schema/Organization/base",
            "name": "WebTolk",
            "url": "https://web-tolk.ru/",
            "logo": {
                "@type": "ImageObject",
                "@id": "https://web-tolk.ru/#/schema/ImageObject/logo",
                "url": "images/webtolk-1080p.jpg",
                "contentUrl": "images/webtolk-1080p.jpg",
                "width": 1920,
                "height": 1080
            },
            "image": {
                "@id": "https://web-tolk.ru/#/schema/ImageObject/logo"
            },
            "sameAs": [
                "https://github.com/WebTolk",
                "https://github.com/sergeytolkachyov",
                "https://vk.com/web_tolk",
                "https://vk.com/webtolkru",
                "https://tenchat.ru/sergeytolkachyov",
                "https://t.me/sergeytolkachyov",
                "https://t.me/webtolkru"
            ]
        },
        {
            "@type": "WebSite",
            "@id": "https://web-tolk.ru/#/schema/WebSite/base",
            "url": "https://web-tolk.ru/",
            "name": "WebTolk",
            "publisher": {
                "@id": "https://web-tolk.ru/#/schema/Organization/base"
            }
        },
        {
            "@type": "WebPage",
            "@id": "https://web-tolk.ru/#/schema/WebPage/base",
            "url": "https://web-tolk.ru/blog/triggery-yadra-joomla-pri-crud-operatsiyakh",
            "name": "Триггеры ядра Joomla при CRUD-операциях - WebTolk",
            "description": "Разработчикам при написании плагинов Joomla используют события-триггеры, в которые могут передаваться данные. Как найти нужное событие для своего плагина в Joomla подскажет эта статья. Список стандартных триггеров Joomla 5+. Получение аргументов события getArguments(), контекста getContext().",
            "isPartOf": {
                "@id": "https://web-tolk.ru/#/schema/WebSite/base"
            },
            "about": {
                "@id": "https://web-tolk.ru/#/schema/Organization/base"
            },
            "inLanguage": "ru-RU",
            "breadcrumb": {
                "@id": "https://web-tolk.ru/#/schema/BreadcrumbList/17"
            }
        },
        {
            "@type": "Article",
            "@id": "https://web-tolk.ru/#/schema/com_content/article/122",
            "isPartOf": {
                "@id": "https://web-tolk.ru/#/schema/WebPage/base"
            }
        }
    ]
}
```
