РАЗРАБОТКА НА БИТРИКС

Автоматическая генерация ORM-классов для любой таблицы в Битрикс

Подписывайтесь на канал для bitrix-разработчиков в Telegram!
В данном кейсе будет рассмотрен простой прием, дающий возможность обернуть любую таблицу в Битриксе в ORM. Это позволит работать с ней стандартными методами D7, такими как getList, getCount, add, update, delete и так далее.

Описание задачи

При решении задачи нужно было загрузить из файла 5000 купонов и добавить их в таблицу b_sale_discount_coupon.

Решение

Автоматическая генерация ORM-классов

Используя фильтр, находим нужную нам таблицу в БД в админке сайта - Настройки > Производительность > Таблицы.
Автоматическая генерация ORM-классов - KISLOROD
Далее используем секретный способ: добавляем GET-параметр orm=y, то есть до # и после ?lang=ru добавляем &orm=y.
Добавление Get параметров в URL страниц - KISLOROD
После такого "взлома матрицы" в контекстном меню таблицы появится дополнительный пункт — ORM.
Создание ORM в 1С-Битрикс - KISLOROD
Нажимаем на этот пункт, и происходит генерация класса DiscountCouponTable, наследуемого от Main\Entity\DataManager и ленгового файла для него.

Код сгенерированного класса

<?php
namespace Bitrix\Sale;

use Bitrix\Main,
	Bitrix\Main\Localization\Loc;
Loc::loadMessages(__FILE__);

/**
 * Class DiscountCouponTable
 * 
 * Fields:
 * <ul>
 * <li> ID int mandatory
 * <li> DISCOUNT_ID int mandatory
 * <li> ACTIVE bool optional default 'Y'
 * <li> ACTIVE_FROM datetime optional
 * <li> ACTIVE_TO datetime optional
 * <li> COUPON string(32) mandatory
 * <li> TYPE int mandatory
 * <li> MAX_USE int mandatory
 * <li> USE_COUNT int mandatory
 * <li> USER_ID int mandatory
 * <li> DATE_APPLY datetime optional
 * <li> TIMESTAMP_X datetime optional
 * <li> MODIFIED_BY int optional
 * <li> DATE_CREATE datetime optional
 * <li> CREATED_BY int optional
 * <li> DESCRIPTION string optional
 * <li> DISCOUNT reference to {@link \Bitrix\Sale\SaleDiscountTable}
 * <li> USER reference to {@link \Bitrix\User\UserTable}
 * <li> MODIFIED_BY reference to {@link \Bitrix\User\UserTable}
 * </ul>
 *
 * @package Bitrix\Sale
 **/

class DiscountCouponTable extends Main\Entity\DataManager
{
	/**
	 * Returns DB table name for entity.
	 *
	 * @return string
	 */
	public static function getTableName()
	{
		return 'b_sale_discount_coupon';
	}

	/**
	 * Returns entity map definition.
	 *
	 * @return array
	 */
	public static function getMap()
	{
		return array(
			'ID' => array(
				'data_type' => 'integer',
				'primary' => true,
				'autocomplete' => true,
				'title' => Loc::getMessage('DISCOUNT_COUPON_ENTITY_ID_FIELD'),
			),
			'DISCOUNT_ID' => array(
				'data_type' => 'integer',
				'required' => true,
				'title' => Loc::getMessage('DISCOUNT_COUPON_ENTITY_DISCOUNT_ID_FIELD'),
			),
			'ACTIVE' => array(
				'data_type' => 'boolean',
				'values' => array('N', 'Y'),
				'title' => Loc::getMessage('DISCOUNT_COUPON_ENTITY_ACTIVE_FIELD'),
			),
			'ACTIVE_FROM' => array(
				'data_type' => 'datetime',
				'title' => Loc::getMessage('DISCOUNT_COUPON_ENTITY_ACTIVE_FROM_FIELD'),
			),
			'ACTIVE_TO' => array(
				'data_type' => 'datetime',
				'title' => Loc::getMessage('DISCOUNT_COUPON_ENTITY_ACTIVE_TO_FIELD'),
			),
			'COUPON' => array(
				'data_type' => 'string',
				'required' => true,
				'validation' => array(__CLASS__, 'validateCoupon'),
				'title' => Loc::getMessage('DISCOUNT_COUPON_ENTITY_COUPON_FIELD'),
			),
			'TYPE' => array(
				'data_type' => 'integer',
				'required' => true,
				'title' => Loc::getMessage('DISCOUNT_COUPON_ENTITY_TYPE_FIELD'),
			),
			'MAX_USE' => array(
				'data_type' => 'integer',
				'required' => true,
				'title' => Loc::getMessage('DISCOUNT_COUPON_ENTITY_MAX_USE_FIELD'),
			),
			'USE_COUNT' => array(
				'data_type' => 'integer',
				'required' => true,
				'title' => Loc::getMessage('DISCOUNT_COUPON_ENTITY_USE_COUNT_FIELD'),
			),
			'USER_ID' => array(
				'data_type' => 'integer',
				'required' => true,
				'title' => Loc::getMessage('DISCOUNT_COUPON_ENTITY_USER_ID_FIELD'),
			),
			'DATE_APPLY' => array(
				'data_type' => 'datetime',
				'title' => Loc::getMessage('DISCOUNT_COUPON_ENTITY_DATE_APPLY_FIELD'),
			),
			'TIMESTAMP_X' => array(
				'data_type' => 'datetime',
				'title' => Loc::getMessage('DISCOUNT_COUPON_ENTITY_TIMESTAMP_X_FIELD'),
			),
			'MODIFIED_BY' => array(
				'data_type' => 'integer',
				'title' => Loc::getMessage('DISCOUNT_COUPON_ENTITY_MODIFIED_BY_FIELD'),
			),
			'DATE_CREATE' => array(
				'data_type' => 'datetime',
				'title' => Loc::getMessage('DISCOUNT_COUPON_ENTITY_DATE_CREATE_FIELD'),
			),
			'CREATED_BY' => array(
				'data_type' => 'integer',
				'title' => Loc::getMessage('DISCOUNT_COUPON_ENTITY_CREATED_BY_FIELD'),
			),
			'DESCRIPTION' => array(
				'data_type' => 'text',
				'title' => Loc::getMessage('DISCOUNT_COUPON_ENTITY_DESCRIPTION_FIELD'),
			),
			'DISCOUNT' => array(
				'data_type' => 'Bitrix\Sale\SaleDiscount',
				'reference' => array('=this.DISCOUNT_ID' => 'ref.ID'),
			),
			'USER' => array(
				'data_type' => 'Bitrix\User\User',
				'reference' => array('=this.USER_ID' => 'ref.ID'),
			),
			'MODIFIED_BY' => array(
				'data_type' => 'Bitrix\User\User',
				'reference' => array('=this.MODIFIED_BY' => 'ref.ID'),
			),
		);
	}
	/**
	 * Returns validators for COUPON field.
	 *
	 * @return array
	 */
	public static function validateCoupon()
	{
		return array(
			new Main\Entity\Validator\Length(null, 32),
		);
	}
}

Код сгенерированного лэнгового файла

<?
$MESS["DISCOUNT_COUPON_ENTITY_ID_FIELD"] = "";
$MESS["DISCOUNT_COUPON_ENTITY_DISCOUNT_ID_FIELD"] = "";
$MESS["DISCOUNT_COUPON_ENTITY_ACTIVE_FIELD"] = "";
$MESS["DISCOUNT_COUPON_ENTITY_ACTIVE_FROM_FIELD"] = "";
$MESS["DISCOUNT_COUPON_ENTITY_ACTIVE_TO_FIELD"] = "";
$MESS["DISCOUNT_COUPON_ENTITY_COUPON_FIELD"] = "";
$MESS["DISCOUNT_COUPON_ENTITY_TYPE_FIELD"] = "";
$MESS["DISCOUNT_COUPON_ENTITY_MAX_USE_FIELD"] = "";
$MESS["DISCOUNT_COUPON_ENTITY_USE_COUNT_FIELD"] = "";
$MESS["DISCOUNT_COUPON_ENTITY_USER_ID_FIELD"] = "";
$MESS["DISCOUNT_COUPON_ENTITY_DATE_APPLY_FIELD"] = "";
$MESS["DISCOUNT_COUPON_ENTITY_TIMESTAMP_X_FIELD"] = "";
$MESS["DISCOUNT_COUPON_ENTITY_MODIFIED_BY_FIELD"] = "";
$MESS["DISCOUNT_COUPON_ENTITY_DATE_CREATE_FIELD"] = "";
$MESS["DISCOUNT_COUPON_ENTITY_CREATED_BY_FIELD"] = "";
$MESS["DISCOUNT_COUPON_ENTITY_DESCRIPTION_FIELD"] = "";
?>
В нашем случае код класса кладем в папку /local/lib/Project_name/DiscountCouponTable, в файл с названием класса с большой буквы — DiscountCouponTable.php.
Там же в /local/lib/Project_name/DiscountCouponTable/ создаем папки с языковыми файлами /lang/ru/ и кладем туда файл DiscountCouponTable.php с содержанием сгенерированного лэнговогого файла.
Создание папки с языковыми файлами в корне сайта 1С-Битрикс - KISLOROD
В файле класса меняем
namespace Bitrix\Sale;
на наше расположение класса
namespace Project_name\DiscountCouponTable;
Всё! Теперь можно работать с таблицей в привычном для D7 синтаксисе. Например:
use \Project_name\DiscountCouponTable\DiscountCouponTable;

//получаем все купоны привязанные к акции у которой айдишник = $discount_id
$params = array(
		'select' => array('DISCOUNT_ID', 'COUPON'),
    'filter' => array('=DISCOUNT_ID' => $discount_id)
     );
$result = DiscountCouponTable::getList($params);

Результат

Класс для работы с таблицей стандартными методами D7 getList, getCount, add, update, delete.

Выводы

В Битриксе есть нормальный ORM, который натягивается на любую таблицу достаточно оперативно и дает широкие возможности жонглировать содержанием этих таблиц. Код получается лаконичный и понятный.
Подписывайтесь на канал для bitrix-разработчиков в Telegram!

Рекомендованные статьи