Класс XoopsObjectHandler
Класс XoopsObjectHandler и его расширение XoopsPersistableObjectHandler предоставляют стандартизированный интерфейс для выполнения операций CRUD (Create, Read, Update, Delete) на экземплярах XoopsObject. Это реализует паттерн Data Mapper, разделяя логику домена от доступа к БД.
Обзор класса
Заголовок раздела «Обзор класса»namespace Xoops\Core;
abstract class XoopsObjectHandler{ protected XoopsDatabase $db;
public function __construct(XoopsDatabase $db); abstract public function create(bool $isNew = true); abstract public function get(int $id); abstract public function insert(XoopsObject $obj, bool $force = false): bool; abstract public function delete(XoopsObject $obj, bool $force = false): bool;}Иерархия класса
Заголовок раздела «Иерархия класса»XoopsObjectHandler (Абстрактная база)└── XoopsPersistableObjectHandler (Расширенная реализация) ├── XoopsUserHandler ├── XoopsGroupHandler ├── XoopsModuleHandler ├── XoopsBlockHandler ├── XoopsConfigHandler └── [Пользовательские обработчики модулей]XoopsObjectHandler
Заголовок раздела «XoopsObjectHandler»Конструктор
Заголовок раздела «Конструктор»public function __construct(XoopsDatabase $db)Параметры:
| Параметр | Тип | Описание |
|---|---|---|
$db | XoopsDatabase | Экземпляр соединения с БД |
Пример:
$db = XoopsDatabaseFactory::getDatabaseConnection();$handler = new MyObjectHandler($db);Создает новый экземпляр объекта.
abstract public function create(bool $isNew = true): ?XoopsObjectПараметры:
| Параметр | Тип | Описание |
|---|---|---|
$isNew | bool | Является ли объект новым (по умолчанию: true) |
Возвращает: XoopsObject|null - Новый экземпляр объекта
Пример:
$handler = xoops_getHandler('user');$user = $handler->create();$user->setVar('uname', 'newuser');Получает объект по его первичному ключу.
abstract public function get(int $id): ?XoopsObjectПараметры:
| Параметр | Тип | Описание |
|---|---|---|
$id | int | Значение первичного ключа |
Возвращает: XoopsObject|null - Экземпляр объекта или null если не найден
Пример:
$handler = xoops_getHandler('user');$user = $handler->get(1);if ($user) { echo $user->getVar('uname');}Сохраняет объект в БД (вставка или обновление).
abstract public function insert( XoopsObject $obj, bool $force = false): boolПараметры:
| Параметр | Тип | Описание |
|---|---|---|
$obj | XoopsObject | Объект для сохранения |
$force | bool | Принудительно выполнить операцию даже если объект не изменился |
Возвращает: bool - True при успехе
Пример:
$handler = xoops_getHandler('user');$user = $handler->create();$user->setVar('uname', 'testuser');$user->setVar('email', 'test@example.com');
if ($handler->insert($user)) { echo "User saved with ID: " . $user->getVar('uid');} else { echo "Save failed: " . implode(', ', $user->getErrors());}Удаляет объект из БД.
abstract public function delete( XoopsObject $obj, bool $force = false): boolПараметры:
| Параметр | Тип | Описание |
|---|---|---|
$obj | XoopsObject | Объект для удаления |
$force | bool | Принудительное удаление |
Возвращает: bool - True при успехе
Пример:
$handler = xoops_getHandler('user');$user = $handler->get(5);
if ($user && $handler->delete($user)) { echo "User deleted";}XoopsPersistableObjectHandler
Заголовок раздела «XoopsPersistableObjectHandler»XoopsPersistableObjectHandler расширяет XoopsObjectHandler дополнительными методами для запросов и массовых операций.
Конструктор
Заголовок раздела «Конструктор»public function __construct( XoopsDatabase $db, string $table, string $className, string $keyName, string $identifierName = '')Параметры:
| Параметр | Тип | Описание |
|---|---|---|
$db | XoopsDatabase | Соединение с БД |
$table | string | Имя таблицы (без префикса) |
$className | string | Полное имя класса объекта |
$keyName | string | Имя поля первичного ключа |
$identifierName | string | Поле идентификатора для человека |
Пример:
class ArticleHandler extends XoopsPersistableObjectHandler{ public function __construct(XoopsDatabase $db) { parent::__construct( $db, 'mymodule_articles', // Имя таблицы 'Article', // Имя класса 'article_id', // Первичный ключ 'title' // Поле идентификатора ); }}getObjects
Заголовок раздела «getObjects»Получает несколько объектов, соответствующих критериям.
public function getObjects( CriteriaElement $criteria = null, bool $idAsKey = false, bool $asObject = true): arrayПараметры:
| Параметр | Тип | Описание |
|---|---|---|
$criteria | CriteriaElement | Критерии запроса (опционально) |
$idAsKey | bool | Использовать первичный ключ как ключ массива |
$asObject | bool | Вернуть объекты (true) или массивы (false) |
Возвращает: array - Массив объектов или ассоциативных массивов
Пример:
$handler = xoops_getHandler('user');
// Получить всех активных пользователей$criteria = new Criteria('level', 0, '>');$users = $handler->getObjects($criteria);
// Получить пользователей с ID как ключ$users = $handler->getObjects($criteria, true);echo $users[1]->getVar('uname'); // Доступ по ID
// Получить как массивы вместо объектов$usersArray = $handler->getObjects($criteria, false, false);foreach ($usersArray as $userData) { echo $userData['uname'];}getCount
Заголовок раздела «getCount»Подсчитывает объекты, соответствующие критериям.
public function getCount(CriteriaElement $criteria = null): intПараметры:
| Параметр | Тип | Описание |
|---|---|---|
$criteria | CriteriaElement | Критерии запроса (опционально) |
Возвращает: int - Количество найденных объектов
Пример:
$handler = xoops_getHandler('user');
// Подсчитать всех пользователей$totalUsers = $handler->getCount();
// Подсчитать активных пользователей$criteria = new Criteria('level', 0, '>');$activeUsers = $handler->getCount($criteria);
echo "Total: $totalUsers, Active: $activeUsers";Получает все объекты (псевдоним для getObjects без критериев).
public function getAll( CriteriaElement $criteria = null, array $fields = null, bool $asObject = true, bool $idAsKey = true): arrayПараметры:
| Параметр | Тип | Описание |
|---|---|---|
$criteria | CriteriaElement | Критерии запроса |
$fields | array | Конкретные поля для получения |
$asObject | bool | Вернуть как объекты |
$idAsKey | bool | Использовать ID как ключ массива |
Пример:
$handler = xoops_getHandler('module');
// Получить все модули$modules = $handler->getAll();
// Получить только конкретные поля$modules = $handler->getAll(null, ['mid', 'name', 'dirname'], false);Получает только первичные ключи найденных объектов.
public function getIds(CriteriaElement $criteria = null): arrayПараметры:
| Параметр | Тип | Описание |
|---|---|---|
$criteria | CriteriaElement | Критерии запроса |
Возвращает: array - Массив значений первичного ключа
Пример:
$handler = xoops_getHandler('user');$criteria = new Criteria('level', 1);$adminIds = $handler->getIds($criteria);// [1, 5, 12, ...] - Массив ID администраторовgetList
Заголовок раздела «getList»Получает список ключ-значение для выпадающих списков.
public function getList(CriteriaElement $criteria = null): arrayВозвращает: array - Ассоциативный массив [id => identifier]
Пример:
$handler = xoops_getHandler('group');$groups = $handler->getList();// [1 => 'Administrators', 2 => 'Registered Users', ...]
// Для выпадающего списка select$form->addElement(new XoopsFormSelect('Group', 'group_id', $default, 1, false));$form->getElement('group_id')->addOptionArray($groups);deleteAll
Заголовок раздела «deleteAll»Удаляет все объекты, соответствующие критериям.
public function deleteAll( CriteriaElement $criteria = null, bool $force = true, bool $asObject = false): boolПараметры:
| Параметр | Тип | Описание |
|---|---|---|
$criteria | CriteriaElement | Критерии для объектов к удалению |
$force | bool | Принудительное удаление |
$asObject | bool | Загрузить объекты перед удалением (запускает события) |
Возвращает: bool - True при успехе
Пример:
$handler = xoops_getModuleHandler('comment', 'mymodule');
// Удалить все комментарии для конкретной статьи$criteria = new Criteria('article_id', $articleId);$handler->deleteAll($criteria);
// Удалить с загрузкой объектов (запускает события удаления)$handler->deleteAll($criteria, true, true);updateAll
Заголовок раздела «updateAll»Обновляет значение поля для всех объектов, соответствующих критериям.
public function updateAll( string $fieldname, mixed $fieldvalue, CriteriaElement $criteria = null, bool $force = false): boolПараметры:
| Параметр | Тип | Описание |
|---|---|---|
$fieldname | string | Поле для обновления |
$fieldvalue | mixed | Новое значение |
$criteria | CriteriaElement | Критерии для объектов к обновлению |
$force | bool | Принудительное обновление |
Возвращает: bool - True при успехе
Пример:
$handler = xoops_getModuleHandler('article', 'mymodule');
// Отметить все статьи автора как черновик$criteria = new Criteria('author_id', $authorId);$handler->updateAll('published', 0, $criteria);
// Обновить счетчик просмотров$criteria = new Criteria('article_id', $id);$handler->updateAll('views', $views + 1, $criteria);insert (Расширенный)
Заголовок раздела «insert (Расширенный)»Расширенный метод insert с дополнительной функциональностью.
public function insert( XoopsObject $obj, bool $force = false): boolПоведение:
- Если объект новый (
isNew() === true): INSERT - Если объект существует (
isNew() === false): UPDATE - Автоматически вызывает
cleanVars() - Устанавливает ID автоинкремента для новых объектов
Пример:
$handler = xoops_getModuleHandler('article', 'mymodule');
// Создать новую статью$article = $handler->create();$article->setVar('title', 'New Article');$article->setVar('content', 'Content here');$handler->insert($article);echo "Created with ID: " . $article->getVar('article_id');
// Обновить существующую статью$article = $handler->get(5);$article->setVar('title', 'Updated Title');$handler->insert($article);Вспомогательные функции
Заголовок раздела «Вспомогательные функции»xoops_getHandler
Заголовок раздела «xoops_getHandler»Глобальная функция для получения основного обработчика.
function xoops_getHandler(string $name, bool $optional = false): ?XoopsObjectHandlerПараметры:
| Параметр | Тип | Описание |
|---|---|---|
$name | string | Имя обработчика (user, module, group, и т. д.) |
$optional | bool | Вернуть null вместо вызова ошибки |
Пример:
$userHandler = xoops_getHandler('user');$moduleHandler = xoops_getHandler('module');$groupHandler = xoops_getHandler('group');$blockHandler = xoops_getHandler('block');$configHandler = xoops_getHandler('config');xoops_getModuleHandler
Заголовок раздела «xoops_getModuleHandler»Получает обработчик, специфичный для модуля.
function xoops_getModuleHandler( string $name, string $dirname = null, bool $optional = false): ?XoopsObjectHandlerПараметры:
| Параметр | Тип | Описание |
|---|---|---|
$name | string | Имя обработчика |
$dirname | string | Имя директории модуля |
$optional | bool | Вернуть null при ошибке |
Пример:
// Получить обработчик из текущего модуля$articleHandler = xoops_getModuleHandler('article');
// Получить обработчик из конкретного модуля$articleHandler = xoops_getModuleHandler('article', 'news');$storyHandler = xoops_getModuleHandler('story', 'news');Создание пользовательских обработчиков
Заголовок раздела «Создание пользовательских обработчиков»Базовая реализация обработчика
Заголовок раздела «Базовая реализация обработчика»<?phpnamespace XoopsModules\MyModule;
use XoopsPersistableObjectHandler;use XoopsDatabase;use CriteriaElement;use Criteria;use CriteriaCompo;
/** * Обработчик для объектов Article */class ArticleHandler extends XoopsPersistableObjectHandler{ /** * Конструктор */ public function __construct(XoopsDatabase $db = null) { parent::__construct( $db, 'mymodule_articles', Article::class, 'article_id', 'title' ); }
/** * Получить опубликованные статьи */ public function getPublished(int $limit = 10, int $start = 0): array { $criteria = new CriteriaCompo(); $criteria->add(new Criteria('published', 1)); $criteria->add(new Criteria('publish_date', time(), '<=')); $criteria->setSort('publish_date'); $criteria->setOrder('DESC'); $criteria->setLimit($limit); $criteria->setStart($start);
return $this->getObjects($criteria); }
/** * Получить статьи по автору */ public function getByAuthor(int $authorId, bool $publishedOnly = true): array { $criteria = new CriteriaCompo(); $criteria->add(new Criteria('author_id', $authorId));
if ($publishedOnly) { $criteria->add(new Criteria('published', 1)); }
$criteria->setSort('created'); $criteria->setOrder('DESC');
return $this->getObjects($criteria); }
/** * Получить статьи по категории */ public function getByCategory(int $categoryId, int $limit = 0): array { $criteria = new CriteriaCompo(); $criteria->add(new Criteria('category_id', $categoryId)); $criteria->add(new Criteria('published', 1)); $criteria->setSort('publish_date'); $criteria->setOrder('DESC');
if ($limit > 0) { $criteria->setLimit($limit); }
return $this->getObjects($criteria); }
/** * Поиск статей */ public function search(string $query, array $fields = ['title', 'content']): array { $criteria = new CriteriaCompo(); $searchCriteria = new CriteriaCompo();
foreach ($fields as $field) { $searchCriteria->add( new Criteria($field, '%' . $query . '%', 'LIKE'), 'OR' ); }
$criteria->add($searchCriteria); $criteria->add(new Criteria('published', 1)); $criteria->setSort('publish_date'); $criteria->setOrder('DESC');
return $this->getObjects($criteria); }
/** * Получить популярные статьи по количеству просмотров */ public function getPopular(int $limit = 5): array { $criteria = new CriteriaCompo(); $criteria->add(new Criteria('published', 1)); $criteria->setSort('views'); $criteria->setOrder('DESC'); $criteria->setLimit($limit);
return $this->getObjects($criteria); }
/** * Увеличить счетчик просмотров */ public function incrementViews(int $articleId): bool { $sql = sprintf( "UPDATE %s SET views = views + 1 WHERE article_id = %d", $this->db->prefix($this->table), $articleId );
return $this->db->queryF($sql) !== false; }
/** * Переопределить insert для пользовательского поведения */ public function insert(\XoopsObject $obj, bool $force = false): bool { // Установить временную метку обновления $obj->setVar('updated', time());
// Если новый, установить временную метку создания if ($obj->isNew()) { $obj->setVar('created', time()); }
return parent::insert($obj, $force); }
/** * Переопределить delete для каскадных операций */ public function delete(\XoopsObject $obj, bool $force = false): bool { // Удалить связанные комментарии $commentHandler = xoops_getModuleHandler('comment', 'mymodule'); $criteria = new Criteria('article_id', $obj->getVar('article_id')); $commentHandler->deleteAll($criteria);
return parent::delete($obj, $force); }}Использование пользовательского обработчика
Заголовок раздела «Использование пользовательского обработчика»// Получить обработчик$articleHandler = xoops_getModuleHandler('article', 'mymodule');
// Создать новую статью$article = $articleHandler->create();$article->setVars([ 'title' => 'My New Article', 'content' => 'Article content here...', 'author_id' => $xoopsUser->getVar('uid'), 'category_id' => 1, 'published' => 1, 'publish_date' => time()]);
if ($articleHandler->insert($article)) { redirect_header('article.php?id=' . $article->getVar('article_id'), 2, 'Article created');}
// Получить опубликованные статьи$articles = $articleHandler->getPublished(10);
// Поиск статей$results = $articleHandler->search('xoops');
// Получить популярные статьи$popular = $articleHandler->getPopular(5);
// Обновить счетчик просмотров$articleHandler->incrementViews($articleId);Лучшие практики
Заголовок раздела «Лучшие практики»-
Используйте Criteria для запросов: Всегда используйте объекты Criteria для типобезопасных запросов
-
Расширяйте для пользовательских методов: Добавьте методы запроса, специфичные для домена, в обработчики
-
Переопределяйте insert/delete: Добавьте каскадные операции и временные метки в переопределениях
-
Используйте транзакции где необходимо: Оберните сложные операции в транзакции
-
Используйте getList: Используйте
getList()для выпадающих списков select, чтобы уменьшить запросы -
Индексируйте ключи: Убедитесь, что поля БД, используемые в критериях, индексированы
-
Ограничьте результаты: Всегда используйте
setLimit()для потенциально больших наборов результатов
Связанная документация
Заголовок раздела «Связанная документация»- XoopsObject - Базовый класс объекта
- ../Database/Criteria - Построение критериев запроса
- ../Database/XoopsDatabase - Операции с БД
См. также: Исходный код XOOPS