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);
}