Архитектура XOOPS
Этот документ обеспечивает всестороннее описание архитектуры системы XOOPS, объясняя, как различные компоненты работают вместе для создания гибкой и расширяемой системы управления содержимым.
XOOPS следует модульной архитектуре, которая разделяет ответственность на отдельные уровни. Система построена вокруг нескольких основных принципов:
- Модульность: функциональность организована в независимые, устанавливаемые модули
- Расширяемость: система может быть расширена без изменения ядра
- Абстракция: слои базы данных и представления изолированы от бизнес-логики
- Безопасность: встроенные механизмы безопасности защищают от распространённых уязвимостей
Слои системы
Заголовок раздела «Слои системы»graph TB subgraph Presentation["🎨 Слой представления"] Themes["Темы"] Templates["Smarty шаблоны"] Blocks["Блоки"] end
subgraph Application["⚙️ Уровень приложения"] Modules["Модули"] Preloads["Preloads"] Controllers["Контроллеры"] BlockHandlers["Обработчики блоков"] end
subgraph Domain["📦 Слой домена"] XoopsObject["XoopsObject"] Handlers["Обработчики объектов"] Criteria["Система Criteria"] end
subgraph Infrastructure["🔧 Слой инфраструктуры"] Database["XoopsDatabase"] Cache["Система кэша"] Session["Менеджер сеанса"] Security["Слой безопасности"] end
Presentation --> Application Application --> Domain Domain --> Infrastructure
style Presentation fill:#e8f5e9,stroke:#388e3c style Application fill:#e3f2fd,stroke:#1976d2 style Domain fill:#fff3e0,stroke:#f57c00 style Infrastructure fill:#fce4ec,stroke:#c2185b1. Слой представления
Заголовок раздела «1. Слой представления»Слой представления обрабатывает рендеринг пользовательского интерфейса с использованием механизма шаблонизации Smarty.
Ключевые компоненты:
- Темы: визуальное оформление и расположение
- Smarty шаблоны: динамический рендеринг содержимого
- Блоки: переиспользуемые виджеты содержимого
2. Уровень приложения
Заголовок раздела «2. Уровень приложения»Уровень приложения содержит бизнес-логику, контроллеры и функциональность модулей.
Ключевые компоненты:
- Модули: независимые пакеты функциональности
- Обработчики: классы манипуляции данными
- Preloads: слушатели событий и hooks
3. Слой домена
Заголовок раздела «3. Слой домена»Слой домена содержит основные бизнес-объекты и правила.
Ключевые компоненты:
- XoopsObject: базовый класс для всех объектов домена
- Обработчики: операции CRUD для объектов домена
4. Слой инфраструктуры
Заголовок раздела «4. Слой инфраструктуры»Слой инфраструктуры предоставляет основные сервисы, такие как доступ к базе данных и кэширование.
Жизненный цикл запроса
Заголовок раздела «Жизненный цикл запроса»Понимание жизненного цикла запроса критически важно для эффективной разработки XOOPS.
Поток Page Controller в XOOPS 2.5.x
Заголовок раздела «Поток Page Controller в XOOPS 2.5.x»Текущий XOOPS 2.5.x использует паттерн Page Controller, где каждый PHP файл обрабатывает свой собственный запрос. Глобальные переменные ($xoopsDB, $xoopsUser, $xoopsTpl и т.д.) инициализируются при загрузке и доступны на всём протяжении выполнения.
sequenceDiagram participant Browser participant Entry as modules/mymod/index.php participant Main as mainfile.php participant Kernel as XOOPS ядро participant DB as $xoopsDB participant User as $xoopsUser participant Handler as MyObjectHandler participant Tpl as $xoopsTpl (Smarty) participant Theme
Browser->>Entry: GET /modules/mymod/index.php
rect rgb(240, 248, 255) Note over Entry,User: Фаза загрузки (mainfile.php) Entry->>Main: include mainfile.php Main->>Kernel: Инициализировать ядро Kernel->>DB: Создать XoopsDatabase (синглтон) Kernel->>User: Загрузить сеанс → $xoopsUser Kernel->>Tpl: Инициализировать Smarty → $xoopsTpl Main-->>Entry: Готовы глобальные переменные end
rect rgb(255, 250, 240) Note over Entry,Handler: Выполнение Page Controller Entry->>Handler: xoops_getModuleHandler('myobject') Handler->>DB: запрос через Criteria DB-->>Handler: Набор результатов Handler-->>Entry: XoopsObject[] end
rect rgb(240, 255, 240) Note over Entry,Theme: Фаза рендеринга Entry->>Tpl: $xoopsTpl->assign('items', $objects) Entry->>Theme: include header.php Entry->>Tpl: $xoopsTpl->display('mymod_index.tpl') Entry->>Theme: include footer.php Theme-->>Browser: Полная HTML-страница endКлючевые глобальные переменные в 2.5.x
Заголовок раздела «Ключевые глобальные переменные в 2.5.x»| Глобальная | Тип | Инициализирована | Назначение |
|---|---|---|---|
$xoopsDB | XoopsDatabase | Загрузка | Подключение к БД (синглтон) |
$xoopsUser | XoopsUser|null | Загрузка сеанса | Текущий авторизованный пользователь |
$xoopsTpl | XoopsTpl | Инициализация шаблонов | Механизм шаблонизации Smarty |
$xoopsModule | XoopsModule | Загрузка модуля | Контекст текущего модуля |
$xoopsConfig | array | Загрузка конфигурации | Конфигурация системы |
1. Фаза загрузки
Заголовок раздела «1. Фаза загрузки»// mainfile.php является точкой входаinclude_once XOOPS_ROOT_PATH . '/mainfile.php';
// Инициализация ядра$xoops = Xoops::getInstance();$xoops->boot();Шаги:
- Загрузить конфигурацию (
mainfile.php) - Инициализировать автозагрузчик
- Установить обработку ошибок
- Установить подключение к БД
- Загрузить сеанс пользователя
- Инициализировать механизм шаблонов Smarty
2. Фаза маршрутизации
Заголовок раздела «2. Фаза маршрутизации»// Маршрутизация запроса к соответствующему модулю$module = $GLOBALS['xoopsModule'];$controller = $module->getController();$controller->dispatch($request);Шаги:
- Разобрать URL запроса
- Идентифицировать целевой модуль
- Загрузить конфигурацию модуля
- Проверить разрешения
- Маршрутизировать к соответствующему обработчику
3. Фаза выполнения
Заголовок раздела «3. Фаза выполнения»// Выполнение контроллера$data = $handler->getObjects($criteria);$xoopsTpl->assign('items', $data);Шаги:
- Выполнить логику контроллера
- Взаимодействовать со слоем данных
- Обработать бизнес-правила
- Подготовить данные представления
4. Фаза рендеринга
Заголовок раздела «4. Фаза рендеринга»// Рендеринг шаблонаinclude XOOPS_ROOT_PATH . '/header.php';$xoopsTpl->display('db:module_template.tpl');include XOOPS_ROOT_PATH . '/footer.php';Шаги:
- Применить макет темы
- Отрендерить шаблон модуля
- Обработать блоки
- Выдать ответ
Основные компоненты
Заголовок раздела «Основные компоненты»XoopsObject
Заголовок раздела «XoopsObject»Базовый класс для всех объектов данных в XOOPS.
<?phpclass MyModuleItem extends XoopsObject{ public function __construct() { $this->initVar('id', XOBJ_DTYPE_INT, null, false); $this->initVar('title', XOBJ_DTYPE_TXTBOX, '', true, 255); $this->initVar('content', XOBJ_DTYPE_TXTAREA, '', false); $this->initVar('created', XOBJ_DTYPE_INT, time(), false); }}Ключевые методы:
initVar()- Определить свойства объектаgetVar()- Получить значения свойствsetVar()- Установить значения свойствassignVars()- Массовое присваивание из массива
XoopsPersistableObjectHandler
Заголовок раздела «XoopsPersistableObjectHandler»Обрабатывает операции CRUD для экземпляров XoopsObject.
<?phpclass MyModuleItemHandler extends XoopsPersistableObjectHandler{ public function __construct(\XoopsDatabase $db) { parent::__construct($db, 'mymodule_items', 'MyModuleItem', 'id', 'title'); }
public function getActiveItems($limit = 10) { $criteria = new CriteriaCompo(); $criteria->add(new Criteria('status', 1)); $criteria->setSort('created'); $criteria->setOrder('DESC'); $criteria->setLimit($limit);
return $this->getObjects($criteria); }}Ключевые методы:
create()- Создать новый экземпляр объектаget()- Получить объект по IDinsert()- Сохранить объект в БДdelete()- Удалить объект из БДgetObjects()- Получить несколько объектовgetCount()- Подсчитать соответствующие объекты
Структура модуля
Заголовок раздела «Структура модуля»Каждый модуль XOOPS следует стандартной структуре директорий:
modules/mymodule/├── class/ # PHP классы│ ├── MyModuleItem.php│ └── MyModuleItemHandler.php├── include/ # Include файлы│ ├── common.php│ └── functions.php├── templates/ # Smarty шаблоны│ ├── mymodule_index.tpl│ └── mymodule_item.tpl├── admin/ # Администраторская область│ ├── index.php│ └── menu.php├── language/ # Переводы│ └── english/│ ├── main.php│ └── modinfo.php├── sql/ # Схема БД│ └── mysql.sql├── xoops_version.php # Информация о модуле├── index.php # Входная точка модуля└── header.php # Заголовок модуляКонтейнер впрыскивания зависимостей
Заголовок раздела «Контейнер впрыскивания зависимостей»Современная разработка XOOPS может использовать впрыскивание зависимостей для лучшей тестируемости.
Базовая реализация контейнера
Заголовок раздела «Базовая реализация контейнера»<?phpclass XoopsDependencyContainer{ private array $services = [];
public function register(string $name, callable $factory): void { $this->services[$name] = $factory; }
public function resolve(string $name): mixed { if (!isset($this->services[$name])) { throw new \InvalidArgumentException("Service not found: $name"); }
$factory = $this->services[$name];
if (is_callable($factory)) { return $factory($this); }
return $factory; }
public function has(string $name): bool { return isset($this->services[$name]); }}Контейнер, совместимый с PSR-11
Заголовок раздела «Контейнер, совместимый с PSR-11»<?phpnamespace Xmf\Di;
use Psr\Container\ContainerInterface;
class BasicContainer implements ContainerInterface{ protected array $definitions = [];
public function set(string $id, mixed $value): void { $this->definitions[$id] = $value; }
public function get(string $id): mixed { if (!$this->has($id)) { throw new \InvalidArgumentException("Service not found: $id"); }
$entry = $this->definitions[$id];
if (is_callable($entry)) { return $entry($this); }
return $entry; }
public function has(string $id): bool { return isset($this->definitions[$id]); }}Пример использования
Заголовок раздела «Пример использования»<?php// Регистрация сервиса$container = new XoopsDependencyContainer();
$container->register('database', function () { return XoopsDatabaseFactory::getDatabaseConnection();});
$container->register('userHandler', function ($c) { return new XoopsUserHandler($c->resolve('database'));});
// Разрешение сервиса$userHandler = $container->resolve('userHandler');$user = $userHandler->get($userId);Точки расширения
Заголовок раздела «Точки расширения»XOOPS обеспечивает несколько механизмов расширения:
1. Preloads
Заголовок раздела «1. Preloads»Preloads позволяют модулям подключаться к основным событиям.
<?phpclass MymoduleCorePreload extends XoopsPreloadItem{ public static function eventCoreHeaderEnd($args) { // Выполнить, когда заканчивается обработка заголовка }
public static function eventCoreFooterStart($args) { // Выполнить, когда начинается обработка подвала }}2. Плагины
Заголовок раздела «2. Плагины»Плагины расширяют конкретную функциональность в модулях.
<?phpclass MymoduleNotifyPlugin{ public function onItemCreate($item) { // Отправить уведомление при создании элемента }}3. Фильтры
Заголовок раздела «3. Фильтры»Фильтры изменяют данные по мере их прохождения через систему.
<?php// Пример фильтра содержимого$myts = MyTextSanitizer::getInstance();$content = $myts->displayTarea($rawContent, 1, 1, 1);Лучшие практики
Заголовок раздела «Лучшие практики»Организация кода
Заголовок раздела «Организация кода»-
Используйте namespaces для нового кода:
namespace XoopsModules\MyModule;class Item extends \XoopsObject{// Реализация} -
Следуйте PSR-4 автозагрузке:
{"autoload": {"psr-4": {"XoopsModules\MyModule\": "class/"}}} -
Разделяйте ответственность:
- Логика домена в
class/ - Представление в
templates/ - Контроллеры в корне модуля
- Логика домена в
Производительность
Заголовок раздела «Производительность»- Используйте кэширование для дорогостоящих операций
- Ленивая загрузка ресурсов, когда это возможно
- Минимизируйте запросы к БД с помощью пакетизации criteria
- Оптимизируйте шаблоны, избегая сложной логики
Безопасность
Заголовок раздела «Безопасность»- Проверяйте весь ввод с помощью
Xmf\Request - Экранируйте вывод в шаблонах
- Используйте подготовленные операторы для запросов к БД
- Проверяйте разрешения перед конфиденциальными операциями
Связанная документация
Заголовок раздела «Связанная документация»- Паттерны проектирования - Паттерны, используемые в XOOPS
- Слой базы данных - Подробности абстракции БД
- Основы Smarty - Документация системы шаблонов
- Лучшие практики безопасности - Рекомендации по безопасности
#xoops #architecture #core #design #system-design