На вашем сайте, внутреннем портале, в интернет-магазине кто-то что-то сделал, а потом всё сломалось: сайт открывается криво (или не открывается вообще?), перестали работать фоновые задачи в планировщике, установились неправильные скидки всем пользователям на все товары... Предположим, что с безопасностью у вас всё хорошо: Joomla свежая, актуальная, расширения - тоже. Да и в логах сервера и логах Joomla тоже чисто... Тогда остаётся ещё один источник информации - Лог действий пользователей Joomla. Основная его задача - помочь быстро найти кому настучать по рогам причину и устранить её.
Статья изначально опубликована на Хабре. Копирую к себе.
Всё, что связано с действиями в админке - может логироваться: от обновления системы и компонентов, изменения настроек до редактирования и сохранения конкретных элементов (статьи, товары, категории и т.д.) и загрузки файлов через медиа менеджер. Лично мне нередко этот функционал помогал найти тех контент-менеджеров, кто дублирует названия товаров, создавая дубли и тем самым негативно влияя на SEO. Или же вдруг обнаруживается недозаполненная, но опубликованная карточка товара, которой не должно было быть, но она появилась. И ладно если б это был единичный случай.
Оговорка 1: статья рассчитана не только на тех, кто хорошо знает Joomla, но и на любопытствующих коллег из других технологических стеков. Поэтому некоторым очевидным терминам всё равно дано краткое пояснение.
Оговорка 2: на данный момент я рассматриваю Joomla скорее как PHP-фреймворк с натянутой на него готовой админкой, а не просто CMS. Расширение типа "компонент" в Joomla обычно представляет из себя набор различных CRUD-ов (в терминологии PHP-фреймворков), записи о действиях в которых можно хранить в логах. Поэтому статью следует больше рассматривать как начальную точку для проектирования и написания своего плагина (расширение, срабатывающие на триггеры событий Event Dispatcher) для своего же (скорее всего) компонента (CRUD-а).
Оглавление
- Список литературы
- Описание возможностей. Скриншоты.
- Архитектура базы данных
- Анализ плагина action logs ядра Joomla
- Решение без создания плагина
- Создание собственного плагина
Список литературы
- User Action Logs - документация для Joomla 3. Практически все положения из неё остались верны и для последующих версий.
- Joomla User Manual - чуть обновлённый вариант документации для Joomla 5. Так же есть ИИ-перевод на русский язык.
- На новом портале документации Joomla manual.joomla.org на момент написания статьи ещё нет примера плагина Action log, но ссылку оставлю, так как вся актуальная информация по ядру собирается именно там.
- Триггеры ядра Joomla при CRUD-операциях - сопутствующая статья.
- Создание плагинов с учётом новой структуры Joomla 4 - сопутствующая статья.
- Joomla Extensions Development - объёмная книга греческого разработчика Николаса Дионисопулоса. Посвящена Joomla разработке в целом, освещает вопросы архитектуры, причины применения некоторых подходов и т.д.
Описание возможностей компонента Лога пользователей Joomla
Этот компонент был добавлен в ядро Joomla начиная с версии 3.9.0. Найти его можно в левом меню панели администратора: Пользователи - Лог действий пользователей.
Он предоставляет собой простой интерфейс для чтения и фильтрации записей.

На скриншоте я выделил колонку "расширение". По ней можно понять контекст записи о действии. На скриншоте видны разные компоненты:
- "расширения" - действия, связанные с установкой, удалением и обновлением расширений, сохранением параметров.
- "материалы" - штатный компонент для создания статей в Joomla. Его же нередко используют для создания каталогов чего угодно.
- "SW JProjects" - сторонний компонент Joomla для ведения каталога расширений Joomla и сервера обновлений для них
- "Лог действий" - собственно компонент лога действий пользователя Joomla
Так, например, компонент "пользователи" (com_users) логирует не только собственно действия с пользователями, но и моменты входа и выхода в админку.
Правильный выход через кнопку "выйти" в наше время никто не делает, конечно. Это скорее исключение, так как все просто закрывают вкладку браузера. Но момент входа записывается точно, поэтому даже если какой-то компонент не умеет записывать логи об интересующих нас действиях пользователей, мы можем резко сузить круг "подозреваемых лиц" до тех, кто в данный момент времени находился в админке.
Мы можем отфильтровать записи по типу расширения и увидеть только то, что нас интересует. Для этого пользуемся кнопкой "параметры поиска" в списке записей событий. Список расширений зависит от установленных компонентов и того, поддерживают ли они стандартный для Joomla action log.

Также есть возможность отфильтровать действия по конкретному пользователю и за выбранный период времени. К сожалению, периоды времени пока что не настраиваются и доступны только предустановленные значения.
Ну и конечно доступна фильтрация записей по конкретному пользователю.
Параметры компонента Лог действий пользователя в Joomla

Настраиваемых параметров немного. Мы можем дополнительно логировать IP-адрес пользователя. По умолчанию эта функция отключена, видимо из-за европейских GDPR.
Самое полезное здесь - это настройка списка компонентов, в которых должны логироваться события.
Самое интересное здесь - возможность логирования запросов к REST API Joomla.

Если мы включим параметр "логировать запросы", то в выпадающем списке можно выбрать какие именно методы логировать: GET (получение данных по REST API). POST (создание сущности) и т.д. Подробнее о REST API в статье на Хабре "Web Services в Joomla 4" (и она же на моём сайте: Web Services в Joomla 4).

Таким образом если ваша Joomla связана с внешними системами по REST API, то историю взаимодействия с ними тоже можно отслеживать.
Версионность контента. Просмотр изменений.
Порой нам хотелось бы знать что именно было изменено и на что. Версионность контента возможна только в тех компонентах, что его поддерживают и где параметр сохранения версий включён. Так, в стандартных материалах Joomla должен быть включён параметр в настройках компонента - Форма - История версий.
Тогда на странице редактирования материала Joomla появится кнопка "версии".
Где можно не только их просмотреть и восстановить...
... но и сравнить, увидев конкретные внесённые изменения. Изменения показываются в отдельном всплывающем окне. Изменения подсвечиваются.

Если вы пишете свой собственный компонент, то можете реализовать это удобнее с точки зрения пользовательского опыта и в своём сообщении добавить сразу ссылку на diff-ы.
Архитектура базы данных
В базе данных Joomla 4 таблицы, связанных с логированием действий пользователей:
- #__actionlogs - основная таблица для хранения логов
- #__actionlogs_extensions - таблица для хранения списка логируемых расширений. Данные этой таблицы образуют список компонентов для параметра Логировать действия в расширениях в настройках компонента. Столбец extension в ней содержит значение системного имени компонента вида com_content, com_menus, com_modules и т.д.
- #__actionlogs_users - параметры логирования действий для конкретных пользователей. Эти параметры можно настроить в профиле пользователя, вкладка "Лог действий"
- #__action_log_config - параметры для конструирования языковой константы сообщения лога и данных для неё.
Анализ плагина action logs ядра Joomla
В Joomla штатные действия ядра записывает плагин Лог действий - Joomla. Он не имеет настраиваемых параметров. Файл класса плагина находится в plugins/actionlog/joomla/src/Extension/Joomla.php.
Логика работы плагина в целом состоит из следующих шагов:
- Проверить, в допустимом ли контексте вызвано событие. Обычно у компонента несколько сущностей (категории материалов и материалы; категории товаров, товары, производители товаров, характеристики товаров и т.д.), список их контекстов заносится в свойство класса плагина.
- Получить системное имя компонента вида com_mycomponent. В разных случаях мы получаем его или из контекста с помощью explode('.', $context), либо из $_GET массива с помощью объекта Input: $option = $app->getInput()->get('option').
- Проверить, а разрешено ли логировать действия в данном компоненте.
- В зависимости от типа события - сконструировать языковую константу и получить данные для подмены плейсхолдеров в ней.
- Собрать массив с сообщением и данными.
- Добавить массив в лог.
Языковые константы
Языковые константы ядра Joomla для лога действий пользователя распределены между файлами локализаций двух плагинов - групп system и actionlog:
- administrator/language/ru-RU/plg_actionlog_joomla.ini
- administrator/language/ru-RU/plg_system_actionlogs.ini
Если мы откроем файлы локализации плагина группы actionlog Joomla, то увидим в нём следующие строки:
PLG_SYSTEM_ACTIONLOGS_CONTENT_ADDED="Пользователь <a href=\"{accountlink}\">{username}</a> создал {type} <a href=\"{itemlink}\">{title}</a>"
PLG_SYSTEM_ACTIONLOGS_CONTENT_ARCHIVED="Пользователь <a href=\"{accountlink}\">{username}</a> переместил в архив {type} <a href=\"{itemlink}\">{title}</a>"
PLG_SYSTEM_ACTIONLOGS_CONTENT_DELETED="Пользователь <a href=\"{accountlink}\">{username}</a> удалил {type} {title}"
PLG_SYSTEM_ACTIONLOGS_CONTENT_PUBLISHED="Пользователь <a href=\"{accountlink}\">{username}</a> опубликовал {type} <a href=\"{itemlink}\">{title}</a>"
PLG_SYSTEM_ACTIONLOGS_CONTENT_TRASHED="Пользователь <a href=\"{accountlink}\">{username}</a> переместил в корзину {type} <a href=\"{itemlink}\">{title}</a>"
PLG_SYSTEM_ACTIONLOGS_CONTENT_UNPUBLISHED="Пользователь <a href=\"{accountlink}\">{username}</a> снял с публикации {type} <a href=\"{itemlink}\">{title}</a>"
PLG_SYSTEM_ACTIONLOGS_CONTENT_UPDATED="Пользователь <a href=\"{accountlink}\">{username}</a> обновил {type} <a href=\"{itemlink}\">{title}</a>"
Имя языковой константы конструируется по формуле [text_prefix] + [entity] + [action]
.
$text_prefix
- это обычно свойство контроллера или модели компонента. В нём хранится системное имя компонента: com_categories
, com_content
, com_menus
. Или [имя компонента + сущность]: com_banners_client
, com_banners_banners
.

Набор типов действий по умолчанию в Joomla интуитивно понятны. Суффикс ADD для вновь созданных элементов, DELETED - для удалённых и т.д.
Фрагмент entity в имени языковой константы в Joomla по умолчанию равен "CONTENT". Он используется в случаях, когда отсутствуют созданные языковые константы, но вывести что-то нужно.
Типы изменяемых сущностей
Ещё ряд языковых констант даёт нам название типов изменяемых сущностей, отвечая на вопрос "что?" - что было изменено / создано / удалено и т.д. В файле administrator/language/ru-RU/plg_actionlog_joomla.ini это строки
;...
PLG_ACTIONLOG_JOOMLA_TYPE_ARTICLE="материал"
PLG_ACTIONLOG_JOOMLA_TYPE_BANNER="баннер"
PLG_ACTIONLOG_JOOMLA_TYPE_BANNER_CLIENT="клиента"
PLG_ACTIONLOG_JOOMLA_TYPE_CATEGORY="категорию"
PLG_ACTIONLOG_JOOMLA_TYPE_COMPONENT="компонент"
PLG_ACTIONLOG_JOOMLA_TYPE_COMPONENT_CONFIG="Настройки компонента"
PLG_ACTIONLOG_JOOMLA_TYPE_CONTACT="контакт"
PLG_ACTIONLOG_JOOMLA_TYPE_FIELD="поле"
;...
Они формируются по формуле [text_prefix] + _TYPE_ + [entity]
.
Плейсхолдеры в языковых константах (переменные для строковой замены)
Вы уже обратили внимание на переменные в составе языковых констант. В примере выше мы можем увидеть
{accountlink}
- ссылку на пользователя в админке Joomla{username}
- имя пользователя{type}
- тип сущности: материал, баннер, модуль, параметры конфигурации, товар и т.д.{itemlink}
- ссылка в админке на сущность, с которой произошло событие{title}
- название / заголовок сущности
Также штатно обрабатываются ещё следующие плейсхолдеры, работающие везде:
{userid}
- id юзера, совершающего действие. Используется для формирования ссылок на него.{app}
- тип приложения: панель управления, API (Joomla REST API), CLI, сайт.
Некоторые плейсхолдеры используются только в определенных частях системы, например в REST API Joomla:
{verb}
- для логирования запросов REST API - тип запроса GET, POST, PUT и т.д.{url}
- для логирования запросов REST API - url запроса
Конструирование языковых констант
Посмотрим на структуру таблицы #__action_log_config
. В ней содержатся необходимые данные для конструирования языковых констант и источники данных для плейсхолдеров.

text_prefix
- см. о нём выше. Префикс для языковых констант.type_alias
- содержит в себе контекст выполнения действия.$context
содержит в себе системное имя компонента и сущности вида<com_component>.<entity>
. Если в этом списке нет нужного контекста - штатный плагин Joomla не сработает.table_name
- имя таблицы базы данных, из которых нужно выбирать данные в некоторых случаях. Например при смене состояния: опубликовано / не опубликовано * перемещено в корзину / перемещено в архив. При пакетных действиях на триггерonContentChangeState
приходит списокid
и чтобы получить заголовок статьи нужно сходить за ним в базу.type_title
- поле, в котором находится фрагмент языковой константы типа изменяемой сущности для данного контекста. Например, для контекстаcom_content.article
при формировании языковой константы для плейсхолдера{type}
будет создано PLG_ACTIONLOG_JOOMLA_TYPE_ARTICLE.id_holder
иtitle_holder
- содержат в себе названия свойств объектаTable
изменяемой сущности. Например, если мы отслеживаем материал Joomla, то для ссылки на созданный / изменённый материал нам нужен егоid
и он хранится в таблице#__content
в столбце с названиемid
. Аналогично заголовок материала хранится в таблице#__content
в столбце с названиемtitle
. Однако, у баннеров столбец для заголовка баннера называетсяname
и т.д.
Посмотрим на примере одного события onContentAfterSave
как работает штатный плагин.
<?php
// \Joomla\Plugin\Actionlog\Joomla\Extension\Joomla::onContentAfterSave
// Файл plugins/actionlog/joomla/src/Extension/Joomla.php
use Joomla\CMS\Event\Model;
/**
* After save content logging method
* This method adds a record to #__action_logs contains (message, date, context, user)
* Method is called right after the content is saved
*
* @param Model\AfterSaveEvent $event The event instance.
*
* @return void
*
* @since 3.9.0
*/
public function onContentAfterSave(Model\AfterSaveEvent $event): void
{
// Контекст вида com_content.article
$context = $event->getContext();
// Исторически это $article, хотя правильнее назвать $item
$article = $event->getItem();
// Логический флаг: создаётся новый элемент или редактируется уже существующий
$isNew = $event->getIsNew();
if (isset($this->contextAliases[$context])) {
$context = $this->contextAliases[$context];
}
// Параметры компонента. Тут находится список
// разрешённых к логированию компонентов.
// Этот список переопределяется настройками
// конкретного юзера в его профиле.
$params = $this->getActionLogParams($context);
// Not found a valid content type, don't process further
if ($params === null) {
return;
}
// $option - это системное имя компонента вида com_component.
[$option, $contentType] = explode('.', $params->type_alias);
// Можно ли логировать действия в данном компонент для данного юзера?
if (!$this->checkLoggable($option)) {
return;
}
// Конструируем языковую константу
// Добавляем нужные суффиксы к языковой константе.
if ($isNew) {
$messageLanguageKey = $params->text_prefix . '_' . $params->type_title . '_ADDED';
$defaultLanguageKey = 'PLG_SYSTEM_ACTIONLOGS_CONTENT_ADDED';
} else {
$messageLanguageKey = $params->text_prefix . '_' . $params->type_title . '_UPDATED';
$defaultLanguageKey = 'PLG_SYSTEM_ACTIONLOGS_CONTENT_UPDATED';
}
// If the content type doesn't have its own language key, use default language key
if (!$this->getApplication()->getLanguage()->hasKey($messageLanguageKey)) {
$messageLanguageKey = $defaultLanguageKey;
}
$id = empty($params->id_holder) ? 0 : $article->{$params->id_holder};
// Массив с сообщением
$message = [
'action' => $isNew ? 'add' : 'update',
'type' => $params->text_prefix . '_TYPE_' . $params->type_title,
'id' => $id,
'title' => $article->{$params->title_holder} ?? '',
'itemlink' => ActionlogsHelper::getContentTypeLink($option, $contentType, $id, $params->id_holder, $article),
];
$this->addLog([$message], $messageLanguageKey, $context);
}
В массиве $message
хранятся данные для плейсхолдеров в языковой константе. Дополнительно, 4-м аргументов в $this->addLog()
можно передать id
пользователя, для которого создаётся запись. Обычно это id
текущего пользователя.
Решение без создания плагина
Можно обойтись и без создания собственного плагина. Если для вас сообщения вида "Пользователь [Сиреневый Енот] [обновил] [сущность] [ссылка на сущность]" достаточно информативны, то можно обойтись просто добавлением своих параметров в базу данных.
Вы добавляете свой компонент в список возможных логируемых компонентов (для выпадающего списка в настройках компонента Лог пользователей) в таблицу #__actionlogs_extensions
и затем добавляете параметры для конструирования языковых констант в таблицу #__action_log_config
. А дальше вам нужно лишь создать 4 файла локализации с текстами сообщений: 2 на английском и 2 на русском языках. Всю дальнейшую работу будет выполнять плагин ядра Joomla.
Сделать это можно при создании очередного релиза вашего компонента в sql-файлах пакета буквально парой запросов.
Задача решена. Дальше статью можно не читать.
Создание своего плагина
Если вам нужны более информативные сообщения в логах, где используется больше плейсхолдеров в языковых константах или же не все данные приходят в объекте Table изменяемой сущности, то тогда потребуется создать полноценный плагин. Создаём плагин группы actionlog по типовой для Joomla 4+ структуре файлов и классов. Здесь читаем статью Создание плагинов с учётом новой структуры Joomla 4 (она же на моём сайте Создание плагинов с учётом новой структуры Joomla 4).
Триггеры событий для плагинов (Event Dispatching)
Ранее писал статью Триггеры ядра Joomla при CRUD-операциях, в которой рассказывается о различных событиях, вызываемых в моделях ядра Joomla. Модели компонентов ядра и немалая часть сторонних компонентов (но далеко не все) наследуют \Joomla\CMS\MVC\Model\AdminModel (libraries/src/MVC/Model/AdminModel.php). Поэтому в них доступны все стандартные события:
- onContentBeforeDelete - перед удалением сущности
- onContentAfterDelete - после удаления
- onContentBeforeSave - перед сохранением данных сущности
- onContentAfterSave - после сохранения
- onContentBeforeChangeState - перед изменением состояния (опубликовано, не опубликовано, в корзине...)
- onContentChangeState - после изменения состояния
- onBeforeBatch - перед пакетной обработкой нескольких сущностей
В некоторых случаях названия события отличаются, подробнее об этом смотрим в указанной статье.
При триггере события в плагин передаются данные, для каждого события - свои. Приведу примеры:
onContentAfterSave - после сохранения
Событие вызывается после сохранения любой сущности в Joomla (повторюсь, если модели компонента наследуют AdminModel). В аргументах события мы имеем:
$context
- string - контекст события вида<component_name>.<entity>
:com_content.article
,com_contact.contact
и т.д.$article
- объектTable
сохранённой сущности. Вообще-то оно должно называться$item
, так как это может быть не только статья, но и что угодно. Но видимо плагин изначально писали для материалов и оно так и осталось.$isNew
- bool - логический флаг новая ли сущность или уже существующая.$data
- array - данные отправленной в модель формы. Не все данные могут быть в объектеTable
, некоторые поля формы могут храниться в других таблицах. Но в триггер передаётся лишь одна. Здесь зависит от того, какое поведение реализует модель компонента.
Штатный плагин подразумевает, что всё-таки большая часть данных формы хранится в одной основной таблице и аргумент $data
не использует.
onContentAfterDelete - после удаления
Доступные аргументы - $context
и $item
. Необходимое нам системное имя компонента - получаем уже из объекта Input.
onContentChangeState - после смены состояния
Состояния: опубликовано / не опубликовано / в корзине / в архиве. Также ваш компонент может иметь собственную, более широкую систему состояний.
В аргументах события:
$context
- string - контекст события вида<component_name>.<entity>
:com_content.article
,com_contact.contact
и т.д.$pks
- array - массив с id изменяемых сущностей.$value
- int - числовое значение состояние. 0 - не опубликовано, 1 - опубликовано, 2 - в архиве, -2 - в корзине.
Далее, на каждое событие вы конструируете языковые константы тем же образом. что и штатный плагин. А в массив $message помещаете данные для всех необходимых плейсхолдеров. Приведу пример из плагина логирования действий пользователей в админке компонента SW JProjects (GitHub).
<?php
/**
* After save content logging method.
* This method adds a record to `#__action_logs` contains (message, date, context, user)
* Method is called right after the content is saved
*
* @param string $context
* @param object $item
* @param bool $isNew
* @param array $data
*
* @return void
*
* @since 2.4.0 // $context, $item, $isNew, $data
* @todo use Model\AfterSaveEvent $event when Joomla 6 will be released
*/
public function onContentAfterSave($context, $item, $isNew, $data): void
{
// На момент выпуска релиза ещё немало сайтов было на Joomla 4,
// поэтому из-за сохранения обратной совместимости с ней
// используется ещё старый подход.
// На новые рельсы перейдём после релиза Joomla 6 осенью 2025г.
// $context = $event->getContext();
// $item = $event->getItem();
// $isNew = $event->getIsNew();
// $data = $event->getData();
// Массив с допустимыми контекстами для данного компонента
if (!in_array($context, $this->contextList))
{
return;
}
list($option, $contentType) = explode('.', $context);
// Можно ли логировать данный компонент для конкретного юзера?
if (!$this->checkLoggable($option))
{
return;
}
// Новая сущность или редактируемая старая?
if ($isNew) {
$messageLanguageKey = 'PLG_ACTIONLOG_SWJPROJECTS_' . strtoupper($contentType) . '_ADDED';
$data['id'] = $item->id;
} else if ($context == 'com_swjprojects.key' && $data['key_regenerate'] == 1) {
$messageLanguageKey = 'PLG_ACTIONLOG_SWJPROJECTS_KEY_REGENERATED';
} else {
$messageLanguageKey = 'PLG_ACTIONLOG_SWJPROJECTS_' . strtoupper($contentType) . '_UPDATED';
}
// Для получения title отдельный метод, так как в компоненте не стандартная мультиязычность
$message = [
'action' => $isNew ? 'add' : 'update',
'type' => 'PLG_ACTIONLOG_SWJPROJECTS_TYPE_' . strtoupper($contentType),
'id' => $item->id,
'title' => $this->getItemTitle($context, $data),
'itemlink' => 'index.php?option=com_swjprojects&task=' . $contentType . '.edit&id=' . $item->id,
];
// В случае необходимости можно использовать любое количество
// плейсхолдеров для замены.
// Добавляем здесь нужные для нужных контекстов.
if (!in_array($contentType, ['project', 'category', 'key']))
{
$message['projectTitle'] = $this->getProjectTitle($item->project_id);
$message['projectLink'] = 'index.php?option=com_swjprojects&task=project.edit&id=' . $item->project_id;
}
$this->addLog([$message], $messageLanguageKey, $context);
}
В этом примере видно, что для некоторых контекстов (категория, проект и лицензионный ключ) нам не хватает стандартных значений и мы добавляем свои. Языковые константы выглядят следующим образом:
; Добавление документации для цифрового проекта
PLG_ACTIONLOG_SWJPROJECTS_DOCUMENT_ADDED="Пользователь <a href=\"{accountlink}\">{username}</a> создал документацию <a href=\"{itemlink}\">{title}</a> для проекта <a href=\"{projectLink}\">{projectTitle}</a> в компоненте SW JProjects"
; Добавление лицензионного ключа
PLG_ACTIONLOG_SWJPROJECTS_KEY_ADDED="Пользователь <a href=\"{accountlink}\">{username}</a> создал лицензионный ключ id <code>{title}</code> в компоненте SW JProjects"
; Работа с версиями программного обеспечения
PLG_ACTIONLOG_SWJPROJECTS_VERSION_PUBLISHED="Пользователь <a href=\"{accountlink}\">{username}</a> опубликовал версию <a href=\"{itemlink}\">{title}</a> для проекта <a href=\"{projectLink}\">{projectTitle}</a> в компоненте SW JProjects"
PLG_ACTIONLOG_SWJPROJECTS_VERSION_TRASHED="Пользователь <a href=\"{accountlink}\">{username}</a> переместил в корзину версию <a href=\"{itemlink}\">{title}</a> для проекта <a href=\"{projectLink}\">{projectTitle}</a> в компоненте SW JProjects"
Так это выглядит в панели администратора.
Дополнительные детали
Метод checkLoggable()
Конструктор класса плагина обычно выглядит следующим образом:
<?php
/**
* Constructor.
*
* @param DispatcherInterface $dispatcher The dispatcher
* @param array $config An optional associative array of configuration settings
*
* @since 2.4.0
*/
public function __construct(DispatcherInterface $dispatcher, array $config)
{
parent::__construct($dispatcher, $config);
$params = ComponentHelper::getComponent('com_actionlogs')->getParams();
// Массив с системными именами логируемых компонентов
$this->loggableExtensions = $params->get('loggable_extensions', []);
// То же самое для REST API
$this->loggableApi = $params->get('loggable_api', 0);
// Логируемые методы REST API
$this->loggableVerbs = $params->get('loggable_verbs', []);
}
А сам метод проверки выглядит так:
<?php
/**
* Function to check if a component is loggable or not
*
* @param string $extension The extension that triggered the event
*
* @return boolean
*
* @since 2.4.0
*/
protected function checkLoggable(string $extension): bool
{
return in_array($extension, $this->loggableExtensions);
}
Заключение
Иногда сохранённые логи действий пользователей помогают быстрее найти решение проблемы, если она вызвана человеческим фактором. Да, может быть не всё удобно с точки зрения удобства использования и поиска, но это Open Source и это в составе ядра Joomla.
Надеюсь, мне удалось понятно изложить эту тему и по этой статье можно будет быстро внедрить нужный функционал в ваши компоненты Joomla.