В блог

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 — красивая и простая реализация шаблона ActiveRecord для работы с базами данных.
Каждая таблица имеет соответствующий класс-модель, который используется для работы с этой таблицей.
Модели позволяют запрашивать данные из таблиц, а также вставлять в них новые записи.

Про модели 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 в проекте.

Хочу проект
Закрыть