Как получить местоположение пользователя мы уже узнали в статье "Определение местоположения d7"
Теперь разберем, как работать с местоположениями в магазине(sale)
Для работы с местоположениями магазина используется класс \Bitrix\Sale\Location\LocationTable
Получение информации о местоположении по ID
$locationItem = \Bitrix\Sale\Location\LocationTable::getById(151167)->fetch();
/* Array
(
[ID] => 151167
[CODE] => 0000445112
[LEFT_MARGIN] => 188545
[RIGHT_MARGIN] => 188586
[DEPTH_LEVEL] => 3
[SORT] => 100
[PARENT_ID] => 58
[TYPE_ID] => 5
[LATITUDE] => 0.000000
[LONGITUDE] => 0.000000
[COUNTRY_ID] => 24
[REGION_ID] => 58
[CITY_ID] => 151167
[LOC_DEFAULT] => N
)*/
Получение информации о местоположении по CODE. Фактически это обертка над \Bitrix\Sale\Location\LocationTable::getList(). В отличии от getById() мы можем получить уже больше полей местоположения.
$locationItem = \Bitrix\Sale\Location\LocationTable::getByCode('0000445112', array(
'filter' => array('=NAME.LANGUAGE_ID' => LANGUAGE_ID),
'select' => array('*', 'NAME_RU' => 'NAME.NAME')
))->fetch();
/*Array
(
[ID] => 151167
[CODE] => 0000445112
[LEFT_MARGIN] => 188545
[RIGHT_MARGIN] => 188586
[DEPTH_LEVEL] => 3
[SORT] => 100
[PARENT_ID] => 58
[TYPE_ID] => 5
[LATITUDE] => 0.000000
[LONGITUDE] => 0.000000
[COUNTRY_ID] => 24
[REGION_ID] => 58
[CITY_ID] => 151167
[LOC_DEFAULT] => N
[NAME_RU] => Ростов-на-Дону
)*/
Теперь перейдем к основному методу работы с местоположениями: \Bitrix\Sale\Location\LocationTable::getList(). Получим список местоположений с названиями на текущем языке и типами местоположений:
$dbLocationItems = \Bitrix\Sale\Location\LocationTable::getList(array(
'filter' => array('=NAME.LANGUAGE_ID' => LANGUAGE_ID),
'select' => array('*', 'NAME_RU' => 'NAME.NAME', 'TYPE_CODE' => 'TYPE.CODE')
));
while($locationItem = $dbLocationItems->fetch())
{
// ...
}
/*Array
(
[ID] => 151167
[CODE] => 0000445112
[LEFT_MARGIN] => 188545
[RIGHT_MARGIN] => 188586
[DEPTH_LEVEL] => 3
[SORT] => 100
[PARENT_ID] => 58
[TYPE_ID] => 5
[LATITUDE] => 0.000000
[LONGITUDE] => 0.000000
[COUNTRY_ID] => 24
[REGION_ID] => 58
[CITY_ID] => 151167
[LOC_DEFAULT] => N
[NAME_RU] => Ростов-на-Дону
[TYPE_CODE] => CITY
)*/
Для работы с типами местоположений, используется класс \Bitrix\Sale\Location\TypeTable. Остановимся на нем подробнее позднее.
Получаем потомков указанного местоположения:
$dbLocationItems = \Bitrix\Sale\Location\LocationTable::getList(array(
'filter' => array(
'=ID' => 151167,
'=CHILDREN.NAME.LANGUAGE_ID' => LANGUAGE_ID,
'=CHILDREN.TYPE.NAME.LANGUAGE_ID' => LANGUAGE_ID,
),
'select' => array(
"CHILDREN_ID" => 'CHILDREN.ID',
"CHILDREN_CODE" => 'CHILDREN.CODE',
'CHILDREN_NAME_RU' => 'CHILDREN.NAME.NAME',
'CHILDREN_TYPE_CODE' => 'CHILDREN.TYPE.CODE',
'CHILDREN_TYPE_NAME_RU' => 'CHILDREN.TYPE.NAME.NAME'
)
));
while($locationItem = $dbLocationItems->fetch())
{
// ...
}
/*Array
(
[CHILDREN_ID] => 151168
[CHILDREN_CODE] => 0000447883
[CHILDREN_NAME_RU] => свх Ливенцовский 4 отделение посёлок
[CHILDREN_TYPE_CODE] => VILLAGE
[CHILDREN_TYPE_NAME_RU] => Село
)*/
Получаем ближайшего родителя указанного местоположения:
$dbLocationItems = \Bitrix\Sale\Location\LocationTable::getList(array(
'filter' => array(
'=ID' => 151167,
'=PARENT.NAME.LANGUAGE_ID' => LANGUAGE_ID,
'=PARENT.TYPE.NAME.LANGUAGE_ID' => LANGUAGE_ID,
),
'select' => array(
"I_PARENT_ID" => 'PARENT.ID',
"I_PARENT_CODE" => 'PARENT.CODE',
'I_PARENT_NAME_RU' => 'PARENT.NAME.NAME',
'I_PARENT_TYPE_CODE' => 'PARENT.TYPE.CODE',
'I_PARENT_TYPE_NAME_RU' => 'PARENT.TYPE.NAME.NAME'
)
));
while($locationItem = $dbLocationItems->fetch())
{
// ...
}
/*Array
(
[I_PARENT_ID] => 58
[I_PARENT_CODE] => 0000028056
[I_PARENT_NAME_RU] => Ростовская область
[I_PARENT_TYPE_CODE] => REGION
[I_PARENT_TYPE_NAME_RU] => Область
)*/
Получение местоположений от корня дерева до текущего элемента:
$dbLocationItems = \Bitrix\Sale\Location\LocationTable::getList(array(
'filter' => array(
'=ID' => 151167,
'=PARENTS.NAME.LANGUAGE_ID' => LANGUAGE_ID,
'=PARENTS.TYPE.NAME.LANGUAGE_ID' => LANGUAGE_ID,
),
'select' => array(
"I_PARENT_ID" => 'PARENTS.ID',
"I_PARENT_CODE" => 'PARENTS.CODE',
'I_PARENT_NAME_RU' => 'PARENTS.NAME.NAME',
'I_PARENT_TYPE_CODE' => 'PARENTS.TYPE.CODE',
'I_PARENT_TYPE_NAME_RU' => 'PARENTS.TYPE.NAME.NAME'
)
));
while($locationItem = $dbLocationItems->fetch())
{
// ...
}
/*Array
(
[I_PARENT_ID] => 24
[I_PARENT_CODE] => 0000028023
[I_PARENT_NAME_RU] => Россия
[I_PARENT_TYPE_CODE] => COUNTRY
[I_PARENT_TYPE_NAME_RU] => Страна
)
Array
(
[I_PARENT_ID] => 58
[I_PARENT_CODE] => 0000028056
[I_PARENT_NAME_RU] => Ростовская область
[I_PARENT_TYPE_CODE] => REGION
[I_PARENT_TYPE_NAME_RU] => Область
)
Array
(
[I_PARENT_ID] => 151167
[I_PARENT_CODE] => 0000445112
[I_PARENT_NAME_RU] => Ростов-на-Дону
[I_PARENT_TYPE_CODE] => CITY
[I_PARENT_TYPE_NAME_RU] => Город
)*/
Так же, для получения полной цепочки местоположения по ID можно использовать метод getPathToNode, а по коду местоположения метод getPathToNodeByCode:
$resLocation = \Bitrix\Sale\Location\LocationTable::getPathToNode(151167, [
'select' => [
'ID',
'LNAME' => 'NAME.NAME',
'SHORT_NAME' => 'NAME.SHORT_NAME',
],
'filter' => [
'NAME.LANGUAGE_ID' => LANGUAGE_ID
]
]);
if ($resLocation ) {
$resLocation ->addReplacedAliases(array('LNAME' => 'NAME'));
while($locationItem = $resLocation ->Fetch()) {
$arLoc[] = $locationItem['NAME'];
}
}
echo implode(', ', $arLoc);
//Россия, Ростовская область, Ростов-на-Дону
Для работы с избранными местоположениями обращаемся напрямую к базе данных:
$connection = Bitrix\Main\Application::getConnection();
$sqlHelper = $connection->getSqlHelper();
$sql = "SELECT LOCATION_CODE FROM b_sale_loc_def2site WHERE SITE_ID='".SITE_ID."' ORDER BY SORT";
$recordset = $connection->query($sql);
while ($record = $recordset->fetch())
{
$arResultTmp[] = $record["LOCATION_CODE"];
}
Поиск местоположения можно осуществить с помощью метода \Bitrix\Sale\Location\Search\Finder::find(), и как сказанно в документации: "Параметры поиска, аналогичные параметрам LocationTable::getList(). Дополнительно используется ключ PHRASE – поисковая фраза". Но на данный момент это некорректное утверждение, так как фильтровать полученные результаты по типу местоположения не получится и в результате мы видим огромную портянку местоположений со всеми деревнями и областями:
$resLocation = \Bitrix\Sale\Location\Search\Finder::find([
'filter' => ['=NAME.LANGUAGE_ID' => "RU", '=TYPE.CODE' => 'CITY', 'PHRASE' => "Рост"],
'select' => [
'*',
'ID' => 'ID',
'NAME_RU' => 'NAME.NAME',
'TYPE_CODE' => 'TYPE.CODE',
'CODE' => 'CODE'
]
],[
'FALLBACK_TO_NOINDEX_ON_NOTFOUND' => true,
'USE_INDEX' => true,//Использовать поисковый индекс
'USE_ORM' => true
]);
while($locationItem = $resLocation ->fetch())
{
// ...
}
/*Array
(
[ID] => 96631
[CODE] => 0000273315
[SORT] => 100
[LT_SORT] => 100
[NAME] => Ростов
[LEFT_MARGIN] => 297700
[RIGHT_MARGIN] => 297715
)
Array
(
[ID] => 151167
[CODE] => 0000445112
[SORT] => 100
[LT_SORT] => 100
[NAME] => Ростов-на-Дону
[LEFT_MARGIN] => 188545
[RIGHT_MARGIN] => 188586
)
Array
(
[ID] => 157266
[CODE] => 0000503467
[SORT] => 100
[LT_SORT] => 200
[NAME] => Роста село
[LEFT_MARGIN] => 176310
[RIGHT_MARGIN] => 176311
)
Array
(
[ID] => 117826
[CODE] => 0000337934
[SORT] => 100
[LT_SORT] => 200
[NAME] => Ростани деревня
[LEFT_MARGIN] => 255148
[RIGHT_MARGIN] => 255149
)*/
Так же поиск местоположения можно осуществить через \Bitrix\Sale\Location\LocationTable::getList(). Тут мы можем отфильтровать по типу местоположений, чтобы исключить лишние:
$resLocation = \Bitrix\Sale\Location\LocationTable::getList(array(
'filter' => [
'=TYPE.CODE' => 'CITY',
'=NAME.LANGUAGE_ID' => LANGUAGE_ID,
'NAME_RU' => 'Рост%'
],
'select' => [
'*',
'ID' => 'ID',
'NAME_RU' => 'NAME.NAME',
'TYPE_CODE' => 'TYPE.CODE',
]
));
while($locationItem = $resLocation->fetch()) {
// ...
}
/*Array
(
[ID] => 96631
[CODE] => 0000273315
[LEFT_MARGIN] => 297700
[RIGHT_MARGIN] => 297715
[DEPTH_LEVEL] => 4
[SORT] => 100
[PARENT_ID] => 96604
[TYPE_ID] => 5
[LATITUDE] => 0.000000
[LONGITUDE] => 0.000000
[COUNTRY_ID] => 24
[REGION_ID] => 42
[CITY_ID] => 96631
[LOC_DEFAULT] => N
[NAME_RU] => Ростов
[TYPE_CODE] => CITY
)
Array
(
[ID] => 151167
[CODE] => 0000445112
[LEFT_MARGIN] => 188545
[RIGHT_MARGIN] => 188586
[DEPTH_LEVEL] => 3
[SORT] => 100
[PARENT_ID] => 58
[TYPE_ID] => 5
[LATITUDE] => 0.000000
[LONGITUDE] => 0.000000
[COUNTRY_ID] => 24
[REGION_ID] => 58
[CITY_ID] => 151167
[LOC_DEFAULT] => N
[NAME_RU] => Ростов-на-Дону
[TYPE_CODE] => CITY
)*/