Перейти к содержимому

Поля разделов и пользователей - выборка, множественные значения, файлы

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

Решение

Забираем поля раздела той же выборкой:

$res = CIBlockSection::GetList(['SORT' => 'ASC'], ['IBLOCK_ID' => 5, 'ACTIVE' => 'Y'],
false, ['ID', 'NAME', 'UF_BANNER', 'UF_SHORT_TEXT']);
while ($row = $res->GetNext()) {
printf("%-30s баннер=%s\n", $row['NAME'], $row['UF_BANNER'] ?: '-');
}
// поля перечисляют в списке полей выборки: сами они не приходят

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

Читаем множественное поле типа файл:

foreach ((array)$row['UF_GALLERY'] as $fileId) {
$file = CFile::GetFileArray($fileId); // путь получают по идентификатору
printf("%s (%d байт)\n", $file['SRC'], $file['FILE_SIZE']);
}

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

Читаем поля пользователя:

global $USER_FIELD_MANAGER;
$fields = $USER_FIELD_MANAGER->GetUserFields('USER', $userId, LANGUAGE_ID);
foreach ($fields as $code => $field) {
printf("%-20s тип=%-10s значение=%s\n", $code, $field['USER_TYPE_ID'],
is_array($field['VALUE']) ? implode(', ', $field['VALUE']) : $field['VALUE']);
}

Поля пользователя удобнее брать менеджером полей: он отдаёт значение вместе с типом и настройками. Тип нужен для вывода: одно и то же число может оказаться и файлом, и ссылкой на элемент.

Сортируем список по своему полю:

$res = CIBlockSection::GetList(['UF_ORDER' => 'ASC', 'SORT' => 'ASC'],
['IBLOCK_ID' => 5], false, ['ID', 'NAME', 'UF_ORDER']);
// по множественному полю сортировка даёт повторы строк

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

Свои поля привязаны к конкретной сущности, а не к платформе целиком. Поле раздела одного инфоблока не видно в другом, и попытка обратиться к нему возвращает пустое значение без всякой ошибки.

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

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

Типичные проблемы

Поля раздела приходят пустыми.

Они не перечислены в списке полей самой выборки. Пользовательские поля не приходят в выборку сами по себе, их запрашивают явно.

Список разделов открывается медленно.

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

В шаблоне выводится число вместо картинки.

В поле типа файл лежит только идентификатор файла. Путь к файлу получают отдельным вызовом по этому идентификатору.

Код падает на разделе с одним значением.

Множественное поле возвращает массив даже с одной записью. Приведение значения к массиву снимает этот вопрос целиком.

После смены типа поля значения исчезли.

Данные хранятся в виде, зависящем от типа самого поля. Перенос значений делают скриптом до смены типа, а не после неё.

Частые вопросы

Чем поле раздела отличается от свойства элемента?

Это разные механизмы: свойства есть только у элементов инфоблока, поля - у любой сущности платформы. Хранятся они в разных таблицах.

Как вывести поле раздела в компоненте каталога?

Указать его в списке полей раздела в параметрах компонента. Без этого шаблон получит пустое значение.

Можно ли фильтровать по своему полю?

Да, по имени поля в фильтре выборки. На множественных полях фильтр даёт повторы, их убирают группировкой.

Где хранятся значения полей?

В отдельной таблице значений для каждой сущности. Поэтому выборка со своими полями всегда означает соединение таблиц.

Смежное

Первоисточник