Completed
Push — master ( 4a3e49...406f94 )
by Alejandro
16s queued 12s
created

GeoLite2LocationResolver::resolveIpLocation()   A

Complexity

Conditions 3
Paths 5

Size

Total Lines 9
Code Lines 7

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 7
CRAP Score 3

Importance

Changes 0
Metric Value
eloc 7
dl 0
loc 9
ccs 7
cts 7
cp 1
rs 10
c 0
b 0
f 0
cc 3
nc 5
nop 1
crap 3
1
<?php
2
declare(strict_types=1);
3
4
namespace Shlinkio\Shlink\IpGeolocation\Resolver;
5
6
use GeoIp2\Database\Reader;
7
use GeoIp2\Exception\AddressNotFoundException;
8
use GeoIp2\Model\City;
9
use GeoIp2\Record\Subdivision;
10
use MaxMind\Db\Reader\InvalidDatabaseException;
11
use Shlinkio\Shlink\Common\Exception\WrongIpException;
12
use Shlinkio\Shlink\IpGeolocation\Model;
13
use Shlinkio\Shlink\IpGeolocation\Resolver\IpLocationResolverInterface;
14
15
use function Functional\first;
16
17
class GeoLite2LocationResolver implements IpLocationResolverInterface
18
{
19
    /** @var Reader */
20
    private $geoLiteDbReader;
21
22 3
    public function __construct(Reader $geoLiteDbReader)
23
    {
24 3
        $this->geoLiteDbReader = $geoLiteDbReader;
25
    }
26
27
    /**
28
     * @throws WrongIpException
29
     */
30 3
    public function resolveIpLocation(string $ipAddress): Model\Location
31
    {
32
        try {
33 3
            $city = $this->geoLiteDbReader->city($ipAddress);
34 1
            return $this->mapFields($city);
35 2
        } catch (AddressNotFoundException $e) {
36 1
            throw WrongIpException::fromIpAddress($ipAddress, $e);
37 1
        } catch (InvalidDatabaseException $e) {
38 1
            throw new WrongIpException('Provided GeoLite2 db file is invalid', 0, $e);
39
        }
40
    }
41
42 1
    private function mapFields(City $city): Model\Location
43
    {
44
        /** @var Subdivision $region */
45 1
        $region = first($city->subdivisions);
46
47 1
        return new Model\Location(
48 1
            $city->country->isoCode ?? '',
49 1
            $city->country->name ?? '',
50 1
            $region->name ?? '',
51 1
            $city->city->name ?? '',
52 1
            (float) ($city->location->latitude ?? ''),
53 1
            (float) ($city->location->longitude ?? ''),
54 1
            $city->location->timeZone ?? ''
55
        );
56
    }
57
}
58