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

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
Наверх