Download the PHP package enjame/bitrix-models without Composer

On this page you can find all versions of the php package enjame/bitrix-models. It is possible to download/install these versions without Composer. Possible dependencies are resolved automatically.

FAQ

After the download, you have to make one include require_once('vendor/autoload.php');. After that you have to import the classes with use statements.

Example:
If you use only one package a project is not needed. But if you use more then one package, without a project it is not possible to import the classes with use statements.

In general, it is recommended to use always a project to download your libraries. In an application normally there is more than one library needed.
Some PHP packages are not free to download and because of that hosted in private repositories. In this case some credentials are needed to access such packages. Please use the auth.json textarea to insert credentials, if a package is coming from a private repository. You can look here for more information.

  • Some hosting areas are not accessible by a terminal or SSH. Then it is not possible to use Composer.
  • To use Composer is sometimes complicated. Especially for beginners.
  • Composer needs much resources. Sometimes they are not available on a simple webspace.
  • If you are using private repositories you don't need to share your credentials. You can set up everything on our site and then you provide a simple download link to your team member.
  • Simplify your Composer build process. Use our own command line tool to download the vendor folder as binary. This makes your build process faster and you don't need to expose your credentials for private repositories.
Please rate this library. Is it a good library?

Informations about the package bitrix-models

Latest Stable Version Total Downloads Build Status Scrutinizer Quality Score

Bitrix models

Вступление

Данный пакет привносит Model Layer в Битрикс. Этот слой логически состоит из двух частей:

  1. Модели для сущностей битрикса (в дальнейшем будем называть их "Битрикс-модели") работающие внутри через API Битрикса (CIBlockElement и т д) и представляющие собой надстройку над ним. С внешней же стороны эта надстройка напоминает Eloquent.
  2. Модели для произвольных таблицы работающие через illuminate/database в целом и Eloquent в частности.

Установка

  1. Регистрируем пакет в init.php - Arrilot\BitrixModels\ServiceProvider::register();

Использование моделей Bitrix

Для наследования доступны следующие модели:

Для пример далее везде будем рассматривать модель для элемента инфоблока (ElementModel). Для других сущностей API практически идентичен.

ElementModel полноценно поддерживает только инфоблоки второй версии (та что хранит свойства в отдельных таблицах). С первой версией некоторые моменты могут не работать должным образом из-за особенностей работы CIBlockElement::GetList(). Самая большая проблема: Если в инфоблоке есть множественные свойства, то запросы с limit(), take(), и first() будут отрабатывать неверно и получать меньше элементов чем нужно и не с полным набором множественных свойств. Если вы всё же собираетесь использовать ElementModel с инфоблоками первой версии, то обязательно выставите const IBLOCK_VERSION = 1; внутри класса модели.

Создадим, модель для инфоблока Товары.

Для работы модели необходимо лишь задать ID инфоблока в константе. Для юзеров не требуется и этого.

Если вы не хотите привязываться к ID инфоблоков, можно переопределить в моделе метод public static iblockId() и получать в нём ID инфоблока например по коду. Это дает большую гибкость, но скорее всего вам потребуются дополнительные запросы в БД.

В дальнейшем мы будем использовать наш класс Product как в статическом, так и в динамическом контексте.

Добавление продукта

Заметка: В случае если поля $product в дальнейшем как-то используются, рекомендуется сразу же обновить объект новым запросом в БД . Нужно это из-за того, что форматы полей в CIblockElement::Add() и CIblockElement::GetList() не совпадают на 100% Делается это так:

Обновление

Инстанцирование модели без запросов к базе.

Для ряда операций нет необходимости в получении информации из БД, достаточно лишь ID объекта. В этом случае достаточно инстанцировать объект модели, передав в конструктор идентификатор.

Получение полей объекта из базы

Описанные методы сохраняют данные из БД внутри экземпляра класса-модели. Объекты-модели реализуют ArrayAccess, поэтому с ними можно во многом работать как с массивами.

Преобразование моделей в массив/json.

По умолчанию, все поля модели становятся доступными в массиве, что не всегда желательно. У моделей есть специальные свойства protected $visible = []; и protected $hidden = [];, при помощи которых можно составить белый/черный список полей для преобразования модели в массив/json.

Получение информации из базы

Наиболее распостраненный сценарий работы с моделями - получение элементов/списков из БД. Для построение запроса используется "Fluent API", который использует в недрах себя стандартный Битриксовый API.

Для начала построения запроса используется статический метод ::query(). Данный метод возвращает объект-построитель запроса (ElementQuery, SectionQuery или UserQuery), через который уже строится цепочка запроса.

Простейший пример:

На самом деле данная форма приведена больше для понимания, есть более удобный вид, который использует __callStatic для передачи управления в объект-запрос.

Любая цепочка запросов должна заканчиваться одним из следующих методов:

  1. ->getList() - получение коллекции (см. http://laravel.com/docs/master/collections) объектов. По умолчанию ключом каждого элемента является его ID.
  2. ->getById($id) - получение объекта по его ID.
  3. ->first() - получение одного (самого первого) объекта удовлетворяющего параметрам запроса.
  4. ->count() - получение количества объектов.
  5. ->paginate() или ->simplePaginate() - получение спагинированного списка с мета-данными (см. http://laravel.com/docs/master/pagination)
  6. Методы для отдельных сущностей: ->getByLogin($login) и ->getByEmail($email) - получение первого попавшегося юзера с данным логином/email. ->getByCode($code) и ->getByExternalId($id) - получение первого попавшегося элемента или раздела ИБ по CODE/EXTERNAL_ID

Управление выборкой

  1. ->sort($array) - аналог $arSort (первого параметра CIBlockElement::GetList)

    Примеры:

    ->sort(['NAME' => 'ASC', 'ID => 'DESC'])

    ->sort('NAME', 'DESC') // = ->sort(['NAME' => 'DESC'])

    ->sort('NAME') // = ->sort(['NAME' => 'ASC'])

  2. ->filter($array) - аналог $arFilter
  3. ->navigation($array)
  4. ->select(...) - аналог $arSelect

    Примеры:

    ->select(['ID', 'NAME'])

    ->select('ID', 'NAME')

    select() поддерживает два дополнительных значения - 'FIELDS' (выбрать все поля), 'PROPS' (выбрать все свойства). Для пользователей также можно указать 'GROUPS' (добавить группы пользователя в выборку). Значение по-умолчанию для ElementModel - ['FIELDS', 'PROPS']

  5. ->limit($int), ->take($int), ->page($int), ->forPage($page, $perPage) - для навигации

Fetch и GetNext

По-умолчанию, внутри моделей для итерации по полученным из базы элементам/разделам/юзерам используется производительный метод ->Fetch() В отличии от ->GetNext(), он не приводит данные в html безопасный вид и не преобразует DETAIL_PAGE_URL, SECTION_PAGE_URL в реальные урлы элементов и категорий. Если в результате выборки вам нужны эти преобразования, то можно переключиться на этот метод.

  1. Можно переключить сразу всю модель задав ей свойство

  2. Можно переключить для одного единственного запроса.

Некоторые дополнительные моменты:

  1. Для ограничения выборки добавлены алиасы limit($value) (соответсвует nPageSize) и page($num) (соответсвует iNumPage)
  2. В некоторых местах API более дружелюбный чем в самом Битриксе. Допустим в фильтре по пользователям не обязательно использовать 'GROUP_IDS'. При передаче 'GROUP_ID' (именно такой ключ требует Битрикс допустим при создании пользователя) или 'GROUPS' результат будет аналогичен.
  3. При создании или изменении элементов и разделов инфоблоков Битрикс перестраивает поисковый индекс и позволяет пропустить это перестаривание для конкретного вызова Add/Update для увеличения производиельности. В моделях вы можете добиться того же эффекта либо сразу одним махом установив непосредственно в классе-модели protected static $updateSearch = false;, либо уже непосредственно перед добавлением/обновлением вызвав отдельный статический метод Product::setUpdateSearch(false).
  4. Флагами $bWorkFlow и $bResizePictures для CIBlockElement::Add/Update можно управлять аналогичным образом.

Query Scopes

Построитель запросов можно расширять добавляя "query scopes" в модель. Для этого необходимо создать публичный метод начинаюзищися со scope.

Пример "query scope"-a уже присутсвующего в пакете.

В "query scopes" можно также передавать дополнительные параметры.

Данные скоупы уже присутсвуют в пакете, ими можно пользоваться.

Остановка действия

Иногда требуется остановить выборку из базы из query scope. Для этого достаточно вернуть false. Пример:

В результате запрос в базу не будет сделан - getList() вернёт пустую коллекцию, getById() - false, а count() - 0.

Того же самого эффекта можно добиться вызвав вручную метод ->stopQuery()

Кэширование запросов

Для всех вышеупомнянутых Битрикс-моделей есть простой встроенный механизм кэширования. Достаточно лишь добавитьв цепочку вызовов ->cache($minutes)-> и результат выборки из базы будет закэширован на указанное количество минут. Пример: $products = Products::query()->cache(30)->filter(['ACTIVE' => 'Y'])->getList() Под капотом кэширование происходит используя стандартный механизм из d7 Битрикса. Клоюч кэширования зависит от модели и всех параметров запроса.

Accessors

Временами возникает потребность как то модифицировать данные между выборкой их из базы и получением их из модели. Для этого используются акссессоры. Также как и для "query scopes", для добавления аксессора необходимо добавить метод в соответсвующую модель.

Правило именования метода - $methodName = "get".camelCase($field)."Attribute". Пример:

Этим надо пользоваться с осторожностью, потому оригинальное значение становится недоступным.

Аксессоры можно создавать также и для несуществущих (виртуальных) полей, например:

Для того чтобы такие виртуальные аксессоры отображались в toArray() и toJson(), их необходимо явно указать в поле $appends модели.

Языковые аксессоры

Для многоязычных сайтов типичным является подход, когда для каждого языка создается своё свойство, например, UF_TITLE_RU, UF_TITLE_BY В этом случае для каждого такого поля можно создать аксессор:

Так как эти аксессоры однотипны и имеют неприятную особенность засорять модели, то для них можно использовать специальный краткий синтаксис

События моделей (Model Events)

События позволяют вклиниваться в различные точки жизненного цикла модели и выполнять в них произвольный код. Например, автоматически проставлять символьный код при создании элемента. События моделей не используют событийную модель Битрикса (ни старого ядра, ни D7) и касаются лишь того, что происходит внутри моделей. Использование Битриксовых событий покрывает больше кейсов.

Обработчик события задается переопределением соответсвующего метода в классе-модели.

Сигнатуры обработчиков других событий совпадают с приведенными выше.

Список доступных эвентов:

  1. onBeforeCreate - перед добавлением записи
  2. onAfterCreate(bool $result) - после добавления записи
  3. onBeforeUpdate - перед обновлением записи
  4. onAfterUpdate(bool $result) - после обновления записи
  5. onBeforeSave - перед добавлением или обновлением записи
  6. onAfterSave(bool $result) - после добавления или обновления записи
  7. onBeforeDelete - перед удалением записи
  8. onAfterDelete(bool $result) - после удаления записи

Если сделать return false; из обработчика onBefore...() то последующее действие будет отменено. В обработчиках можно получить дополнительную информацию используя свойства объекта текущей модели. Например, в onBefore...() обработчиках доступны все поля через $this->fields Во всех onAfter...() доступен массив ошибок через $this->eventErrors; В onBeforeUpdate() и onBeforeSave() доступен массив $this->fieldsSelectedForSave, в котором содержатся ключи полей которые мы собираемся обновлять.

D7 Model

Немного особняком стоит D7Model В отличии от предыдущих моделей она вместо старых GetList-ов и т д использует в качестве бэкэнда D7 Через неё можно работать как с обычными сущностями D7, так и с хайлоадблоками

Пример для хайлоадблока:

Понятно, что логика получения класса хайлоадблока может быть любой, но важно не забыть скомпилировать его, иначе он не будет работать. Пожалуй самый удобный вариант - использовать вспомогательный пакет https://github.com/arrilot/bitrix-iblock-helper/ С ним мы получаем следующее:

Если мы работаем не с хайлоадблоком, а с полноценной сущностью D7 ORM, то просто возвращаем в этом методе полное название класса этой сущности. Цепочки вызовов и названия методов для D7Model такие же как и для предыдущих моделей. Всё что мы передаем в эти методы будет передано далее в D7.

Пример получения всех подписчиков с именем John и с кэшированием на 5 минут:

Полный список методов следующий

За подробностями смотрите vendor/arrilot/bitrix-models/src/Models/D7Model.php и vendor/arrilot/bitrix-models/src/Queries/D7Query.php

Связи между моделями (Relations)

Помимо работы с отдельными Битрикс-моделями, также имеется возможность и строить связи между моделями, что делает их легко-доступными для получения через основные объекты данных. Например, товар связан с вопросами о товарах. С помощью объявления этой связи вы можете получить объекты модели вопроса с помощью выражения $product->questions, которое возвращает информацию о вопросах в виде колелкции объектов класса Question (дочерний класс BaseBitrixModel).

Объявление связей

Имена связей чувствительны к регистру.

При объявлении связи, вы должны указать следующую информацию:

Доступ к связным данным

После объявления связей вы можете получать доступ к связным данным с помощью имён связей. Доступ осуществляется по свойствам объекта. Название свойства = название метода связи (но без скобочек метода конечно)

Отложеная и жадная загрузка

В примерах выше используется отложенная загрузка (данные загружаются при первом обращении к ним). Когда идет работа с массивами данных, получаем запросы в цикле, проблему n + 1.

Чтобы избежать это необходимо использовать жадную загрузку:

Использование моделей Eloquent

Вторая часть пакета - интеграция ORM Eloquent для пользовательских таблиц в Битриксе, то есть созданных при разработке вручную, а не поставляемых вместе системой. По сути это альтернатива прямым запросам в базу, D7 ORM и моделям D7Model из этого пакета.

Через Eloquent можно работать не только с пользовательскими таблицами, но и с Highload-блоками, что очень удобно. При этом мы работаем с таблицей Highload-блока минуя какое-бы то ни было API Битрикса.

Стоит учитывать, что в отличии от Битрикса, Eloquent использует в качестве расширения PHP для доступа к mysql не mysql/mysqli, а PDO. А это значит что:

  1. необходимо чтобы PDO был установлен и настроен
  2. будут создаваться два подключения к базе на запрос.

Заметка: Вопрос: Зачем в одном пакете Eloquent если уже есть D7Model? Что лучше выбрать? Ответ: Выбор между ними зависит от условий проекта и личных предпочтений. Eloquent удобнее и функциональнее чем всё что есть в Битриксе и в D7Model Например там есть полноценные связи между моделями через промежуточные таблицы и т д С другой стороны это большая внешняя зависимость со своими требованиями

Недостатки

Установка

Первым делом нужно поставить еще одну зависимость - composer require illuminate/database После этого добавляем в init.php еще одну строку - Arrilot\BitrixModels\ServiceProvider::registerEloquent(); Теперь уже можно создавать Eloquent модели наследуясь от EloquentModel

Если таблица называется products (множественная форма названия класса), то protected $table = 'products'; можно опустить - это стандартное для Eloquent поведение. Из нестандартного

  1. Первичным ключом является ID, а не id
  2. Поля для времени создания и обновления записи называются UF_CREATED_AT и UF_UPDATED_AT, а не created_at и updated_at

Если вы решили не добавлять в таблицу поля UF_CREATED_AT и UF_UPDATED_AT, то в модели нужно задать public $timestamps = false;

Работа с хайлоадблоком через Eloquent

Представим что мы создали Highload-блок для брендов Brands, задали для него таблицу brands и добавили в него свойство UF_NAME. Тогда класс-модель для него будет выглядеть так:

А для добавления новой записи в него достаточно следующего кода:

Для полноценной работой с Eloquent-моделями важно ознакомиться с официальной документацией данной ORM (ссылка еще раз)

В заключение обращу внимание на то что, несмотря на то что API моделей Битрикса и моделей Eloquent очень похожи (во многом из-за того что bitrix-models разрабатывались под влияением Eloquent) это всё же разные вещи и внутри они совершенно независимые. Нельзя допустим сделать связь (relation) Eloquent модели и Битриксовой модели.

Множественные свойства highload-блока и Eloquent модели

Множественные свойства в хайлоадблоках реализованы немного хитро. Данные хранятся сразу в 2х местах:

  1. непосредственно в таблице хайлоадблока в сериализованном виде.
  2. в дополнительной таблице для этого свойства. К счастью пакет умеет довольно неплохо решает эту проблему. При добавлении множественного свойства достаточно добавить в модель код этого свойства в поле-массив $multipleHighloadBlockFields модели Например public $multipleHighloadBlockFields = ['UF_SOME_MULTIPLE_FIELD']; После этого:
  3. $model['UF_SOME_MULTIPLE_FIELD'] будет возвращать десериализованный массив
  4. Для добавления/обновления значения поля, тоже достаточно положить в $model['UF_SOME_MULTIPLE_FIELD'] массив, вручную сериализовать его не нужно.
  5. При добавлении/обновлении значения поля изменения будут автоматически применены к вспомогательной таблице. Вручную в ней ничего менять не требуется. Чтобы последний пункт работал требуется установить дополнительную зависимость - composer require illuminate/events. Без этой зависимости вспомогательные таблицы обновляться не будут. Немного подробнее про неё написано в следующем абзаце.

События в Eloquent моделях

В Eloquent есть так называемые События моделей / Model events, которые позволяют вклиниться в какой-то момент работы модели. В целом довольно похожая на Битриксовые события OnBeforeIblockElementUpdate и т д вещь. Если они вам нужны, то вместе с illuminate/database вам нужно поставить еще и зависимость illuminate/events:

composer require illuminate/events

Query Builder

При подключении Eloquent мы бесплатно получаем и Query Builder от Laravel https://laravel.com/docs/master/queries, который очень полезен если необходима прямая работа с БД минуя уровень абстракции моделей. Он удобнее и несравнимо безопаснее чем $DB->Query() и прочее.

Работа с билдером проводится через глобально доступный класс DB. Например добавление элемента бренда в HL-блок будет выглядеть так:

Постраничная навигация (pagination)

И Битрикс-модели и Eloquent-модели поддерживают ->paginate() и ->simplePaginate() (см. http://laravel.com/docs/master/pagination) Для того чтобы затем отобразить постраничную навигацию через ->links() нужно

  1. Установить https://github.com/arrilot/bitrix-blade/
  2. Скопировать дефолтные вьюшки из https://github.com/laravel/framework/tree/master/src/Illuminate/Pagination/resources/views в local/views/pagination

После этого вьюшки можно модифицировать или создавать новые.

Активность элементов в D7Model/EloquentModel

В инфоблоках битрикса есть поле ACTIVE = 'Y'/'N', фильтрация по которому очень часто используется. В хайлоадблоках и кастомных таблицах такого поля по-умолчанию нет, однако пакет предоставляет trait который помогает в создании подобной функциональности. Как это работает:

  1. Добавляем поле UF_DEACTIVATED_AT типа datetime в таблицу/хайлоадблок.
  2. Добавляем в D7Model/EloquentModel трейт use \Arrilot\BitrixModels\Models\Traits\DeactivationTrait;
  3. Теперь в модели доступны следуюющие методы:

    3.1. $model->deactivate() и $model->activate() - деактивирует или активирует элемент в БД.

    3.2. $model->markForDeactivation() и $model->markForActivation() - тоже самое, но только меняет php переменную, не выполняет ->save(). Полезно если вместе с активацией нужно сделать и другие изменения в таблице и не хочется делать дополнительный запрос в БД.

    3.3. Скоупы ->active() и ->deactivated(). Например SomeD7Model::query()->active()->getList().


All versions of bitrix-models with dependencies

PHP Build Version
Package Version
Requires php Version >=5.6.4
Composer command for our command line client (download client) This client runs in each environment. You don't need a specific PHP version etc. The first 20 API calls are free. Standard composer command

The package enjame/bitrix-models contains the following files

Loading the files please wait ....