ORM в инфоблоках, получение информации об элементах инфоблока на D7

Просмотров: 4886

Задача: собрать полные данные об элементах инфоблока, применяя ORM/D7, который пришел на смену устаревшему CIBlockElement::GetList.

Метод CIBlockElement::GetList в позволяет получить практически все данные об элементе: стандартные поля, свойства, цены и другие сведения.

Однако его заменила ORM-методология, где ElementTable::getList не предоставляет готового доступа ко всем данным. Для сбора полной информации, данные нужно подгружать по частям, включая использование классов Bitrix\Iblock\PropertyTable, Bitrix\Iblock\PropertyEnumerationTable и других.

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

Видео пример использования ORM D7 в инфоблоках показал в одной из серий видеокурса:
Свой компонент: список объявлений пользователя

Включение ORM в инфоблоках

Для работы с ORM достаточно задать API-идентификатор в настройках инфоблока:

Получение полной информации об элементах инфоблока с использованием ORM

Пример кода c использованием ORM инфоблока:

use Bitrix\Main\Loader,
       Bitrix\Iblock\Iblock,
       Bitrix\Iblock\SectionTable,
       Bitrix\Catalog\PriceTable,
       Bitrix\Catalog\ProductTable;

Loader::includeModule('iblock');

$IBLOCK_ID = 1;

// Инициализация класса инфоблока
$iblockClass = Iblock::wakeUp($IBLOCK_ID)->getEntityDataClass();

$getElements = $iblockClass::getList([
    'select' => [
        // Получаем все поля элемента
        '*',

        // Дополучаем шаблон URL из инфоблока
        'URL' => 'IBLOCK.DETAIL_PAGE_URL',

        // Дополучаем свойство типа строка
        'PREFS_' => 'ATT_PREFS',

        // Дополучаем свойство типа файл
        'PHOTOS_' => 'MORE_PHOTO.FILE',

        // Дополучаем свойство типа список
        'PROCESSOR_' => 'ATT_PROCESSOR.ITEM',

        // Дополучаем свойство типа привязка к элементам
        'RELATED_' => 'ATT_RELATED.ELEMENT',

        // Дополучаем свойство типа привязка к разделам
        'BRANDS_' => 'ATT_RELATED.SECTION',
    ],
])->fetchAll();

foreach ($getElements as $resElement) {

    // Из шаблона ссылки получаем реальный url элемента
    $resElement['URL'] = CIBlock::ReplaceDetailUrl(
        $resElement["URL"],
        $resElement,
        true,
        'E'
    );

    // По ID детальной картинки получаем путь к ней
    $resElement['DETAIL_PICTURE_SRC'] = CFile::GetPath(
        $resElement['DETAIL_PICTURE']
    );

    // Дополучаем цены элемента
    $resElement['PRICES'] = PriceTable::getList([
        'filter' => [
            '=PRODUCT_ID' => $resElement['ID']
        ],
        'select' => [
            '*'
        ]
    ])->fetch();

    // Дополучаем данные о разделе инфоблока в котором элемент
     $resElement['SECTION'] = SectionTable::getList([
        'filter' => [
            'ID' => $resElement['IBLOCK_SECTION_ID']
        ],
        'select' => [
            '*' // Все поля раздела, но можно отобрать только нужные 
        ]
    ])->fetch();

    // Получение остатков товара
    $resElement['QUANTITY'] = ProductTable::getList([
        'filter' => ['ID' => $item['ID']],
        'select' => ['QUANTITY']
    ])->fetch();

    // Получаем SEO информацию об элементе
    $ipropValues = new \Bitrix\Iblock\InheritedProperty\ElementValues(
       $resElement['IBLOCK_ID'],
       $resElement['ID']
    );
    $resElement['IPROPERTY_VALUES'] = $ipropValues->getValues();


    // Распечатываем полученную информацию
    var_dump($resElement);
}

Метод Iblock::wakeUp получает ORM-класс инфоблока, задав его ID, после чего доступен метод getList.

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

В цикле перебора каждого элемента дополняем информацию: получаем URL элемента, путь к детальной картинке и данные о ценах.

Метод ::getList сгенерированного ORM класса инфоблока, как и в обычных классах D7 принимает параметры:

$res = \Запрос\К нужному классу::getList([
    'order' => // массив- сортировка
    'select' => // массив- выбираемые поля
    'filter' => // массив- фильтр
    'group' =>  // массив- группировка, order должен быть пустой
    'limit' => // число- ограничение выбираемого кол-ва
    'offset' => // число- смещение первого столбца в результате
    'count_total' => // число- дает возможность получить кол-во элементов через метод getCount()
    'runtime' =>  // массив полей сущности, создающихся динамически
    'data_doubling' => // булево (ум. false) - получение одинаковых записей
    'cache' => array( // массив-  кеширование запроса запроса
        'ttl' => 1000,
        'cache_joins' => true
    ),
]);

Получение множественных значений свойств элементов инфоблока через ORM

Если вы попытаетесь получить множественные свойства элемента, используя описанный выше метод, в результате массив будет содержать дублирующиеся элементы в зависимости от количества множественных значений у каждого элемента.

Чтобы этого избежать, можно переработать результирующий массив для обработки множественных свойств каждого элемента.

Ниже приведен упрощенный вариант с двумя множественными свойствами, из которых нам нужны только значения:

use Bitrix\Main\Loader;
use Bitrix\Iblock\Iblock;

Loader::includeModule('iblock');

$IBLOCK_ID = 2;
$iblockClass = Iblock::wakeUp($IBLOCK_ID)->getEntityDataClass();

$getElements = $iblockClass::getList([
    'select' => [
        'NAME',
        'ID',
        'BRAND_REF_' => 'BRAND_REF', // Множественное свойство
        'MATERIAL_' => 'MATERIAL',   // Множественное свойство
    ]
]);

$elements = [];
while ($element = $getElements->Fetch()) {
    $id = $element['ID'];

    // Если элемент еще не добавлен в массив, добавляем его
    if (!isset($elements[$id])) {
        $elements[$id] = [
            'NAME' => $element['NAME'],
            'ID' => $id,
            // Подготавливаем ключи для свойств
            'BRAND_REF_VALUE' => [],
            'MATERIAL_VALUE' => []
        ];
        // Здесь можно выполнить дополнительные обработки, из примера выше
    }

    // Добавляем значения множественных свойств только если отсутствуют
    if (
        !empty($element['BRAND_REF_VALUE']) && 
        !in_array($element['BRAND_REF_VALUE'], $elements[$id]['BRAND_REF_VALUE'])
    ) {
        $elements[$id]['BRAND_REF_VALUE'][] = $element['BRAND_REF_VALUE'];
    }
    if (!empty($element['MATERIAL_VALUE']) && 
        !in_array($element['MATERIAL_VALUE'], $elements[$id]['MATERIAL_VALUE'])
    ) {
        $elements[$id]['MATERIAL_VALUE'][] = $element['MATERIAL_VALUE'];
    }
}

foreach ($elements as $element) {
    // Распечатываем полученную информацию
    var_dump($element);
}
  • Создается запрос getList, который выбирает элементы из информационного блока, указав необходимые поля: NAME, ID и два множественных свойства BRAND_REF и MATERIAL.
  • Если элемент еще не добавлен в массив $elements, он добавляется с инициализацией массива для множественных значений.
  • Если множественные значения свойств присутствуют, они добавляются в соответствующие массивы BRAND_REF_VALUE и MATERIAL_VALUE. Добавление происходит без повторов значений.

Почему стоит использовать ORM вместо старого метода CIBlockElement::GetList

Использование ORM для работы с инфоблоками, вместо старого метода CIBlockElement::GetList, имеет ряд значительных преимуществ.

Во-первых, ORM обеспечивает структурированный и читаемый код, что особенно важно в крупных проектах с большим объемом данных и сложной логикой. ORM позволяет работать с объектами и свойствами инфоблока, как с сущностями базы данных, что упрощает манипуляции с данными и делает код более поддерживаемым.

Во-вторых, ORM интегрируется с современными механизмами кеширования и оптимизации запросов, благодаря чему уменьшается нагрузка на базу данных и ускоряется выполнение скриптов. Это делает ORM особенно ценным инструментом для масштабируемых и производительных приложений, требующих гибкости и скорости.

Стоимость разработки на 1С-Битрикс:

Индивидуальная разработка магазина

от 500 000 руб. от 5-ти недель

Разработка магазина на 1С-Битрикс с нуля. Дизайн, сборка и оптимизация производительности под конкретный проект и требования. Реализация любого функционала без ограничений готовых решений.

Запуск сайта на готовом решении

от 100 000 руб. от 7-ми дней

Вариант для тех, кто не хочет тратить много средств на индивидуальный проект, и не имеет серьезных требований к сайту. Магазин, быстро запускается на базе одного из 200-та готовых решений.

Мобильное приложение

от 500 000 руб. от 1-го месяца

Разработка кроссплатформенного мобильного приложения, которое не уступает нативным решениям как в производительности, так и пользовательском опыте. Публикуется в AppStore, GooglePlay и RuStore

Сайт компании

от 350 000 руб. от 1-го месяца

Корпоративный сайт с информационными разделами, каталогом товаров или услуг. Включает формы обратной связи карточек каталога, любое количество статичных и динамичных разделов.

Инфресурс

от 400 000 руб. от 5-ти недель

Информационный ресурс любой сложности. Сайт для СМИ, городской портал или многопользовательская доска объявлений. Внутренние форумы, блоги- по необходимости.

Лечение сайтов от вирусов

от 40 000 руб. от 2-х дней

Выполню полную проверку сайта и окружения. В случае обнаружения вирусов проведу полный комплекс лечения проекта и закрытия лазеек.