263 $res = static::getAllLocations();
265 if($res->isSuccess())
267 $locations = $res->getData();
269 if(is_array($locations) && !empty($locations))
271 $res = static::setMap($locations);
273 if(!$res->isSuccess())
274 $result->addErrors($res->getErrors());
279 $result->addErrors($res->getErrors());
299 if(!\
Bitrix\Main\
IO\File::isFileExists($path))
302 $content = \Bitrix\Main\IO\File::getFileContents($path);
304 if($content ===
false)
309 if(intval($srvId) < 0)
312 $lines = explode(
"\n", $content);
314 if(!is_array($lines))
319 foreach($lines as $line)
321 $columns = explode(
';', $line);
323 if(!is_array($columns) || count($columns) != 2)
326 $res = LocationTable::getList(array(
328 '=CODE' => $columns[0],
330 'select' => array(
'ID')
333 if($loc = $res->fetch())
334 if(self::setExternalLocation($srvId, $loc[
'ID'], $columns[1]))
380 if(static::EXTERNAL_SERVICE_CODE ==
'')
383 static $result =
null;
388 $res = ExternalServiceTable::getList(array(
389 'filter' => array(
'=CODE' => static::EXTERNAL_SERVICE_CODE)
392 if($srv = $res->fetch())
394 $result = $srv[
'ID'];
398 $res = ExternalServiceTable::add(array(
'CODE' => static::EXTERNAL_SERVICE_CODE));
400 if(!$res->isSuccess())
406 $result = $res->getId();
431 protected static function setMap(array $cities)
438 $xmlIdExist = array();
439 $locationIdExist = array();
440 $xmlIds = array_keys($cities);
441 $srvId = static::getExternalServiceId();
443 $res = ExternalTable::getList(array(
445 '=SERVICE_ID' => $srvId
449 while($map = $res->fetch())
451 $xmlIdExist[] = $map[
'XML_ID'];
452 $locationIdExist[] = $map[
'LOCATION_ID'];
455 if(in_array($map[
'XML_ID'], $xmlIds))
456 unset($cities[$map[
'XML_ID']]);
463 foreach($cities as $city)
466 $locId = static::getLocationIdByNames($city[static::CITY_NAME_IDX],
'',
'', $city[static::REGION_NAME_IDX]);
468 if(intval($locId) > 0 && !in_array($xmlId, $xmlIdExist) && !in_array($locId, $locationIdExist))
470 ExternalTable::add(array(
471 'SERVICE_ID' => $srvId,
472 'LOCATION_ID' => $locId,
476 $xmlIdExist[] = $xmlId;
477 $locationIdExist[] = $locId;
480 unset($cities[$xmlId]);
504 if(intval($locationId) <= 0)
507 static $locCache = array();
509 if(!isset($locCache[$srvId]))
511 $locCache[$srvId] = array();
513 $eRes = ExternalTable::getList(array(
515 '=SERVICE_ID' => $srvId,
517 'select' => array(
'ID',
'SERVICE_ID',
'LOCATION_ID',
'XML_ID')
520 while($loc = $eRes->fetch())
521 $locCache[$srvId][$loc[
'LOCATION_ID'].
'##'.$loc[
'XML_ID']] = $loc[
'ID'];
524 if(!empty($locCache[$srvId][$locationId.
'##'.$xmlId]))
528 $res = ExternalTable::update(
529 $locCache[$srvId][$locationId.
'##'.$xmlId],
531 'SERVICE_ID' => $srvId,
533 'LOCATION_ID' => $locationId
540 $result = new \Bitrix\Main\Entity\UpdateResult();
541 $result->addError(
new Error(
'External location already exists',
'EXTERNAL_LOCATION_EXISTS'));
547 $res = ExternalTable::add(array(
548 'SERVICE_ID' => $srvId,
550 'LOCATION_ID' => $locationId
553 $locCache[$srvId][$locationId.
'##'.$xmlId] = $res->getId();
596 $startTime = mktime(
true);
597 $lastProcessedId = 0;
598 $con = \Bitrix\Main\Application::getConnection();
599 $sqlHelper = $con->getSqlHelper();
601 if(intval($startId) <= 0)
602 $con->queryExecute(
"DELETE FROM b_sale_hdaln");
611 INNER JOIN b_sale_loc_name AS N ON L.ID = N.LOCATION_ID
612 INNER JOIN b_sale_loc_type AS T ON L.TYPE_ID = T.ID
615 AND (T.CODE = 'VILLAGE' OR T.CODE = 'CITY')";
617 if($startId !==
false)
618 $query .=
" AND L.ID > ".strval(intval($startId));
620 $query .=
" ORDER BY ID ASC";
621 $res = $con->query($query);
623 while($loc = $res->fetch())
627 b_sale_hdaln (LOCATION_ID, LEFT_MARGIN, RIGHT_MARGIN, NAME)
629 ".intval($loc[
'ID']).
",
630 ".intval($loc[
'LEFT_MARGIN']).
",
631 ".intval($loc[
'RIGHT_MARGIN']).
",
632 '".$sqlHelper->forSql(
634 '/\s*(\(.*\))/i'.BX_UTF_PCRE_MODIFIER,
641 $lastProcessedId = $loc[
'ID'];
643 if($timeout > 0 && (mktime(
true)-$startTime) >= $timeout)
647 return $lastProcessedId;
661 public static function getLocationIdByNames($name, $city, $subregion, $region, $country =
'', $exactOnly =
false)
663 $nameNorm = Comparator::normalizeEntity($name,
'LOCALITY');
664 $subregionNorm =
null;
667 $searchNames = array($name);
672 $searchNames = array_map(array(
'\Bitrix\Sale\Location\Comparator',
'flatten'), $searchNames);
673 $searchNames = array_map(
function($name){
return "'".$name.
"'";}, $searchNames);
675 if(empty($searchNames))
678 $con = \Bitrix\Main\Application::getConnection();
679 $sqlHelper = $con->getSqlHelper();
683 N.LOCATION_ID AS LOCATION_ID,
684 N.LEFT_MARGIN AS LEFT_MARGIN,
685 N.RIGHT_MARGIN AS RIGHT_MARGIN,
689 LEFT JOIN b_sale_loc_ext AS E
690 ON N.LOCATION_ID = E.LOCATION_ID AND E.SERVICE_ID = ".$sqlHelper->forSql(self::getExternalServiceId()).
"
692 E.LOCATION_ID IS NULL
693 AND NAME IN (".implode(
', ', $searchNames).
")");
698 while($loc = $res->fetch())
700 if(Comparator::isEntityEqual($loc[
'NAME'], $nameNorm,
'LOCALITY'))
702 $margins[] = array($loc[
'LOCATION_ID'], $loc[
'LEFT_MARGIN'], $loc[
'RIGHT_MARGIN'], $loc[
'NAME']);
703 $results[$loc[
'LOCATION_ID']] = array(
'NAME' =>
true);
705 if($loc[
'NAME'] == $nameNorm[
"NAME"])
706 $exact[] = $loc[
'LOCATION_ID'];
713 $marginFilter = array(
'LOGIC' =>
'OR');
715 foreach($margins as $v)
716 $marginFilter[] = array(
'<LEFT_MARGIN' => $v[1],
'>RIGHT_MARGIN' => $v[2]);
718 $res = LocationTable::getList(array(
720 '=NAME.LANGUAGE_ID' => LANGUAGE_ID,
721 '=TYPE.CODE' => array(
'SUBREGION',
'REGION',
'CITY'),
726 'PARENTS_NAME_UPPER' =>
'NAME.NAME_UPPER',
727 'PARENTS_TYPE_CODE' =>
'TYPE.CODE',
728 'LEFT_MARGIN',
'RIGHT_MARGIN'
732 while($loc = $res->fetch())
738 if(in_array(
false, $results[$id],
true))
743 if($loc[
'PARENTS_TYPE_CODE'] ==
'REGION' && $region <>
'')
745 if(!is_array($regionNorm))
746 $regionNorm = Comparator::normalizeEntity($region,
'REGION');
748 $found = Comparator::isEntityEqual($loc[
'PARENTS_NAME_UPPER'], $regionNorm,
'REGION');
750 elseif($subregion <>
'' && $loc[
'PARENTS_TYPE_CODE'] ==
'SUBREGION')
752 if(!is_array($subregionNorm))
753 $subregionNorm = Comparator::normalizeEntity($subregion,
'SUBREGION');
755 $found = Comparator::isEntityEqual($loc[
'PARENTS_NAME_UPPER'], $subregionNorm,
'SUBREGION');
757 elseif($city <>
'' && $loc[
'PARENTS_TYPE_CODE'] ==
'CITY')
759 if(!is_array($cityNorm))
760 $subregionNorm = Comparator::normalizeEntity($city,
'LOCALITY');
762 $found = Comparator::isEntityEqual($loc[
'PARENTS_NAME_UPPER'], $cityNorm,
'LOCALITY');
767 $isInExact = in_array($id, $exact);
768 $results[$id][$loc[
'PARENTS_TYPE_CODE']] = $found;
770 if($results[$id][
'REGION'] ===
true && $results[$id][
'SUBREGION'] ===
true && $isInExact)
773 if($found ===
false && $isInExact)
775 $key = array_search($id, $exact);
785 foreach($exact as $e)
786 if(!in_array(
false, $results[$e],
true))
789 $resCandidates = array();
791 foreach($results as $id => $result)
793 if(!in_array(
false, $result,
true))
795 $resCandidates[$id] = count($result);
799 if(empty($resCandidates))
802 if(count($resCandidates) > 1)
804 arsort($resCandidates);
805 reset($resCandidates);
808 return key($resCandidates);