IpApi::geolocate()   A
last analyzed

Complexity

Conditions 5
Paths 8

Size

Total Lines 29
Code Lines 17

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 5
eloc 17
c 1
b 0
f 0
nc 8
nop 2
dl 0
loc 29
rs 9.3888
1
<?php
2
3
namespace LeKoala\GeoTools\Services;
4
5
use Exception;
6
use LeKoala\GeoTools\Models\Address;
7
use LeKoala\GeoTools\Models\Country;
8
use LeKoala\GeoTools\Models\Coordinates;
9
10
/**
11
 * @link http://ip-api.com/docs/api:json
12
 */
13
class IpApi implements Geolocator
14
{
15
    const API_URL = 'http://ip-api.com/json/{ip}';
16
17
    /**
18
     * @param string $ip
19
     * @param array<int|string,mixed> $params
20
     * @return Address
21
     * @throws Exception
22
     */
23
    public function geolocate($ip, $params = [])
24
    {
25
        $url = str_replace('{ip}', $ip, self::API_URL);
26
        if (!empty($params)) {
27
            $url .= '?' . http_build_query($params);
28
        }
29
        $result = file_get_contents($url);
30
        if (!$result) {
31
            throw new Exception("The api returned no result");
32
        }
33
34
        $data = json_decode($result, true);
35
36
        if (!$data) {
37
            throw new Exception("Failed to decode api results");
38
        }
39
40
        if ($data['status'] != 'success') {
41
            throw new Exception("Api returned an error");
42
        }
43
44
        $country = new Country($data['countryCode'], $data['country']);
45
        $coordinates = new Coordinates($data['lat'], $data['lon']);
46
47
        $addressData = [
48
            'postalCode' => $data['zip'],
49
            'locality' => $data['city'],
50
        ];
51
        return new Address($addressData, $country, $coordinates);
52
    }
53
}
54