Несмотря на то что со стороны базы данных сущности описываются в разных таблицах, программистам удобнее работать с комплексными структурами наиболее качественно описывающими сущность.
Для упрощения работы программистов со стороны платформы часто предоставляются специальные структуры которые могут облегчить жизнь.
Полное описание сущности
Когда мы говорим об абстрактной сущности и ее полях мы можем использовать сколько угодно таблиц для ее описания, однако при наличии повторяющихся полей с одинаковой логикой не имеет никакого смысла дублировать эти таблицы. Для унификации этой ситуации битрикс создает комплексные таблицы и добавляет поля указывающие на тип сущности и ее идентификатор.
Обычно в таблицах они имеют ключи OWNER_TYPE_ID (для идентификатора типа) и OWNER_ID (для идентификатора элемента), иногда встречаются и такие поля как ENTITY_ID (мнемонический код типа) и ELEMENT_ID (идентификатора элемента).
В системе существует определенное количество системных сущностей и для каждой сущности закреплено мнемонический код, ее порядковый номер и комплексный префикс.
Мнемонические коды и порядковые номера представлены в классе CCrmOwnerType.
Константы порядковых идентификатор в названии имеют только название сущности, в то время как к мнемоническим кодам добавляется постфикс Name.
Например: порядковый номер лида находится в константе \CCrmOwnerType::Lead, а его мнемонический код в константе \CCrmOwnerType::LeadName. Не имеет смысла приводить полный перечень таких кодов, ознакомиться с доступными в вашей версии модуля вы можете самостоятельно.
С появлением модуля “Корзина” (recyclebin) и “Машинное обучение” (ml) были введены специальные код Suspended* (для каждого типа сущности) и ScoringName которые являются техническими кодами для обозначения элементов.
Помимо порядкового номера и мнемонического кода существуют так же комплексные префиксы. Префиксы необходимо для того чтобы в одном поле можно было хранить идентификаторы разных сущностей. Например: для создания поля которое должно было бы хранить и контакты и компании потребовалось либо хранить структуру данных либо отказаться от этой идеи в пользу двух полей.
Для работы с сокращенными названиями (с использованием комплексных префиксов) существует класс CCrmOwnerTypeAbbr и механизм хранения префиксов аналогичен механизму хранения мнемонических кодов сущностей.
API
Получение ссылок на страницы сущностей
Для получения ссылок на страницы сущностей используются методы:
\CCrmOwnerType::GetEntityShowPath($typeID, $ID, $bCheckPermissions = false, array $options = null) и \CCrmOwnerType::GetEntityEditPath($typeID, $ID, $bCheckPermissions = false, array $options = null), который возвращают относительные ссылки на просмотр и редактирование сущностей.
В обоих методах:
$typeID - идентификатор типа сущности
$ID - идентификатор сущности
$bCheckPermissions - флаг необходимости проверки прав. В случае если он установлен в true и у пользователя нет прав, вернется пустая строка.
$options - массив дополнительных опций для формирования ключей.
На данный момент $options обрабатывает только один ключ ENABLE_SLIDER. В определенный момент, модуль допускал 2 варианта отображения карточек: устаревший “show” и актуальный “detail”. В настоящее время мы рекомендуем не изменять параметры выдачи ссылок и оставить доп.опции без изменений.
$entityTypeId = \CCrmOwnerType::Lead;
$entityId = 123;
/**
* Display: /crm/lead/details/123/
*/
echo \CCrmOwnerType::GetEntityShowPath( $entityTypeId, $entityId );
/**
* Display: /crm/lead/details/123/?init_mode=edit
*/
echo \CCrmOwnerType::GetEntityEditPath( $entityTypeId, $entityId );
Получение ссылки на страницы списка
За предоставление ссылок отвечает метод \CCrmOwnerType::GetListUrl($typeID, $bCheckPermissions = false). Его механика аналогична методам получения ссылки на карточки элементов.
$entityTypeId = \CCrmOwnerType::Lead;
/**
* Display: /crm/lead/list/
*/
echo \CCrmOwnerType::GetListUrl( $entityTypeId );
Проверка существования типа
/**
* Checked type
* @var int
*/
$typeID = 1234;
/**
* Is type defined?
* @var bool
*/
$isDefinedType = \CCrmOwnerType::IsDefined($typeID);
Является ли тип основной сущностью
/**
* @var bool
*/
$isEntity = \CCrmOwnerType::IsEntity( \CCrmOwnerType::Lead );
Конвертация мнемонического кода в ID
/**
* @see CCrmOwnerType::*
* @var integer
*/
$entityTypeId = \CCrmOwnerType::ResolveID( \CCrmOwnerType::LeadName );
Конвертация ID в мнемонический код
/**
* @see CCrmOwnerType::*Name
* @var string
*/
$entityTypeName = \CCrmOwnerType::ResolveName( \CCrmOwnerType::Lead );
Получение префикса по коду сущности
/**
* @see CCrmOwnerTypeAbbr::*Name
* @var string
*/
$prefix = \CCrmOwnerTypeAbbr::ResolveByTypeID( \CCrmOwnerType::Lead ); // display: L
Обработка комплексного префикса
Часто возникает необходимость разобрать составные названия на идентификатор сущности и идентификатор типа сущности. За это отвечает метод \CCrmOwnerType::ParseEntitySlug($slug)
/**
* @var array
*/
$parsed = \CCrmOwnerType::ParseEntitySlug('L_1');
var_dump($parsed);
/*
array(2) {
["ENTITY_TYPE_ID"]=>
int(1)
["ENTITY_ID"]=>
int(1)
}
*/
Коммуникационные поля
Исторически для описания таких полей как Телефон, Email, Сайт, IM используется структура Коммуникационные поля (crm_multifield).
Все данные сохраняются в таблице b_crm_field_multi
| Поле | Тип данных |
|---|---|
| ID | int(18) |
| ENTITY_ID | varchar(16) |
| ELEMENT_ID | int(18) |
| TYPE_ID | varchar(16) |
| VALUE_TYPE | varchar(50) |
| COMPLEX_ID | varchar(100) |
| VALUE | varchar(250) |
ID - уникальный идентификатор значения
ENTITY_ID - мнемонический код сущности
ELEMENT_ID - идентификатор сущности к которому относится значение
TYPE_ID - симв.код сохраняемого значения
VALUE_TYPE - подтип сохраняемого значения
COMPLEX_ID - комплексный идентификатор. Состоит из полей TYPE_ID и VALUE_TYPE объединенных символом подчеркивания
VALUE - сохраняемое значение.
Пример: сохраненная почта some@email как рабочая почта для лида ID:123
| Поле | Значение |
|---|---|
| ID | 12345 |
| ENTITY_ID | LEAD |
| ELEMENT_ID | 123 |
| TYPE_ID | |
| VALUE_TYPE | HOME |
| COMPLEX_ID | EMAIL_HOME |
| VALUE | some@email |
За работу с множественными полями отвечает класс CCrmFieldMulti.
Список поддерживаемых на данный момент полей представлен в виде констант, аналогично с \CCrmOwnerType: \CCrmFieldMulti::PHONE, \CCrmFieldMulti::EMAIL, \CCrmFieldMulti::WEB, \CCrmFieldMulti::IM
API
Полезные методы
Проверка доступности типа
Проверка доступности типа осуществляется методом \CCrmFieldMulti::IsSupportedType($typeID), который возвращает true, в случае если данный тип обрабатывается классом.
/**
* @var string
*/
$typeID = \CCrmFieldMulti::PHONE;
/**
* @var boolean
*/
$IsSupportedType = \CCrmFieldMulti::IsSupportedType($typeID);
Список доступных типов
Получить список доступных системных типов можно через статический метод \CCrmFieldMulti::GetEntityTypeInfos()
var_dump(\CCrmFieldMulti::GetEntityTypeInfos());
/*
array(4) {
["PHONE"]=>
array(1) {
["NAME"]=>
string(14) "Телефон"
}
["EMAIL"]=>
array(1) {
["NAME"]=>
string(6) "E-mail"
}
["WEB"]=>
array(1) {
["NAME"]=>
string(8) "Сайт"
}
["IM"]=>
array(1) {
["NAME"]=>
string(20) "Мессенджер"
}
}
*/
Получение структуры описывающий типы
Получить список доступных системных типов можно через статический метод \CCrmFieldMulti::GetEntityTypes(). Метод возвращает ассоциативную иерархию из TYPE и VALUE_TYPE значений.
var_dump(\CCrmFieldMulti::GetEntityTypes());
Усеченный пример результата вызова:
array(4) {
["PHONE"]=>
array(7) {
["WORK"]=>
array(4) {
["FULL"]=>
string(29) "Рабочий телефон"
["SHORT"]=>
string(14) "Рабочий"
["ABBR"]=>
string(7) "Раб."
["TEMPLATE"]=>
string(41) "<a href="callto:#VALUE#">#VALUE_HTML#</a>"
}
["MOBILE"]=>
array(4) {
["FULL"]=>
string(33) "Мобильный телефон"
["SHORT"]=>
string(18) "Мобильный"
["ABBR"]=>
string(7) "Моб."
["TEMPLATE"]=>
string(41) "<a href="callto:#VALUE#">#VALUE_HTML#</a>"
}
...
}
}
Получить тип значения по-умолчанию
Для получения типа значения по-умолчанию используется статический метод \CCrmFieldMulti::GetDefaultValueType($entityTypeID), который всегда возвращает тип значения по-умолчанию для указанного типа.
echo \CCrmFieldMulti::GetDefaultValueType( \CCrmFieldMulti::PHONE ); // WORK
Списочные методы
Для получения множественных полей можно воспользоваться методом статическим методом GetListEx для фильтрации, сортировки, группировки и постраничной навигации.
CCrmFieldMulti::GetListEx($arOrder = array(), $arFilter = array(), $arGroupBy = false, $arNavStartParams = false, $arSelectFields = array(), $arOptions = array())
Принципы фильтрации и общие методы работы изложены в документации к методу CIblockElement::GetList.
Добавление
За добавление нового множественного поля отвечает нестатический метод Add($arFields, array $options = null).
$arFields - ассоциативный массив описания значения.
$options - массив дополнительных опций при обработке. В настоящее время принимается только одна опция ENABLE_NOTIFICATION которая дает понять механизму что нужно сообщить контроллеру дубликатов что поля изменились.
Пример добавления нового рабочего телефонного номера:
/**
* @var array
*/
$multiField = [
'ENTITY_ID' => \CCrmOwnerType::LeadName,
'ELEMENT_ID' => 123,
'TYPE_ID' => 'PHONE',
'VALUE_TYPE' => 'WORK',
'VALUE' => '+7 (666) 555-44-33'
];
$multi = new \CCrmFieldMulti();
$rowId = $multi->Add(
$multiField,
[
'ENABLE_NOTIFICATION' => true,
]
);
if ( !$rowId )
{
// Error when add. You can find:
// $GLOBALS['APPLICATION']->LAST_ERROR;
}
Редактирование
За редактирование значения множественного поля отвечает нестатический метод Update($ID, $arFields, array $options = null).
$ID - идентификатор удаляемого телефона.
$arFields - ассоциативный массив описания значения.
$options - массив дополнительных опций при обработке. В настоящее время принимается только одна опция ENABLE_NOTIFICATION которая дает понять механизму что нужно сообщить контроллеру дубликатов что поля изменились.
/**
* @var array
*/
$multiField = [
'TYPE_ID' => 'PHONE',
'VALUE_TYPE' => 'WORK',
'VALUE' => '+7 (666) 555-44-33'
];
/**
* @var integer
*/
$rowId = 123;
$multi = new \CCrmFieldMulti();
$rowId = $multi->Update(
$rowId,
$multiField,
[
'ENABLE_NOTIFICATION' => true,
]
);
if ( !$rowId )
{
// Error when add. You can find:
// $GLOBALS['APPLICATION']->LAST_ERROR;
}
Удаление
Удаление телефонного номера
Если вы знаете ID удаляемого телефона, вы можете воспользоваться нестатическим методом Delete для удаления CCrmFieldMulti::Delete($ID, array $options = null).
$ID - идентификатор удаляемого телефона.
$options - массив дополнительных опций при обработке. В настоящее время принимается только одна опция ENABLE_NOTIFICATION которая дает понять механизму что нужно сообщить контроллеру дубликатов что поля изменились.
/**
* @var integer
*/
$rowId = 1234;
$multi = new \CCrmFieldMulti();
$clearResult = $multi->Delete(
$rowId,
[
'ENABLE_NOTIFICATION' => true,
]
);
if ( $clearResult === false )
{
// Incorrect parameters
}
else
{
// Deleted rows count
var_dump($clearResult->AffectedRowsCount());
}
Удаление всех множественных полей элемента
Осуществляется нестатическим методом DeleteByElement($entityId, $elementId)
Пример: удаление всех множественных полей лида с ID:123
$multi = new \CCrmFieldMulti();
$clearResult = $multi->DeleteByElement(
\CCrmFieldMulti::LeadName,
123
);
if ( $clearResult === false )
{
// Incorrect parameters
}
else
{
// Deleted rows count
var_dump($clearResult->AffectedRowsCount());
}
Пакетное сохранение
Несмотря на существование точечных методов на добавление, редактирование и удаление элементов для упрощения работы с ними можно использовать пакетный метод, который сам определить необходимые к изменению элементы.
За эту работу отвечает нестатический метод SetFields($entityId, $elementId, $arFieldData, array $options = null).
$entityId - мнемонический код изменяемой сущности.
$elementId - идентификатор элемента.
$arFieldData - массив описывающий изменяемую структуру.
$options - не используемый параметр в данный момент.
Пример составления структуры arFieldData:
$arFieldData = [
'PHONE' => [
// Add phone
'n0' => [
'VALUE_TYPE' => 'WORK',
'VALUE' => '8 (800) 200-06-00',
],
// Add another phone
'n1' => [
'VALUE_TYPE' => 'HOME',
'VALUE' => '+7 (495) 222-22-22',
],
// Delete row with id 123
'123' => [
'VALUE' => '',
],
// Change phone with rowId 456
'456' => [
'VALUE' => '88002000601',
],
],
'EMAIL' => [
// Add email
'n0' => [
'VALUE_TYPE' => 'WORK',
'VALUE' => 'work@email.com',
],
// Delete row with id 567
'123' => [
'VALUE' => '',
],
]
];
Пример использования структуры выше для лида 123
$fieldMulti = new CCrmFieldMulti();
$fieldMulti->SetFields(
\CCrmOwnerType::LeadName,
123,
$arFieldData
);