Выборка элементов, разделов и инфоблоков через GetList: фильтры, документооборот и пагинация
Где смотреть поля и таблицы
Структура модуля iblock описана в документации по полям: какие столбцы у элементов, разделов и версий есть в базе и как они отражены в фильтрах. Это полезно, когда нужно понять, почему GetList «молчит» при видимости записи через прямой SQL.
Элементы: CIBlockElement::GetList
Три главных параметра остаются привычными: сортировка, фильтр и список полей. По умолчанию выводят только опубликованные строки для текущего сайта и языка активности; ключи ACTIVE и ACTIVE_DATE в фильтре лучше задавать явно, если сценарий не стандартный.
Для поиска по символьному коду почти всегда нужно точное сравнение: в фильтре ключ =CODE, а не CODE. В последнем случае движок превращает условие в LIKE с подстановкой символов SQL-шаблона.
$sortSpec = ['SORT' => 'ASC'];
$filterSpec = [
'IBLOCK_ID' => $portfolioIblockPk,
'ID' => $detailElementPk,
'ACTIVE' => 'Y',
'ACTIVE_DATE' => 'Y',
'=PROPERTY_PROMO_TOGGLE' => 'Y',
];
$columnSpec = [
'ID',
'CODE',
'NAME',
'PREVIEW_PICTURE',
'DETAIL_PICTURE',
'PREVIEW_TEXT',
'DETAIL_TEXT',
'PROPERTY_BROCHURE',
'ACTIVE_FROM',
'ACTIVE_TO',
];
$navigator = false;
$elementCursor = CIBlockElement::GetList(
$sortSpec,
$filterSpec,
false,
$navigator,
$columnSpec
);
while ($row = $elementCursor->Fetch()) {
/* обработка $row */
}Документооборот и черновики
Если инфоблок подключён к цепочке согласования, новые ревизии могут висеть как «ещё не опубликованные». Обычный GetList их не вернёт. Для смешанной выборки добавляют в фильтр 'SHOW_NEW' => 'Y'. Последнюю рабочую копию в цепочке иногда берут точечным вызовом CIBlockElement::WF_GetLast() — когда нужен именно хвост workflow, а не полный список.
Счёт строк в БД без версий документа
Если в таблице есть поле связи версий родителя, «живые» строки элементов считают по связке родителя, обнуляющуюся только у корневой записи:
SELECT COUNT(*) AS tally
FROM b_iblock_element
WHERE IBLOCK_ID = ?
AND WF_PARENT_ELEMENT_ID IS NULL;
Плейсхолдер ? передаётся через параметризованный запрос на стороне приложения.
Разделы: CIBlockSection::GetList
Вторым аргументом иногда передают $bIncCnt — пересчёт количества элементов в разделе; для тяжёлых деревьев его лучше не включать без необходимости. Пользовательские поля раздела в $arSelect называются с префиксом UF_* и должны быть заведены в настройках инфоблока.
$sortSpec = ['LEFT_MARGIN' => 'ASC'];
$filterSpec = [
'IBLOCK_ID' => $faqIblockPk,
'SECTION_ID' => $parentSlicePk,
'DEPTH_LEVEL' => 2,
];
$columnSpec = ['ID', 'NAME', 'UF_ICON_TOKEN', 'UF_BADGE_NOTE'];
$sliceCursor = CIBlockSection::GetList(
$sortSpec,
$filterSpec,
false,
$columnSpec,
false
);
while ($slice = $sliceCursor->Fetch()) {
/* обработка $slice */
}Сами инфоблоки: CIBlock::GetList
Это уже выборка описателей типов блоков в текущей языковой связке: в фильтре участвуют TYPE, привязка к сайту, активность записи описателя. Типичная ошибка с чужих шпаргалок — подставить в этот метод ключ IBLOCK_ID как у элементов. Для точечного блока нужен ключ ID (номер описателя инфоблока), а для перечисления каталогов на сайте фильтруют по LID, ACTIVE и при необходимости TYPE.
$sortSpec = ['SORT' => 'ASC'];
$filterSpec = [
'ID' => $docsIblockPk,
'SITE_ID' => SITE_ID,
'ACTIVE' => 'Y',
];
$iblockWalker = CIBlock::GetList($sortSpec, $filterSpec, false);
if ($meta = $iblockWalker->Fetch()) {
/* $meta['ID'] можно передать как IBLOCK_ID в выборках элементов */
}Для списка всех активных блоков сайта ограничивают не IBLOCK_ID элементного уровня, а условием по типу и привязке: TYPE, LID или «сайтовым» ключам из актуальной справочной таблицы полей фильтра.
Фильтр пользователей по числовому ключу
В выборках пользовательского слоя давно есть отдельное имя фильтра для строгого сравнения по целому идентификатору. Для многих задач следует использовать =ID либо (в зависимости от версии и контекста) эквивалент «точного» ключа вида ID_EQUAL_EXACT, а не голый листовой ID, чтобы не получить диапазонное поведение в обёрнутых API.
Пагинация в компоненте
Когда $arResult['ITEMS'] — это объект постраничной выборки, вывести текстовую строку переходов можно через стандартную обвязку навигатора. Ни минимальный скелет без лишнего HTML:
$arResult['ITEMS']->NavStart(25, false);
$arResult['PAGE_CHAIN'] =
$arResult['ITEMS']->GetPageNavStringEx(
$componentTemplate,
'Новости',
'pager_new',
'Y'
);
/* сравните $arResult["ITEMS"]->NavRecordCount с порогом, если цепочку скрывают */
Связь с D7
Для новых сервисных модулей выгоднее ORM элементов и разделов: меньше сюрпризов с префиксами PROPERTY_* и проще статический анализ. Легаси GetList всё равно остаётся в эксплуатационных скриптах, генераторах контента и кастомных компонентах — знание фильтров и документооборота экономит время на отладке «пустого» результата.
Итог
- Для кода свойств и символьных полей элементов добавляют
=там, где нужно точное совпадение. - Черновики workflow ищут с
SHOW_NEWили черезWF_GetLast(). - Разделы тянут
UF_*напрямую в select. - Для описателей инфоблока не смешивают синтаксис фильтров с уровнем элементов.
Не хотите копаться сами?
Починю за 1-3 дня. Без предоплаты — оплата по результату.
15+ лет опыта с 1С-Битрикс · Без предоплаты · 7 дней гарантии