Создавать пользовательские поля («кликая» в админке) удобно только на этапе прототипирования.
Когда проект переходит в стадию поддержки и деплоя, все изменения структуры БД должны выполняться программно (в миграциях или агентах).
1. Создание самого поля (CUserTypeEntity)
За описание поля отвечает класс CUserTypeEntity.
Основные параметры:
- ENTITY_ID: Сущность, к которой вяжем поле (USER, IBLOCK_3_SECTION, HLBLOCK_5).
- FIELD_NAME: Код поля (обязательно начинается с UF_).
- USER_TYPE_ID: Тип данных (string, double, integer, boolean, file, enumeration (список), iblock_element и др.).
$oUserTypeEntity = new CUserTypeEntity();
$arFields = [
'ENTITY_ID' => 'USER', // Добавляем поле пользователю
'FIELD_NAME' => 'UF_SKILL_LEVEL',
'USER_TYPE_ID' => 'enumeration', // Тип "Список"
'XML_ID' => 'UF_SKILL_LEVEL',
'SORT' => 100,
'MULTIPLE' => 'N', // Одиночное
'MANDATORY' => 'N', // Не обязательное
'SHOW_FILTER' => 'I', // Показывать в фильтре (I - точное совпадение)
'SHOW_IN_LIST' => 'Y', // Показывать в списке
'EDIT_IN_LIST' => 'Y', // Разрешить редактирование
'IS_SEARCHABLE' => 'N',
'SETTINGS' => [ // Доп. настройки зависят от типа
'DISPLAY' => 'LIST', // Вид списка (LIST, CHECKBOX)
'LIST_HEIGHT' => 5
],
// Языковые названия
'EDIT_FORM_LABEL' => ['ru' => 'Уровень навыка', 'en' => 'Skill Level'],
'LIST_COLUMN_LABEL' => ['ru' => 'Уровень', 'en' => 'Level'],
'LIST_FILTER_LABEL' => ['ru' => 'Уровень навыка', 'en' => 'Skill Level'],
];
$fieldId = $oUserTypeEntity->Add($arFields);
if ($fieldId) {
echo "Поле создано с ID: " . $fieldId;
} else {
// В случае ошибки выводим application exception
if ($ex = $APPLICATION->GetException()) {
echo $ex->GetString();
}
}2. Добавление значений списка (CUserFieldEnum)
Если вы создали поле типа enumeration (список), оно будет пустым. Значения добавляются отдельно через класс CUserFieldEnum.
if ($fieldId) {
$oUserFieldEnum = new CUserFieldEnum();
// Подготавливаем значения
$arValues = [
'n0' => ['XML_ID' => 'JUNIOR', 'VALUE' => 'Младший', 'DEF' => 'N', 'SORT' => 100],
'n1' => ['XML_ID' => 'MIDDLE', 'VALUE' => 'Средний', 'DEF' => 'Y', 'SORT' => 200],
'n2' => ['XML_ID' => 'SENIOR', 'VALUE' => 'Старший', 'DEF' => 'N', 'SORT' => 300],
];
// SetEnumValues полностью перезаписывает значения для поля!
// Первым параметром передаем ID поля (которое получили выше)
$success = $oUserFieldEnum->SetEnumValues($fieldId, $arValues);
if ($success) {
echo "Значения списка добавлены.";
}
}- Ключи n0, n1… используются для новых значений.
- Если нужно обновить существующие значения, вместо n… указывается ID значения списка.
Как проверить, существует ли поле?
Перед созданием всегда проверяйте наличие поля, чтобы миграция была идемпотентной (повторный запуск не ломал систему).
$res = CUserTypeEntity::GetList([], ["ENTITY_ID" => "USER", "FIELD_NAME" => "UF_SKILL_LEVEL"]);
if (!$res->Fetch()) {
// Поля нет, создаем
}Вывод:
Программное создание полей — единственный надежный способ синхронизировать структуру БД между локальной разработкой, тестовым сервером и продакшеном.
CUserTypeEntity, CUserFieldEnum, создание UF полей программно, миграции битрикс, добавление свойств, пользовательские поля API.