• Модуль: sale
  • Путь к файлу: ~/bitrix/modules/sale/lib/location/connector.php
  • Класс: BitrixSaleLocationConnector
  • Вызов: Connector::normalizeLocationList
static function normalizeLocationList($denormalizedList = array())
{
	if(empty($denormalizedList))
		return array();

	$useCodes = static::getUseCodes();

	$denormalizedList = array_flip($denormalizedList);

	$query = new EntityQuery('BitrixSaleLocationLocation');

	$query->setSelect(array(
		'PARENT_ID',
		'ID',
		'CODE',
		'LNAME' => 'NAME.NAME' // tmp
	));

	$query->setFilter(array('NAME.LANGUAGE_ID' => LANGUAGE_ID)); // tmp
	$query->setOrder(array('LEFT_MARGIN' => 'desc')); // important

	$res = $query->exec();

	// make table of children count for each node

	$relations = array();
	$selected = array();
	while($item = $res->fetch())
	{
		if(!isset($relations[$item['ID']]['name'])) // tmp
			$relations[$item['ID']]['name'] = $item['LNAME'];

		if(!isset($relations[$item['ID']]['total']))
			$relations[$item['ID']]['total'] = 0;

		if(!isset($relations[$item['ID']]['selected']))
			$relations[$item['ID']]['selected'] = 0;

		///
		if($item['PARENT_ID'] != 0)
		{
			if(!isset($relations[$item['PARENT_ID']]['total']))
				$relations[$item['PARENT_ID']]['total'] = 0;
			if(!isset($relations[$item['PARENT_ID']]['selected']))
				$relations[$item['PARENT_ID']]['selected'] = 0;
		}

		$relations[$item['PARENT_ID']]['total'] += (1 + $relations[$item['ID']]['total']);

		if(isset($denormalizedList[$item['ID']]))
		{
			$relations[$item['PARENT_ID']]['selected'] += (1 + $relations[$item['ID']]['selected']);
			$selected[$item['ID']] = $item;
		}
	}

	// now make up list of nodes to remove
	$removeItems = array();
	$removeChildrenOf = array();
	foreach($relations as $id => $rel)
	{
		if($rel['total'] > 0) // item has children
		{
			if($rel['total'] == $rel['selected']) // selected N of N of all children, remove all those children
			{
				if(isset($selected[$id])) // item should be selected itself to remove its children
					$removeChildrenOf[$id] = true;
			}
			elseif($rel['selected'] > 0) // selected M of N of children, where M > 0, so remove item itself
				$removeItems[$id] = true;
		}
	}

	$normalized = array();
	foreach($selected as $id => $item)
	{
		if(!($item['PARENT_ID'] && $removeChildrenOf[$item['PARENT_ID']]) && !$removeItems[$item['ID']])
			$normalized[] = $item[$useCodes ? 'CODE' : 'ID'];
	}

	return $normalized;
}