С выходом 20-й версии 1С Битрикс, появилась возможность работы с элементами инфоблока средствами ORM. Для того, чтобы начать использовать эту возможность вам необходимо зайти в настройки информационного блока и задать значения для поля «Символьный код API». Согласно документации, символьный код API это строка от 1 до 50 символов состоящая из букв и цифр, начинающаяся с буквы. Я взял инфоблок «Одежда» из коробки БУС редакции «Бизнес» и задал код products
.
Для работы с элементами инфоблока средствами ORM, необходимо использовать класс \Bitrix\Iblock\Elements\Element_Символьный_код_API_инфоблока_Table, в моём случае это класс \Bitrix\Iblock\Elements\ElementProductsTable. Можно убедиться в этом вызвав следующий код:
1 2 3 4 5 |
//Подключим модуль «Информационные блоки» \Bitrix\Main\Loader::includeModule('iblock'); //Имя ORM класса для работы с инфоблоком «Одежда» echo \Bitrix\Iblock\Iblock::wakeUp(IBLOCK_CATALOG_ID)->getEntityDataClass(); //Где IBLOCK_CATALOG_ID - содержит ID инфоблока «Одежда» |
Выведет строку \Bitrix\Iblock\Elements\ElementProductsTable. Давайте рассмотрим практические примеры работы, подберём аналоги уже привычных нам методов старого ядра.
Аналог CIBlockElement::GetById() в ORM
Для получения данных по элементу инфоблока, по ID этого элемента, используется метод getByPrimary()
вашего «виртуального класса»:
1 2 3 |
$product = \Bitrix\Iblock\Elements\ElementProductsTable::getByPrimary(10, [ //10 - ID товара, «Платье, Красная фея» 'select' => ['ID', 'NAME', 'PREVIEW_TEXT', 'DETAIL_PICTURE', 'MANUFACTURER', 'MATERIAL'], ])->fetch(); |
В переменной $product
будет примерно такая информация:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
Содержимое переменной: Array ( [ID] => 10 [NAME] => Платье Красная Фея [PREVIEW_TEXT] => [DETAIL_PICTURE] => 68 [IBLOCK_ELEMENTS_ELEMENT_PRODUCTS_MANUFACTURER_ID] => 2148 [IBLOCK_ELEMENTS_ELEMENT_PRODUCTS_MANUFACTURER_IBLOCK_ELEMENT_ID] => 10 [IBLOCK_ELEMENTS_ELEMENT_PRODUCTS_MANUFACTURER_IBLOCK_PROPERTY_ID] => 10 [IBLOCK_ELEMENTS_ELEMENT_PRODUCTS_MANUFACTURER_VALUE] => Россия "Модница" [IBLOCK_ELEMENTS_ELEMENT_PRODUCTS_MATERIAL_ID] => 2156 [IBLOCK_ELEMENTS_ELEMENT_PRODUCTS_MATERIAL_IBLOCK_ELEMENT_ID] => 10 [IBLOCK_ELEMENTS_ELEMENT_PRODUCTS_MATERIAL_IBLOCK_PROPERTY_ID] => 11 [IBLOCK_ELEMENTS_ELEMENT_PRODUCTS_MATERIAL_VALUE] => трикотаж ) |
Обратите внимание, что ключи пользовательских свойств инфоблока, MANUFACTURER
и MATERIAL
указываются как есть, без префикса PROPERTY_
. Чтобы избежать таких длинных ключей как IBLOCK_ELEMENTS_ELEMENT_PRODUCTS_MANUFACTURER_IBLOCK_ELEMENT_ID
в результирующем массиве, можно использовать псевдонимы, вот так:
1 2 3 |
$product = \Bitrix\Iblock\Elements\ElementProductsTable::getByPrimary(10, [ //10 - ID товара, «Платье, Красная фея» 'select' => ['ID', 'NAME', 'PREVIEW_TEXT', 'DETAIL_PICTURE', 'MANUFACTURER_' => 'MANUFACTURER', 'MATERIAL_'=>'MATERIAL'], ])->fetch(); |
В таком случае, данные приходят в более удобном виде:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
Содержимое переменной: Array ( [ID] => 10 [NAME] => Платье Красная Фея [PREVIEW_TEXT] => [DETAIL_PICTURE] => 68 [MANUFACTURER_ID] => 2148 [MANUFACTURER_IBLOCK_ELEMENT_ID] => 10 [MANUFACTURER_IBLOCK_PROPERTY_ID] => 10 [MANUFACTURER_VALUE] => Россия "Модница" [MATERIAL_ID] => 2156 [MATERIAL_IBLOCK_ELEMENT_ID] => 10 [MATERIAL_IBLOCK_PROPERTY_ID] => 11 [MATERIAL_VALUE] => трикотаж ) |
Элемент инфоблока как объект
С данными элемента инфоблока можно работать не только как с массивом, но и как с объектом. Для этого используйте метод fetchObject()
вместо fetch()
после вызова getByPrimary()
.
1 2 3 |
$product = \Bitrix\Iblock\Elements\ElementProductsTable::getByPrimary(10, [ //10 - ID товара, «Платье, Красная фея» 'select' => ['ID', 'NAME', 'PREVIEW_TEXT', 'DETAIL_PICTURE', 'MANUFACTURER_' => 'MANUFACTURER', 'MATERIAL_'=>'MATERIAL'], ])->fetchObject(); |
В данном случае, в $product
будет получен объект класса Bitrix\Iblock\Elements\EO_ElementProducts с множеством методов для работы с ним. Например:
1 2 3 4 5 6 7 8 |
//Получить id товара echo $product->getId(); //10 //Получить наименование товара echo $product->getName(); //"Платье Красная Фея" //Получить id детального изображения echo $product->getDetailPicture(); //68 |
Как видите для получения значений элемента инфоблока используются так называемые геттеры (методы getXXXX где XXX — название поля в «верблюжьей нотации» или CamelCase). Существует так же общий метод get()
который принимает наименование поля, значение которого вам нужно получить. Например:
1 2 3 4 5 |
//Получим id элемента echo $product->Get('ID'); // 10 //Получим наименование элемента echo $product->Get('NAME'); // "Платье Красная фея" |
Свойства элемента
Свойства элементов (когда мы работаем с ними в виде объекта) так же получаются при помощи геттеров (методов getXXXX где XXXX — код свойства записанный как CamelCase). У каждого свойства есть поле значения VALUE
и описания DESCRIPTION
и соответcnвующие методы для доступа к ним getValue()
и getDescription()
. Рассмотрим пример:
1 2 3 4 5 6 7 |
//Получим данные товара $product = \Bitrix\Iblock\Elements\ElementProductsTable::getByPrimary(10, [ //10 - ID товара, «Платье, Красная фея» 'select' => ['ID', 'NAME', 'PREVIEW_TEXT', 'DETAIL_PICTURE', 'MANUFACTURER', 'MATERIAL'], //MANUFACTURER и MATERIAL свойства типа «Строка» ])->fetchObject(); //Получим значение свойства MANUFACTURER var_dump($product->getManufacturer()->getValue()); |
В результате получим строку:
1 |
string(29) "Россия "Модница"" |
Чтобы получить дополнительную информацию для некоторых типов свойств через ORM, нужно указать дополнительный ключ при выборке свойства:
- FILE — свойство типа файл
- ITEM — свойство типа список,
- ELEMENT — свойство типа привязка к элементу инфоблока
- SECTION — свойство типа привязка к разделу инфоблока
Давайте рассмотрим это детальнее. У нашего элемента есть следующие свойства требуемых типов:
- MORE_PHOTO — Картинки галереи (тип файл)
- NEWPRODUCT — Новинка (тип список)
- RECOMMEND — С этим товаром рекомендуем (тип привязка к элементу)
- NEWS_SECTION — Показывать в рекламном блоке в новостях (тип привязка к разделу), это я создал для теста, в «коробке» такого нет
Давайте получим их в ORM:
1 2 3 4 5 6 7 8 9 10 11 12 13 |
//Получим данные товара $product = \Bitrix\Iblock\Elements\ElementProductsTable::getByPrimary(10, [ 'select' => [ 'ID', 'NAME', 'PREVIEW_TEXT', 'DETAIL_PICTURE', 'MORE_PHOTO.FILE', //Обратите внимание на доп.ключи 'NEWPRODUCT.ITEM', 'RECOMMEND.ELEMENT', 'NEWS_SECTION.SECTION' ], ])->fetchObject(); |
Свойство типа файл в ORM
1 2 3 4 |
//Выведем доп.фотографии товара foreach ($product->getMorePhoto()->getAll() as $photo){ echo '<img src="/upload/' . $photo->getFile()->getSubdir() . '/' . $photo->getFile()->getFileName() . '" alt="'. $product->getName() .'" />'; } |
Обратите внимание во первых на метод getAll()
, т.к. свойство MORE_PHOTO — множественное, по сути оно представляет из себя коллекцию значений. Чтобы получить всю коллекцию и применяют метод getAll()
. Далее при обходе элемента коллекции свойства типа файл мы получаем в распоряжение метод getFile()
, который в свою очередь открывает нам доступ к методам getSubdir()
и getFileName()
для получения дополнительной информации о файле.
Свойство типа список в ORM
1 2 3 4 5 6 7 |
//Свойство типа список var_dump($product->getNewproduct()->getItem()->getId()); //int(1) var_dump($product->getNewproduct()->getItem()->getXmlId()); //string(1) "Y" var_dump($product->getNewproduct()->getItem()->getValue()); //string(4) "да" |
getItem()
который позволяет получить ID значения списка методом getId()
, внешний код значения getXmlId()
и само значение методом getValue()
.
Свойство типа привязка к элементам инфоблока в ORM
1 2 3 4 |
//Получим привязанные элементы foreach ($product->getRecommend()->getAll() as $recommendedProduct){ echo 'Рекомендуемый товар ID -' . $recommendedProduct->getElement()->getId() . ' наименование - ' . $recommendedProduct->getElement()->getName() . '<br/>'; } |
getAll()
. Далее мы видим, что элементу коллекции доступен метод getElement()
через который мы можем узнать некоторую информацию об элементе, например ID getId()
и наименование getName()
.
Свойство типа привязка к разделу инфоблока в ORM
1 2 3 4 |
//Получим id привязанного раздела var_dump($product->getNewsSection()->getSection()->getId()); //Получим наименование привязанного раздела var_dump($product->getNewsSection()->getSection()->getName()); |
Аналог CIBlockElement::GetList() в ORM
В качестве аналога к всем полюбившимся методу CIBlockElement::GetList()
используется getList()
из D7 который применялся к HL-блокам ранее. Приведу пример:
1 2 3 4 5 6 7 |
$products = \Bitrix\Iblock\Elements\ElementProductsTable::getList([ 'select' => ['ID', 'NAME', 'PREVIEW_TEXT', 'DETAIL_PICTURE', 'MANUFACTURER_' => 'MANUFACTURER', 'MATERIAL_'=>'MATERIAL'], 'filter' => ['=ACTIVE' => 'Y'], ])->fetchAll(); foreach ($products as $product) { //...что-то делаем с данными продуктов... } |
Тут всё как в HL блоках D7, поэтому детально разбирать этот вопрос я не стану.
Кеширование результата выборки данных
В Битрикс ORM несколько упростили процедуру кеширования результатов выборки из инфоблока. Для этого вам достаточно добавить в массив параметра метода getList()
поле cache и указать параметры кеширования:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
$product = \Bitrix\Iblock\Elements\ElementCatalogTable::getList([ 'select' => [ 'ID', 'NAME', 'PREVIEW_TEXT', 'DETAIL_PICTURE' ], 'filter' => [ 'ID' => 10, ], 'cache' => [ 'ttl' => 3600 ], ])->fetchObject(); |
В одной из ближайших статей я напишу простой компонент в двух версиях, старой с использованием классических приёмов работы с ифноблокми и новой с использованием ORM и сравню производительность.
Надеюсь статья окажется для вас полезной, желаю удачи!
Оставьте первый комментарий!