2018-11-11 12:40:40 +01:00
|
|
|
<?php
|
|
|
|
|
declare(strict_types=1);
|
|
|
|
|
|
2019-08-10 13:56:06 +02:00
|
|
|
namespace Shlinkio\Shlink\IpGeolocation\Resolver;
|
2018-11-11 12:40:40 +01:00
|
|
|
|
|
|
|
|
use GeoIp2\Database\Reader;
|
|
|
|
|
use GeoIp2\Exception\AddressNotFoundException;
|
|
|
|
|
use GeoIp2\Model\City;
|
2018-11-11 18:57:32 +01:00
|
|
|
use GeoIp2\Record\Subdivision;
|
2018-11-11 12:40:40 +01:00
|
|
|
use MaxMind\Db\Reader\InvalidDatabaseException;
|
|
|
|
|
use Shlinkio\Shlink\Common\Exception\WrongIpException;
|
2019-08-10 13:56:06 +02:00
|
|
|
use Shlinkio\Shlink\IpGeolocation\Model;
|
|
|
|
|
use Shlinkio\Shlink\IpGeolocation\Resolver\IpLocationResolverInterface;
|
2019-02-26 22:56:43 +01:00
|
|
|
|
2018-11-11 18:57:32 +01:00
|
|
|
use function Functional\first;
|
2018-11-11 12:40:40 +01:00
|
|
|
|
|
|
|
|
class GeoLite2LocationResolver implements IpLocationResolverInterface
|
|
|
|
|
{
|
2018-11-20 19:30:27 +01:00
|
|
|
/** @var Reader */
|
2018-11-11 12:40:40 +01:00
|
|
|
private $geoLiteDbReader;
|
|
|
|
|
|
|
|
|
|
public function __construct(Reader $geoLiteDbReader)
|
|
|
|
|
{
|
|
|
|
|
$this->geoLiteDbReader = $geoLiteDbReader;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* @throws WrongIpException
|
|
|
|
|
*/
|
2019-02-17 12:59:55 +01:00
|
|
|
public function resolveIpLocation(string $ipAddress): Model\Location
|
2018-11-11 12:40:40 +01:00
|
|
|
{
|
|
|
|
|
try {
|
|
|
|
|
$city = $this->geoLiteDbReader->city($ipAddress);
|
|
|
|
|
return $this->mapFields($city);
|
|
|
|
|
} catch (AddressNotFoundException $e) {
|
|
|
|
|
throw WrongIpException::fromIpAddress($ipAddress, $e);
|
|
|
|
|
} catch (InvalidDatabaseException $e) {
|
|
|
|
|
throw new WrongIpException('Provided GeoLite2 db file is invalid', 0, $e);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2019-02-17 12:59:55 +01:00
|
|
|
private function mapFields(City $city): Model\Location
|
2018-11-11 12:40:40 +01:00
|
|
|
{
|
2018-11-11 18:57:32 +01:00
|
|
|
/** @var Subdivision $region */
|
|
|
|
|
$region = first($city->subdivisions);
|
|
|
|
|
|
2019-02-17 12:59:55 +01:00
|
|
|
return new Model\Location(
|
|
|
|
|
$city->country->isoCode ?? '',
|
|
|
|
|
$city->country->name ?? '',
|
|
|
|
|
$region->name ?? '',
|
|
|
|
|
$city->city->name ?? '',
|
|
|
|
|
(float) ($city->location->latitude ?? ''),
|
|
|
|
|
(float) ($city->location->longitude ?? ''),
|
|
|
|
|
$city->location->timeZone ?? ''
|
|
|
|
|
);
|
2018-11-11 12:40:40 +01:00
|
|
|
}
|
|
|
|
|
}
|