Server IP : 80.87.202.40 / Your IP : 216.73.216.169 Web Server : Apache System : Linux rospirotorg.ru 5.14.0-539.el9.x86_64 #1 SMP PREEMPT_DYNAMIC Thu Dec 5 22:26:13 UTC 2024 x86_64 User : bitrix ( 600) PHP Version : 8.2.27 Disable Function : NONE MySQL : OFF | cURL : ON | WGET : ON | Perl : ON | Python : OFF | Sudo : ON | Pkexec : ON Directory : /home/bitrix/ext_www/rospirotorg.ru/bitrix/modules/lpost.delivery/lib/main/ |
Upload File : |
<?php namespace Lpost\Delivery\Main; use Bitrix\Main\Localization\Loc; Loc::loadMessages(__FILE__); class City extends Base { protected static $tableName = 'CityCoordTable'; protected static $arCityData = []; // регион => столица const CITY_REGION_MAIN = [ 'Республика Адыгея' => 'Майкоп', 'Республика Башкортостан' => 'Уфа', 'Республика Бурятия' => 'Улан-Удэ', 'Республика Алтай' => 'Горно-Алтайск', 'Республика Дагестан' => 'Махачкала', 'Республика Ингушетия' => 'Магас', 'Кабардино-Балкарская Республика' => 'Нальчик', 'Республика Калмыкия' => 'Элиста', 'Карачаево-Черкесская Республика' => 'Черкесск', 'Республика Карелия' => 'Петрозаводск', 'Республика Коми' => 'Сыктывкар', 'Республика Марий Эл' => 'Йошкар-Ола', 'Республика Мордовия' => 'Саранск', 'Республика Саха (Якутия)' => 'Якутск', 'Республика Северная Осетия-Алания' => 'Владикавказ', 'Республика Татарстан' => ['Казань','Набережные Челны'], 'Республика Тыва' => 'Кызыл', 'Удмуртская Республика' => 'Ижевск', 'Республика Хакасия' => 'Абакан', 'Чеченская Республика' => 'Грозный', 'Чувашская Республика' => 'Чебоксары', 'Республика Крым' => 'Симферополь', 'Крым' => 'Симферополь', 'Еврейская автономная область' => 'Биробиджан', 'Ненецкий автономный округ' => 'Нарьян-Мар', 'Ханты-Мансийский автономный округ' => 'Ханты-Мансийск', 'Чукотский автономный округ' => 'Анадырь', 'Ямало-Ненецкий автономный округ' => 'Салехард', 'Алтайский край' => 'Барнаул', 'Камчатский край' => 'Петропавловск-Камчатский', 'Хабаровский край' => 'Хабаровск', 'Краснодарский край' => 'Краснодар', 'Красноярский край' => 'Красноярск', 'Пермский край' => 'Пермь', 'Приморский край' => 'Владивосток', 'Ставропольский край' => 'Ставрополь', 'Забайкальский край' => 'Чита', 'Амурская область' => 'Благовещенск', 'Архангельская область' => 'Архангельск', 'Астраханская область' => 'Астрахань', 'Белгородская область' => 'Белгород', 'Брянская область' => 'Брянск', 'Челябинская область' => 'Челябинск', 'Иркутская область' => 'Иркутск', 'Ивановская область' => 'Иваново', 'Калининградская область' => 'Калининград', 'Калужская область' => 'Калуга', 'Кемеровская область' => 'Кемерово', 'Кировская область' => 'Киров', 'Костромская область' => 'Кострома', 'Курганская область' => 'Курган', 'Курская область' => 'Курск', 'Ленинградская область' => 'Санкт-Петербург', 'Липецкая область' => 'Липецк', 'Магаданская область' => 'Магадан', 'Московская область' => 'Москва', 'Мурманская область' => 'Мурманск', 'Нижегородская область' => 'Нижний Новгород', 'Новгородская область' => 'Великий Новгород', 'Новосибирская область' => 'Новосибирск', 'Омская область' => 'Омск', 'Оренбургская область' => 'Оренбург', 'Орловская область' => 'Орёл', 'Пензенская область' => 'Пенза', 'Псковская область' => 'Псков', 'Ростовская область' => 'Ростов-на-Дону', 'Рязанская область' => 'Рязань', 'Сахалинская область' => 'Южно-Сахалинск', 'Самарская область' => 'Самара', 'Саратовская область' => 'Саратов', 'Смоленская область' => 'Смоленск', 'Свердловская область' => 'Екатеринбург', 'Тамбовская область' => 'Тамбов', 'Томская область' => 'Томск', 'Тверская область' => 'Тверь', 'Тульская область' => 'Тула', 'Тюменская область' => 'Тюмень', 'Ульяновская область' => 'Ульяновск', 'Владимирская область' => 'Владимир', 'Волгоградская область' => 'Волгоград', 'Вологодская область' => 'Вологда', 'Воронежская область' => 'Воронеж', 'Ярославская область' => 'Ярославль', //'Запорожская область' => 'Мелитополь', //'Херсонская область' => 'Геническ', ]; const CITY_REGION_MAIN_REG = [ 'Адыгея' => 'Республика Адыгея', 'Башкортостан' => 'Республика Башкортостан', 'Бурятия' => 'Республика Бурятия', 'Алтай' => 'Республика Алтай', 'Дагестан' => 'Республика Дагестан', 'Ингушетия' => 'Республика Ингушетия', 'Кабардино-Балкарская' => 'Кабардино-Балкарская Республика', 'Калмыкия' => 'Республика Калмыкия', 'Карачаево-Черкесская' => 'Карачаево-Черкесская Республика', 'Карелия' => 'Республика Карелия', 'Коми' => 'Республика Коми', 'Марий Эл' => 'Республика Марий Эл', 'Мордовия' => 'Республика Мордовия', 'Саха' => 'Республика Саха (Якутия)', 'Северная Осетия-' => 'Республика Северная Осетия-Алания', 'Северная Осетия ' => 'Республика Северная Осетия-Алания', 'Татарстан' => 'Республика Татарстан', 'Тыва' => 'Республика Тыва', 'Удмуртская' => 'Удмуртская Республика', 'Хакасия' => 'Республика Хакасия', 'Чеченская' => 'Чеченская Республика', 'Чувашская' => 'Чувашская Республика', 'Крым' => 'Республика Крым', 'Еврейская' => 'Еврейская автономная область', 'Ненецкий' => 'Ненецкий автономный округ', 'Ханты-Мансийский' => 'Ханты-Мансийский автономный округ', 'Чукотский' => 'Чукотский автономный округ', 'Ямало-Ненецкий' => 'Ямало-Ненецкий автономный округ', 'Алтайский' => 'Алтайский край', 'Камчатский' => 'Камчатский край', 'Хабаровский' => 'Хабаровский край', 'Краснодарский' => 'Краснодарский край', 'Красноярский' => 'Красноярский край', 'Пермский' => 'Пермский край', 'Приморский' => 'Приморский край', 'Ставропольский' => 'Ставропольский край', 'Забайкальский' => 'Забайкальский край', 'Амурская' => 'Амурская область', 'Архангельская' => 'Архангельская область', 'Астраханская' => 'Астраханская область', 'Белгородская' => 'Белгородская область', 'Брянская' => 'Брянская область', 'Челябинская' => 'Челябинская область', 'Иркутская' => 'Иркутская область', 'Ивановская' => 'Ивановская область', 'Калининградская' => 'Калининградская область', 'Калужская' => 'Калужская область', 'Кемеровская' => 'Кемеровская область', 'Кировская' => 'Кировская область', 'Костромская' => 'Костромская область', 'Курганская' => 'Курганская область', 'Курская' => 'Курская область', 'Ленинградская' => 'Ленинградская область', 'Липецкая' => 'Липецкая область', 'Магаданская' => 'Магаданская область', 'Московская' => 'Московская область', 'Мурманская' => 'Мурманская область', 'Нижегородская' => 'Нижегородская область', 'Новгородская' => 'Новгородская область', 'Новосибирская' => 'Новосибирская область', 'Омская' => 'Омская область', 'Оренбургская' => 'Оренбургская область', 'Орловская' => 'Орловская область', 'Пензенская' => 'Пензенская область', 'Псковская' => 'Псковская область', 'Ростовская' => 'Ростовская область', 'Рязанская' => 'Рязанская область', 'Сахалинская' => 'Сахалинская область', 'Самарская' => 'Самарская область', 'Саратовская' => 'Саратовская область', 'Смоленская' => 'Смоленская область', 'Свердловская' => 'Свердловская область', 'Тамбовская' => 'Тамбовская область', 'Томская' => 'Томская область', 'Тверская' => 'Тверская область', 'Тульская' => 'Тульская область', 'Тюменская' => 'Тюменская область', 'Ульяновская' => 'Ульяновская область', 'Владимирская' => 'Владимирская область', 'Волгоградская' => 'Волгоградская область', 'Вологодская' => 'Вологодская область', 'Воронежская' => 'Воронежская область', 'Ярославская' => 'Ярославская область', //'Запорожская' => 'Запорожская область', //'Херсонская' => 'Херсонская область', ]; /** * @param $bitrixCityCode - bitrix location id or code * @return array */ public static function getCityData($bitrixCityCode): array { if(empty(self::$arCityData[$bitrixCityCode])) { \CModule::IncludeModule('sale'); $city = \Bitrix\Sale\Location\LocationTable::getList([ 'filter' => ['=CODE' => $bitrixCityCode, '=NAME.LANGUAGE_ID' => LANGUAGE_ID], 'select' => ['*', 'NAME_RU' => 'NAME.NAME', 'SHORT_NAME_RU' => 'NAME.SHORT_NAME'] ])->fetch(); // \Bitrix\Main\Diag\Debug::writeToFile($city, date("d.m.Y H:i:s") . " city ", "/bitrix/php_interface/lpost.delivery.all.txt"); if (!$city) $city = \Bitrix\Sale\Location\LocationTable::getList([ 'filter' => ['=ID' => $bitrixCityCode, '=NAME.LANGUAGE_ID' => LANGUAGE_ID], 'select' => ['*', 'NAME_RU' => 'NAME.NAME', 'SHORT_NAME_RU' => 'NAME.SHORT_NAME'] ])->fetch(); if (isset($city['CODE'])) $bitrixCityCode = $city['CODE']; $cityId = $city['ID']; $cityName = !empty($city['SHORT_NAME_RU']) ? $city['SHORT_NAME_RU'] : $city['NAME_RU']; $cityFullName = $cityName; $regionName = ''; if ($city) { $arCityData = self::getCityDataBitrix($cityId); if (!empty($arCityData['REGION_NAME'])) { $regionName = $arCityData['REGION_NAME']; if ($arCityData['REGION_NAME'] != $cityName) $cityFullName = $cityName . ', ' . $arCityData['REGION_NAME']; } } $arResult = \Lpost\Delivery\Entity\CityCoordTable::getList([ "filter" => [ "city_id" => $cityId ], ])->fetch(); if (empty($arResult) or empty((int)$arResult["coord_lat"]) or empty((int)$arResult["coord_long"])) { $coords = self::requestGeocodeCoords($cityFullName); self::saveCacheCoords([ //// lpost_delivery_city_coord "city_id" => $cityId, "name" => $cityName, //// cityFullName "coord_lat" => $coords["coord_lat"] ?: 0, "coord_long" => $coords["coord_long"] ?: 0, "params" => [], ]); $arResult = \Lpost\Delivery\Entity\CityCoordTable::getList([ "filter" => [ "city_id" => $cityId ], ])->fetch(); } if (!empty($arResult)) { $arResult['region_name'] = $regionName; $arResult['full_name'] = $cityFullName; $arResult['arCityData'] = $arCityData; } self::$arCityData[$bitrixCityCode] = $arResult ?: []; } return self::$arCityData[$bitrixCityCode]; } /** * @param $bitrixCityCode - bitrix location id or code * @return array */ public static function getCityDataBitrix($bitrixCityCode): array { \Bitrix\Main\Loader::IncludeModule('sale'); $city = \Bitrix\Sale\Location\LocationTable::getList([ 'filter' => ['=CODE' => $bitrixCityCode, '=NAME.LANGUAGE_ID' => LANGUAGE_ID], 'select' => ['*', 'NAME_RU' => 'NAME.NAME'] ])->fetch(); if(!$city) $city = \Bitrix\Sale\Location\LocationTable::getList([ 'filter' => ['=ID' => $bitrixCityCode, '=NAME.LANGUAGE_ID' => LANGUAGE_ID], 'select' => ['*', 'NAME_RU' => 'NAME.NAME'] ])->fetch(); if(isset($city['ID'])){ $cityId = $city['ID']; $arCityData = []; $cache = \Bitrix\Main\Data\Cache::createInstance(); $cacheTime = 1; //86400; !!!!! $cacheId = 'city_id_data_'.$cityId; $cacheDir = 'city_id_data'; if ($cache->initCache($cacheTime, $cacheId, $cacheDir)) { $arCityData = $cache->getVars(); } elseif ($cache->startDataCache()) { $res = \Bitrix\Sale\Location\LocationTable::getList(array( 'filter' => array( '=ID' => $cityId, '=PARENTS.TYPE.CODE' => array('COUNTRY_DISTRICT', 'CITY', 'REGION'), '=PARENTS.NAME.LANGUAGE_ID' => LANGUAGE_ID, '=PARENTS.TYPE.NAME.LANGUAGE_ID' => LANGUAGE_ID, ), 'select' => array( //'ID' => 'ID', 'I_ID' => 'PARENTS.ID', 'I_CODE' => 'PARENTS.CODE', 'I_NAME_RU' => 'PARENTS.NAME.NAME', 'I_SHORT_NAME_RU' => 'PARENTS.NAME.SHORT_NAME', 'I_TYPE_CODE' => 'PARENTS.TYPE.CODE', 'I_TYPE_NAME_RU' => 'PARENTS.TYPE.NAME.NAME' ), 'order' => array( 'PARENTS.DEPTH_LEVEL' => 'asc' ) )); $cityRegion = [Loc::getMessage('Moscow'), Loc::getMessage('StPetersburg')]; while($item = $res->fetch()) { if($item['I_TYPE_CODE'] == 'COUNTRY_DISTRICT') // округ { $distingId = $item['I_ID']; $distingName = $item['I_NAME_RU']; } elseif($item['I_TYPE_CODE'] == 'REGION' || ($item['I_TYPE_CODE'] == 'CITY' && in_array($item['I_NAME_RU'], $cityRegion)) ) // регион или МСК или СПБ { $regionId = $item['I_ID']; $regionCode = $item['I_CODE']; $regionName = $item['I_NAME_RU']; $cityName = !empty($item['I_SHORT_NAME_RU']) ? $item['I_SHORT_NAME_RU'] : $item['I_NAME_RU']; $cityCode = $item['I_CODE']; } elseif( $item['I_TYPE_CODE'] == 'CITY' && $cityId == $item['I_ID'] ) // город { $cityName = !empty($item['I_SHORT_NAME_RU']) ? $item['I_SHORT_NAME_RU'] : $item['I_NAME_RU']; $cityCode = $item['I_CODE']; } } $arCityData = [ 'CITY_NAME' => $cityName, 'CITY_CODE' => $cityCode, 'REGION_ID' => $regionId, 'REGION_CODE' => $regionCode, 'REGION_NAME' => $regionName, 'DISTING_ID' => $distingId, 'DISTING_NAME' => $distingName, ]; if(isset(self::CITY_REGION_MAIN[$regionName])) $arCityData['MAIN_CITY_REGION'] = self::CITY_REGION_MAIN[$regionName]; else { $findMainCity = self::findCityRegion($regionName); if (!empty($findMainCity)) { $arCityData['MAIN_CITY_REGION'] = $findMainCity['city']; $arCityData['REGION_NAME'] = $findMainCity['region']; } } $cache->endDataCache($arCityData); } if(!empty($arCityData)) $arCityData['CITY_ID'] = $city['ID']; } return $arCityData ?: []; } /** * @param $regionName * @return array|null */ public static function findCityRegion($regionName){ foreach(self::CITY_REGION_MAIN as $region => $city){ if(stripos($region, $regionName) !== false){ return [ 'city' => $city, 'region' => $region, ]; } } foreach(self::CITY_REGION_MAIN_REG as $region => $regionFull){ if(preg_match('/'.$region.'/', $regionName)){ if(isset(self::CITY_REGION_MAIN[$regionFull])) return [ 'city' => self::CITY_REGION_MAIN[$regionFull], 'region' => $regionFull, ]; } } return null; } /** * ������ �� ��������� ��������� ����� �������������� * @param $cityName * @return array|bool */ public static function requestGeocodeCoords($cityName) { $yandexApiToken = \Lpost\Delivery\Settings::getInstance()->getOption("yandex_map_api_key"); if(!$yandexApiToken) { return false; } $url = 'https://geocode-maps.yandex.ru/1.x/?' . http_build_query([ "apikey" => $yandexApiToken, "format" => "json", "geocode" => \Bitrix\Main\Text\Encoding::convertEncoding($cityName, LANG_CHARSET, "UTF-8") ]); $ch = curl_init(); curl_setopt($ch, CURLOPT_URL, $url); curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); curl_setopt($ch, CURLOPT_HTTPGET, 1); curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1); $data = curl_exec($ch); if(!empty($data)) $data = \Bitrix\Main\Web\Json::decode($data); $coords = []; if(isset($data['response']['GeoObjectCollection']['featureMember'])) { foreach($data['response']['GeoObjectCollection']['featureMember'] as $entry) { $yndexCoords = explode(" ", $entry['GeoObject']['Point']['pos']); $coords['coord_lat'] = $yndexCoords[1]; $coords['coord_long'] = $yndexCoords[0]; break; } } curl_close($ch); return $coords; } /** * ���������� �������� � ������� * @param array $data */ public static function saveCacheCoords(array $data) { $res = \Lpost\Delivery\Entity\CityCoordTable::getList([ "filter" => [ "city_id" => $data['city_id'] ], "select" => ["id"] ])->fetch(); if(empty($res)) { \Lpost\Delivery\Entity\CityCoordTable::add($data); } else { \Lpost\Delivery\Entity\CityCoordTable::update([ "id" => $res['id'], "city_id" => $data['city_id'] ], [ "coord_lat" => $data['coord_lat'], "coord_long" => $data['coord_long'], ]); } } }