These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more
1 | <?php namespace Cornford\Googlmapper; |
||
2 | |||
3 | use Cornford\Googlmapper\Contracts\MappingInterface; |
||
4 | use Cornford\Googlmapper\Exceptions\MapperArgumentException; |
||
5 | use Cornford\Googlmapper\Exceptions\MapperException; |
||
6 | use Cornford\Googlmapper\Exceptions\MapperSearchException; |
||
7 | use Cornford\Googlmapper\Exceptions\MapperSearchKeyException; |
||
8 | use Cornford\Googlmapper\Exceptions\MapperSearchLimitException; |
||
9 | use Cornford\Googlmapper\Exceptions\MapperSearchResponseException; |
||
10 | use Cornford\Googlmapper\Exceptions\MapperSearchResultException; |
||
11 | use Cornford\Googlmapper\Models\Location; |
||
12 | use Cornford\Googlmapper\Models\Map; |
||
13 | use Cornford\Googlmapper\Models\Streetview; |
||
14 | use Exception; |
||
15 | |||
16 | class Mapper extends MapperBase implements MappingInterface { |
||
17 | |||
18 | const GOOGLE_RESPONSE_OK = 'OK'; |
||
19 | const GOOGLE_RESPONSE_ZERO_RESULTS = 'ZERO_RESULTS'; |
||
20 | const GOOGLE_RESPONSE_QUERY_LIMIT = 'OVER_QUERY_LIMIT'; |
||
21 | const GOOGLE_RESPONSE_DENIED = 'REQUEST_DENIED'; |
||
22 | const GOOGLE_RESPONSE_INVALID = 'INVALID_REQUEST'; |
||
23 | const GOOGLE_RESPONSE_UNKNOWN = 'UNKNOWN_ERROR'; |
||
24 | |||
25 | /** |
||
26 | * Renders and returns Google Map code. |
||
27 | * |
||
28 | * @param integer $item |
||
29 | * |
||
30 | * @return string |
||
31 | */ |
||
32 | public function render($item = -1) |
||
33 | { |
||
34 | if (!$this->isEnabled()) { |
||
35 | return; |
||
36 | } |
||
37 | |||
38 | return $this->view->make('googlmapper::mapper') |
||
39 | ->withView($this->view) |
||
40 | ->withOptions($this->generateRenderOptions($item)) |
||
41 | ->withItems($item > -1 ? [$item => $this->getItem($item)] : $this->getItems()) |
||
42 | ->render(); |
||
43 | } |
||
44 | |||
45 | /** |
||
46 | * Renders and returns Google Map javascript code. |
||
47 | * |
||
48 | * @return string |
||
49 | */ |
||
50 | public function renderJavascript() |
||
51 | { |
||
52 | if (!$this->isEnabled()) { |
||
53 | return; |
||
54 | } |
||
55 | |||
56 | return $this->view->make('googlmapper::javascript') |
||
57 | ->withView($this->view) |
||
58 | ->withOptions($this->generateRenderOptions()) |
||
59 | ->render(); |
||
60 | } |
||
61 | |||
62 | /** |
||
63 | * Generates the render options for Google Map. |
||
64 | * |
||
65 | * @param integer $item |
||
66 | * |
||
67 | * @return string |
||
68 | */ |
||
69 | protected function generateRenderOptions($item = -1) |
||
70 | { |
||
71 | $options = $this->getOptions(); |
||
72 | |||
73 | foreach (($item > -1 ? [$this->getItem($item)] : $this->getItems()) as $model) { |
||
74 | foreach ($model->getOptions() as $key => $option) { |
||
75 | if (array_key_exists($key, $this->getOptions()) && $this->getOptions()[$key] !== $option) { |
||
76 | $options[$key] = $option; |
||
77 | } |
||
78 | } |
||
79 | } |
||
80 | |||
81 | return $options; |
||
82 | } |
||
83 | |||
84 | /** |
||
85 | * Search for a location against Google Maps Api. |
||
86 | * |
||
87 | * @param string $location |
||
88 | * |
||
89 | * @return mixed |
||
90 | */ |
||
91 | protected function searchLocation($location) |
||
92 | { |
||
93 | $request = file_get_contents( |
||
94 | sprintf( |
||
95 | 'https://maps.googleapis.com/maps/api/geocode/json?address=%s&sensor=false&key=%s', |
||
96 | urlencode($location), |
||
97 | $this->getKey() |
||
98 | ) |
||
99 | ); |
||
100 | |||
101 | return json_decode($request); |
||
102 | } |
||
103 | |||
104 | /** |
||
105 | * Locate a location and return a Location instance. |
||
106 | * |
||
107 | * @param string $location |
||
108 | * |
||
109 | * @throws MapperArgumentException |
||
110 | * @throws MapperSearchException |
||
111 | * @throws MapperSearchResponseException |
||
112 | * @throws MapperSearchResultException |
||
113 | * @throws MapperSearchKeyException |
||
114 | * @throws MapperSearchLimitException |
||
115 | * @throws MapperException |
||
116 | * |
||
117 | * @return Location |
||
118 | */ |
||
119 | public function location($location) |
||
120 | { |
||
121 | if (empty($location)) { |
||
122 | throw new MapperArgumentException('Invalid location search term provided.'); |
||
123 | } |
||
124 | |||
125 | try { |
||
126 | $resultObject = $this->searchLocation($location); |
||
127 | } catch (Exception $exception) { |
||
128 | throw new MapperSearchException('Unable to perform location search, the error was: "' . $exception->getMessage() . '".'); |
||
129 | } |
||
130 | |||
131 | if (isset($resultObject->status) && |
||
132 | $resultObject->status == self::GOOGLE_RESPONSE_DENIED && |
||
133 | property_exists($resultObject, 'error_message') && |
||
134 | $resultObject->error_message == 'The provided API key is invalid.' |
||
135 | ) { |
||
136 | throw new MapperSearchKeyException('Unable to perform location search, provided API key is invalid.'); |
||
137 | } |
||
138 | |||
139 | if (isset($resultObject->status) && $resultObject->status == self::GOOGLE_RESPONSE_QUERY_LIMIT) { |
||
140 | throw new MapperSearchLimitException('Unable to perform location search, your API key is over your quota.'); |
||
141 | } |
||
142 | |||
143 | if (isset($resultObject->status) && |
||
144 | in_array( |
||
145 | $resultObject->status, |
||
146 | [ |
||
147 | self::GOOGLE_RESPONSE_DENIED, |
||
148 | self::GOOGLE_RESPONSE_INVALID, |
||
149 | self::GOOGLE_RESPONSE_UNKNOWN |
||
150 | ] |
||
151 | ) |
||
152 | ) { |
||
153 | throw new MapperSearchResponseException('An error occurred performing the location search, the error was: "' . (property_exists($resultObject, 'error_message') ? $resultObject->error_message : 'Unknown') . '".'); |
||
154 | } |
||
155 | |||
156 | if ((isset($resultObject->status) && $resultObject->status == self::GOOGLE_RESPONSE_ZERO_RESULTS) || |
||
157 | !isset($resultObject->results) || |
||
158 | (isset($resultObject->results) && count($resultObject->results) == 0) |
||
159 | ) { |
||
160 | throw new MapperSearchResultException('No results found for the location search.'); |
||
161 | } |
||
162 | |||
163 | if (!isset($resultObject->results[0]->formatted_address) || |
||
164 | !isset($resultObject->results[0]->address_components[0]->types[0]) || |
||
165 | !isset($resultObject->results[0]->geometry->location->lat) || |
||
166 | !isset($resultObject->results[0]->geometry->location->lng) || |
||
167 | !isset($resultObject->results[0]->place_id) || |
||
168 | isset($resultObject->status) && $resultObject->status != self::GOOGLE_RESPONSE_OK |
||
169 | ) { |
||
170 | throw new MapperException('The location search return invalid result data.'); |
||
171 | } |
||
172 | |||
173 | return new Location([ |
||
174 | 'mapper' => $this, |
||
175 | 'search' => $location, |
||
176 | 'address' => $resultObject->results[0]->formatted_address, |
||
177 | 'type' => $resultObject->results[0]->address_components[0]->types[0], |
||
178 | 'latitude' => $resultObject->results[0]->geometry->location->lat, |
||
179 | 'longitude' => $resultObject->results[0]->geometry->location->lng, |
||
180 | 'placeId' => $resultObject->results[0]->place_id, |
||
181 | ]); |
||
182 | } |
||
183 | |||
184 | /** |
||
185 | * Add a new map. |
||
186 | * |
||
187 | * @param float $latitude |
||
188 | * @param float $longitude |
||
189 | * @param array $options |
||
190 | * |
||
191 | * @return self |
||
192 | */ |
||
193 | public function map($latitude, $longitude, array $options = []) |
||
194 | { |
||
195 | $parameters = array_replace_recursive( |
||
196 | $this->getOptions(), |
||
197 | [ |
||
198 | 'latitude' => $latitude, |
||
199 | 'longitude' => $longitude, |
||
200 | 'map' => 'map_' . count($this->getItems()) |
||
201 | ], |
||
202 | $options |
||
203 | ); |
||
204 | |||
205 | $item = new Map($parameters); |
||
206 | $this->addItem($item); |
||
207 | |||
208 | return $this; |
||
209 | } |
||
210 | |||
211 | /** |
||
212 | * Add a new street view map. |
||
213 | * |
||
214 | * @param float $latitude |
||
215 | * @param float $longitude |
||
216 | * @param integer $heading |
||
217 | * @param integer $pitch |
||
218 | * @param array $options |
||
219 | * |
||
220 | * @return self |
||
221 | */ |
||
222 | public function streetview($latitude, $longitude, $heading, $pitch, array $options = []) |
||
223 | { |
||
224 | $parameters = array_replace_recursive( |
||
225 | $this->getOptions(), |
||
226 | [ |
||
227 | 'latitude' => $latitude, |
||
228 | 'longitude' => $longitude, |
||
229 | 'heading' => $heading, |
||
230 | 'pitch' => $pitch, |
||
231 | 'map' => 'map_' . count($this->getItems()) |
||
232 | ], |
||
233 | $options |
||
234 | ); |
||
235 | |||
236 | $item = new Streetview($parameters); |
||
237 | $this->addItem($item); |
||
238 | |||
239 | return $this; |
||
240 | } |
||
241 | |||
242 | /** |
||
243 | * Add a new map marker. |
||
244 | * |
||
245 | * @param float $latitude |
||
246 | * @param float $longitude |
||
247 | * @param array $options |
||
248 | * |
||
249 | * @throws MapperException |
||
250 | * |
||
251 | * @return self |
||
252 | */ |
||
253 | public function marker($latitude, $longitude, array $options = []) |
||
254 | { |
||
255 | $items = $this->getItems(); |
||
256 | |||
257 | if (empty($items)) { |
||
258 | throw new MapperException('No map found to add a marker to.'); |
||
259 | } |
||
260 | |||
261 | $item = end($items); |
||
262 | $parameters = $this->getOptions(); |
||
263 | $options = array_replace_recursive( |
||
264 | ['user' => $parameters['user']], |
||
265 | ['markers' => $parameters['markers']], |
||
266 | $item->getOptions()['markers'], |
||
267 | $options |
||
268 | ); |
||
269 | |||
270 | $item->marker($latitude, $longitude, $options); |
||
271 | |||
272 | return $this; |
||
273 | } |
||
274 | |||
275 | /** |
||
276 | * Add a new map information window. |
||
277 | * |
||
278 | * @param float $latitude |
||
279 | * @param float $longitude |
||
280 | * @param string $content |
||
281 | * @param array $options |
||
282 | * |
||
283 | * @throws MapperException |
||
284 | * |
||
285 | * @return self |
||
286 | */ |
||
287 | public function informationWindow($latitude, $longitude, $content, array $options = []) |
||
288 | { |
||
289 | $items = $this->getItems(); |
||
290 | |||
291 | if (empty($items)) { |
||
292 | throw new MapperException('No map found to add a information window to.'); |
||
293 | } |
||
294 | |||
295 | $item = end($items); |
||
296 | $parameters = $this->getOptions(); |
||
297 | $options = array_replace_recursive( |
||
298 | ['user' => $parameters['user']], |
||
299 | ['markers' => $parameters['markers']], |
||
300 | $item->getOptions()['markers'], |
||
301 | $options |
||
302 | ); |
||
303 | |||
304 | $item->marker($latitude, $longitude, array_replace_recursive($options, ['markers' => ['content' => $content]])); |
||
305 | |||
306 | return $this; |
||
307 | } |
||
308 | |||
309 | /** |
||
310 | * Add a new map polyline. |
||
311 | * |
||
312 | * @param array $coordinates |
||
313 | * @param array $options |
||
314 | * |
||
315 | * @throws MapperException |
||
316 | * |
||
317 | * @return self |
||
318 | */ |
||
319 | public function polyline(array $coordinates = [], array $options = []) |
||
320 | { |
||
321 | $items = $this->getItems(); |
||
322 | |||
323 | if (empty($items)) { |
||
324 | throw new MapperException('No map found to add a polyline to.'); |
||
325 | } |
||
326 | |||
327 | $defaults = [ |
||
328 | 'coordinates' => $coordinates, |
||
329 | 'geodesic' => false, |
||
330 | 'strokeColor' => '#FF0000', |
||
331 | 'strokeOpacity' => 0.8, |
||
332 | 'strokeWeight' => 2, |
||
333 | 'editable' => false |
||
334 | ]; |
||
335 | |||
336 | $item = end($items); |
||
337 | $parameters = $this->getOptions(); |
||
338 | $options = array_replace_recursive( |
||
339 | ['user' => $parameters['user']], |
||
340 | $defaults, |
||
341 | ['user' => $item->getOptions()['user']], |
||
342 | $options |
||
343 | ); |
||
344 | |||
345 | $item->shape('polyline', $coordinates, $options); |
||
346 | |||
347 | return $this; |
||
348 | } |
||
349 | |||
350 | /** |
||
351 | * Add a new map polygon. |
||
352 | * |
||
353 | * @param array $coordinates |
||
354 | * @param array $options |
||
355 | * |
||
356 | * @throws MapperException |
||
357 | * |
||
358 | * @return self |
||
359 | */ |
||
360 | View Code Duplication | public function polygon(array $coordinates = [], array $options = []) |
|
0 ignored issues
–
show
|
|||
361 | { |
||
362 | $items = $this->getItems(); |
||
363 | |||
364 | if (empty($items)) { |
||
365 | throw new MapperException('No map found to add a polygon to.'); |
||
366 | } |
||
367 | |||
368 | $defaults = [ |
||
369 | 'coordinates' => $coordinates, |
||
370 | 'strokeColor' => '#FF0000', |
||
371 | 'strokeOpacity' => 0.8, |
||
372 | 'strokeWeight' => 2, |
||
373 | 'fillColor' => '#FF0000', |
||
374 | 'fillOpacity' => 0.35, |
||
375 | 'editable' => false |
||
376 | ]; |
||
377 | |||
378 | $item = end($items); |
||
379 | $parameters = $this->getOptions(); |
||
380 | $options = array_replace_recursive( |
||
381 | ['user' => $parameters['user']], |
||
382 | $defaults, |
||
383 | ['user' => $item->getOptions()['user']], |
||
384 | $options |
||
385 | ); |
||
386 | |||
387 | $item->shape('polygon', $coordinates, $options); |
||
388 | |||
389 | return $this; |
||
390 | } |
||
391 | |||
392 | /** |
||
393 | * Add a new map rectangle. |
||
394 | * |
||
395 | * @param array $coordinates |
||
396 | * @param array $options |
||
397 | * |
||
398 | * @throws MapperException |
||
399 | * |
||
400 | * @return self |
||
401 | */ |
||
402 | View Code Duplication | public function rectangle(array $coordinates = [], array $options = []) |
|
0 ignored issues
–
show
This method seems to be duplicated in your project.
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.
Loading history...
|
|||
403 | { |
||
404 | $items = $this->getItems(); |
||
405 | |||
406 | if (empty($items)) { |
||
407 | throw new MapperException('No map found to add a rectangle to.'); |
||
408 | } |
||
409 | |||
410 | $defaults = [ |
||
411 | 'coordinates' => $coordinates, |
||
412 | 'strokeColor' => '#FF0000', |
||
413 | 'strokeOpacity' => 0.8, |
||
414 | 'strokeWeight' => 2, |
||
415 | 'fillColor' => '#FF0000', |
||
416 | 'fillOpacity' => 0.35, |
||
417 | 'editable' => false |
||
418 | ]; |
||
419 | |||
420 | $item = end($items); |
||
421 | $parameters = $this->getOptions(); |
||
422 | $options = array_replace_recursive( |
||
423 | ['user' => $parameters['user']], |
||
424 | $defaults, |
||
425 | ['user' => $item->getOptions()['user']], |
||
426 | $options |
||
427 | ); |
||
428 | |||
429 | $item->shape('rectangle', $coordinates, $options); |
||
430 | |||
431 | return $this; |
||
432 | } |
||
433 | |||
434 | /** |
||
435 | * Add a new map circle. |
||
436 | * |
||
437 | * @param array $coordinates |
||
438 | * @param array $options |
||
439 | * |
||
440 | * @throws MapperException |
||
441 | * |
||
442 | * @return self |
||
443 | */ |
||
444 | View Code Duplication | public function circle(array $coordinates = [], array $options = []) |
|
0 ignored issues
–
show
This method seems to be duplicated in your project.
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.
Loading history...
|
|||
445 | { |
||
446 | $items = $this->getItems(); |
||
447 | |||
448 | if (empty($items)) { |
||
449 | throw new MapperException('No map found to add a circle to.'); |
||
450 | } |
||
451 | |||
452 | $defaults = [ |
||
453 | 'coordinates' => $coordinates, |
||
454 | 'strokeColor' => '#FF0000', |
||
455 | 'strokeOpacity' => 0.8, |
||
456 | 'strokeWeight' => 2, |
||
457 | 'fillColor' => '#FF0000', |
||
458 | 'fillOpacity' => 0.35, |
||
459 | 'radius' => 100000, |
||
460 | 'editable' => false |
||
461 | ]; |
||
462 | |||
463 | $item = end($items); |
||
464 | $parameters = $this->getOptions(); |
||
465 | $options = array_replace_recursive( |
||
466 | ['user' => $parameters['user']], |
||
467 | $defaults, |
||
468 | ['user' => $item->getOptions()['user']], |
||
469 | $options |
||
470 | ); |
||
471 | |||
472 | $item->shape('circle', $coordinates, $options); |
||
473 | |||
474 | return $this; |
||
475 | } |
||
476 | |||
477 | } |
||
478 |
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.