Passed
Pull Request — master (#258)
by Alejandro
04:00
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
cc 3
eloc 7
nc 5
nop 1
dl 0
loc 9
ccs 7
cts 7
cp 1
crap 3
rs 10
c 0
b 0
f 0
1
<?php
2
declare(strict_types=1);
3
4
namespace Shlinkio\Shlink\Common\IpGeolocation;
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 function Functional\first;
13
14
class GeoLite2LocationResolver implements IpLocationResolverInterface
15
{
16
    /**
17
     * @var Reader
18
     */
19
    private $geoLiteDbReader;
20
21 3
    public function __construct(Reader $geoLiteDbReader)
22
    {
23 3
        $this->geoLiteDbReader = $geoLiteDbReader;
24
    }
25
26
    /**
27
     * @throws WrongIpException
28
     */
29 3
    public function resolveIpLocation(string $ipAddress): array
30
    {
31
        try {
32 3
            $city = $this->geoLiteDbReader->city($ipAddress);
33 1
            return $this->mapFields($city);
34 2
        } catch (AddressNotFoundException $e) {
35 1
            throw WrongIpException::fromIpAddress($ipAddress, $e);
36 1
        } catch (InvalidDatabaseException $e) {
37 1
            throw new WrongIpException('Provided GeoLite2 db file is invalid', 0, $e);
38
        }
39
    }
40
41 1
    private function mapFields(City $city): array
42
    {
43
        /** @var Subdivision $region */
44 1
        $region = first($city->subdivisions);
45
46
        return [
47 1
            'country_code' => $city->country->isoCode ?? '',
48 1
            'country_name' => $city->country->name ?? '',
49 1
            'region_name' => $region->name ?? '',
50 1
            'city' => $city->city->name ?? '',
51 1
            'latitude' => $city->location->latitude ?? '',
52 1
            'longitude' => $city->location->longitude ?? '',
53 1
            'time_zone' => $city->location->timeZone ?? '',
54
        ];
55
    }
56
}
57