Несмотря на то что со стороны базы данных сущности описываются в разных таблицах, программистам удобнее работать с комплексными структурами наиболее качественно описывающими сущность.
Для упрощения работы программистов со стороны платформы часто предоставляются специальные структуры которые могут облегчить жизнь.
Полное описание сущности
Когда мы говорим об абстрактной сущности и ее полях мы можем использовать сколько угодно таблиц для ее описания, однако при наличии повторяющихся полей с одинаковой логикой не имеет никакого смысла дублировать эти таблицы. Для унификации этой ситуации битрикс создает комплексные таблицы и добавляет поля указывающие на тип сущности и ее идентификатор.
Обычно в таблицах они имеют ключи 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
);