onGetFieldConflictResolver
Изменение стратегии объединения полей
onGetFieldConflictResolver
При объединении сущностей, в цикле производится попытка объединения значений каждого поля этих сущностей.
Если в ходе объединения ни в одном из полей не возникло конфликта, измененные значения основной сущности сохраняются, объединяемая сущность удаляется.
Если в ходе объединения в одном из полей возник конфликт, объединение прерывается и может быть продолжено только в ручном режиме, когда пользователь явно выбирает, какое из значений является корректным.
Каждый тип поля имеет свои особенности, поэтому существует ряд классов-стратегий, наследников \Bitrix\Crm\Merger\ConflictResolver\Base
, определяющих правила сравнения и объединения значений.
Событие onGetFieldConflictResolver
позволяет переопределить стратегии объединения определенных полей при определенных условиях. Это позволяет максимально гибко менять логику процедуры объединения в соответствии с вашими требованиями.
В событие передаются следующие параметры:
Параметр | Формат | Описание |
---|---|---|
entityTypeId | int | Идентификатор типа объединяемой сущности. Может принимать значения 1 (лид), 2 (сделка), 3 (контакт) или 4 (компания). |
fieldId | string | Код поля, например NAME , ASSIGNED_BY_ID и т.п. |
type | string | Тип поля, например string , integer и т.п. |
Пример переопределения
Если обработчик события хочет переопределить стратегию объединения значений текущего поля, необходимо добавить к событию результат с типом \Bitrix\Main\EventResult::SUCCESS
и в ключеconflictResolver
массива параметров результата передать инстанс нового объекта стратегии объединения значений.
\Bitrix\Main\EventManager::getInstance() ->addEventHandler('crm', 'onGetFieldConflictResolver', function(\Bitrix\Main\Event $event) { $fieldId = $event->getParameter('fieldId'); $entityTypeId = $event->getParameter('entityTypeId'); // Если это поле ответственный в контактах: if ($fieldId === 'ASSIGNED_BY_ID' && $entityTypeId === \CCrmOwnerType::Contact) { $event->addResult( new \Bitrix\Main\EventResult( \Bitrix\Main\EventResult::SUCCESS, [ // заменить стратегию сравнения полей на "Игнорировать отличия": 'conflictResolver' => new \Bitrix\Crm\Merger\ConflictResolver\IgnoredField($fieldId), ] ) ); } }) ;
Виды доступных стратегий
Игнорировать отличия
\Bitrix\Crm\Merger\ConflictResolver\IgnoredField
В случае использования никогда не приводит к возникновению конфликта. По умолчанию оставляет значение поля как есть.
$resolver = new \Bitrix\Crm\Merger\ConflictResolver\IgnoredField($fieldId);
Существует возможность замены пустого значения при объединении:
$resolver->setNeedUpdateTargetIfEmpty(true);
В случае, если эта опция установлена, значение поля в основном элементе пустое, а в объединяемом заполнено, то оно будет скопировано в основной элемент.
Существует возможность сохранить в историю значение поля, которое было проигнорировано при объединении, если есть вероятность что эта информация пригодится в будущем:
$resolver->setNeedWriteToHistory(true);
"Умное" объединение строк
\Bitrix\Crm\Merger\ConflictResolver\StringField
В случае использования, при объединении пытается не допустить конфликтов, путем гибкого сравнения значений:
- Игнорируется регистр букв, пробелы в начале и в конце, точка в конце строки.
- Двойные, тройные и прочие дублированные пробелы между словами заменяются при сравнении на один пробел.
Пример результата объединения:
"Иван" + " ИВАН." = "Иван"
Объединение многострочных текстов
\Bitrix\Crm\Merger\ConflictResolver\TextField
В случае использования, значение поля объединяемого элемента дописывается к значению поля основного элемента через разделитель.
По-умолчанию разделитель представляет собой строку вида ----- 31.12.2022 07:09 -----
, содержащую время, когда произошло объединение.
Разделитель можно изменить, создав наследника класса TextField
и переопределив метод getSeparator():
class MyMultilineField extends \Bitrix\Crm\Merger\ConflictResolver\TextField { protected function getSeparator(): string { return ' ~~~~~~~~~~~~~~~~ '; } }
Пример результата объединения:
"Комментарий к компании" + "Еще какой-то текст" = "Комментарий к компании ----- 31.12.2022 07:09 ----- Еще какой-то текст"
Объединение многострочных HTML
\Bitrix\Crm\Merger\ConflictResolver\HtmlField
От TextField
отличается тем, что качестве переноса строк используется <br&qt;
вместо \n
.
Создание собственной стратегии
Если логика текущих стратегий сравнения полей не устраивает, можно запрограммировать собственную.
Для создания собственной стратегии достаточно создать наследника класса Base
и переопределить метод resolveByValue(&$seedValue, &$targetValue)
, запрограммировав там вашу логику.
Этот метод принимает на вход два параметра - сравниваемые значения полей, и должен вернуть true
если конфликта не возникло.
Пример:
class MyFieldStrategy extends \Bitrix\Crm\Merger\ConflictResolver\Base { protected function resolveByValue(&$seedValue, &$targetValue): bool { if (/* your custom logic to find conflict in $seedValue and $targetValue values */) { // можно не только сравнить значения полей, но и установить новое итоговое значение: $resultFieldValue = 'это значение будет записано в результат' . $targetValue . $seedValue; $this->setNewTargetValue($resultFieldValue); return true; // конфликта не возникло } return false; // при сравнении значений полей возник конфликт } }