Документация для разработчиков
Темная тема

onGetFieldConflictResolver

Изменение стратегии объединения полей


onGetFieldConflictResolver

При объединении сущностей, в цикле производится попытка объединения значений каждого поля этих сущностей.

Если в ходе объединения ни в одном из полей не возникло конфликта, измененные значения основной сущности сохраняются, объединяемая сущность удаляется.

Если в ходе объединения в одном из полей возник конфликт, объединение прерывается и может быть продолжено только в ручном режиме, когда пользователь явно выбирает, какое из значений является корректным.

Каждый тип поля имеет свои особенности, поэтому существует ряд классов-стратегий, наследников \Bitrix\Crm\Merger\ConflictResolver\Base, определяющих правила сравнения и объединения значений.

Событие onGetFieldConflictResolver позволяет переопределить стратегии объединения определенных полей при определенных условиях. Это позволяет максимально гибко менять логику процедуры объединения в соответствии с вашими требованиями.

В событие передаются следующие параметры:

ПараметрФорматОписание
entityTypeIdintИдентификатор типа объединяемой сущности. Может принимать значения 1 (лид), 2 (сделка), 3 (контакт) или 4 (компания).
fieldIdstringКод поля, например 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; // при сравнении значений полей возник конфликт
	}
}





© «Битрикс», 2001-2024, «1С-Битрикс», 2024