Поля разделов и пользователей - выборка, множественные значения, файлы
Разбираем пользовательские поля у разделов и пользователей: как получать их вместе с основной выборкой и что делать с множественными значениями.
Решение
Забираем поля раздела той же выборкой:
$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']);// по множественному полю сортировка даёт повторы строкСортировка по своему полю задаётся именем этого поля наравне с обычными. По множественному полю сортировать нельзя: каждое значение даёт свою строку, и список раздваивается.
Свои поля привязаны к конкретной сущности, а не к платформе целиком. Поле раздела одного инфоблока не видно в другом, и попытка обратиться к нему возвращает пустое значение без всякой ошибки.
Список своих полей стоит держать коротким и осмысленным. Каждое поле - это соединение таблиц в выборке, и три десятка полей у раздела превращают обычный список подразделов в заметно медленный запрос.
Смена типа уже заполненного поля почти всегда означает потерю его значений. Данные хранятся в виде, зависящем от типа, и переносить их приходится скриптом до смены, а не после.
Типичные проблемы
Поля раздела приходят пустыми.
Они не перечислены в списке полей самой выборки. Пользовательские поля не приходят в выборку сами по себе, их запрашивают явно.
Список разделов открывается медленно.
Значение поля запрашивается отдельным запросом для каждой строки списка. Поля забирают той же выборкой, что и сами разделы.
В шаблоне выводится число вместо картинки.
В поле типа файл лежит только идентификатор файла. Путь к файлу получают отдельным вызовом по этому идентификатору.
Код падает на разделе с одним значением.
Множественное поле возвращает массив даже с одной записью. Приведение значения к массиву снимает этот вопрос целиком.
После смены типа поля значения исчезли.
Данные хранятся в виде, зависящем от типа самого поля. Перенос значений делают скриптом до смены типа, а не после неё.
Частые вопросы
Чем поле раздела отличается от свойства элемента?
Это разные механизмы: свойства есть только у элементов инфоблока, поля - у любой сущности платформы. Хранятся они в разных таблицах.
Как вывести поле раздела в компоненте каталога?
Указать его в списке полей раздела в параметрах компонента. Без этого шаблон получит пустое значение.
Можно ли фильтровать по своему полю?
Да, по имени поля в фильтре выборки. На множественных полях фильтр даёт повторы, их убирают группировкой.
Где хранятся значения полей?
В отдельной таблице значений для каждой сущности. Поэтому выборка со своими полями всегда означает соединение таблиц.
Смежное
- Пользовательские поля - оглавление подтемы
- Пользовательское поле не работает: разбор причин - почему выборка не видит поле
- Пользовательское поле: заведение, вывод значения, типы - как завести поле
- Разделы инфоблока: вывод дерева и адреса - выборка самих разделов
- Свойства инфоблока: чтение, запись и фильтрация по значению - соседний механизм для элементов
- Инфоблоки - устройство хранилища целиком
- Свой тип пользовательского поля: регистрация, формы, значение - свой тип рядом со штатными