Eloquent модели в Битриксе
В версии 18.1.1 Главного модуля, 1С-Битрикс обновили свой ORM, сделав его по-настоящему объектно-ориентированным.
К сожалению, многие базовые вещи на момент написания статьи в обновленной версии не работали, а техподдержка не хотела классифицировать это, как недоработки и посылала на сайт идей.
Функциональный ORM необходим в сложных проектах и мы отправились на поиски подходящего решения. Им оказалось bitrix-models.
Решение позволяет работать с:
- Сущностями Битрикса (Элементы инфоблока, Разделы инфоблока, Пользователи, D7 таблицы)
- Моделями Eloquent
Какой из вариантов работы выбрать – вопрос удобства и привычки, сейчас мы рассмотрим подключение Eloquent моделей к 1С-Битрикс.
Установка расширения
В той же 18.1.1 версии, Битрикс добавили поддержку composer в папке /bitrix/, поэтому создаем ней файл composer.json со следующим содержимым:
{
"require": {
"arrilot/bitrix-models": "^0.7.13",
"illuminate/database": "^5.6.39",
"michaelachrisco/readonly": "^0.32.0",
"wikimedia/composer-merge-plugin": "dev-master"
},
"extra": {
"merge-plugin": {
"require": [
"composer-bx.json"
]
}
},
"autoload": {
"psr-4": {
"App\\": "php_interface/src"
}
}
}
Более подробно про composer в Битриксе можно почитать в документации.
После установки необходимых зависимостей, добавляем в init.php следующее:
<?php use Arrilot\BitrixModels\ServiceProvider; require_once __DIR__ . '/../vendor/autoload.php'; ServiceProvider::register(); ServiceProvider::registerEloquent();
Модели Eloquent
Каждая таблица имеет соответствующий класс-модель, который используется для работы с этой таблицей.
Модели позволяют запрашивать данные из таблиц, а также вставлять в них новые записи.
Про модели Eloquent можно почитать на официальном сайте или на русском языке.
В секции autoload файла composer.json мы определили, что классы будут находиться в папке /bitrix/php_interface/src/.
Создадим модель чата:
<?php
// /bitrix/php_interface/src/Models/Chat/Chat.php
namespace App\Models\Chat;
use App\Models\Bitrix\User;
use Illuminate\Database\Eloquent\Model;
class Chat extends Model
{
protected $table = 'b_prominado_mobile_chats'; // Название таблицы
protected $fillable = [
'topic' // поля, доступные для редактирования
];
public function users() // отношение Many to Many с моделью User
{
return $this->belongsToMany(User::class, 'b_prominado_mobile_chat_users', 'chat_id', 'user_id');
}
public function messages() // отношение One to Many с моделью Message
{
return $this->hasMany(Message::class, 'chat_id', 'id');
}
}
Сообщения:
<?php
// /bitrix/php_interface/src/Models/Chat/Message.php
namespace App\Models\Chat;
use Illuminate\Database\Eloquent\Model;
class Message extends Model
{
protected $table = 'b_prominado_mobile_messages';
protected $fillable = [
'user_id',
'chat_id',
'text',
'file_id',
];
}
И пользователя, который будет использовать штатную таблицу b_user.
<?php
// /bitrix/php_interface/src/Models/Bitrix/User.php
namespace App\Models\Bitrix;
use App\Models\Chat\Chat;
use Illuminate\Database\Eloquent\Model;
use MichaelAChrisco\ReadOnly\ReadOnlyTrait;
class User extends Model
{
use ReadOnlyTrait; // Запрещаем добавлять, изменять и удалять пользователей с помощью Eloquent
protected $table = 'b_user';
public const CREATED_AT = 'DATE_REGISTER'; // Переопределяем поле Дата создания
public const UPDATED_AT = 'TIMESTAMP_X'; // Переопределяем поле Дата изменения
public function chats() // обратное отношение Many to Many с моделью Chat
{
return $this->belongsToMany(Chat::class, 'b_prominado_mobile_chat_users', 'user_id', 'chat_id');
}
}
Например, чтобы получить количество пользователей и сообщений чата выполним запрос:
<?php
require_once $_SERVER['DOCUMENT_ROOT'] . '/bitrix/modules/main/include/prolog_before.php';
$chat = \App\Models\Chat\Chat::query()
->where('ID', '=', 1)
->with(['messages', 'users'])
->firstOrFail();
echo 'Пользователей в чате: ' . $chat->users()->get()->count() . '<br />';
echo 'Сообщений в чате: ' . $chat->messages()->get()->count() . '<br />';
Таким образом, мы подключили модели Eloquent к 1С-Битрикс и можем использовать многофункциональный ORM в проекте.
