Completed
Push — AUTOMATED_TESTING ( aecfa5...b401db )
by Gordon
12:37
created

MapAPI::geocoding()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 16
Code Lines 12

Duplication

Lines 0
Ratio 0 %
Metric Value
dl 0
loc 16
rs 9.4286
cc 2
eloc 12
nc 2
nop 1
1
<?php
2
3
/*
4
*
5
* This script is distributed in the hope that it will be useful,
6
* but WITHOUT ANY WARRANTY; without even the implied warranty of
7
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
8
* GNU General public License for more details.
9
*
10
* This copyright notice MUST APPEAR in all copies of the script!
11
*
12
*  @author            CERDAN Yohann <[email protected]>
13
*  @copyright      (c) 2009  CERDAN Yohann, All rights reserved
14
*  @ version         18:13 26/05/2009
15
*/
16
17
class MapAPI extends ViewableData
18
{
19
20
	 /** GoogleMap key **/
21
	protected $googleMapKey = '';
22
23
	/** GoogleMap ID for the HTML DIV  **/
24
	protected $googleMapId = 'googlemapapi';
25
26
	/** GoogleMap  Direction ID for the HTML DIV **/
27
	protected $googleMapDirectionId = 'route';
28
29
	/* Additional CSS classes to use when rendering the map */
30
	protected $set_additional_css_classes = '';
31
32
	/** Width of the gmap **/
33
	protected $width = 800;
34
35
	/** Height of the gmap **/
36
	protected $height = 600;
37
38
	/** Icon width of the gmarker **/
39
	protected $iconWidth = 20;
40
41
	/** Icon height of the gmarker **/
42
	protected $iconHeight = 34;
43
44
	/* array of lines to be drawn on the map */
45
	protected $lines = array();
46
47
	/* kml file to be rendered */
48
	protected $kmlFiles = array();
49
50
	/** Default zoom of the gmap **/
51
	protected $zoom = 9;
52
53
	/** Enable the zoom of the Infowindow **/
54
	protected $enableWindowZoom = false;
55
56
	/** Default zoom of the Infowindow **/
57
	protected $infoWindowZoom = 13;
58
59
	/** Lang of the gmap **/
60
	protected $lang = 'en';
61
62
	/**Center of the gmap **/
63
	protected $center = 'Paris, France';
64
65
	/*
66
	 Additional CSS classes to render as a class attribute for the div of the
67
	 map.  Use this if you want more  fine grained control over your map using
68
	 CSS.  If blank it will be ignored
69
	 */
70
	protected $additional_css_classes = '';
71
72
73
	/* Decided whether or not to show the inline map css style on div creation */
74
	protected $show_inline_map_div_style = true;
75
76
	protected $latLongCenter = null;
77
78
	protected $jsonMapStyles = '[]';
79
80
	protected $delayLoadMapFunction = false;
81
82
	/**
83
	 * Type of the gmap, can be:
84
	 *  'road' (roadmap),
85
	 *  'satellite' (sattelite/aerial photographs)
86
	 *  'hybrid' (hybrid of road and satellite)
87
	 *  'terrain' (terrain)
88
	 *  The JavaScript for the mapping service will convert this into a suitable mapping type
89
	 */
90
91
	protected $mapType = 'road';
92
93
94
	/** Content of the HTML generated **/
95
	protected $content = '';
96
97
	protected $mapService = 'google';
98
99
	/** Add the direction button to the infowindow **/
100
	protected $displayDirectionFields = false;
101
102
	/** Hide the marker by default **/
103
	protected $defaultHideMarker = false;
104
105
	/** Extra content (marker, etc...) **/
106
	protected $contentMarker = '';
107
108
	// a list of markers, markers being associative arrays
109
	protected $markers = array();
110
111
	/** Use clusterer to display a lot of markers on the gmap **/
112
	protected $useClusterer = false;
113
	protected $gridSize = 50;
114
	protected $maxZoom = 17;
115
	protected $clustererLibraryPath = "/mappable/javascript/google/markerclusterer.js";
116
117
	/** Enable automatic center/zoom **/
118
	protected $enableAutomaticCenterZoom = false;
119
120
	/** maximum longitude of all markers **/
121
	protected $maxLng = -1000000;
122
123
	/** minimum longitude of all markers **/
124
	protected $minLng = 1000000;
125
126
	/** max latitude of all markers **/
127
	protected $maxLat = -1000000;
128
129
	/** min latitude of all markers **/
130
	protected $minLat = 1000000;
131
132
	/** map center latitude (horizontal), calculated automatically as markers
133
	are added to the map **/
134
	protected $centerLat = null;
135
136
	/** map center longitude (vertical),  calculated automatically as markers
137
	are added to the map **/
138
	protected $centerLng = null;
139
140
	/** factor by which to fudge the boundaries so that when we zoom encompass,
141
	the markers aren't too close to the edge **/
142
	protected $coordCoef = 0.01;
143
144
	/* set this to true to render button to maximize / minimize a map */
145
	protected $allowFullScreen = null;
146
147
148
	protected static $include_download_javascript = false;
149
150
151
	/**
152
	 * Class constructor
153
	 *
154
	 * @param string  $googleMapKey the googleMapKey
155
	 */
156
157
	public function __construct($googleMapKey = '') {
158
		$this->googleMapKey = $googleMapKey;
159
	}
160
161
	/**
162
	 * Set the key of the gmap
163
	 *
164
	 * @param string  $googleMapKey the googleMapKey
165
	 *
166
	 * @return void
167
	 */
168
169
	public function setKey($googleMapKey) {
170
		$this->googleMapKey = $googleMapKey;
171
		return $this;
172
	}
173
174
	public function setIncludeDownloadJavascript($inclusion) {
175
		self::$include_download_javascript = $inclusion;
176
		return $this;
177
	}
178
179
180
	public function setShowInlineMapDivStyle($new_show_inline_map_div_style) {
181
		$this->show_inline_map_div_style = $new_show_inline_map_div_style;
182
		return $this;
183
	}
184
185
	public function setAdditionalCSSClasses($new_additional_css_classes) {
186
		$this->additional_css_classes = $new_additional_css_classes;
187
		return $this;
188
	}
189
190
191
	public function setMapStyle($newStyles) {
192
		$this->jsonMapStyles = $newStyles;
193
		return $this;
194
	}
195
196
197
198
	public function setDelayLoadMapFunction($newDelay) {
199
		$this->delayLoadMapFunction = $newDelay;
200
		return $this;
201
	}
202
203
	/**
204
	 * Set the useClusterer parameter (optimization to display a lot of marker)
205
	 *
206
	 * @param boolean $useClusterer     use cluster or not
207
	 * @param int     $gridSize         grid size
208
	 * @param int     $maxZoom 			max zoom to cluster at
209
	 *
210
	 * * @return MapAPI This same object, in order to enable chaining of methods
211
	 */
212
213
	public function setClusterer($useClusterer, $gridSize = 50, $maxZoom = 17,
214
		$clustererLibraryPath = '/mappable/javascript/google/markerclusterer.js') {
215
		$this->useClusterer = $useClusterer;
216
		$this->gridSize = $gridSize;
217
		$this->maxZoom = $maxZoom;
218
		$this->clustererLibraryPath = $clustererLibraryPath;
219
		return $this;
220
	}
221
222
	/**
223
	 * Set the ID of the default gmap DIV
224
	 *
225
	 * @param string  $googleMapId the google div ID
226
	 *
227
	 * @return MapAPI This same object, in order to enable chaining of methods
228
	 */
229
230
	public function setDivId($googleMapId) {
231
		$this->googleMapId = $googleMapId;
232
		return $this;
233
	}
234
235
	/**
236
	 * Set the ID of the default gmap direction DIV
237
	 *
238
	 * @param string  $googleMapDirectionId GoogleMap  Direction ID for the HTML DIV
239
	 *
240
	 * @return MapAPI This same object, in order to enable chaining of methods
241
	 */
242
243
	public function setDirectionDivId($googleMapDirectionId) {
244
		$this->googleMapDirectionId = $googleMapDirectionId;
245
		return $this;
246
	}
247
248
	/**
249
	 * Set the size of the gmap.  If these values are not provided
250
	 * then CSS is used instead
251
	 *
252
	 * @param int     $width  GoogleMap  width
253
	 * @param int     $height GoogleMap  height
254
	 *
255
	 * @return MapAPI This same object, in order to enable chaining of methods
256
	 */
257
258
	public function setSize($width, $height) {
259
		$this->width = $width;
260
		$this->height = $height;
261
		return $this;
262
	}
263
264
265
	/**
266
	 * Set the size of the icon markers
267
	 *
268
	 * @param int     $iconWidth  GoogleMap  marker icon width
269
	 * @param int     $iconHeight GoogleMap  marker icon height
270
	 *
271
	 * @return MapAPI This same object, in order to enable chaining of methods
272
	 */
273
274
	public function setIconSize($iconWidth, $iconHeight) {
275
		$this->iconWidth = $iconWidth;
276
		$this->iconHeight = $iconHeight;
277
		return $this;
278
	}
279
280
	/**
281
	 * Set the lang of the gmap
282
	 *
283
	 * @param string  $lang GoogleMap  lang : fr,en,..
284
	 *
285
	 * @return MapAPI This same object, in order to enable chaining of methods
286
	 */
287
288
	public function setLang($lang) {
289
		$this->lang = $lang;
290
		return $this;
291
	}
292
293
	/**
294
	 * Set the zoom of the gmap
295
	 *
296
	 * @param int $zoom GoogleMap zoom.
297
	 *
298
	 * @return MapAPI This same object, in order to enable chaining of methods
299
	 */
300
301
	public function setZoom($zoom) {
302
		$this->zoom = $zoom;
303
		return $this;
304
	}
305
306
	/**
307
	 * Set the zoom of the infowindow
308
	 *
309
	 * @param int 	$infoWindowZoom GoogleMap information window zoom.
310
	 *
311
	 * @return MapAPI This same object, in order to enable chaining of methods
312
	 */
313
314
	public function setInfoWindowZoom($infoWindowZoom) {
315
		$this->infoWindowZoom = $infoWindowZoom;
316
		return $this;
317
	}
318
319
	/**
320
	 * Enable the zoom on the marker when you click on it
321
	 *
322
	 * @param int $enableWindowZoom info window enabled zoom.
323
	 *
324
	 * @return MapAPI This same object, in order to enable chaining of methods
325
	 */
326
327
	public function setEnableWindowZoom($enableWindowZoom) {
328
		$this->enableWindowZoom = $enableWindowZoom;
0 ignored issues
show
Documentation Bug introduced by
The property $enableWindowZoom was declared of type boolean, but $enableWindowZoom is of type integer. Maybe add a type cast?

This check looks for assignments to scalar types that may be of the wrong type.

To ensure the code behaves as expected, it may be a good idea to add an explicit type cast.

$answer = 42;

$correct = false;

$correct = (bool) $answer;
Loading history...
329
		return $this;
330
	}
331
332
	/**
333
	 * Enable theautomatic center/zoom at the gmap load
334
	 *
335
	 * @param int $enableAutomaticCenterZoom enable automatic centre zoom
336
	 *
337
	 * @return MapAPI This same object, in order to enable chaining of methods
338
	 */
339
340
	public function setEnableAutomaticCenterZoom($enableAutomaticCenterZoom) {
341
		$this->enableAutomaticCenterZoom = $enableAutomaticCenterZoom;
0 ignored issues
show
Documentation Bug introduced by
The property $enableAutomaticCenterZoom was declared of type boolean, but $enableAutomaticCenterZoom is of type integer. Maybe add a type cast?

This check looks for assignments to scalar types that may be of the wrong type.

To ensure the code behaves as expected, it may be a good idea to add an explicit type cast.

$answer = 42;

$correct = false;

$correct = (bool) $answer;
Loading history...
342
		return $this;
343
	}
344
345
	/**
346
	 * Set the center of the gmap (an address)
347
	 *
348
	 * @param string  $center GoogleMap  center (an address)
349
	 *
350
	 * @return MapAPI This same object, in order to enable chaining of methods
351
	 */
352
353
	public function setCenter($center) {
354
		$this->center = $center;
355
		return $this;
356
	}
357
358
	/**
359
	 * Set the type of the gmap.  Also takes into account legacy settings
360
	 *
361
	 * FIXME - allow other valid settings in config for map type
362
	 *
363
	 * @param string  $mapType  Can be one of road,satellite,hybrid or terrain. Defaults to road
364
	 *
365
	 * @return MapAPI This same object, in order to enable chaining of methods
366
	 */
367
368
	public function setMapType($mapType) {
369
		$this->mapType = $mapType;
370
371
		// deal with legacy values for backwards compatbility
372
		switch ($mapType) {
373
			case 'google.maps.MapTypeId.SATELLITE':
374
				$this->mapType = "satellite";
375
				break;
376
			case 'google.maps.MapTypeId.G_HYBRID_MAP':
377
				$this->mapType = "hybrid";
378
				break;
379
			case 'google.maps.MapTypeId.G_PHYSICAL_MAP':
380
				$this->mapType = "terrain";
381
				break;
382
			default:
383
				$this->MapType = "road";
0 ignored issues
show
Bug introduced by
The property MapType does not seem to exist. Did you mean mapType?

An attempt at access to an undefined property has been detected. This may either be a typographical error or the property has been renamed but there are still references to its old name.

If you really want to allow access to undefined properties, you can define magic methods to allow access. See the php core documentation on Overloading.

Loading history...
384
				break;
385
		}
386
387
		return $this;
388
	}
389
390
	/*
391
	Set whether or not to allow the full screen tools
392
	@return MapAPI This same object, in order to enable chaining of methods
393
	*/
394
	public function setAllowFullScreen($allowed) {
395
		$this->allowFullScreen = $allowed;
396
		return $this;
397
	}
398
399
	/**
400
	* Set the center of the gmap
401
	*
402
	* @return MapAPI This same object, in order to enable chaining of methods
403
	**/
404
	public function setLatLongCenter($center) {
405
		$this->latLongCenter = $center;
406
		return $this;
407
	}
408
409
	/**
410
	 * Decide whether or not to show direction controls
411
	 *
412
	 * @param boolean $displayDirectionFields display directions or not in the info window
413
	 *
414
	 * @return MapAPI This same object, in order to enable chaining of methods
415
	 */
416
417
	public function setDisplayDirectionFields($displayDirectionFields) {
418
		$this->displayDirectionFields = $displayDirectionFields;
419
		return $this;
420
	}
421
422
	/**
423
	 * Set the defaultHideMarker
424
	 *
425
	 * @param boolean $defaultHideMarker hide all the markers on the map by default
426
	 *
427
	 * @return void
428
	 */
429
430
	public function setDefaultHideMarker($defaultHideMarker) {
431
		$this->defaultHideMarker = $defaultHideMarker;
432
		return $this;
433
	}
434
435
	/**
436
	 * Get the google map content
437
	 *
438
	 * @return string the google map html code
439
	 */
440
441
	public function getGoogleMap() {
442
		return $this->content;
443
	}
444
445
446
	/**
447
	 * Get URL content using cURL.
448
	 *
449
	 * @param string  $url the url
450
	 *
451
	 * @return string the html code
452
	 *
453
	 * @todo add proxy settings
454
	 */
455
456
	public function getContent($url) {
457
		$curl = curl_init();
458
		curl_setopt($curl, CURLOPT_TIMEOUT, 10);
459
		curl_setopt($curl, CURLOPT_CONNECTTIMEOUT, 5);
460
		curl_setopt($curl, CURLOPT_RETURNTRANSFER, TRUE);
461
		curl_setopt($curl, CURLOPT_URL, $url);
462
		$data = curl_exec($curl);
463
		curl_close($curl);
464
		return $data;
465
	}
466
467
	/**
468
	 * Geocoding an address (address -> lat,lng)
469
	 *
470
	 * @param string  $address an address
471
	 *
472
	 * @return array array with precision, lat & lng
473
	 */
474
475
	public function geocoding($address) {
476
		$geocoder = new MappableGoogleGeocoder();
477
		$locations = $geocoder->getLocations($address);
478
		$result = null;
479
		if (!empty($locations)) {
480
			$place = $locations[0];
481
			$location = $place['geometry']['location'];
482
			$result = array(
483
				'lat' => $location['lat'],
484
				'lon' => $location['lng'],
485
				'geocoded' => true
486
			);
487
488
		}
489
		return $result;
490
	}
491
492
	/**
493
	 * Add marker by his coord
494
	 *
495
	 * @param string  $lat      lat
496
	 * @param string  $lng      lngs
497
	 * @param string  $html     html code display in the info window
498
	 * @param string  $category marker category
499
	 * @param string  $icon     an icon url
500
	 *
501
	 * @return void
502
	 */
503
504
	public function addMarkerByCoords($lat, $lng, $html = '', $category = '', $icon = '') {
505
		$m = array(
506
			'latitude' => $lat,
507
			'longitude' => $lng,
508
			'html' => $html,
509
			'category' => $category,
510
			'icon' => $icon
511
		);
512
		array_push($this->markers, $m);
513
		return $this;
514
	}
515
516
517
	/**
518
	 * Add marker by his address
519
	 *
520
	 * @param string  $address  an ddress
521
	 * @param string  $content  html code display in the info window
522
	 * @param string  $category marker category
523
	 * @param string  $icon     an icon url
524
	 *
525
	 * @return void
526
	 */
527
528
	public function addMarkerByAddress($address, $content = '', $category = '', $icon = '') {
529
		$point = $this->geocoding($address);
530
		if ($point !== null) {
531
			$this->addMarkerByCoords($point[2], $point[3], $content, $category, $icon);
532
		}
533
		return $this;
534
	}
535
536
	/**
537
	 * Add marker by an array of coord
538
	 *
539
	 * @param array  $coordtab an array of lat,lng,content
540
	 * @param string  $category marker category
541
	 * @param string  $icon     an icon url
542
	 *
543
	 * @return void
544
	 */
545
546
	public function addArrayMarkerByCoords($coordtab, $category = '', $icon = '') {
547
		foreach ($coordtab as $coord) {
548
			$this->addMarkerByCoords($coord[0], $coord[1], $coord[2], $category, $icon);
549
		}
550
		return $this;
551
	}
552
553
554
	/**
555
	 * Adds a {@link ViewableData} object that implements {@link Mappable}
556
	 * to the map.
557
	 * @param   $infowindowtemplateparams Optional array of extra parameters to pass to the map info window
558
	 *
559
	 * @param ViewableData $obj
560
	 */
561
	public function addMarkerAsObject(ViewableData $obj, $infowindowtemplateparams = null) {
562
		$extensionsImplementMappable = false;
563
		$extensions = Object::get_extensions(get_class($obj));
564
		if (is_array($extensions)) {
565
			foreach ($extensions as $extension) {
566
				$class = new ReflectionClass($extension);
567
				if ($class->implementsInterface('Mappable')) {
568
					$extensionsImplementMappable = true;
569
				}
570
571
			}
572
		}
573
574
		if ($extensionsImplementMappable ||
575
			($obj instanceof Mappable) ||
576
			(Object::has_extension($obj->ClassName, 'MapExtension'))
577
		) {
578
			$cat = $obj->hasMethod('getMappableMapCategory') ? $obj->getMappableMapCategory() : "default";
579
			if ($infowindowtemplateparams !== null) {
580
				foreach ($infowindowtemplateparams as $key => $value) {
581
					$obj->{$key} = $value;
582
				}
583
			}
584
			$this->addMarkerByCoords(
585
				$obj->getMappableLatitude(),
586
				$obj->getMappableLongitude(),
587
				$obj->getMappableMapContent(),
588
				$cat,
589
				$obj->getMappableMapPin()
590
			);
591
		}
592
593
		return $this;
594
	}
595
596
597
	/**
598
	 * Draws a line between two {@link ViewableData} objects
599
	 *
600
	 * @param ViewableData $one   The first point
601
	 * @param ViewableData $two   The second point
602
	 * @param string  $color The hexidecimal color of the line
603
	 */
604
	public function connectPoints(ViewableData $one, ViewableData $two, $color = "#FF3300") {
605
		$this->addLine(
606
			array($one->getMappableLatitude(), $one->getMappableLongitude()),
607
			array($two->getMappableLatitude(), $two->getMappableLongitude()),
608
			$color
609
		);
610
	}
611
612
613
	public function forTemplate() {
614
		$this->generate();
615
		return $this->getGoogleMap();
616
	}
617
618
619
	/**
620
	 * Add marker by an array of address
621
	 *
622
	 * @param array  $coordtab an array of address
623
	 * @param string  $category marker category
624
	 * @param string  $icon     an icon url
625
	 *
626
	 * @return void
627
	 */
628
629
	public function addArrayMarkerByAddress($coordtab, $category = '', $icon = '') {
630
		foreach ($coordtab as $coord) {
631
			$this->addMarkerByAddress($coord[0], $coord[1], $category, $icon);
632
		}
633
		return $this;
634
	}
635
636
	/**
637
	 * Set a direction between 2 addresss and set a text panel
638
	 *
639
	 * @param string  $from    an address
640
	 * @param string  $to      an address
641
	 * @param string  $idpanel id of the div panel
642
	 *
643
	 * @return void
644
	 */
645
646
	public function addDirection($from, $to, $idpanel = '') {
647
		$this->contentMarker .= 'addDirection("'.$from.'","'.$to.'","'.$idpanel.'");';
648
	}
649
650
	/**
651
	 * Parse a KML file and add markers to a category
652
	 *
653
	 * @param string  $url      url of the kml file compatible with gmap and gearth
654
	 *
655
	 * @return void
656
	 */
657
658
	public function addKML($url) {
659
		array_push($this->kmlFiles, $url);
660
		return $this;
661
	}
662
663
664
	/*
665
	Add a line to the map
666
667
	*/
668
	public function addLine($from = array(), $to = array(), $color = "#FF3300") {
669
		$line = array(
670
			'lat1' => $from[0],
671
			'lon1' => $from[1],
672
			'lat2' => $to[0],
673
			'lon2' => $to[1],
674
			'color' => $color
675
		);
676
677
		array_push($this->lines, $line);
678
		return $this;
679
	}
680
681
682
	/*
683
	For php 5.3
684
	*/
685
	private function jsonRemoveUnicodeSequences($struct) {
686
		 return preg_replace("/\\\\u([a-f0-9]{4})/e",
687
		 					"iconv('UCS-4LE','UTF-8',pack('V', hexdec('U$1')))",
688
		 					json_encode($struct));
689
	}
690
691
692
	/**
693
	 * Generate the gmap
694
	 *
695
	 * @return void
696
	 */
697
698
	public function generate() {
699
		// from http://stackoverflow.com/questions/3586401/cant-decode-json-string-in-php
700
		$jsonMarkers = null;
0 ignored issues
show
Unused Code introduced by
$jsonMarkers is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
701
		$linesJson = null;
0 ignored issues
show
Unused Code introduced by
$linesJson is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
702
		$kmlJson = null;
0 ignored issues
show
Unused Code introduced by
$kmlJson is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
703
704
		// prior to PHP version 5.4, one needs to use regex
705
		if (PHP_VERSION_ID < 50400) {
706
			$jsonMarkers = stripslashes($this->jsonRemoveUnicodeSequences($this->markers));
707
			$linesJson = stripslashes($this->jsonRemoveUnicodeSequences($this->lines));
708
			$kmlJson = stripslashes($this->jsonRemoveUnicodeSequences($this->kmlFiles));
709
		} else {
710
			$jsonMarkers = stripslashes(json_encode($this->markers, JSON_UNESCAPED_UNICODE));
711
			$linesJson = stripslashes(json_encode($this->lines, JSON_UNESCAPED_UNICODE));
712
			$kmlJson = stripslashes(json_encode($this->kmlFiles, JSON_UNESCAPED_UNICODE));
713
		}
714
715
		 // Center of the GMap
716
		$geocodeCentre = ($this->latLongCenter) ?
717
							$this->latLongCenter : $this->geocoding($this->center);
718
719
		// coordinates for centre depending on which method used
720
		if (isset($geocodeCentre['geocoded'] )) {
721
			$latlngCentre = array(
722
				'lat' => $geocodeCentre['lat'],
723
				'lng' => $geocodeCentre['lon']
724
			);
725
		} else { // Paris
726
			$latlngCentre = array('lat'=>48.8792, 'lng' => 2.34778);
727
		}
728
729
		$this->LatLngCentreJSON = stripslashes(json_encode($latlngCentre));
0 ignored issues
show
Documentation introduced by
The property LatLngCentreJSON does not exist on object<MapAPI>. Since you implemented __set, maybe consider adding a @property annotation.

Since your code implements the magic setter _set, this function will be called for any write access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

Since the property has write access only, you can use the @property-write annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
730
731
		$lenLng = $this->maxLng - $this->minLng;
732
		$lenLat = $this->maxLat - $this->minLat;
733
		$this->minLng -= $lenLng * $this->coordCoef;
734
		$this->maxLng += $lenLng * $this->coordCoef;
735
		$this->minLat -= $lenLat * $this->coordCoef;
736
		$this->maxLat += $lenLat * $this->coordCoef;
737
738
		// add the css class mappable as a handle onto the map styling
739
		$this->additional_css_classes .= ' mappable';
740
741
		if (!$this->enableAutomaticCenterZoom) {
742
			$this->enableAutomaticCenterZoom = 'false';
0 ignored issues
show
Documentation Bug introduced by
The property $enableAutomaticCenterZoom was declared of type boolean, but 'false' is of type string. Maybe add a type cast?

This check looks for assignments to scalar types that may be of the wrong type.

To ensure the code behaves as expected, it may be a good idea to add an explicit type cast.

$answer = 42;

$correct = false;

$correct = (bool) $answer;
Loading history...
743
		}
744
745
		if (!$this->useClusterer) {
746
			$this->useClusterer = 'false';
0 ignored issues
show
Documentation Bug introduced by
The property $useClusterer was declared of type boolean, but 'false' is of type string. Maybe add a type cast?

This check looks for assignments to scalar types that may be of the wrong type.

To ensure the code behaves as expected, it may be a good idea to add an explicit type cast.

$answer = 42;

$correct = false;

$correct = (bool) $answer;
Loading history...
747
		}
748
749
		if (!$this->defaultHideMarker) {
750
			$this->defaultHideMarker = 'false';
0 ignored issues
show
Documentation Bug introduced by
The property $defaultHideMarker was declared of type boolean, but 'false' is of type string. Maybe add a type cast?

This check looks for assignments to scalar types that may be of the wrong type.

To ensure the code behaves as expected, it may be a good idea to add an explicit type cast.

$answer = 42;

$correct = false;

$correct = (bool) $answer;
Loading history...
751
		}
752
753
		if (!$this->MapTypeId) {
0 ignored issues
show
Bug introduced by
The property MapTypeId does not seem to exist. Did you mean mapType?

An attempt at access to an undefined property has been detected. This may either be a typographical error or the property has been renamed but there are still references to its old name.

If you really want to allow access to undefined properties, you can define magic methods to allow access. See the php core documentation on Overloading.

Loading history...
754
			$this->MapTypeId = 'false';
0 ignored issues
show
Bug introduced by
The property MapTypeId does not seem to exist. Did you mean mapType?

An attempt at access to an undefined property has been detected. This may either be a typographical error or the property has been renamed but there are still references to its old name.

If you really want to allow access to undefined properties, you can define magic methods to allow access. See the php core documentation on Overloading.

Loading history...
755
		}
756
757
		// initialise full screen as the config value if not already set
758
		if ($this->allowFullScreen === null) {
759
			$this->allowFullScreen = Config::inst()->get('Mappable', 'allow_full_screen');
760
		}
761
762
		if (!$this->allowFullScreen) {
763
			$this->allowFullScreen = 'false';
764
		}
765
766
767
768
		$vars = new ArrayData(array(
769
				'JsonMapStyles' => $this->jsonMapStyles,
770
				'AdditionalCssClasses' => $this->additional_css_classes,
771
				'Width' => $this->width,
772
				'Height' => $this->height,
773
				'ShowInlineMapDivStyle' => $this->show_inline_map_div_style,
774
				'InfoWindowZoom' => $this->infoWindowZoom,
775
				'EnableWindowZoom' => $this->enableWindowZoom,
776
				'MapMarkers' => $jsonMarkers,
777
				'DelayLoadMapFunction' => $this->delayLoadMapFunction,
778
				'DefaultHideMarker' => $this->defaultHideMarker,
779
				'LatLngCentre' => $this->LatLngCentreJSON,
0 ignored issues
show
Documentation introduced by
The property LatLngCentreJSON does not exist on object<MapAPI>. Since you implemented __get, maybe consider adding a @property annotation.

Since your code implements the magic getter _get, this function will be called for any read access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

If the property has read access only, you can use the @property-read annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
780
				'EnableAutomaticCenterZoom' => $this->enableAutomaticCenterZoom,
781
				'Zoom' => $this->zoom,
782
				'MaxZoom' => $this->maxZoom,
783
				'GridSize' => $this->gridSize,
784
				'MapType' => $this->mapType,
785
				'GoogleMapID' => $this->googleMapId,
786
				'Lang'=>$this->lang,
787
				'UseClusterer'=>$this->useClusterer,
788
				'DownloadJS' => !(self::$include_download_javascript),
789
				'ClustererLibraryPath' => $this->clustererLibraryPath,
790
				'ClustererMaxZoom' => $this->maxZoom,
791
				'ClustererGridSize' => $this->gridSize,
792
				'Lines' => $linesJson,
793
				'KmlFiles' => $kmlJson,
794
				'AllowFullScreen' => $this->allowFullScreen,
795
				'UseCompressedAssets' => Config::inst()->get('Mappable', 'use_compressed_assets')
796
			)
797
		);
798
799
		// HTML component of the map
800
		$this->content = $this->processTemplateHTML('Map', $vars);
801
	}
802
803
	function processTemplateJS($templateName, $templateVariables = null) {
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
804
		if (!$templateVariables) {
805
			$templateVariables = new ArrayList();
806
		}
807
		$mappingService = Config::inst()->get('Mappable', 'mapping_service');
808
		$result = $templateVariables->renderWith($templateName.$mappingService.'JS');
809
		return $result;
810
	}
811
812
	function processTemplateHTML($templateName, $templateVariables = null) {
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
813
		if (!$templateVariables) {
814
			$templateVariables = new ArrayList();
815
		}
816
		$mappingService = Config::inst()->get('Mappable', 'mapping_service');
817
		$result = $templateVariables->renderWith($templateName.$mappingService.'HTML');
818
		return $result;
819
	}
820
}
821