Привет! Меня зовут Артём, я бэкенд-разработчик. Продолжаем разбирать неочевидные грабли REST API Битрикс24. Сегодня у нас микро-кейс, который сбил меня с толку несколько лет назад, когда я только начинал глубоко копать интеграции.
Задача тривиальная: менеджер нажимает в нашей админке кнопку «Очистить комментарий к сделке». Комментарий хранится в пользовательском поле UF_CRM_COMMENT. Я посылаю стандартный crm.deal.update, передавая этому полю пустую строку "". Иду в Битрикс, смотрю — комментарий на месте! API вернул true, но ничего не обновилось.
Почему Битрикс игнорирует пустые строки?
В основе логики обновления Битрикса лежит принцип «не трогай, если нет смысла». Когда ядро видит пустую строку для текстового поля, оно решает: «Ага, фронтенд ничего не прислал, видимо, это поле не меняли, оставляем как было». Это сделано для оптимизации базы данных и логирования изменений (чтобы в историю изменений не падали пустые события).
Первое, что пробуют новички — отправить null.
'fields' => [
'UF_CRM_COMMENT' => null
]
Для большинства текстовых, числовых и DatePicker полей передача null действительно сработает. Битрикс поймет это как жесткую директиву «сбросить значение в базу на NULL». Но есть исключения!
Опасность со свойствами типа «Список»
Если вы попытаетесь очистить множественный список (тот самый enum, о котором я писал ранее), передав null или пустую строку, API либо проигнорирует это, либо вернет ошибку валидации. Как мы уже знаем, для списков нужно передавать пустой массив [].
Мой универсальный санитайзер полей
Чтобы не держать в голове все эти исключения (где null, где [], а где ""), я написал небольшой метод-санитайзер, который прогоняет массив полей перед отправкой в Битрикс24.
private function sanitizeFields(array $fields, array $listFieldNames): array
{
foreach ($fields as $key => &$value) {
if ($value === '' || $value === null) {
// Если это известное нам поле типа "Список" - ставим пустой массив
if (in_array($key, $listFieldNames)) {
$value = [];
} else {
// Для всех остальных полей жестко ставим null
$value = null;
}
}
}
return $fields;
}
Да, это требует заранее знать, какие поля у вас являются списками. Я обычно вытягиваю их через crm.deal.userfield.list при старте скрипта и формирую массив $listFieldNames.
Еще один важный нюанс: если вы используете метод crm.item.update (для Smart-процессов), там логика еще строже. Пустая строка там может реально затереть поле, в отличие от классических сделок. Всегда тестируйте очистку полей на тестовом портале, прежде чем запускать скрипт на проде. Пару раз я случайно затирал важные поля пустотой просто потому, что фронтенд прислал lacks-значение.
Пока нет комментариев
Будьте первым, кто оставит комментарий к этой статье