Заметки
Пустое значение поля в CRM может быть не null
Почему пустое поле CRM в Bitrix24 не стоит проверять только через null.
Пустое CRM-поле не всегда приходит как null. В коде лучше явно решить,
какие значения считать пустыми, а какие — осознанно заполненными.
Проблема
В CRM-полях Bitrix24 пустота может выглядеть по-разному. Иногда это null,
иногда пустая строка, 0, '0', пустой массив или вообще
отсутствующий ключ в массиве.
Если проверять поле только через $value === null, часть пустых значений
можно пропустить. Если проверять через empty(), можно случайно смешать
пустоту и нормальное значение вроде 0.
Чаще всего в CRM-данных можно встретить такие варианты:
null;- пустая строка
''; - строка
'0'; - число
0; - пустой массив;
- отсутствующий ключ в массиве.
Поэтому перед условиями лучше привести значение к понятному внутреннему состоянию: пусто, да, нет, выбрано, не выбрано и так далее.
Проверка значений
Надёжнее не пытаться одной проверкой закрыть все типы полей, а отдельно описывать правила для конкретного поля и конкретной задачи.
Проверка только на null слишком узкая. Она не поймает пустую строку,
если поле пришло из CRM именно так.
<?php
$field_value = $deal_data['UF_CRM_EXAMPLE_FIELD'] ?? null;
if ($field_value === null) {
// Сработает только для null или отсутствующего ключа.
} empty() тоже не всегда подходит. В PHP значения 0 и
'0' считаются пустыми, хотя для CRM-поля это может быть осмысленное значение.
<?php
$field_value = $deal_data['UF_CRM_EXAMPLE_FIELD'] ?? null;
if (empty($field_value)) {
// Сюда попадут null, '', 0, '0', false и пустой массив.
} Поле Да/Нет
С полем типа Да/Нет лучше быть особенно осторожным. В прикладной логике
у него часто не два, а три состояния:
- поле не заполнено;
- выбрано «Да»;
- выбрано «Нет».
Если проверять такое поле как обычный true или false,
можно смешать «Нет» и «не заполнено».
<?php
$field_value = $deal_data['UF_CRM_EXAMPLE_BOOLEAN'] ?? null;
if ($field_value) {
// Так лучше не делать для CRM-поля Да/Нет.
} Лучше явно определить, какие значения в этой задаче означают «Да», какие — «Нет», а какие нужно считать незаполненным полем.
Нормализация значения
Пример ниже показывает общий подход: получить значение поля, привести его к одному из внутренних состояний и дальше работать уже с этим состоянием.
<?php
use Bitrix\Main\Loader;
const CRM_MODULE_ID = 'crm';
const DEAL_ID = 0;
const YES_NO_FIELD = 'UF_CRM_EXAMPLE_BOOLEAN';
const VALUE_EMPTY = 'empty';
const VALUE_YES = 'yes';
const VALUE_NO = 'no';
Loader::includeModule(CRM_MODULE_ID);
$deal_data = fetchDealData(DEAL_ID);
$field_value = $deal_data[YES_NO_FIELD] ?? null;
$field_state = normalizeYesNoValue($field_value);
if ($field_state === VALUE_EMPTY) {
// Поле не заполнено.
}
if ($field_state === VALUE_YES) {
// Выбрано Да.
}
if ($field_state === VALUE_NO) {
// Выбрано Нет.
}
/**
* Получает данные сделки.
*/
function fetchDealData(int $deal_id): array
{
if ($deal_id <= 0) {
return [];
}
$deal_result = CCrmDeal::GetListEx(
[],
['ID' => $deal_id],
false,
false,
['ID', YES_NO_FIELD]
);
$deal_data = $deal_result ? $deal_result->Fetch() : false;
return is_array($deal_data) ? $deal_data : [];
}
/**
* Приводит значение поля Да/Нет к внутреннему состоянию.
*/
function normalizeYesNoValue(mixed $field_value): string
{
if ($field_value === null || $field_value === '') {
return VALUE_EMPTY;
}
if ($field_value === true || $field_value === 1 || $field_value === '1' || $field_value === 'Y') {
return VALUE_YES;
}
if ($field_value === false || $field_value === 0 || $field_value === '0' || $field_value === 'N') {
return VALUE_NO;
}
return VALUE_EMPTY;
}
Такой подход удобен тем, что вся спорная логика остаётся в одной функции.
Дальше по коду уже не нужно каждый раз вспоминать, что именно пришло из CRM:
null, пустая строка, 0 или 'N'.