Model level for Bitrix entities (bitrix models layer)
During the development of almost any application, a convenient mechanism for working with data from the database is needed. In this article we will talk about the extension for CMS Bitrix alexpr94/bitrix-modelsinstalled using the composer package manager.
This package introduces a Model Layer and allows you to generate model classes for the main CMS Bitrix entities, such as infoblocks, infoblock sections, highload blocks and users.
When generating models, the package automatically reads all existing custom fields and properties of the Bitrix entity and, based on them, creates special types of classes with a set of the same custom fields and properties as in your database in lowerCamelCase format.
As a result, you are given the opportunity to use the system of hints built into the code editor (IDE) for possible fields and class properties.
You can install this package in your application with the following command
composer require alexpr94/bitrix-models
Generating models for infoblocks
To generate an information block model, create a script following the example below, edit the parameters of the IBlockGenerator generator constructor according to your requirements, indicating the necessary symbolic code of the information block, the namespace of future generated classes and their saving paths. Next, run the script. After execution, you can delete the script.
use Alexpr94\BitrixModels\Generator\Models\IBlockModels\IBlockGenerator;
require($_SERVER['DOCUMENT_ROOT'] . '/bitrix/header.php');
$pathSaving = $_SERVER['DOCUMENT_ROOT'] . '/local/classes/IBlockModels';
$namespace="Classes\\IBlockModels";
$codeIblock = 'catalog';
$generator = new IBlockGenerator($codeIblock, $pathSaving, $namespace);
if (!$generator->generate()) {
var_dump($generator->getErrors());
}
The code generator will create PHP class files using the specified paths, which will contain all the fields and custom properties of the elements/sections of the specified information block, which will give you the opportunity, through the prompts of the code editor (IDE), to quickly select the necessary properties and fields of elements/sections when writing the code of your application . All classes will begin with the name of the information block symbolic code in CamelCase format.
An example of the structure of the generated files for the information block of products with the symbolic code catalog:
IBlockModels/Catalog/CatalogModel.php – model for selecting elements
IBlockModels/Catalog/CatalogSectionModel.php – model for selecting sections
IBlockModels/Catalog/Overrides/CatalogElementQuery.php – overriding the base ElementQuery request class
IBlockModels/Catalog/Overrides/CatalogModelCollection.php – overriding the base collection class BaseModelsCollection
IBlockModels/Catalog/Overrides/CatalogPropsData.php – overriding the base class of element properties IBElementPropsData
IBlockModels/Catalog/Overrides/CatalogSectionModelCollection.php – overriding the base collection class BaseModelsCollection
IBlockModels/Catalog/Overrides/CatalogSectionPropsData.php – overriding the base class of section properties IBSectionPropsData
IBlockModels/Catalog/Overrides/CatalogSectionQuery.php – overriding the base SectionQuery request class
To work you must use two classes: CatalogModel and CatalogSectionModel. All classes in the Overrides/ folder override the base system classes for working with models and should not be directly created using the new operator. These overrides are necessary for the correct operation of the code editor's (IDE) hint system when writing code for your application.
Generating models for highload blocks
Example code for generating highload block models:
use Alexpr94\BitrixModels\Generator\Models\HLModels\HLModelGenerator;
require($_SERVER['DOCUMENT_ROOT'] . '/bitrix/header.php');
$hlCodes = [
'WarehouseOrders',
'Regions',
'HistoricityFieldsOrder'
];
$pathSave = $_SERVER['DOCUMENT_ROOT'] . '/local/classes/HLModels/';
$namespace="Classes\\HLModels";
foreach ($hlCodes as $hlCode) {
$generator = new HLModelGenerator($hlCode, $pathSave, $namespace);
if (!$generator->generate()) {
var_dump($generator->getErrors());
}
}
Specify the array of highload block codes for which models are needed, and the necessary other parameters of the HLModelGenerator class constructor.
An example of the structure of the generated files for a highload block with the Regions code:
HLModels/Regions/RegionsModel.php – model for selecting records
HLModels/Regions/Overrides/RegionsCollection.php – overriding the base collection class BaseModelsCollection
HLModels/Regions/Overrides/RegionsQuery.php – overriding the base query class for DataManagerQuery tables
Generating a model for users
use Alexpr94\BitrixModels\Generator\Models\UserModels\UserModelGenerator;
require_once($_SERVER['DOCUMENT_ROOT'] . '/local/php_interface/include/header.php');
$generator = new UserModelGenerator($_SERVER['DOCUMENT_ROOT'] . '/local/classes', 'Classes');
$generator->generate();
if (!empty($generator->getErrors())) {
var_dump($generator->getErrors());
}
Structure of generated files for users:
User/UserModel.php – model for selecting records
User/Overrides/UserModelsCollection.php – overriding the base collection class UserModelsCollection
User/Overrides/UserPropsData.php – overriding the base class of user properties UserPropsData
User/Overrides/UserQuery.php – overriding the base query class UserQuery
Using Models
Model selection
To retrieve data, all generated models, regardless of the entity type, have a static query() method that returns a query builder class. In the query builder class, you can set fields and properties for selection, set filters, sorting, pagination options, etc.
Example of partition selection:
$collection = CatalogSectionModel::query()
->setMethodGettingRecordInLoop(BaseIBlockQuery::METHOD_GETTING_FETCH)
->setOrder(['ID' => 'ASC'])
->setNPageSize(10)
->setINumPage(10)
->all();
$models = $collection->items();
foreach ($models as $model) {
var_dump($model->fields);
var_dump($model->props());
}
The query builder's all() method returns a model collection object.
To select one model, instead of the all() method, you can use the one() method, which will immediately return an instance of the model to you:
$model = CatalogSectionModel::query()
->setMethodGettingRecordInLoop(BaseIBlockQuery::METHOD_GETTING_FETCH)
->setOrder(['ID' => 'ASC'])
->setFilter(['ID' => 16])
->one();
var_dump($model->fields->xmlId);
The setMethodGettingRecordInLoop() method of the query builder is required to specify the method for retrieving data by Bitrix. Possible values for the method parameter:
BaseIBlockQuery::METHOD_GETTING_FETCH – 'Fetch'
BaseIBlockQuery::METHOD_GETTING_GET_NEXT – 'GetNext'
BaseIBlockQuery::METHOD_GETTING_GET_NEXT_ELEMENT – 'GetNextElement'
Deleting a model
To delete, all models have a delete() method.
Saving a model for a highload block
For a highload block, use the save() method of the model instance.
Saving models for information blocks, sections and users
Due to the complex structure of storing these entities in the database, in terms of performance, it was decided to leave the save() method unimplemented for these models. In them, the save() method contains stub code that returns false. You can override this method at your discretion.