1
|
|
|
<?php namespace Geocoder\Laravel; |
2
|
|
|
|
3
|
|
|
/** |
4
|
|
|
* This file is part of the Geocoder Laravel package. |
5
|
|
|
* For the full copyright and license information, please view the LICENSE |
6
|
|
|
* file that was distributed with this source code. |
7
|
|
|
* |
8
|
|
|
* @author Mike Bronner <[email protected]> |
9
|
|
|
* @license MIT License |
10
|
|
|
*/ |
11
|
|
|
|
12
|
|
|
use Geocoder\Dumper\GeoJson; |
13
|
|
|
use Geocoder\Dumper\Gpx; |
14
|
|
|
use Geocoder\Dumper\Kml; |
15
|
|
|
use Geocoder\Dumper\Wkb; |
16
|
|
|
use Geocoder\Dumper\Wkt; |
17
|
|
|
use Geocoder\Geocoder; |
18
|
|
|
use Geocoder\Query\GeocodeQuery; |
19
|
|
|
use Geocoder\Query\ReverseQuery; |
20
|
|
|
use Geocoder\Laravel\Exceptions\InvalidDumperException; |
21
|
|
|
use Geocoder\ProviderAggregator; |
22
|
|
|
use Illuminate\Support\Collection; |
23
|
|
|
use ReflectionClass; |
24
|
|
|
|
25
|
|
|
/** |
26
|
|
|
* @SuppressWarnings(PHPMD.TooManyPublicMethods) |
27
|
|
|
*/ |
28
|
|
|
class ProviderAndDumperAggregator |
29
|
|
|
{ |
30
|
|
|
protected $aggregator; |
31
|
|
|
protected $limit; |
32
|
|
|
protected $results; |
33
|
|
|
|
34
|
19 |
|
public function __construct(int $limit = null) |
35
|
|
|
{ |
36
|
19 |
|
$this->aggregator = new ProviderAggregator($limit); |
37
|
19 |
|
$this->limit = $limit; |
38
|
19 |
|
$this->results = collect(); |
39
|
19 |
|
} |
40
|
|
|
|
41
|
|
|
/** |
42
|
|
|
* @deprecated Use `get()` instead. |
43
|
|
|
*/ |
44
|
1 |
|
public function all() : array |
45
|
|
|
{ |
46
|
1 |
|
return $this->results->all(); |
47
|
|
|
} |
48
|
|
|
|
49
|
13 |
|
public function get() : Collection |
50
|
|
|
{ |
51
|
13 |
|
return $this->results; |
52
|
|
|
} |
53
|
|
|
|
54
|
2 |
|
public function dump(string $dumper) : Collection |
55
|
|
|
{ |
56
|
2 |
|
$dumperClasses = collect([ |
57
|
2 |
|
'geojson' => GeoJson::class, |
58
|
|
|
'gpx' => Gpx::class, |
59
|
|
|
'kml' => Kml::class, |
60
|
|
|
'wkb' => Wkb::class, |
61
|
|
|
'wkt' => Wkt::class, |
62
|
|
|
]); |
63
|
|
|
|
64
|
2 |
|
if (!$dumperClasses->has($dumper)) { |
65
|
1 |
|
$errorMessage = implode('', [ |
66
|
1 |
|
"The dumper specified ('{$dumper}') is invalid. Valid dumpers ", |
67
|
1 |
|
"are: geojson, gpx, kml, wkb, wkt.", |
68
|
|
|
]); |
69
|
1 |
|
throw new InvalidDumperException($errorMessage); |
70
|
|
|
} |
71
|
|
|
|
72
|
1 |
|
$dumperClass = $dumperClasses->get($dumper); |
73
|
1 |
|
$dumper = new $dumperClass; |
74
|
1 |
|
$results = collect($this->results->all()); |
75
|
|
|
|
76
|
|
|
return $results->map(function ($result) use ($dumper) { |
77
|
1 |
|
return $dumper->dump($result); |
78
|
1 |
|
}); |
79
|
|
|
} |
80
|
|
|
|
81
|
1 |
|
public function geocodeQuery(GeocodeQuery $query) : self |
82
|
|
|
{ |
83
|
1 |
|
$cacheKey = serialize($query); |
84
|
1 |
|
$this->results = app('cache')->remember( |
85
|
1 |
|
"geocoder-{$cacheKey}", |
86
|
1 |
|
config('geocoder.cache-duraction', 0), |
87
|
|
|
function () use ($query) { |
88
|
1 |
|
return collect($this->aggregator->geocodeQuery($query)); |
89
|
1 |
|
} |
90
|
|
|
); |
91
|
|
|
|
92
|
1 |
|
return $this; |
93
|
|
|
} |
94
|
|
|
|
95
|
1 |
|
public function reverseQuery(ReverseQuery $query) : self |
96
|
|
|
{ |
97
|
1 |
|
$cacheKey = serialize($query); |
98
|
1 |
|
$this->results = app('cache')->remember( |
99
|
1 |
|
"geocoder-{$cacheKey}", |
100
|
1 |
|
config('geocoder.cache-duraction', 0), |
101
|
|
|
function () use ($query) { |
102
|
1 |
|
return collect($this->aggregator->reverseQuery($query)); |
103
|
1 |
|
} |
104
|
|
|
); |
105
|
|
|
|
106
|
1 |
|
return $this; |
107
|
|
|
} |
108
|
|
|
|
109
|
1 |
|
public function getName() : string |
110
|
|
|
{ |
111
|
1 |
|
return $this->aggregator->getName(); |
112
|
|
|
} |
113
|
|
|
|
114
|
12 |
View Code Duplication |
public function geocode(string $value) : self |
115
|
|
|
{ |
116
|
12 |
|
$cacheKey = str_slug(strtolower(urlencode($value))); |
117
|
12 |
|
$this->results = app('cache')->remember( |
118
|
12 |
|
"geocoder-{$cacheKey}", |
119
|
12 |
|
config('geocoder.cache-duraction', 0), |
120
|
|
|
function () use ($value) { |
121
|
12 |
|
return collect($this->aggregator->geocode($value)); |
122
|
12 |
|
} |
123
|
|
|
); |
124
|
|
|
|
125
|
12 |
|
return $this; |
126
|
|
|
} |
127
|
|
|
|
128
|
1 |
View Code Duplication |
public function reverse(float $latitude, float $longitude) : self |
129
|
|
|
{ |
130
|
1 |
|
$cacheKey = str_slug(strtolower(urlencode("{$latitude}-{$longitude}"))); |
131
|
1 |
|
$this->results = app('cache')->remember( |
132
|
1 |
|
"geocoder-{$cacheKey}", |
133
|
1 |
|
config('geocoder.cache-duraction', 0), |
134
|
|
|
function () use ($latitude, $longitude) { |
135
|
1 |
|
return collect($this->aggregator->reverse($latitude, $longitude)); |
136
|
1 |
|
} |
137
|
|
|
); |
138
|
|
|
|
139
|
1 |
|
return $this; |
140
|
|
|
} |
141
|
|
|
|
142
|
1 |
|
public function limit(int $limit) : self |
143
|
|
|
{ |
144
|
1 |
|
$this->aggregator = new ProviderAggregator(null, $limit); |
|
|
|
|
145
|
1 |
|
$this->registerProvidersFromConfig(collect(config('geocoder.providers'))); |
146
|
1 |
|
$this->limit = $limit; |
147
|
|
|
|
148
|
1 |
|
return $this; |
149
|
|
|
} |
150
|
|
|
|
151
|
1 |
|
public function getLimit() : int |
152
|
|
|
{ |
153
|
1 |
|
return $this->limit; |
154
|
|
|
} |
155
|
|
|
|
156
|
1 |
|
public function registerProvider($provider) : self |
157
|
|
|
{ |
158
|
1 |
|
$this->aggregator->registerProvider($provider); |
159
|
|
|
|
160
|
1 |
|
return $this; |
161
|
|
|
} |
162
|
|
|
|
163
|
19 |
|
public function registerProviders(array $providers = []) : self |
164
|
|
|
{ |
165
|
19 |
|
$this->aggregator->registerProviders($providers); |
166
|
|
|
|
167
|
19 |
|
return $this; |
168
|
|
|
} |
169
|
|
|
|
170
|
5 |
|
public function using(string $name) : self |
171
|
|
|
{ |
172
|
5 |
|
$this->aggregator = $this->aggregator->using($name); |
173
|
|
|
|
174
|
5 |
|
return $this; |
175
|
|
|
} |
176
|
|
|
|
177
|
1 |
|
public function getProviders() : Collection |
178
|
|
|
{ |
179
|
1 |
|
return collect($this->aggregator->getProviders()); |
180
|
|
|
} |
181
|
|
|
|
182
|
|
|
protected function getProvider() |
183
|
|
|
{ |
184
|
|
|
return $this->aggregator->getProvider(); |
185
|
|
|
} |
186
|
|
|
|
187
|
19 |
|
public function registerProvidersFromConfig(Collection $providers) : self |
188
|
|
|
{ |
189
|
19 |
|
$this->registerProviders($this->getProvidersFromConfiguration($providers)); |
190
|
|
|
|
191
|
19 |
|
return $this; |
192
|
|
|
} |
193
|
|
|
|
194
|
|
|
protected function getProvidersFromConfiguration(Collection $providers) : array |
195
|
|
|
{ |
196
|
19 |
|
$providers = $providers->map(function ($arguments, $provider) { |
197
|
19 |
|
$arguments = $this->getArguments($arguments, $provider); |
198
|
19 |
|
$reflection = new ReflectionClass($provider); |
199
|
|
|
|
200
|
19 |
|
if ($provider === 'Geocoder\Provider\Chain\Chain') { |
201
|
19 |
|
return $reflection->newInstance($arguments); |
202
|
|
|
} |
203
|
|
|
|
204
|
19 |
|
return $reflection->newInstanceArgs($arguments); |
205
|
19 |
|
}); |
206
|
|
|
|
207
|
19 |
|
return $providers->toArray(); |
208
|
|
|
} |
209
|
|
|
|
210
|
19 |
|
protected function getArguments(array $arguments, string $provider) : array |
211
|
|
|
{ |
212
|
19 |
|
if ($provider === 'Geocoder\Provider\Chain\Chain') { |
213
|
19 |
|
return $this->getProvidersFromConfiguration( |
214
|
19 |
|
collect(config('geocoder.providers.Geocoder\Provider\Chain\Chain')) |
215
|
|
|
); |
216
|
|
|
} |
217
|
|
|
|
218
|
19 |
|
$adapter = $this->getAdapterClass($provider); |
219
|
|
|
|
220
|
19 |
|
if ($adapter) { |
221
|
19 |
|
array_unshift($arguments, (new $adapter)); |
222
|
|
|
} |
223
|
|
|
|
224
|
19 |
|
return $arguments; |
225
|
|
|
} |
226
|
|
|
|
227
|
19 |
|
protected function getAdapterClass(string $provider) : string |
228
|
|
|
{ |
229
|
19 |
|
$specificAdapters = collect([ |
230
|
19 |
|
'Geocoder\Provider\GeoIP2' => 'Geocoder\Adapter\GeoIP2Adapter', |
231
|
|
|
'Geocoder\Provider\MaxMindBinary' => null, |
232
|
|
|
]); |
233
|
|
|
|
234
|
19 |
|
if ($specificAdapters->has($provider)) { |
235
|
|
|
return $specificAdapters->get($provider); |
236
|
|
|
} |
237
|
|
|
|
238
|
19 |
|
return config('geocoder.adapter'); |
239
|
|
|
} |
240
|
|
|
} |
241
|
|
|
|
This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue.
If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress.
In this case you can add the
@ignore
PhpDoc annotation to the duplicate definition and it will be ignored.