1 | <?php |
||
2 | |||
3 | declare(strict_types=1); |
||
4 | |||
5 | /* |
||
6 | * This file is part of the Geocoder package. |
||
7 | * For the full copyright and license information, please view the LICENSE |
||
8 | * file that was distributed with this source code. |
||
9 | * |
||
10 | * @license MIT License |
||
11 | */ |
||
12 | |||
13 | namespace Geocoder\Provider\FreeGeoIp; |
||
14 | |||
15 | use Geocoder\Collection; |
||
16 | use Geocoder\Exception\UnsupportedOperation; |
||
17 | use Geocoder\Http\Provider\AbstractHttpProvider; |
||
18 | use Geocoder\Model\AddressBuilder; |
||
19 | use Geocoder\Model\AddressCollection; |
||
20 | use Geocoder\Provider\Provider; |
||
21 | use Geocoder\Query\GeocodeQuery; |
||
22 | use Geocoder\Query\ReverseQuery; |
||
23 | use Psr\Http\Client\ClientInterface; |
||
24 | use Psr\Http\Message\RequestInterface; |
||
25 | |||
26 | /** |
||
27 | * @author William Durand <[email protected]> |
||
28 | */ |
||
29 | final class FreeGeoIp extends AbstractHttpProvider implements Provider |
||
30 | { |
||
31 | /** |
||
32 | * @var string|null |
||
33 | */ |
||
34 | private $baseUrl; |
||
35 | |||
36 | 27 | public function __construct(ClientInterface $client, string $baseUrl = 'https://freegeoip.app/json/%s') |
|
37 | { |
||
38 | 27 | parent::__construct($client); |
|
39 | |||
40 | 27 | $this->baseUrl = $baseUrl; |
|
41 | } |
||
42 | |||
43 | 25 | public function geocodeQuery(GeocodeQuery $query): Collection |
|
44 | { |
||
45 | 25 | $address = $query->getText(); |
|
46 | |||
47 | 25 | if (!filter_var($address, FILTER_VALIDATE_IP)) { |
|
48 | 1 | throw new UnsupportedOperation('The FreeGeoIp provider does not support street addresses.'); |
|
49 | } |
||
50 | |||
51 | 24 | if (in_array($address, ['127.0.0.1', '::1'])) { |
|
52 | 2 | return new AddressCollection([$this->getLocationForLocalhost()]); |
|
53 | } |
||
54 | |||
55 | 22 | $request = $this->getRequest(sprintf($this->baseUrl, $address)); |
|
56 | |||
57 | 22 | if (null !== $query->getLocale()) { |
|
58 | /** @var RequestInterface $request */ |
||
59 | 5 | $request = $request->withHeader('Accept-Language', $query->getLocale()); |
|
60 | } |
||
61 | |||
62 | 22 | $body = $this->getParsedResponse($request); |
|
63 | 11 | $data = json_decode($body, true); |
|
64 | |||
65 | // Return empty collection if address was not found |
||
66 | 11 | if ('' === $data['region_name'] |
|
67 | 11 | && '' === $data['region_code'] |
|
68 | 11 | && 0 === $data['latitude'] |
|
69 | 11 | && 0 === $data['longitude'] |
|
70 | 11 | && '' === $data['city'] |
|
71 | 11 | && '' === $data['zip_code'] |
|
72 | 11 | && '' === $data['country_name'] |
|
73 | 11 | && '' === $data['country_code'] |
|
74 | 11 | && '' === $data['time_zone']) { |
|
75 | 1 | return new AddressCollection([]); |
|
76 | } |
||
77 | |||
78 | 10 | $builder = new AddressBuilder($this->getName()); |
|
79 | |||
80 | 10 | if (!empty($data['region_name'])) { |
|
81 | 7 | $builder->addAdminLevel(1, $data['region_name'], $data['region_code'] ?? null); |
|
82 | } |
||
83 | |||
84 | 10 | if (0 !== $data['latitude'] || 0 !== $data['longitude']) { |
|
85 | 10 | $builder->setCoordinates($data['latitude'] ?? null, $data['longitude'] ?? null); |
|
86 | } |
||
87 | 10 | $builder->setLocality(empty($data['city']) ? null : $data['city']); |
|
88 | 10 | $builder->setPostalCode(empty($data['zip_code']) ? null : $data['zip_code']); |
|
89 | 10 | $builder->setCountry(empty($data['country_name']) ? null : $data['country_name']); |
|
90 | 10 | $builder->setCountryCode(empty($data['country_code']) ? null : $data['country_code']); |
|
91 | 10 | $builder->setTimezone(empty($data['time_zone']) ? null : $data['time_zone']); |
|
92 | |||
93 | 10 | return new AddressCollection([$builder->build()]); |
|
94 | } |
||
95 | |||
96 | 1 | public function reverseQuery(ReverseQuery $query): Collection |
|
97 | { |
||
98 | 1 | throw new UnsupportedOperation('The FreeGeoIp provider is not able to do reverse geocoding.'); |
|
99 | } |
||
100 | |||
101 | 13 | public function getName(): string |
|
102 | { |
||
103 | 13 | return 'free_geo_ip'; |
|
104 | } |
||
105 | } |
||
106 |