Passed
Pull Request — master (#258)
by Alejandro
04:00
created

IpApiLocationResolver   A

Complexity

Total Complexity 5

Size/Duplication

Total Lines 39
Duplicated Lines 0 %

Test Coverage

Coverage 88.24%

Importance

Changes 0
Metric Value
eloc 18
dl 0
loc 39
ccs 15
cts 17
cp 0.8824
rs 10
c 0
b 0
f 0
wmc 5

3 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 3 1
A mapFields() 0 10 1
A resolveIpLocation() 0 9 3
1
<?php
2
declare(strict_types=1);
3
4
namespace Shlinkio\Shlink\Common\IpGeolocation;
5
6
use GuzzleHttp\Client;
7
use GuzzleHttp\Exception\GuzzleException;
8
use Shlinkio\Shlink\Common\Exception\InvalidArgumentException;
9
use Shlinkio\Shlink\Common\Exception\WrongIpException;
10
use function Shlinkio\Shlink\Common\json_decode;
11
use function sprintf;
12
13
class IpApiLocationResolver implements IpLocationResolverInterface
14
{
15
    private const SERVICE_PATTERN = 'http://ip-api.com/json/%s';
16
17
    /**
18
     * @var Client
19
     */
20
    private $httpClient;
21
22 2
    public function __construct(Client $httpClient)
23
    {
24 2
        $this->httpClient = $httpClient;
25
    }
26
27
    /**
28
     * @throws WrongIpException
29
     */
30 2
    public function resolveIpLocation(string $ipAddress): array
31
    {
32
        try {
33 2
            $response = $this->httpClient->get(sprintf(self::SERVICE_PATTERN, $ipAddress));
34 1
            return $this->mapFields(json_decode((string) $response->getBody()));
35 1
        } catch (GuzzleException $e) {
36 1
            throw WrongIpException::fromIpAddress($ipAddress, $e);
37
        } catch (InvalidArgumentException $e) {
38
            throw new WrongIpException('IP-API returned invalid body while locating IP address', 0, $e);
39
        }
40
    }
41
42 1
    private function mapFields(array $entry): array
43
    {
44
        return [
45 1
            'country_code' => $entry['countryCode'] ?? '',
46 1
            'country_name' => $entry['country'] ?? '',
47 1
            'region_name' => $entry['regionName'] ?? '',
48 1
            'city' => $entry['city'] ?? '',
49 1
            'latitude' => $entry['lat'] ?? '',
50 1
            'longitude' => $entry['lon'] ?? '',
51 1
            'time_zone' => $entry['timezone'] ?? '',
52
        ];
53
    }
54
}
55