%PDF- %PDF-
| Direktori : /proc/self/root/home/bitrix/www/bitrix/modules/sale/lib/location/ |
| Current File : //proc/self/root/home/bitrix/www/bitrix/modules/sale/lib/location/geoip.php |
<?
namespace Bitrix\Sale\Location;
use Bitrix\Main\Service\GeoIp\Data;
use Bitrix\Main\Service\GeoIp\Result;
use Bitrix\Main\Service\GeoIp\Manager;
use Bitrix\Sale\Location\Normalizer\Builder;
class GeoIp
{
/**
* @param string $ip Ip address.
* @param string $lang Language identifier.
* @return int Location id.
*/
public static function getLocationId($ip = '', $lang = LANGUAGE_ID)
{
$fields = array();
$geoData = self::getData($ip, $lang);
if($geoData)
$fields = self::getLocationFields($geoData, $lang);
return intval($fields['ID']) > 0 ? intval($fields['ID']) : 0;
}
/**
* @param string $ip Ip address.
* @param string $lang Language identifier.
* @return string Location code.
*/
public static function getLocationCode($ip = '', $lang = LANGUAGE_ID)
{
$fields = array();
$geoData = self::getData($ip, $lang);
if($geoData)
$fields = self::getLocationFields($geoData, $lang);
return strlen($fields['CODE']) > 0 ? $fields['CODE'] : '';
}
/**
* @param string $ip Ip address.
* @param string $lang Language.
* @return string Zip (postal) code.
*/
public static function getZipCode($ip, $lang = LANGUAGE_ID)
{
$data = self::getData($ip, $lang);
if(!$data)
$result = '';
else
$result = strlen($data->getGeoData()->zipCode) > 0 ? $data->getGeoData()->zipCode : '';
return $result;
}
/**
* @param string $ip Ip address.
* @param string $lang Language identifier.
* @return Result.
*/
protected static function getData($ip, $lang)
{
Manager::useCookieToStoreInfo(true);
return Manager::getDataResult($ip, $lang, array('cityName'));
}
/**
* @param Result $geoIpData.
* @param string $lang
* @return array Location fields.
*/
protected static function getLocationFields(Result $geoIpData, $lang = LANGUAGE_ID)
{
if(!$geoIpData->isSuccess())
{
return [];
}
$geoData = $geoIpData->getGeoData();
if($geoData->cityName == \Bitrix\Main\Service\GeoIp\Manager::INFO_NOT_AVAILABLE)
{
return [];
}
$res = LocationTable::getList([
'filter' => [
'=NAME.NAME_UPPER' => ToUpper($geoData->cityName),
'=NAME.LANGUAGE_ID' => $lang
],
'select' => ['ID', 'CODE', 'LEFT_MARGIN', 'RIGHT_MARGIN']
]);
$locations = [];
while($loc = $res->fetch())
{
$locations[$loc['ID']] = $loc;
}
if(count($locations) == 1)
{
$result = current($locations);
}
else
{
$result = self::specifyLocationByParents($geoData, $locations, $lang);
}
return $result;
}
protected static function specifyLocationByParents(Data $geoData, array $locations, $lang)
{
$marginConditions = [
'LOGIC' => 'OR'
];
foreach($locations as $location)
{
$marginConditions[] = [
'LOGIC' => 'AND',
'<LEFT_MARGIN' => $location['LEFT_MARGIN'],
'>RIGHT_MARGIN' => $location['RIGHT_MARGIN']
];
}
$params = [
'filter' => [
$marginConditions,
'NAME.LANGUAGE_ID' => $lang,
],
'select' => [
'ID', 'LEFT_MARGIN', 'RIGHT_MARGIN',
'LOCATION_NAME_UPPER' => 'NAME.NAME_UPPER'
]
];
$res = \Bitrix\Sale\Location\LocationTable::getList($params);
$weight = [];
$result = [];
while($loc = $res->fetch())
{
if(self::isNameMatched($geoData, $loc['LOCATION_NAME_UPPER'], $lang))
{
$locationIds = self::getLocationIdsByMargins($locations, $loc['LEFT_MARGIN'], $loc['RIGHT_MARGIN']);
foreach($locationIds as $locationId)
{
if(!isset($locationId))
{
$weight[$locationId] = 0;
}
$weight[$locationId]++;
}
}
}
if(!empty($weight))
{
arsort($weight);
reset($weight);
$id = key($weight);
if(isset($locations[$id]))
{
$result = $locations[$id];
}
}
return $result;
}
protected static function getLocationIdsByMargins(array $locations, $leftMargin, $rightMargin)
{
$result = [];
foreach($locations as $locationId => $location)
{
if($location['LEFT_MARGIN'] >= $leftMargin && $location['RIGHT_MARGIN'] <= $rightMargin)
{
$result[] = $location['ID'];
}
}
return $result;
}
protected static function isNameMatched(Data $geoData, $name, $lang)
{
static $normalizer = null;
if($normalizer === null)
{
$normalizer = Builder::build($lang);
}
$name = $normalizer->normalize($name);
return $normalizer->normalize($geoData->countryName) == $name
|| $normalizer->normalize($geoData->regionName) == $name
|| $normalizer->normalize($geoData->subRegionName) == $name;
}
}