Глава 7. Архитектура и разработка плагинов

07-07-26 10:41

Плагины (расширения) в Seditio представляют собой гибкие и легкие программные компоненты, предназначенные для модификации поведения ядра или добавления новых функций без прямого изменения оригинальных файлов CMS. В этой главе рассматриваются концепция хуков, файловая структура плагинов, синтаксис манифестов частей, режимы работы и система безопасности.


7.1. Отличие плагинов от модулей и концепция хуков (Hooks)

7.1.1. Модули vs. Плагины

  • Модули (Modules): Это крупные, самостоятельные контентные блоки (например, Страницы, Форумы, Галерея). Они обладают выделенными контроллерами, собственной точкой входа через фронт-контроллер (index.php?module=имя_модуля) и часто имеют автономную панель управления.
  • Плагины (Plugins): Это расширения общего назначения (например, капча, антиспам, вывод статистики, сжатие HTML). Они работают «под капотом» системы, подписываясь на определенные точки расширения (хуки) ядра и модулей.

7.1.2. Механизм работы системы хуков (Hooks)

Система хуков позволяет внедрять код плагинов в строго определенные места системных файлов. В ядре Seditio точки расширения обозначаются специальным PHP-комментарием и блоком вызова:

/* === Hook === */
$extp = sed_getextplugins('имя_хука');
if (is_array($extp)) {
	foreach ($extp as $k => $pl) {
		include(SED_ROOT . '/plugins/' . $pl['pl_code'] . '/' . $pl['pl_file'] . '.php');
	}
}
/* ===== */
  • sed_getextplugins('имя_хука', $cond): Функция ядра сканирует таблицу sed_plugins в базе данных (которая кэшируется в $sed_plugins при инициализации) и возвращает отсортированный массив активных файлов плагинов, подписанных на этот хук. Параметр $cond (по умолчанию 'R') указывает необходимый уровень прав доступа к плагину для его выполнения.
  • include(...): Ядро поочередно подключает PHP-файлы этих плагинов. Код плагина выполняется в том же контексте (области видимости), что и сам вызывающий файл ядра, получая прямой доступ к его глобальным переменным (например, $usr, $cfg, $L, $t для XTemplate).

7.2. Файловая структура и части плагина

Все плагины в Seditio располагаются в каталоге plugins. Папка плагина должна носить имя, совпадающее с его системным кодом (пишется в нижнем регистре, слитно, например, plugins/myplugin).

7.2.1. Соглашение об именах файлов

Ниже представлена стандартная файловая структура кастомного плагина myplugin:

plugins/myplugin/
├── myplugin.setup.php            # Общий манифест установки и конфигурация
├── myplugin.install.php          # SQL/PHP скрипт установки (опционально)
├── myplugin.uninstall.php        # SQL/PHP скрипт удаления (опционально)
├── myplugin.urls.php             # Правила ЧПУ роутинга плагина (опционально)
├── myplugin.php                  # Исполняемый файл части (part) плагина
├── myplugin.admin.php            # Дополнительный исполняемый файл части админки
├── admin/
│   └── myplugin.admin.menu.php   # Возвращает массив для интеграции в меню админки (опционально)
├── inc/
│   └── myplugin.functions.php    # Пользовательские функции плагина (опционально)
├── lang/
│   ├── myplugin.en.lang.php      # Перевод настроек и интерфейса на английский
│   └── myplugin.ru.lang.php      # Перевод настроек и интерфейса на русский
└── tpl/
    ├── myplugin.tpl              # Шаблон вывода автономной страницы (опционально)
    └── myplugin.admin.tpl        # Шаблон административной панели плагина (опционально)

7.2.2. Концепция частей (Parts) плагина

В отличие от других CMS, где плагин представляет собой один большой файл, в Seditio плагин разделяется на изолированные части (Parts). Каждому исполняемому PHP-файлу в папке плагина (за исключением файлов setup, install, uninstall и urls) соответствует своя часть плагина. Например, плагин может выполнять валидацию формы при регистрации, логировать авторизацию и выводить виджет на главную страницу:

  • Для валидации формы создается файл myplugin.register.php (подписывается на хук users.register.add.first).
  • Для логирования создается файл myplugin.login.php (подписывается на хук users.auth.done).
  • Для вывода виджета создается файл myplugin.php (подписывается на хук index.tags).

7.3. Манифест плагина {код_плагина}.setup.php

Файл .setup.php (например, trashcan.setup.php) содержит общие метаданные для инсталлятора Seditio.

7.3.1. Метаданные инсталлятора ([BEGIN_SED_EXTPLUGIN])

Этот блок регистрирует плагин в системе, задает зависимости и права доступа по умолчанию:

/* ====================
[BEGIN_SED]
File=plugins/myplugin/myplugin.setup.php
Version=185
Updated=2026-apr-10
Type=Plugin
Author=Developer
Description=My custom plugin
[END_SED]

[BEGIN_SED_EXTPLUGIN]
Code=myplugin                     ; Уникальный текстовый код плагина
Name=My Plugin                    ; Название плагина
Description=Handles custom hooks  ; Описание
Version=1.0.0                     ; Версия плагина
Date=2026-apr-10                  ; Дата создания
Author=Developer                  ; Автор
Copyright=                        ; Копирайт
Notes=                            ; Примечания
SQL=                              ; Зарезервировано
Auth_guests=R                     ; Права гостей по умолчанию (Read)
Lock_guests=W12345A               ; Заблокированные права гостей
Auth_members=R                    ; Права зарегистрированных пользователей (Read)
Lock_members=W12345A              ; Заблокированные права участников
Requires_modules=page,pfs         ; Необходимые модули (через запятую, опционально)
Requires_plugins=tags             ; Необходимые плагины (через запятую, опционально)
[END_SED_EXTPLUGIN]
==================== */

7.3.2. Конфигурация плагина ([BEGIN_SED_EXTPLUGIN_CONFIG])

Объявляет настройки плагина, которые выводятся в панели управления по адресу /admin/config?n=edit&o=plug&p=myplugin. Опции описываются по следующему шаблону: имя_переменной=порядок:тип:варианты:значение_по_умолчанию:описание

Пример:

[BEGIN_SED_EXTPLUGIN_CONFIG]
limit=01:select:5,10,15,20:10:Лимит записей для вывода
enable_logs=02:radio:0,1:1:Логировать действия пользователей
custom_title=03:string::Заголовок:Название блока на главной
[END_SED_EXTPLUGIN_CONFIG]

Эти настройки автоматически импортируются в общую таблицу конфигурации sed_config при установке плагина и доступны в коде через глобальный массив $cfg['plugin']['myplugin']['имя_переменной'].


7.4. Анатомия исполняемых файлов частей и регистрация хуков

Каждый исполняемый PHP-файл части плагина (например, trashcan.admin.home.php) должен содержать локальный манифест [BEGIN_SED_EXTPLUGIN] ... [END_SED_EXTPLUGIN] в своем заголовке.

7.4.1. Локальный манифест части плагина

Пример содержимого заголовка файла myplugin.admin.php:

<?php
/* ====================
[BEGIN_SED]
File=plugins/myplugin/myplugin.admin.php
Version=1.0.0
Updated=2026-apr-10
Type=Plugin
[END_SED]

[BEGIN_SED_EXTPLUGIN]
Code=myplugin                     ; Код плагина, к которому относится этот файл
Part=admin                        ; Идентификатор (название) этой части
Hooks=admin.home.first            ; Системные хуки, на которые вешается обработчик (через запятую при мультихуках)
File=myplugin.admin               ; Имя этого PHP-файла (без расширения .php)
Order=10                          ; Порядок выполнения (0..99, по умолчанию 10)
Lock=0                            ; Флаг блокировки: 1 - нельзя отключить отдельно эту часть, 0 - можно
[END_SED_EXTPLUGIN]
==================== */

if (!defined('SED_CODE')) { die('Wrong URL.'); }

// PHP-код обработчика...
  • Поддержка множественных хуков (Multihooks): Начиная с версии 1.7.3, одна часть плагина может быть подписана на несколько хуков одновременно. Для этого в параметре Hooks перечисляются системные хуки через запятую (например, Hooks=index.tags,header.tags). В параметре Order также можно указать соответствующие приоритеты через запятую (например, Order=10,20 или Order=10 для всех).
  • Параметр блокировки Lock: Если установлено Lock=1, то в панели администрирования плагинов данную часть нельзя будет временно поставить на паузу (деактивировать) отдельно от всего плагина.

7.4.2. Алгоритм регистрации плагина инсталлятором

При переходе администратора в раздел управления плагинами /admin/plug:

  1. Инсталлятор сканирует папку /plugins/myplugin/ и находит все файлы с расширением .php (исключая setup, install, uninstall и urls).
  2. Из каждого PHP-файла считывается секция [BEGIN_SED_EXTPLUGIN].
  3. Для каждой найденной части в таблицу базы данных sed_plugins вставляется запись со следующей структурой:
    • pl_code — код плагина (myplugin).
    • pl_part — имя части (admin).
    • pl_hook — хук (admin.home.first).
    • pl_file — подключаемый файл (myplugin.admin).
    • pl_order — приоритет выполнения (10).
    • pl_active — статус активности части (1 или 0).
    • pl_lock — флаг защиты от отключения (0 или 1).
  4. При обработке ядром хука admin.home.first вызовется SQL-запрос для поиска всех активных плагинов этого хука, отсортированных по полю pl_order, после чего файлы подключатся через include.

7.5. Режимы работы плагинов

В зависимости от назначения и привязанных хуков, плагины могут работать в нескольких режимах:

7.5.1. Режим обработчиков (Hook-плагины)

Это классический режим. Плагин встраивается в цепочку выполнения PHP на бэкенде.

  • Он может обрабатывать входящие массивы данных (например, очищать переменные в $_POST перед сохранением).
  • Может генерировать TPL-теги. Например, часть плагина, привязанная к хуку index.tags, может присвоить значение тегу шаблона главной страницы:
    $t->assign("MYPLUGIN_WIDGET", "Привет, это данные из плагина!");
    

7.5.2. Автономный режим (Standalone-плагины)

Позволяет плагину работать в качестве полноценного изолированного раздела сайта со стандартным оформлением. Для этого часть плагина должна быть зарегистрирована на хук standalone.

  • Ссылка на плагин: Адрес плагина формируется как /plug/myplugin при включенном ЧПУ (или index.php?module=plug&e=myplugin при отключенном ЧПУ).
  • Маршрутизация: Запрос перенаправляется на системный контроллер system/core/plug/plug.php, который считывает параметр e (или ЧПУ-параметр), проверяет права доступа пользователя к этому плагину и подключает файл части, зарегистрированной на хук standalone (через system/core/plug/plug.inc.php).
  • Шаблонизация: Ядро Seditio автоматически подключает глобальный заголовок system/header.php (выводящий header.tpl) перед выполнением плагина и подвал system/footer.php (выводящий footer.tpl) после его выполнения. Поиск TPL-шаблона плагина происходит в следующем порядке:
    1. Текущий скин: skins/{skin_name}/{plugin_code}.tpl
    2. Папка плагина: plugins/{plugin_code}/{plugin_code}.tpl
    3. Системный шаблон-заглушка: skins/{skin_name}/plugin.tpl (в этом случае переменные PLUGIN_TITLE и PLUGIN_BODY заполняются автоматически из кода плагина).

7.5.3. Режим прямого вызова (Direct-плагины)

Предоставляет плагину полный контроль над формированием вывода. Для активации этого режима часть плагина должна быть зарегистрирована на хук direct.

  • Ссылка на плагин: Вызывается так же, как и standalone — /plug/myplugin (или index.php?module=plug&e=myplugin без ЧПУ).
  • Главное отличие: В отличие от Standalone-режима, ядро Seditio не подключает системные файлы header.php и footer.php. Плагин выполняется напрямую, благодаря чему разработчик может выводить собственную HTML-разметку, формировать XML/RSS-ленты, отдавать файлы на скачивание или возвращать JSON-данные.
  • Права доступа: Ядро по-прежнему проверяет права доступа к плагину перед подключением исполняемого файла.

7.5.4. Режим Popup (Всплывающие окна)

Используется для вызова плагина во всплывающем окне с упрощенным оформлением. Для активации этого режима часть плагина должна быть зарегистрирована на хук popup.

  • Ссылка на плагин: Вызывается по адресу /plug?o=myplugin (или index.php?module=plug&o=myplugin без ЧПУ).
  • Особенности: Ядро подключает упрощенный шаблон popup.tpl (или skins/{skin_name}/popup.myplugin.tpl), автоматически передает имя родительской формы/поля в JS-функцию add(text) для вставки данных (например, BB-кодов или смайлов в форму ввода текста на основной странице).

7.5.5. Режим AJAX

Используется для обработки фоновых запросов без перезагрузки страниц. Для активации этого режима часть плагина должна быть зарегистрирована на хук ajax.

  • Ссылка на плагин: Вызывается по адресу /plug?ajx=myplugin (или index.php?module=plug&ajx=myplugin без ЧПУ).
  • Особенности: Не подключаются никакие шаблоны, заголовки или подвалы. Возвращаются только те данные, которые плагин выведет напрямую (через echo или exit).

7.5.6. Режим ручного запуска (Code Launchers)

Позволяет выполнять скрипты без регистрации частей в таблице sed_plugins.

  • Ссылка на скрипт: Вызывается по адресу /plug?r=myscript (или index.php?module=plug&r=myscript без ЧПУ).
  • Особенности: Вызов напрямую загружает PHP-файл по пути plugins/code/myscript.php (если файл существует). Это полезно для утилит или административных скриптов, выполняющихся вне общей архитектуры хуков.

7.5.7. ЧПУ-роутинг плагина

Кастомный плагин может объявить собственные правила преобразования URL, создав файл myplugin.urls.php в своей папке. Структура файла полностью идентична файлу ЧПУ модулей (см. Глава 6. Архитектура и разработка модулей). Правила трансляции из этого файла автоматически импортируются ядром при перегенерации кэша ЧПУ.


7.6. Скрипты инсталляции, интеграции в меню и права доступа (ACL)

7.6.1. SQL и PHP при инсталляции (myplugin.install.php)

Скрипт установки myplugin.install.php запускается администратором в один клик при установке плагина из панели управления. В нем описывается создание таблиц в СУБД, импорт базовых данных и проверка прав записи на системные папки:

<?php
if (!defined('SED_CODE') || !defined('SED_ADMIN')) { die('Wrong URL.'); }

// Пример создания таблицы для плагина
$db_myplugin_table = $cfg['sqldbprefix'] . 'myplugin_table';
sed_sql_query("CREATE TABLE IF NOT EXISTS $db_myplugin_table (
    log_id int(11) NOT NULL auto_increment,
    log_text text NOT NULL,
    PRIMARY KEY (log_id)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;");

Скрипт деинсталляции myplugin.uninstall.php выполняет обратную операцию — удаляет таблицы плагина из базы данных при его деинсталляции.

7.6.2. Интеграция ссылки плагина в меню админки (admin/{код_плагина}.admin.menu.php)

Если плагин добавляет свой раздел в панель управления (через хук admin.plug), то для добавления ссылки в левый сайдбар административной панели создается файл admin/myplugin.admin.menu.php, возвращающий массив конфигурации пункта меню:

<?php
if (!defined('SED_CODE')) { die('Wrong URL.'); }

return array(
	'title'     => 'My Plugin',               // Заголовок пункта меню (можно использовать строки локализации $L)
	'order'     => 15,                        // Порядок сортировки в боковом меню
	'adminlink' => sed_url('admin', 'm=trashcan'), // Ссылка на административную часть плагина
	'auth'      => array('plug', 'myplugin', 'A'), // Правило проверки прав доступа: область, код, опция
	'sections'  => array()                    // Дополнительные подразделы меню (опционально)
);

7.6.3. Разграничение прав доступа (ACL) в плагинах

Права доступа к плагинам настраиваются администратором в разделе /admin/users для каждой группы. При установке плагина система берет права по умолчанию из параметров Auth_guests и Auth_members файла setup-манифеста.

Внутри PHP-кода плагина (особенно в режиме standalone, ajax или admin) разработчик должен проверить наличие прав у посетителя:

// Проверяем права на чтение (Read) текущего плагина
// Первая колонка прав 'plug' указывает, что проверяется плагин
list($usr['auth_read'], $usr['auth_write'], $usr['isadmin']) = sed_auth('plug', 'myplugin');

// Блокируем доступ, если прав на чтение нет
sed_block($usr['auth_read']);

Благодаря этой проверке плагин защищается от несанкционированных вызовов через фронт-контроллер.

Оценка:
(0.00)

Пока комментариев нет