Как стать автором
Обновить

Логирование действий пользователя в Joomla. Создание плагина Actionlog

Время на прочтение16 мин
Количество просмотров264

На вашем сайте, внутреннем портале, в интернет-магазине кто-то что-то сделал, а потом всё сломалось: сайт открывается криво (или не открывается вообще?), перестали работать фоновые задачи в планировщике, установились неправильные скидки всем пользователям на все товары... Предположим, что с безопасностью у вас всё хорошо: Joomla свежая, актуальная, расширения - тоже. Да и в логах сервера и логах Joomla тоже чисто... Тогда остаётся ещё один источник информации - Лог действий пользователей Joomla. Основная его задача - помочь быстро найти кому настучать по рогам причину и устранить её.

Всё, что связано с действиями в админке - может логироваться: от обновления системы и компонентов, изменения настроек до редактирования и сохранения конкретных элементов (статьи, товары, категории и т.д.) и загрузки файлов через медиа менеджер. Лично мне нередко этот функционал помогал найти тех контент-менеджеров, кто дублирует названия товаров, создавая дубли и тем самым негативно влияя на SEO. Или же вдруг обнаруживается недозаполненная, но опубликованная карточка товара, которой не должно было быть, но она появилась. И ладно если б это был единичный случай.

Оговорка 1: статья рассчитана не только на тех, кто хорошо знает Joomla, но и на любопытствующих коллег из других технологических стеков. Поэтому некоторым очевидным терминам всё равно дано краткое пояснение.

Оговорка 2: на данный момент я рассматриваю Joomla скорее как PHP-фреймворк с натянутой на него готовой админкой, а не просто CMS. Расширение типа "компонент" в Joomla обычно представляет из себя набор различных CRUD-ов (в терминологии PHP-фреймворков), записи о действиях в которых можно хранить в логах. Поэтому статью следует больше рассматривать как начальную точку для проектирования и написания своего плагина (расширение, срабатывающие на триггеры событий Event Dispatcher) для своего же (скорее всего) компонента (CRUD-а).

Оглавление

Список литературы

Описание возможностей компонента Лога пользователей Joomla

Этот компонент был добавлен в ядро Joomla начиная с версии 3.9.0. Найти его можно в левом меню панели администратора: Пользователи - Лог действий пользователей.

Он предоставляет собой простой интерфейс для чтения и фильтрации записей.

Для всех записей указано расширение, к которому запись о событии относится.
Для всех записей указано расширение, к которому запись о событии относится.

На скриншоте я выделил колонку "расширение". По ней можно понять контекст записи о действии. На скриншоте видны разные компоненты:

  • "расширения" - действия, связанные с установкой, удалением и обновлением расширений, сохранением параметров.

  • "материалы" - штатный компонент для создания статей в Joomla. Его же нередко используют для создания каталогов чего угодно.

  • "SW JProjects" - сторонний компонент Joomla для ведения каталога расширений Joomla и сервера обновлений для них

  • "Лог действий" - собственно компонент лога действий пользователя Joomla

Так, например, компонент "пользователи" (com_users) логирует не только собственно действия с пользователями, но и моменты входа и выхода в админку.

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

Мы можем отфильтровать записи по типу расширения и увидеть только то, что нас интересует. Для этого пользуемся кнопкой "параметры поиска" в списке записей событий. Список расширений зависит от установленных компонентов и того, поддерживают ли они стандартный для Joomla action log.

Фильтр действий пользователя Joomla по расширению
Фильтр действий пользователя Joomla по расширению

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

Ну и конечно доступна фильтрация записей по конкретному пользователю.

Параметры компонента Лог действий пользователя в Joomla

Настройки компонента Лог действий пользователей Joomla
Настройки компонента Лог действий пользователей Joomla

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

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

Самое интересное здесь - возможность логирования запросов к REST API Joomla.

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

Пользователь Joomla выполнил GET запрос по
Пользователь Joomla выполнил GET запрос по

Таким образом если ваша 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.

Логика работы плагина в целом состоит из следующих шагов:

  1. Проверить, в допустимом ли контексте вызвано событие. Обычно у компонента несколько сущностей (категории материалов и материалы; категории товаров, товары, производители товаров, характеристики товаров и т.д.), список их контекстов заносится в свойство класса плагина.

  2. Получить системное имя компонента вида com_mycomponent. В разных случаях мы получаем его или из контекста с помощью explode('.', $context), либо из $_GET массива с помощью объекта Input: $option = $app->getInput()->get('option').

  3. Проверить, а разрешено ли логировать действия в данном компоненте.

  4. В зависимости от типа события - сконструировать языковую константу и получить данные для подмены плейсхолдеров в ней.

  5. Собрать массив с сообщением и данными.

  6. Добавить массив в лог.

Языковые константы

Языковые константы ядра 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. В ней содержатся необходимые данные для конструирования языковых констант и источники данных для плейсхолдеров.

Скриншот таблицы #__action_log_config Joomla
Скриншот таблицы #__action_log_config Joomla
  • 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.

Триггеры событий для плагинов (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.

Аргументированные замечания и предложения с радостью приму в комментариях.

Полезные ресурсы

Ресурсы сообщества:

Telegram:

Мой личный Telegram-канал - WebTolkRu.

Теги:
Хабы:
Если эта публикация вас вдохновила и вы хотите поддержать автора — не стесняйтесь нажать на кнопку
+5
Комментарии0

Публикации

Работа

PHP программист
82 вакансии

Ближайшие события