Passed
Pull Request — master (#258)
by Alejandro
03:13
created

IpApiLocationResolver   A

Complexity

Total Complexity 5

Size/Duplication

Total Lines 41
Duplicated Lines 0 %

Test Coverage

Coverage 88.24%

Importance

Changes 0
Metric Value
eloc 18
dl 0
loc 41
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
     * @param string $ipAddress
29
     * @return array
30
     * @throws WrongIpException
31
     */
32 2
    public function resolveIpLocation(string $ipAddress): array
33
    {
34
        try {
35 2
            $response = $this->httpClient->get(sprintf(self::SERVICE_PATTERN, $ipAddress));
36 1
            return $this->mapFields(json_decode((string) $response->getBody()));
37 1
        } catch (GuzzleException $e) {
38 1
            throw WrongIpException::fromIpAddress($ipAddress, $e);
39
        } catch (InvalidArgumentException $e) {
40
            throw new WrongIpException('IP-API returned invalid body while locating IP address', 0, $e);
41
        }
42
    }
43
44 1
    private function mapFields(array $entry): array
45
    {
46
        return [
47 1
            'country_code' => $entry['countryCode'] ?? '',
48 1
            'country_name' => $entry['country'] ?? '',
49 1
            'region_name' => $entry['regionName'] ?? '',
50 1
            'city' => $entry['city'] ?? '',
51 1
            'latitude' => $entry['lat'] ?? '',
52 1
            'longitude' => $entry['lon'] ?? '',
53 1
            'time_zone' => $entry['timezone'] ?? '',
54
        ];
55
    }
56
}
57