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\HostIp; |
14
|
|
|
|
15
|
|
|
use Geocoder\Collection; |
16
|
|
|
use Geocoder\Exception\UnsupportedOperation; |
17
|
|
|
use Geocoder\Http\Provider\AbstractHttpProvider; |
18
|
|
|
use Geocoder\Model\Address; |
19
|
|
|
use Geocoder\Model\AddressCollection; |
20
|
|
|
use Geocoder\Provider\Provider; |
21
|
|
|
use Geocoder\Query\GeocodeQuery; |
22
|
|
|
use Geocoder\Query\ReverseQuery; |
23
|
|
|
|
24
|
|
|
/** |
25
|
|
|
* @author William Durand <[email protected]> |
26
|
|
|
* @author Oleg Andreyev <[email protected]> |
27
|
|
|
*/ |
28
|
|
|
abstract class AbstractHostIp extends AbstractHttpProvider implements Provider |
29
|
|
|
{ |
30
|
|
|
abstract protected function executeQuery(string $url): AddressCollection; |
31
|
|
|
|
32
|
|
|
/** |
33
|
|
|
* {@inheritdoc} |
34
|
|
|
*/ |
35
|
17 |
|
public function geocodeQuery(GeocodeQuery $query): Collection |
36
|
|
|
{ |
37
|
17 |
|
$address = $query->getText(); |
38
|
17 |
|
if (!filter_var($address, FILTER_VALIDATE_IP)) { |
39
|
2 |
|
throw new UnsupportedOperation('The '.get_class($this).' provider does not support Street addresses.'); |
40
|
|
|
} |
41
|
|
|
|
42
|
|
|
// This API does not support IPv6 |
43
|
15 |
|
if (filter_var($address, FILTER_VALIDATE_IP, FILTER_FLAG_IPV6)) { |
44
|
4 |
|
throw new UnsupportedOperation('The HostIp provider does not support IPv6 addresses.'); |
45
|
|
|
} |
46
|
|
|
|
47
|
11 |
|
if ('127.0.0.1' === $address) { |
48
|
2 |
|
return new AddressCollection([$this->getLocationForLocalhost()]); |
49
|
|
|
} |
50
|
|
|
|
51
|
9 |
|
$url = sprintf(static::ENDPOINT_URL, $address); |
52
|
|
|
|
53
|
9 |
|
return $this->executeQuery($url); |
54
|
|
|
} |
55
|
|
|
|
56
|
|
|
/** |
57
|
|
|
* {@inheritdoc} |
58
|
|
|
*/ |
59
|
2 |
|
public function reverseQuery(ReverseQuery $query): Collection |
60
|
|
|
{ |
61
|
2 |
|
throw new UnsupportedOperation('The HostIp provider is not able to do reverse geocoding.'); |
62
|
|
|
} |
63
|
|
|
|
64
|
|
|
/** |
65
|
|
|
* @param array $data |
66
|
|
|
* |
67
|
|
|
* @return bool |
68
|
|
|
*/ |
69
|
4 |
View Code Duplication |
protected function isUnknownLocation(array $data): bool |
|
|
|
|
70
|
|
|
{ |
71
|
4 |
|
return empty($data['lat']) |
72
|
4 |
|
&& empty($data['lng']) |
73
|
4 |
|
&& '(Unknown City?)' === $data['city'] |
74
|
4 |
|
&& '(Unknown Country?)' === $data['country_name'] |
75
|
4 |
|
&& 'XX' === $data; |
76
|
|
|
} |
77
|
|
|
|
78
|
|
|
/** |
79
|
|
|
* @param array $data |
80
|
|
|
* |
81
|
|
|
* @return bool |
82
|
|
|
*/ |
83
|
4 |
View Code Duplication |
protected function isPrivateLocation(array $data): bool |
|
|
|
|
84
|
|
|
{ |
85
|
4 |
|
return empty($data['lat']) |
86
|
4 |
|
&& empty($data['lng']) |
87
|
4 |
|
&& '(Private Address)' === $data['city'] |
88
|
4 |
|
&& '(Private Address)' === $data['country_name'] |
89
|
4 |
|
&& 'XX' === $data; |
90
|
|
|
} |
91
|
|
|
|
92
|
|
|
/** |
93
|
|
|
* @param array $data |
94
|
|
|
* |
95
|
|
|
* @return AddressCollection |
96
|
|
|
*/ |
97
|
4 |
|
protected function prepareAddressCollection(array $data): AddressCollection |
98
|
|
|
{ |
99
|
|
|
// Return empty collection if address was not found |
100
|
4 |
|
if ($this->isUnknownLocation($data)) { |
101
|
|
|
return new AddressCollection([]); |
102
|
|
|
} |
103
|
|
|
|
104
|
|
|
// Return empty collection if address was not found |
105
|
4 |
|
if ($this->isPrivateLocation($data)) { |
106
|
|
|
return new AddressCollection([]); |
107
|
|
|
} |
108
|
|
|
|
109
|
4 |
|
return new AddressCollection([ |
110
|
4 |
|
Address::createFromArray([ |
111
|
4 |
|
'providedBy' => $this->getName(), |
112
|
4 |
|
'latitude' => $data['lat'] ?? null, |
113
|
4 |
|
'longitude' => $data['lng'] ?? null, |
114
|
4 |
|
'locality' => $data['city'], |
115
|
4 |
|
'country' => $data['country_name'], |
116
|
4 |
|
'countryCode' => $data['country_code'], |
117
|
|
|
]), |
118
|
|
|
]); |
119
|
|
|
} |
120
|
|
|
} |
121
|
|
|
|
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.
You can also find more detailed suggestions in the “Code” section of your repository.