D7 ORM позволяет работать не только со стандартными сущностями (ElementTable, UserTable), но и описывать свои собственные для любых таблиц в базе данных.
Это позволяет получить все преимущества ORM (удобные выборки, объекты, события, валидацию) для ваших кастомных данных, делая код чистым и типизированным.
Задача: Создадим ORM-сущность для таблицы my_company_reviews (отзывы).
Шаг 0: Подготовка таблицы в Базе Данных
Прежде всего, нам нужна сама таблица в БД. Создадим ее с помощью SQL-запроса.
CREATE TABLE my_company_reviews (
ID INT PRIMARY KEY AUTO_INCREMENT,
AUTHOR_NAME VARCHAR(255) NOT NULL,
RATING INT NOT NULL,
COMMENT TEXT NULL,
DATE_CREATED DATETIME NOT NULL,
CREATED_BY INT NULL
);
Мы добавили поле CREATED_BY для будущей связи с таблицей пользователей.
Шаг 1: Файловая структура и автозагрузка
Все ORM-сущности должны располагаться в папке lib вашего модуля.
Название файла и класса должно соответствовать стандарту [EntityName]Table.php.
- Создайте файл: /local/modules/my.module/lib/ReviewTable.php.
- Настройте автозагрузку. Убедитесь, что пространство имен My\Module зарегистрировано в composer.json вашего проекта или в include.php вашего модуля.codePHP
// /local/modules/my.module/include.php \Bitrix\Main\Loader::registerAutoLoadClasses( 'my.module', [ 'My\\Module\\ReviewTable' => 'lib/ReviewTable.php', ] );
Шаг 2: Создание класса-наследника DataManager
Класс сущности должен наследоваться от абстрактного класса \Bitrix\Main\Entity\DataManager.
// /local/modules/my.module/lib/ReviewTable.php
namespace My\Module;
use Bitrix\Main\Entity;
use Bitrix\Main\Type;
use Bitrix\Main\UserTable; // Подключаем сущность пользователей для связи
class ReviewTable extends Entity\DataManager
{
/**
* Возвращает физическое имя таблицы в базе данных.
* @return string
*/
public static function getTableName()
{
return 'my_company_reviews';
}
// Здесь будет метод getMap()
}
Шаг 3: Описание карты полей (getMap) — Сердце сущности
Метод getMap() — самый важный.
Он «объясняет» ORM, из каких полей состоит ваша таблица, какие у них типы, какие являются первичными ключами, какие правила валидации к ним применять и как они связаны с другими таблицами.
/**
* Возвращает описание полей сущности.
* @return array
*/
public static function getMap()
{
return [
// ID: Целое число, первичный ключ, автоинкремент
(new Entity\IntegerField('ID'))
->configurePrimary()
->configureAutocomplete(),
// Имя автора: Строка, обязательное, с валидацией длины
(new Entity\StringField('AUTHOR_NAME', [
'validation' => function() {
return [
new Entity\Validator\Length(2, 50),
];
}
]))
->configureRequired()
->configureTitle('Имя автора'),
// Рейтинг: Целое число, с валидацией диапазона
(new Entity\IntegerField('RATING', [
'validation' => function() {
return [
new Entity\Validator\Range(1, 5),
];
}
]))
->configureRequired()
->configureTitle('Рейтинг'),
// Комментарий: Текстовое поле
(new Entity\TextField('COMMENT'))
->configureTitle('Текст отзыва'),
// Дата создания: Дата/время, со значением по умолчанию
(new Entity\DatetimeField('DATE_CREATED'))
->configureDefaultValue(new Type\DateTime())
->configureTitle('Дата создания'),
// ID создателя: Целое число
(new Entity\IntegerField('CREATED_BY'))
->configureTitle('Кем создан'),
// Связь с пользователем (ReferenceField)
(new Entity\ReferenceField(
'AUTHOR', // Псевдоним для этой связи
UserTable::class, // Класс сущности, с которой связываемся
['=this.CREATED_BY' => 'ref.ID'] // Условие JOIN ON
))
];
}
Разбор getMap():
- Новый синтаксис (чейнинг): Вместо передачи всех параметров в конструктор, можно использовать методы configure*(). Это делает код более читаемым.
- configurePrimary() и configureAutocomplete(): Удобные методы для настройки первичного ключа.
- configureRequired(): Делает поле обязательным.
- configureTitle(): Задает человекопонятное название поля (используется, например, в административных интерфейсах).
- ReferenceField: Это ключ к связям!
- AUTHOR: Псевдоним, по которому мы будем обращаться к связанному пользователю.
- UserTable::class: Сущность, к которой мы «присоединяемся».
- [‘=this.CREATED_BY’ => ‘ref.ID’]: Условие JOIN. this — это наша текущая таблица (ReviewTable), ref — это таблица, к которой присоединяемся (UserTable).
Шаг 4 (Опционально): Метод getUfId()
Если вы планируете добавлять к вашей сущности пользовательские поля (UF-поля) через стандартный интерфейс Битрикс, необходимо реализовать этот метод.
/**
* Возвращает ID для пользовательских полей (UF).
* @return string
*/
public static function getUfId()
{
return 'MY_REVIEW';
}
Это ID должен быть уникальным в рамках всей системы.
Шаг 5: Использование новой сущности
Теперь ваша сущность готова к работе. Вы можете использовать все методы D7 ORM.
use My\Module\ReviewTable;
// Добавляем отзыв
$result = ReviewTable::add([
'AUTHOR_NAME' => 'Иван',
'RATING' => 5,
'COMMENT' => 'Все отлично!',
'CREATED_BY' => 1, // ID текущего пользователя
]);
// Получаем отзывы с именами их авторов
$reviews = ReviewTable::getList([
'select' => [
'ID',
'RATING',
'AUTHOR_NAME',
// Обращаемся к полю связанной сущности через псевдоним
'AUTHOR_LOGIN' => 'AUTHOR.LOGIN'
],
'filter' => ['>=RATING' => 4],
])->fetchAll();
print_r($reviews);
/*
Вывод:
[
[
'ID' => 1,
'RATING' => 5,
'AUTHOR_NAME' => 'Иван',
'AUTHOR_LOGIN' => 'admin'
]
]
*/
Бонус: Создание таблицы из ORM-описания
Если у вас еще нет таблицы в БД, вы можете создать ее на основе вашего getMap().
use Bitrix\Main\Application;
$entity = ReviewTable::getEntity();
$tableName = ReviewTable::getTableName();
$connection = Application::getConnection();
// Проверяем, существует ли таблица
if (!$connection->isTableExists($tableName)) {
// Создаем таблицу
$entity->createDbTable();
}
Этот код удобно размещать в методе DoInstall() вашего модуля.
Вывод:
Создание собственных DataManager-классов — это фундаментальный навык для современной разработки на Битрикс.
Это позволяет инкапсулировать всю логику работы с кастомной таблицей в одном месте, получить все преимущества ORM (включая события, валидацию и связи) и сделать код чистым, типизированным и легко поддерживаемым.
D7 ORM, DataManager, getMap, своя ORM сущность, создать таблицу Битрикс, IntegerField, StringField, ReferenceField, Validator, Битрикс разработка.