• Модуль: sale
  • Путь к файлу: ~/bitrix/modules/sale/lib/delivery/externallocationmap.php
  • Класс: BitrixSaleDeliveryfor
  • Вызов: for::getLocationIdByNames
static function getLocationIdByNames($name, $city, $subregion, $region, $country = '', $exactOnly = false)
{
	$nameNorm = Comparator::normalizeEntity($name, 'LOCALITY');
	$subregionNorm = null;
	$regionNorm = null;
	$cityNorm = null;
	$searchNames = array($name);

	if(!$exactOnly)
		$searchNames = array_merge($searchNames, BitrixSaleLocationComparator::getLocalityNamesArray($nameNorm['NAME'], $nameNorm['TYPE']));

	$searchNames = array_map(array('BitrixSaleLocationComparator', 'flatten'), $searchNames);
	$searchNames = array_map(function($name){return "'".$name."'";}, $searchNames);

	if(empty($searchNames))
		return 0;

	$con = BitrixMainApplication::getConnection();
	$sqlHelper = $con->getSqlHelper();
	$margins = array();
	$res = $con->query("
		SELECT
			N.LOCATION_ID AS LOCATION_ID,
			N.LEFT_MARGIN AS LEFT_MARGIN,
			N.RIGHT_MARGIN AS RIGHT_MARGIN,
			N.NAME AS NAME
		FROM
			b_sale_hdaln AS N
			  LEFT JOIN b_sale_loc_ext AS E
				ON N.LOCATION_ID = E.LOCATION_ID AND E.SERVICE_ID = ".$sqlHelper->forSql(self::getExternalServiceId())."
		WHERE
			E.LOCATION_ID IS NULL
			AND NAME IN (".implode(', ', $searchNames).")");

	$results = array();
	$exact = array();

	while($loc = $res->fetch())
	{
		if(Comparator::isEntityEqual($loc['NAME'], $nameNorm, 'LOCALITY'))
		{
			$margins[] = array($loc['LOCATION_ID'], $loc['LEFT_MARGIN'], $loc['RIGHT_MARGIN'], $loc['NAME']);
			$results[$loc['LOCATION_ID']] = array('NAME' => true);

			if($loc['NAME'] == $nameNorm["NAME"])
				$exact[] = $loc['LOCATION_ID'];
		}
	}

	if(empty($margins))
		return 0;

	$marginFilter = array('LOGIC' => 'OR');

	foreach($margins as $v)
		$marginFilter[] = array(' $v[1], '>RIGHT_MARGIN' => $v[2]);

	$res = LocationTable::getList(array(
		'filter' => array(
			'=NAME.LANGUAGE_ID' => LANGUAGE_ID,
			'=TYPE.CODE' => array('SUBREGION', 'REGION', 'CITY'),
			$marginFilter
		),
		'select' => array(
			'ID',
			'PARENTS_NAME_UPPER' => 'NAME.NAME_UPPER',
			'PARENTS_TYPE_CODE' => 'TYPE.CODE',
			'LEFT_MARGIN', 'RIGHT_MARGIN'
		)
	));

	while($loc = $res->fetch())
	{
		$ids = self::getIdByMargin($loc['LEFT_MARGIN'], $loc['RIGHT_MARGIN'], $margins);

		foreach($ids as $id)
		{
			if(in_array(false, $results[$id], true))
				continue;

			$found = null;

			if($loc['PARENTS_TYPE_CODE'] == 'REGION' && $region <> '')
			{
				if(!is_array($regionNorm))
					$regionNorm = Comparator::normalizeEntity($region, 'REGION');

				$found = Comparator::isEntityEqual($loc['PARENTS_NAME_UPPER'], $regionNorm, 'REGION');
			}
			elseif($subregion <> '' && $loc['PARENTS_TYPE_CODE'] == 'SUBREGION')
			{
				if(!is_array($subregionNorm))
					$subregionNorm = Comparator::normalizeEntity($subregion, 'SUBREGION');

				$found = Comparator::isEntityEqual($loc['PARENTS_NAME_UPPER'], $subregionNorm, 'SUBREGION');
			}
			elseif($city <> '' && $loc['PARENTS_TYPE_CODE'] == 'CITY')
			{
				if(!is_array($cityNorm))
					$subregionNorm = Comparator::normalizeEntity($city, 'LOCALITY');

				$found = Comparator::isEntityEqual($loc['PARENTS_NAME_UPPER'], $cityNorm, 'LOCALITY');
			}

			if($found !== null)
			{
				$isInExact = in_array($id, $exact);
				$results[$id][$loc['PARENTS_TYPE_CODE']] = $found;

				if($results[$id]['REGION'] === true && $results[$id]['SUBREGION'] === true && $isInExact)
					return $id;

				if($found === false && $isInExact)
				{
					$key = array_search($id, $exact);

					if($key !== false)
						unset($exact[$key]);
				}
			}
		}
	}

	if(!empty($exact))
		foreach($exact as $e)
			if(!in_array(false, $results[$e], true))
				return $e;

	$resCandidates = array();

	foreach($results as $id => $result)
	{
		if(!in_array(false, $result, true))
		{
			$resCandidates[$id] = count($result);
		}
	}

	if(empty($resCandidates))
		return 0;

	if(count($resCandidates) > 1)
	{
		arsort($resCandidates);
		reset($resCandidates);
	}

	return key($resCandidates);
}