В 20 версии Битрикс спустя несколько лет после появления ядра D7, призванного превратить Битрикс в современный фреймворк (нет), появилась возможность хоть как-то удобно использовать новое ядро для работы с элементами инфоблоков и их свойствами.
Примеры протестированы на версии 1С-Битрикс: Управление сайтом 20.0.1196. Кстати, не забываем подключить модуль iblock:
\Bitrix\Main\Loader::includeModule('iblock');
Для доступа к возможностям нового ядра у инфоблока нужно задать так называемый Символьный код API. По документации это строка от 1 до 50 символов, начинающаяся с буквы и состоящая из латинских букв и цифр.
Для работы с элементами используется класс \Bitrix\Iblock\Elements\ElementXXXXXTable, где XXXXX - Символьный код API. Для инфоблока на примере выше это будет класс \Bitrix\Iblock\Elements\ElementCatalogTable
. Получить название класса для инфоблока можно следующим методом:
var_dump(\Bitrix\Iblock\Iblock::wakeUp($iblockId)->getEntityDataClass());
// string(43) "\Bitrix\Iblock\Elements\ElementCatalogTable"
Работа с элементом как с массивом
Разберем различные примеры получения элементов. Простейший пример - это аналог CIBlockElement::GetByID:
$element = \Bitrix\Iblock\Elements\ElementCatalogTable::getByPrimary($elementId, [
'select' => ['ID', 'NAME', 'DETAIL_TEXT', 'DETAIL_PICTURE', 'ARTNUMBER'],
])->fetch();
var_dump($element);
/*array(8) {
["ID"]=>
string(1) "4"
["NAME"]=>
string(38) "Штаны Полосатый Рейс"
["DETAIL_TEXT"]=>
string(?) "Брюки-клеш идеально сидят..."
["DETAIL_PICTURE"]=>
string(2) "46"
["IBLOCK_ELEMENTS_ELEMENT_CATALOG_ARTNUMBER_ID"]=>
string(1) "9"
["IBLOCK_ELEMENTS_ELEMENT_CATALOG_ARTNUMBER_IBLOCK_ELEMENT_ID"]=>
string(1) "4"
["IBLOCK_ELEMENTS_ELEMENT_CATALOG_ARTNUMBER_IBLOCK_PROPERTY_ID"]=>
string(1) "9"
["IBLOCK_ELEMENTS_ELEMENT_CATALOG_ARTNUMBER_VALUE"]=>
string(11) "177-77-хх"
}*/
Да, указывается код свойства без префикса "PROPERTY". Правда здесь выходит какое-то безумное именование ключей. Немного получше можно сделать с помощью алиасов:
$element = \Bitrix\Iblock\Elements\ElementCatalogTable::getByPrimary($elementId, [
'select' => ['ID', 'NAME', 'ARTNUMBER_' => 'ARTNUMBER'],
])->fetch();
var_dump($element);
/*
array(6) {
["ID"]=>
string(1) "4"
["NAME"]=>
string(38) "Штаны Полосатый Рейс"
["ARTNUMBER_ID"]=>
string(1) "9"
["ARTNUMBER_IBLOCK_ELEMENT_ID"]=>
string(1) "4"
["ARTNUMBER_IBLOCK_PROPERTY_ID"]=>
string(1) "9"
["ARTNUMBER_VALUE"]=>
string(11) "177-77-хх"
}
*/
Аналогом CIBlockElement::GetList будет getList из D7:
$elements = \Bitrix\Iblock\Elements\ElementCatalogTable::getList([
'select' => ['ID', 'NAME', 'ARTNUMBER_' => 'ARTNUMBER'],
'filter' => ['=ACTIVE' => 'Y'],
])->fetchAll();
foreach ($elements as $element) {
// ...
}
Подробнее рассматривать работу с массивом не буду. Массив всегда можно вывести и посмотреть содержимое. А вот с объектами посложнее, ниже буду рассматривать работу как с объектом. Заменив fetchCollection на fetchAll, а fetchObject на fetchRow можно получить массив полей элемента и вывести то, что получилось. Для удобства именования можно использовать алиасы в select.
Работа с элементом как с объектом
Есть возможность работать с элементами инфоблока как с объектами. Для этого используем методы fetchObject для получения объекта (один элемент) и fetchCollection для получения коллекции объектов (выборка).
Пример для одного элемента:
$element = \Bitrix\Iblock\Elements\ElementCatalogTable::getByPrimary($elementId, array(
'select' => array('ID', 'NAME', 'DETAIL_PICTURE')
))->fetchObject();
var_dump($element->getId());
// int(6)
var_dump($element->getName());
// string(42) "Штаны Цветочная Поляна"
var_dump($element->getDetailPicture());
// int(48)
Пример для нескольких элементов:
$elements = \Bitrix\Iblock\Elements\ElementCatalogTable::getList([
'select' => ['ID', 'NAME', 'DETAIL_PICTURE'],
'filter' => [
'ID' => $elementId,
],
])->fetchCollection();
foreach ($elements as $element) {
var_dump($element->getName());
// string(42) "Штаны Цветочная Поляна"
}
Как видим, для получения значений полей используются методы getXyz, например, getName для получения NAME. Используется CamelCase, т.е. для получения например DETAIL_PICTURE используется метод getDetailPicture. Также поля можно получить методом get:
$element = \Bitrix\Iblock\Elements\ElementCatalogTable::getList([
'select' => ['ID', 'NAME'],
'filter' => [
'ID' => $elementId,
],
])->fetchObject();
var_dump($element->get('NAME'));
// string(46) "Футболка Женская Чистота"
Разделы элементов
Напомню, что элементы могут быть привязаны к нескольким разделам, но GetList-ом можно было получить только один основной раздел инфоблока. Приведу пример аналогичного поведения в новом ядре:
$elements = \Bitrix\Iblock\Elements\ElementCatalogTable::getList([
'select' => ['ID', 'IBLOCK_SECTION'],
'filter' => [
'ID' => $elementId,
],
])->fetchObject();
var_dump ($element->getIblockSection()->getName());
// string(10) "Штаны"
Для получения всех разделов элемента используем поле SECTIONS, так у нас появляется возможность получения коллекции разделов. Получить значения коллекции можно с помощью метода getAll():
$element = \Bitrix\Iblock\Elements\ElementCatalogTable::getList([
'select' => ['ID', 'SECTIONS'],
'filter' => [
'ID' => $elementId,
],
])->fetchObject();
foreach ($element->getSections()->getAll() as $section) {
var_dump($section->getId());
// int(8)
var_dump($section->getCode());
// string(5) "pants"
var_dump($section->getName());
// string(10) "Штаны"
}
Свойства элементов
Свойства можно получить методом getXyz, где Xyz - CamelCased-код свойства. У свойств есть VALUE и DESCRIPTION, которые можно получить методами getValue и getDescription соответственно. Для некоторых типов добавляются дополнительные поля для доступа к дополнительной информации (ITEM - значение свойства типа список, ELEMENT - привязанный элемент, SECTION - привязанный раздел, FILE - файл).
Начнем с простого: свойства типа Текст или Число:
$element = \Bitrix\Iblock\Elements\ElementCatalogTable::getByPrimary($elementId, array(
'select' => array('ID', 'ARTNUMBER')
))->fetchObject();
var_dump($element->getArtnumber()->getValue());
// string(11) "177-79-00"
Если для свойства включен вывод описания, то его можно получить методом getDescription.
Если свойство множественное, то getSomePropertyCode() вернет коллекцию. Получить значения коллекции также можно с помощью метода getAll(). Рассмотрим на примере множественного свойства типа Справочник:
$elements = \Bitrix\Iblock\Elements\ElementCatalogTable::getList([
'select' => ['ID', 'NAME', 'DETAIL_PICTURE', 'BRAND_REF'],
'filter' => [
'ID' => $elementId,
],
])->fetchCollection();
foreach ($elements as $element) {
foreach ($element->getBrandRef()->getAll() as $value) {
var_dump($value->getValue());
}
}
// string(8) "company2"
// string(8) "company3"
// string(6) "brand2"
// string(6) "brand1"
// string(6) "brand3"
Заметили, что получение множественных свойств не создает проблем с дублированием строк, как при одном?
Переходим в свойствам типа Файл. К значениям таких свойств можно привязать информацию из таблицы товаров и получить не только ID файлов, но информацию о файле. Рассмотрим на примере свойства с 2 картинками. Обратите внимание на добавленное к коду свойства слово FILE:
$elements = \Bitrix\Iblock\Elements\ElementCatalogTable::getList([
'select' => ['ID', 'MORE_PHOTO.FILE'],
'filter' => [
'ID' => $elementId,
],
])->fetchCollection();
foreach ($elements as $element) {
foreach ($element->getMorePhoto()->getAll() as $value) {
var_dump('/upload/' . $value->getFile()->getSubdir().'/'.$value->getFile()->getFileName());
}
}
//string(55) "/upload/iblock/2d6/2d6d01a93d220c012e40415616a3d0e1.jpg"
//string(55) "/upload/iblock/dd3/dd3495f96990223e3076c97e99b062d9.jpg"
Со свойства типа Список традиционно всё немного сложнее. Получить просто ID значения достаточно просто:
$element = \Bitrix\Iblock\Elements\ElementCatalogTable::getList([
'select' => ['ID', 'NEWPRODUCT'],
'filter' => [
'ID' => $elementId,
],
])->fetchObject();
var_dump($element->getNewproduct()->getValue());
// int(1)
Если требуется получить ID, XML_ID и значение, то используем ITEM после код свойства, тогда к запросу добавится таблица значений списочных свойств:
$element = \Bitrix\Iblock\Elements\ElementCatalogTable::getList([
'select' => ['ID', 'NEWPRODUCT.ITEM'],
'filter' => [
'ID' => $elementId,
],
])->fetchObject();
var_dump($element->getNewproduct()->getItem()->getId());
// int(1)
var_dump($element->getNewproduct()->getItem()->getXmlId());
// string(1) "Y"
var_dump($element->getNewproduct()->getItem()->getValue());
// string(4) "да"
У свойств типов Привязка к элементам и Привязка к разделам есть подобное дополнительное поле (ELEMENT/SECTION) для доступа к элементу/разделу:
$element = \Bitrix\Iblock\Elements\ElementCatalogTable::getList([
'select' => ['ID', 'RECOMMEND.ELEMENT'],
'filter' => [
'ID' => $elementId,
],
])->fetchObject();
foreach ($element->getRecommend()->getAll() as $linkElement) {
var_dump($linkElement->getElement()->getId());
// int(29)
var_dump($linkElement->getElement()->getName());
// string(34) "Платье Красная Фея"
}
Кеширование
Не забываем про возможность кеширование результатов выборок ORM D7:
$element = \Bitrix\Iblock\Elements\ElementCatalogTable::getList([
'select' => ['ID', 'NAME'],
'filter' => [
'ID' => $elementId,
],
"cache" => ["ttl" => 3600],
])->fetchObject();