166 lines
4.7 KiB
PHP
166 lines
4.7 KiB
PHP
<?php
|
|
|
|
namespace KupShop\I18nBundle\Util;
|
|
|
|
use KupShop\KupShopBundle\Util\Compat\SymfonyBridge;
|
|
use Psr\Log\LoggerInterface;
|
|
use Symfony\Component\HttpFoundation\RequestStack;
|
|
|
|
class IPGeoLocator
|
|
{
|
|
// caching server for geoPlugin server
|
|
protected $host;
|
|
|
|
// the default base currency
|
|
protected $currency = 'CZK';
|
|
|
|
protected $cache;
|
|
protected $proxyCache;
|
|
|
|
/**
|
|
* @var RequestStack
|
|
*/
|
|
protected $requestStack;
|
|
|
|
protected $logger;
|
|
|
|
public function __construct(RequestStack $requestStack, LoggerInterface $logger)
|
|
{
|
|
$this->requestStack = $requestStack;
|
|
$this->logger = $logger;
|
|
|
|
$urlSuffix = '/geoip?ip={IP}&base_currency={CURRENCY}&id_shop={ID_SHOP}';
|
|
$this->host = (isRunningOnCluster() ? 'geoip.services' : 'http://geoip.wpj.cz').$urlSuffix;
|
|
}
|
|
|
|
/**
|
|
* Gets geographical info from users request. When proxy is enabled, it tries to take the info from the headers that the proxy set.
|
|
*
|
|
* @param $fullInfo bool when false, guaranteed IPGeoLocatorResult attributes are only ip, countryCode and currencyCode. When more information is needed (e.g. latitude/longitude), fullInfo parameter has to be true
|
|
*
|
|
* @return IPGeoLocatorResult
|
|
*/
|
|
public function getInfo(bool $fullInfo = false)
|
|
{
|
|
$result = null;
|
|
|
|
if (findModule(\Modules::PROXY_CACHE) && !$fullInfo) {
|
|
$result = $this->getInfoFromProxy();
|
|
}
|
|
|
|
if (!$result) {
|
|
$result = $this->getGeoLocatorInfo();
|
|
}
|
|
|
|
return $result;
|
|
}
|
|
|
|
protected function getGeoLocatorInfo()
|
|
{
|
|
if ($this->cache) {
|
|
return $this->cache;
|
|
}
|
|
|
|
$ip = $this->getClientIp();
|
|
|
|
$data = $this->locate($ip);
|
|
|
|
return $this->cache = $this->createResult($data);
|
|
}
|
|
|
|
protected function getInfoFromProxy()
|
|
{
|
|
if ($this->proxyCache) {
|
|
return $this->proxyCache;
|
|
}
|
|
|
|
$countryCode = $this->getRequest()->headers->get('Cdn-Requestcountrycode');
|
|
|
|
if (!$countryCode) {
|
|
return false;
|
|
}
|
|
|
|
$currencyCode = (new \NumberFormatter('en_'.$countryCode, \NumberFormatter::CURRENCY))->getTextAttribute(\NumberFormatter::CURRENCY_CODE);
|
|
|
|
if (!$currencyCode || $currencyCode == 'XXX') {
|
|
return false;
|
|
}
|
|
|
|
$data = [
|
|
'geoplugin_countryCode' => $countryCode,
|
|
'geoplugin_currencyCode' => $currencyCode,
|
|
'ip' => $this->getClientIp(),
|
|
];
|
|
|
|
return $this->proxyCache = $this->createResult($data);
|
|
}
|
|
|
|
protected function getClientIp()
|
|
{
|
|
return $this->getRequest()->getClientIp();
|
|
}
|
|
|
|
protected function getRequest()
|
|
{
|
|
$request = $this->requestStack->getMainRequest();
|
|
|
|
if (is_null($request)) {
|
|
$request = SymfonyBridge::getCurrentRequest();
|
|
}
|
|
|
|
return $request;
|
|
}
|
|
|
|
protected function fetch($host)
|
|
{
|
|
// use cURL to fetch data
|
|
$ch = curl_init();
|
|
curl_setopt($ch, CURLOPT_URL, $host);
|
|
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
|
|
curl_setopt($ch, CURLOPT_USERAGENT, 'geoPlugin PHP Class v1.0');
|
|
curl_setopt($ch, CURLOPT_TIMEOUT_MS, 1000);
|
|
$response = curl_exec($ch);
|
|
curl_close($ch);
|
|
|
|
return $response;
|
|
}
|
|
|
|
protected function locate($ip)
|
|
{
|
|
$host = str_replace('{IP}', $ip, $this->host);
|
|
$host = str_replace('{CURRENCY}', $this->currency, $host);
|
|
$host = str_replace('{ID_SHOP}', getShopUniqueName(), $host);
|
|
|
|
$response = $this->fetch($host);
|
|
|
|
return json_decode($response, true);
|
|
}
|
|
|
|
/**
|
|
* @param $data array
|
|
*
|
|
* @return IPGeoLocatorResult
|
|
*/
|
|
protected function createResult($data)
|
|
{
|
|
$result = new IPGeoLocatorResult();
|
|
|
|
// set the geoPlugin vars
|
|
$result->ip = $data['ip'] ?? null;
|
|
$result->city = $data['geoplugin_city'] ?? null;
|
|
$result->region = $data['geoplugin_region'] ?? null;
|
|
$result->areaCode = $data['geoplugin_areaCode'] ?? null;
|
|
$result->dmaCode = $data['geoplugin_dmaCode'] ?? null;
|
|
$result->countryCode = $data['geoplugin_countryCode'] ?? null;
|
|
$result->countryName = $data['geoplugin_countryName'] ?? null;
|
|
$result->continentCode = $data['geoplugin_continentCode'] ?? null;
|
|
$result->latitude = $data['geoplugin_latitude'] ?? null;
|
|
$result->longitude = $data['geoplugin_longitude'] ?? null;
|
|
$result->currencyCode = $data['geoplugin_currencyCode'] ?? null;
|
|
$result->currencySymbol = $data['geoplugin_currencySymbol'] ?? null;
|
|
$result->currencyConverter = $data['geoplugin_currencyConverter'] ?? null;
|
|
|
|
return $result;
|
|
}
|
|
}
|