Код, который будет написан ниже я проверял. Считаю себя middle, но почти не получаю критики. Это моя первая статья на Хабре. Для этого я здесь, жду обратную связь.

Начинающему программисту на 1С-Битрикс очень хорошо известна функция для получения элементов инфоблока.

<?php
$iblockId = 12;
\CIBlockElement::getList(
    ['ID' => 'DESC'], // правила сортировка
    [
        '>=DATE_ACTIVE_FROM' => '29.11.2023', 
        'IBLOCK_ID' => $iblockId
    ], // фильтр
    false, // правила группировки
    false, // параметры постраничной навигации
    ['PROPERTY_*', '*'], // выборка
);

В блоке выше описана сигнатура метода для работы с элементами инфоблоков в Битриксе. У неё, на первый взгляд, есть свои преимущества, она задокументирована, о ней много статей на форумах. Её дебагинг уже разобран подробно за время существования CMS. Замечу, что существует ряд задач, для решения которых она не годится. Эта функция в нынешних реалиях разработки встретится даже начинающему программисту довольно быстро.

К счастью, разработчики 1С-Битрикс упорно продолжают распиливать монолитные конструкции, которые начинали писать ещё на рубеже тысячелетий. Сейчас в арсенале у программиста есть, по крайней мере, 2 разных способа работы с элементами инофблоков в d7 ядре. Рассмотрим первый (он плохой, ниже я рассказываю, почему, можно переходить сразу ко второму).

Наследники DataManager в 1С-Битрикс

<?php
use Bitrix\Main\Loader;
use Bitrix\Iblock\ElementTable;

Loader::includeModule('iblock');

$iblockId = 12;
$rsElements = ElementTable::getList([
    'filter' => [
        '>=ACTIVE_FROM' => '29.11.2023',
        'IBLOCK_ID' => $iblockId,
    ],
    'select' => [
        'ID',
        'NAME',
    ],
]);

Обращу внимание на то, что у класса ElementTable и метода getList есть документация. К сожалению, получить свойства информационного блока так не получится. Как известно, что в 1С-Битрикс долго не могли решить проблему раздельного хранения свойств и полей. Этот метод, в свою очередь, подойдёт скорее для беглой выборки идентификаторов и отработает быстрее, чем \CIBlockElement::getList. Для получения свойств данным методом придется поломать голову. С помощью ключа runtime можно докинуть магии, нашёл пример тут.

ORM в 1С-Битрикс

К сожалению, так не пойдёт, рассмотрим другой пример. Во-первых, перейдем в настройки интересующего нас инфоблока. Во-вторых, заполним поле "Символьный код API".

Настройки информационного блока "История состояний"
Настройки информационного блока "История состояний"

Далее будем использовать класс  \Bitrix\Iblock\Elements\Element*****Table, где ***** - "Символьный код API".

<?php
use Bitrix\Main\Loader;

Loader::includeModule('iblock');

$entityClass = "\Bitrix\Iblock\Elements\ElementStateHistoryS1Table";
// символы между Element и Table регистронезависимы
$elementsCollection = $entityClass::getList([
    'filter' => [
        '>=ACTIVE_FROM' => '29.11.2023'
    ],
    'select' => [
        'ID',
        'NAME',
        'STATE', // свойство инфоблока История состояний в Битрикс24
        'IBLOCK_SECTION',
    ],
])->fetchCollection();

foreach ($elementsCollection as $elementObject) {
    #var_dump($elementObject) не сработает, можете проверить (это не массив)
    $name = $elementObject->getName(); # или $elementObject['NAME']
    $id = $elementObject->getId(); # или $elementObject['ID']
    $state = $elementObject->getState()->getValue(); # у по другому
    $iblockSectionId = $elementObject->getIblockSection()->getName();
}

Метод fetchCollection() позволяет получить свойства с правильно именованными ключами. В свою очередь советую попробуйте сами запустить этот блок кода, используя метод fetchAll(), всё будет не так радужно. Для получения мы можем использовать ключ ['STATE'] или же метод getState(). Для правильного использования методов используется CamelCase. Также поля можно получить методом ->get('ID'). $iblockSectionId->getIblockSection()->getName() получает название раздела инфоблока.

К счастью, этим функционал d7 в модуле iblock 1С-Битрикс не ограничивается. Например, мы можем с легкостью, получить нужные нам разделы инфоблоков, работая с разделом, как с объектом. Рассмотрим пример.

<?php
use Bitrix\Main\Loader;
use Bitrix\Main\Config\Option;
use Bitrix\Iblock\Model\Section;

Loader::includeModule('iblock');
$structureIblockId = Option::get('intranet', 'iblock_structure', 3);
$orgStructureEntity = Section::compileEntityByIblock($structureIblockId);

$rsDepartments = $orgStructureEntity::getList([
    'filter' => [
          'UF_HEAD' => 9,
     ],
     'select' => ['ID', 'NAME'],
])->fetchAll();

$managerDepartmentNames = '';
foreach ($rsDepartments as $dep) {
    $managerDepartmentNames .= $dep['NAME'] . ' ';
}

Заметьте, что код выше содержит сразу нескольо подключаемых классов. Об этом поговорим в следующем разделе статьи. В данном куске кода я получаю названия всех отделов, в которых руководителем является пользователь с 9 идентификатором. Замечу, что этот код относится к продукту Битрикс24 компании 1С-Битрикс. Итак, с помощью метода Section::compileEntityByIblock() мы получаем класс для работы с разделами инфоблока оргуструктуры. Напомню, что нечто подобное мы делали выше, когда создавали символьный код API для инфоблока и писали его класс в коде напрямую. В свою очередь, для работы с разделами используется такой метод. Обращу ваше внимание на то, что ключи у массива, передаваемого в getList, те же, что и у элементов, фильтровать по дополнительным полям легко, также как и получить их (добавить в массив ['ID', 'NAME', 'UF_HEAD']).

Полезные ссылки

О классе Option очень хорошо написано в официальной документации. О классе DataManager также читаем там.

Заключение

Я постараюсь писать больше статей о ядре d7. Вероятно я расскажу подробнее о кэшировании запросов (и о кэшировании в 1С-Битрикс в принципе).

Комментарии (18)


  1. bazrik
    02.12.2023 17:07

    интересно, когда в d7 будет update? =)


    1. sashazenit4 Автор
      02.12.2023 17:07

      я уже перестал надеяться


  1. MKMatriX
    02.12.2023 17:07

    Вот только если запросить так несуществующее свойство все уйдет в тайм-аут по переполнению) а массовый апдейт есть)


    1. sashazenit4 Автор
      02.12.2023 17:07

      Если работаем с getList класса \Bitrix\Iblock\Elements\Element*****Table и в select передадим неизвестное свойство, то отдаст ошибку "Unknown field definition". Про массовый апдейт было бы интересно почитать


      1. MKMatriX
        02.12.2023 17:07

        Ну с инфоблоками через эту фигню было такое зависание. А для массовых действий - fetchCollection и ее уже сохранять)


      1. MKMatriX
        02.12.2023 17:07

        Ну или через гетлист проблем меньше, я обычно через кваери юзаю. Хотя для быстрых кусков использую доступ к таблицам, тоже d7 query) Впрочем d7 для инфблоков все еще сырой, хотя бы на момент написания статьи.


        1. sashazenit4 Автор
          02.12.2023 17:07

          И да, сейчас 2023 год)


  1. Lodin
    02.12.2023 17:07
    +1

    Всё-таки есть что-то неизменное в наше время. Во всём мире уже началась эпоха ИИ, а авторы битрикса всё так же мощно пытаются в рефакторинг...


    1. sashazenit4 Автор
      02.12.2023 17:07

      Не вижу уже давно, что они пытаются в рефакторинг. Сейчас мне кажется, что России мало хороших продуктов для разработки ПО, каких-то платформ, SDK. Возможно, я ошибаюсь. Поэтому надо писать самим


  1. alex8079
    02.12.2023 17:07
    +2

    Я, наверное, тупой (не сарказм), но не могу понять "от слова совсем", зачем современные битриксоиды так усиленно надувают щеки на тему D7, когда это *** уже 100500 существует, но до сих пор не обладает полным функционалом оригинального ядра, а "1C-Bitrix", продавая свой продукт за не очень гуманные деньги (где-то тихо стоит спокойно наблюдает за этим беспределом wordpress), не способна написать адекватную документацию. За что деньги платит потребитель? (вопрос риторический)

    Адекватная документация - это уровень оф. доков PHP, т.е. с релевантными примерами и объяснениями, что этот медод делает, а не тот бред, который битриксоиды называют документацией, когда релевантные примеры с объяснениями работы очередного "черного ящика" приходится искать с фонарями по всему интернету, который, в данном случае (упс) ограничен русскоязычным сегментом.
    Да, еще забыл про "магию", когда где-то что-то появляется, исполняется, инклдудится и т.п. магическим образом, а инфа об этом если и есть, то разбросана по 100500 страницам оф. сайта.

    Про надувание щек - это, например, "мы пишем на ядре D7" в некоторых вакансиях. Выглядит, как дешевые понты.


    Старое ядро - полнофункциональное. D7 - недопиленный огрызок, недопиленность которго уже давно вошла в хроническую стадию.

    P.S.: Я не против битрикса как такового. Сам сейчас его ковыряю.

    P.P.S: Это мнение НЕ профессионала, а так - персонажа типа "мимо пробегал".


    1. sashazenit4 Автор
      02.12.2023 17:07

      Так как на него есть спрос, работу начинающему разрабу с низким порогом входа (битрикс) найти очень легко. У меня так было 3 года назад, сейчас много читаю, чтобы учить best practice (laravel, symfony)


  1. Sline-X
    02.12.2023 17:07
    +1

    Почему не используйте для построения запросов query, в котором строится запрос с помощью addselect(), where() и т.д.? Можно также пользоваться методом getquery() в конце построителя запроса, чтобы проанализировать, что произойдет в запросе, чтобы уже после делать выбор какой fetch использовать, fetchcollection, fetchobject или fetchall?


    1. sashazenit4 Автор
      02.12.2023 17:07

      В этой статье я не описывал класс Bitrix\Main\Entity\Query, так как хотел показать именно эти способы обращения к сущностям инфоблоков и не ставил задачу рассказать о нём. Но я думаю будет правильно о нём рассказать в ближайшем будущем.


  1. IgorAlentyev
    02.12.2023 17:07
    +4

    Всем кто ещё работает с битриксом могу только пожелать поскорее свичнуться на ларавель или симфони. Сам 7 лет просидел на нем из за лени, но собравшись с силами ушел в ларавел и безумно этому рад.

    Если хочется добавить немного приятности в работу с бд в Битриксе, рекомендую попробовать вот этот пакет (вторую его часть)

    https://github.com/arrilot/bitrix-models

    А d7 это какой то прикол. Скоро 10 лет будет как он появился и это все такой же мусор без документации.


    1. isa3v
      02.12.2023 17:07
      -1

      Данная библиотека уже устаревшая и в разработке есть Query и ORM для инфоблоков, которые хорошо описаны в документации.

      По поводу документации тоже не соглашусь. Да, у Laravel документация на много лучше. Но у битрикса для работы с ORM описано все что можно:
      https://dev.1c-bitrix.ru/learning/course/index.php?COURSE_ID=43&CHAPTER_ID=05748&LESSON_PATH=3913.3516.5748


      1. IgorAlentyev
        02.12.2023 17:07

        Данная библиотека уже устаревшая

        Это правда. Но что это меняет? Битрикс сам по себе устаревший

        и в разработке есть Query и ORM для инфоблоков, которые хорошо описаны в документации.

        Суть этой фразы не понял. Половина классов как не имели ORM представления так и не имеют. Сделать запрос в инфоблок можно и на чистом SQL это не проблема.

        Старое апи позволяло нормально и удобно работать со всеми сущностями, а главное это было задокументировано с кучей примеров. Для работы с заказами до сих пор приходится ходить на сторонние сайты вместо офф. доки. Это нормально?

        По поводу документации тоже не соглашусь. Да, у Laravel документация на много лучше. Но у битрикса для работы с ORM описано все что можно:

        Я боюсь вы сами себе противоречите.
        Назвать "это" хорошей докой у меня лично язык не повернется.

        Ну и кстати она такая уже лет 5 точно, то есть развития просто 0.


  1. NightPilgrim
    02.12.2023 17:07
    +1

    Наконец-то, хоть какая-то инфа по этому d7, официалы не удосуживаются нормальную доку по нему запилить. Спасибо тебе автор, надеюсь она не последняя!)


  1. maksim272
    02.12.2023 17:07
    +1

    Хотелось бы добавить, что $entityClass можно получить ещё следующим способом
    $iblockId = 1;
    $iblock = \Bitrix\Iblock\Iblock::wakeUp($iblockId);
    $entityClass = $iblock->getEntityDataClass();