Элементы инфоблока и их свойства в ORM Битрикс ядра D7

В многострадальном ядре D7 Битрикса появились методы позволяющие производить выборку элементов инфоблока и их свойств.

Небольшой экскурс под катом ниже.

Содержание

Первое, что нужно сделать — прописать символьный код API в свойствах инфоблока:

Перед работой с ORM нужно подключить модуль инфоблоков

use Bitrix\Main\Loader;

Loader::includeModule('iblock');

Также давайте договоримся, что во всех примерах ниже будем использовать следующий use:

use Bitrix\Iblock\Elements\ElementCatalogTable;

Пространство имен и класс инфоблока

Для работы с элементами инфоблока необходимо использовать класс

Bitrix\Iblock\Elements\Element{Символьный_код_API_инфоблока}Table

где {Символьный_код_API_инфоблока} пишется с заглавной буквы.

В данном примере это

Bitrix\Iblock\Elements\ElementProductsTable

Искомый неймспейс инфоблока и его класса можно также получить с помощью метода getEntityDataClass(), который является методом класса Bitrix\Iblock\Iblock .

Примеры:

use Bitrix\Iblock\Iblock;

// Неймспейс и класс инфоблока по его ID
Iblock::wakeUp(IBLOCK_ID)->getEntityDataClass(); 
use Bitrix\Iblock\IblockTable;

$iblock = IblockTable::getList([
    'select' => ['ID', 'API_CODE'],
    'filter' => [
       // some filter
    ],
])->fetchObject();

if (!$iblock || empty($iblock->getApiCode())) {
    return false;
}

// Неймспейс и класс инфоблока, полученного из выборки инфоблока по фильтру
$iblockEntity = $iblock->getEntityDataClass();

Элемент инфоблока как массив

В старом ядре свойства элемента инфоблока можно было получить с помощью CIBlockElement::GetByID.

В новом ядре это можно сделать так:

$element = 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-хх"
}*/

Какие жуткие ключи массива… Исправим это с помощью алиасов:

$element = 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-хх"
}
*/

Если нам необходимо сделать выборку через getList, то код будет примерно такой:

$elements = ElementCatalogTable::getList([
    'select' => ['ID', 'NAME', 'ARTNUMBER_' => 'ARTNUMBER'],
    'filter' => ['=ACTIVE' => 'Y'],
])->fetchAll();
foreach ($elements as $element) {
    // ...
}

Документацию по getList-у D7 можно найти в официальной документации.

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

Элемент инфоблока как объект

Для получения элементов инфоблока как объектов, необходимо к результатам выборки применить

Выборка свойств одного элемента:

$element = 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 = ElementCatalogTable::getList([
    'select' => ['ID', 'NAME', 'DETAIL_PICTURE'],
    'filter' => [
        'ID' => $elementId,
    ],
])->fetchCollection();

foreach ($elements as $element) {
    var_dump($element->getName());
    // string(42) "Штаны Цветочная Поляна"
}

Для получения свойств элемента инфоблока используются геттеры (методы getXXX где XXX — название поля в «верблюжьей нотации» или CamelCase). Существует так же общий метод get(), который принимает наименование поля, значение которого вам нужно получить.

//Получить id товара
echo $element->getId(); //10

//Получить наименование товара
echo $element->getName(); //"Платье Красная Фея"

//Получить id детального изображения
echo $element->getDetailPicture(); //68

//Получим id элемента
echo $element->get('ID'); // 10

//Получим наименование элемента
echo $element->get('NAME'); // "Платье Красная фея"

Стоит отметить, что лучше использовать общий «геттер» get() , так как для runtime полей, создаваемых в рамках отдельных запросов, предусмотрен только универсальный «геттер» get(). Так ваш код будет выглядеть чище.

Свойства элемента инфоблока

Элемент инфоблока может содержать свойства самых разных типов. Это могут быть как предопределенные свойства (название, описание, preview картинка и т.п.), так и созданные администратором на странице редактирования инфоблока.

У кастомных свойств (которые созданы админом на странице редактирования инфоблока) есть VALUE и DESCRIPTION, которые можно получить методами getValue() и getDescription() соответственно. Для некоторых типов свойств нужно указать дополнительные поля в выборку для доступа к информации:

  • FILE — свойство типа «Файл»
  • ITEM — свойство типа «Список»
  • ELEMENT — свойство типа «Привязка к элементу инфоблока»
  • SECTION — свойство типа «Привязка к разделу инфоблока»

Рассмотрим примеры получения свойств различных типов.

Свойства типа «Текст» или «Число»

Здесь все максимально просто:

$element = ElementCatalogTable::getByPrimary($elementId, array(
    'select' => array('ID', 'ARTNUMBER')
))->fetchObject();

var_dump($element->getArtnumber()->getValue());
// string(11) "177-79-00"

Свойства типа «Файл»

Обратите внимание на добавленное к коду свойства слово FILE.

$elements = ElementCatalogTable::getList([
    'select' => ['ID', 'MORE_PHOTO.FILE'],
    'filter' => [
        'ID' => $elementId,
    ],
])->fetchCollection();

foreach ($elements as $element) {
    var_dump('/upload/' . $element->getMorePhoto()->getFile()->getSubdir().'/'.$element->getMorePhoto()->getFile()->getFileName());
}

//string(55) "/upload/iblock/2d6/2d6d01a93d220c012e40415616a3d0e1.jpg"
//string(55) "/upload/iblock/dd3/dd3495f96990223e3076c97e99b062d9.jpg"

Свойства типа «Список»

Для получения ID значения можно получить getValue() элемента.

$element = ElementCatalogTable::getList([
    'select' => ['ID', 'NEWPRODUCT'],
    'filter' => [
        'ID' => $elementId,
    ],
])->fetchObject();

var_dump($element->getNewproduct()->getValue());
// int(1)

Если требуется получить ID, XML_ID и значение, то используем ITEM после кода свойства — тогда к запросу добавится таблица значений списочных свойств.

$element = 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 = ElementCatalogTable::getList([
    'select' => ['ID', 'RECOMMEND.ELEMENT'],
    'filter' => [
        'ID' => $elementId,
    ],
])->fetchObject();

var_dump($element->getRecommend()->getElement()->getId());
// int(29)
var_dump($element->getRecommend()->getElement()->getName());
// string(34) "Платье Красная Фея"

Аналогично — для раздела.

Множественные свойства

Если свойство множественное, то получение его через «геттер» вернет коллекцию. Получить значения этой коллекции можно с помощью метода getAll().

Пример вывода значений множественного свойства:

$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"

Здесь свойство BRAND_REF — множественное.

p.s.

Статья вдохновлена следующими источниками: