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

Пользовательское поле не работает - разбор причин

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

С чего начать

Смотрим определение поля как оно есть:

$res = \CUserTypeEntity::GetList([], ['ENTITY_ID' => 'IBLOCK_12_SECTION']);
while ($row = $res->Fetch()) {
printf("%s тип=%s множественное=%s\n",
$row['FIELD_NAME'], $row['USER_TYPE_ID'], $row['MULTIPLE']);
}
// код поля обязан начинаться с UF_ и состоять из заглавных латинских букв

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

Проверяем запись значения:

global $USER_FIELD_MANAGER;
$USER_FIELD_MANAGER->Update('IBLOCK_12_SECTION', $sectionId, ['UF_COLOR' => 'красный']);
// значения пишет менеджер полей, а не класс определения поля
// таблица определений годится только для чтения метаданных
// у каждой сущности свой идентификатор: элементы, разделы, пользователи

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

Смотрим варианты списочного поля:

$res = \CUserFieldEnum::GetList([], ['USER_FIELD_NAME' => 'UF_COLOR']);
while ($v = $res->Fetch()) { printf("%d = %s\n", $v['ID'], $v['VALUE']); }
// в поле пишут идентификатор варианта, а не его текст
// при создании вариантов ключи массива начинаются с буквы n: n1, n2

Списочное поле хранит ссылку на вариант. Текст вместо идентификатора не сохраняется молча, а требование к ключам при создании вариантов - отдельная частая причина «варианты не завелись».

Причины

  1. Код поля без обязательного префикса примерно 30% случаев

    ПризнакПоле создано, но нигде не появляется: ни в форме, ни в выборке.

    ПроверкаСмотрим код поля в списке определений: он должен начинаться с положенного префикса.

    Что делатьПересоздаём поле с правильным кодом: код задаётся при создании и потом не меняется.

  2. Пытаются поменять тип или сущность поля примерно 25% случаев

    ПризнакОбновление определения проходит, а поле ведёт себя как прежде или ломается.

    ПроверкаСмотрим, какие свойства меняет код обновления: тип, сущность, код и множественность неизменны.

    Что делатьЗаводим новое поле, переносим значения и удаляем старое: сменить эти свойства нельзя.

  3. Значение пишут не тем классом примерно 20% случаев

    ПризнакКод отрабатывает без ошибок, значение у объекта остаётся пустым.

    ПроверкаСмотрим, чем именно записывается значение: менеджером полей или классом определения.

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

  4. Варианты списка заданы неправильно примерно 15% случаев

    ПризнакСписок пустой или в поле сохраняется пустота вместо выбранного значения.

    ПроверкаСмотрим список вариантов поля и то, что передаёт код: текст или идентификатор.

    Что делатьПередаём идентификатор варианта, а при создании вариантов соблюдаем требование к ключам.

  5. Поле не видно в выборке через ORM примерно 10% случаев

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

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

    Что делатьОбъявляем идентификатор сущности в классе таблицы: без него поля в выборке недоступны.

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

Можно ли переименовать код поля?

Нет, код задаётся при создании и дальше неизменен. Смена кода означает новое поле и перенос значений, а не правку определения.

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

В отдельных таблицах сущности, а не в её основной таблице. Поэтому читать и писать их надо через менеджер полей или через ORM с объявленной сущностью.

Почему удаление поля забрало и данные?

Удаление определения удаляет и все значения. Перед удалением проверяют, где поле используется, и при необходимости выгружают значения.

Как добавить своё поведение полю?

Регистрацией своего типа пользовательского поля обработчиком события. Так появляются собственные формы ввода и правила проверки значений.

Почему поле не показывается в форме элемента?

Оно заведено для другой сущности: у разделов, элементов и пользователей идентификаторы сущностей разные. Проверяют, к какой сущности привязано определение.

Смежное

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