Documentation

onGetFieldConflictResolver

Editing field merge strategy


onGetFieldConflictResolver

When merging entities, the cycle attempts to merge values for each field of these entities.

If any of these fields are merged without conflicts - updated main entity fields are saved and merged entity is deleted.

In case of conflicts during the merging, its interrupted and can be continued only in manual mode, when user clearly selects, which value is correct.

Each type of field has its own specifics, with several classes-strategies, descendant of \Bitrix\Crm\Merger\ConflictResolver\Base and defining rules for comparison and merging of fields.

The event onGetFieldConflictResolver allows re-defining merge strategies for specific fields under custom conditions. This allows to maximally flexibly change logic of merge procedure according to your requirements.

The following parameters are passed to the event:

ParameterFormatDescription
entityTypeIdintMerged entity type ID. Can receive values: 1 (lead), 2 (deal), 3 (contact) or 4 (company).
fieldIdstringField code, for example NAME, ASSIGNED_BY_ID and etc.
type stringField type, for example string, integer and etc.


Example of redefining


When event handler wants to redefine the merge strategy for current field values, add result with type \Bitrix\Main\EventResult::SUCCESS to the event and pass a new object instance for the value merge strategy within the key conflictResolver.


\Bitrix\Main\EventManager::getInstance()
	->addEventHandler('crm', 'onGetFieldConflictResolver', function(\Bitrix\Main\Event $event) {
		$fieldId = $event->getParameter('fieldId'); 
		$entityTypeId = $event->getParameter('entityTypeId'); 

		// When this field is responsible in contacts:
		if ($fieldId === 'ASSIGNED_BY_ID' && $entityTypeId === \CCrmOwnerType::Contact) 
		{
			$event->addResult(
				new \Bitrix\Main\EventResult(
					\Bitrix\Main\EventResult::SUCCESS,
					[
						// replace field comparison strategy to "Ignore differences":
						'conflictResolver' => new \Bitrix\Crm\Merger\ConflictResolver\IgnoredField($fieldId),
					]
				)
			);
		}
	})
;

Types of available strategies


Ignore differences


\Bitrix\Crm\Merger\ConflictResolver\IgnoredField

Using this strategy avoids conflicts altogether. Leaves field value as is by default.

$resolver = new \Bitrix\Crm\Merger\ConflictResolver\IgnoredField($fieldId);

Empty value can be replaced when merging:

$resolver->setNeedUpdateTargetIfEmpty(true);

In case this option is set, and field value is empty in the main element and filled in the merged field: it will be copied into the main element.

There is an option to save into history field value which was ignored when merging (if you may need this information in the future):

$resolver->setNeedWriteToHistory(true);

"Smart" string merging


\Bitrix\Crm\Merger\ConflictResolver\StringField

When used, attempts to avoid conflicts by flexibly comparing the values:

  • Ignores character cases, spaces both at the start and the end of sentences, as well as a period at the end of strings.
  • Double, triple and other duplicated spaces between words are replaced with a single space when compared.

Merging example:
"Smith" + " SMITH." = "Smith"

Merging multi-stringed texts


\Bitrix\Crm\Merger\ConflictResolver\TextField

When used, merged element field value is additionally written to the main element field value, separated by delimiter.

By default, delimiter is a string type as follows: ----- 31.12.2022 07:09 -----, containing time of merging.

Delimiter can be edited by creating a descendant of class TextField and by re-defining the method getSeparator():

class MyMultilineField extends \Bitrix\Crm\Merger\ConflictResolver\TextField
{
	protected function getSeparator(): string
	{
		return ' ~~~~~~~~~~~~~~~~ ';
	}
}

Merging example:
    "Company comment"

    +

    "Some extra text"

    =

    "Company comment

    ----- 31.12.2022 07:09 -----

    Some more extra text"

Merging multi-string HTML


\Bitrix\Crm\Merger\ConflictResolver\HtmlField

In contrast to TextField, Uses <br&qt; as string delimiter instead of \n.

Creating a custom strategy


If the logic of current comparison strategies is not satisfactory, you can program your own.

To create your own strategy, its sufficient to create descendant of class Base and re-define the method resolveByValue(&$seedValue, &$targetValue), by programming your own logic there.

This method receives two input parameters - compared field values, and returns true if no conflict occurred.


Example:
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 */)
		{
			// you may also set a new final value in addition to comparing field values:
			$resultFieldValue = 'writes this value into result' . $targetValue . $seedValue; 
			$this->setNewTargetValue($resultFieldValue);

			return true; // conflict occurred
		}

		return false; // field value comparison resulted in conflict
	}
}



© «Bitrix24», 2001-2024