• Модуль: crm
  • Путь к файлу: ~/bitrix/modules/crm/lib/merger/entitymerger.php
  • Класс: Bitrix\Crm\Merger\EntityMerger
  • Вызов: EntityMerger::mergeEntityFieldsBatch
static function mergeEntityFieldsBatch(array &$seeds, array &$targ, array &$fieldInfos, $skipEmpty = false, array $options = null)
{
	if(empty($seeds))
	{
		return;
	}

	if($options === null)
	{
		$options = array();
	}

	$conflictResolutionMode = isset($options['conflictResolutionMode'])
		? (int)$options['conflictResolutionMode'] : ConflictResolutionMode::UNDEFINED;
	if(!ConflictResolutionMode::isDefined($conflictResolutionMode))
	{
		$conflictResolutionMode = self::getDefaultConflictResolutionMode();
	}

	if($conflictResolutionMode === ConflictResolutionMode::ALWAYS_OVERWRITE)
	{
		throw new EntityMergerException(
			\CCrmOwnerType::Undefined,
			0,
			self::ROLE_UNDEFINED,
			EntityMergerException::CONFLICT_RESOLUTION_NOT_SUPPORTED,
			'',
			0,
			null,
			array('conflictResolutionMode' => $conflictResolutionMode)
		);
	}

	if($conflictResolutionMode === ConflictResolutionMode::MANUAL)
	{
		throw new EntityMergerException(
			\CCrmOwnerType::Undefined,
			0,
			self::ROLE_UNDEFINED,
			EntityMergerException::CONFLICT_OCCURRED,
			'',
			0,
			null,
			array('conflictResolutionMode' => $conflictResolutionMode)
		);
	}

	$seedMap = array();
	foreach($seeds as $seed)
	{
		static::checkEntityMergePreconditions($seed, $targ);
		$seedMap[$seed['ID']] = $seed;
	}

	$map = null;
	if(isset($options['map']) && is_array($options['map']))
	{
		$map = $options['map'];
	}
	$enableMap = $map !== null && !empty($map);

	$historyItems = [];
	foreach($fieldInfos as $fieldID => $fieldInfo)
	{
		if(!static::canMergeEntityField($fieldID))
		{
			continue;
		}

		// Skip READONLY and PROGRESS fields
		if(isset($fieldInfo['ATTRIBUTES']) && is_array($fieldInfo['ATTRIBUTES']))
		{
			if (in_array(\CCrmFieldInfoAttr::ReadOnly, $fieldInfo['ATTRIBUTES'], true)
				|| in_array(\CCrmFieldInfoAttr::Progress, $fieldInfo['ATTRIBUTES'], true)
				|| in_array(\CCrmFieldInfoAttr::Hidden, $fieldInfo['ATTRIBUTES'], true)
			)
			{
				continue;
			}
		}

		if($enableMap)
		{
			foreach($seeds as $seed)
			{
				$seedID = $seed['ID'];
				if(isset($map[$fieldID]) && is_array($map[$fieldID]))
				{
					$sourceIDs = isset($map[$fieldID]['SOURCE_ENTITY_IDS']) && is_array($map[$fieldID]['SOURCE_ENTITY_IDS'])
						? $map[$fieldID]['SOURCE_ENTITY_IDS'] : array();
					if(in_array($seedID, $sourceIDs))
					{
						//\CCrmFieldInfoAttr::Multiple
						static::applyMappedValue($fieldID, $seed, $targ);
						break;
					}
				}
			}
			continue;
		}

		$targFlg = static::doesFieldHaveValue($fieldInfo, $targ, $fieldID, $skipEmpty);

		$seedValueMap = array();
		foreach($seedMap as $seedID => $seed)
		{
			$seedFlg = static::doesFieldHaveValue($fieldInfo, $seed, $fieldID, $skipEmpty);

			if($seedFlg)
			{
				$seedValueMap[$seedID] = $seed[$fieldID];
			}
		}

		if(empty($seedValueMap))
		{
			continue;
		}

		if($conflictResolutionMode === ConflictResolutionMode::ASK_USER && ($targFlg || count($seedValueMap) > 1))
		{
			$currentSeedIDs = array_keys($seedValueMap);
			$currentTarg = $targFlg ? $targ : $seedMap[array_shift($currentSeedIDs)];

			$fieldConflictResolver = static::getFieldConflictResolver($fieldID, $fieldInfo['TYPE'] ?? 'string');
			$fieldConflictResolver->setTarget($currentTarg);

			foreach($currentSeedIDs as $seedID)
			{
				$fieldConflictResolver->addSeed((int)$seedID, $seedMap[$seedID]);
			}
			$resolveResult = $fieldConflictResolver->resolve();
			if(!$resolveResult->isSuccess())
			{
				throw new EntityMergerException(
					\CCrmOwnerType::Undefined,
					0,
					self::ROLE_UNDEFINED,
					EntityMergerException::CONFLICT_OCCURRED
				);
			}
			$targFlg = $targFlg || $resolveResult->isTargetChanged();
			$resolveResult->updateTarget($targ);

			foreach($currentSeedIDs as $seedID)
			{
				$resolveResult->updateSeed((int)$seedID, $seedMap[$seedID]);
			}
			$historyItems = array_merge($historyItems, $resolveResult->getHistoryItems());
		}

		// Skip if target entity field is defined
		// Skip if seed entity field is not defined
		if(!$targFlg)
		{
			$targ[$fieldID] = $seedValueMap[array_keys($seedValueMap)[0]];
		}
	}
	if (!empty($historyItems))
	{
		$targ['HISTORY_ITEMS'] = $historyItems;
	}
}