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:
Parameter | Format | Description |
---|---|---|
entityTypeId | int | Merged entity type ID. Can receive values: 1 (lead), 2 (deal), 3 (contact) or 4 (company). |
fieldId | string | Field code, for example NAME , ASSIGNED_BY_ID and etc. |
type | string | Field 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 } }