Completed
Push — AUTOMATED_TESTING ( 4cfed4...8e1a94 )
by Gordon
18:08
created

MapAPI::processTemplateJS()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 8
Code Lines 6

Duplication

Lines 0
Ratio 0 %
Metric Value
dl 0
loc 8
rs 9.4286
cc 2
eloc 6
nc 2
nop 2
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
	/* Additional CSS classes to use when rendering the map */
27
	protected $set_additional_css_classes = '';
28
29
	/** Width of the gmap **/
30
	protected $width = 800;
31
32
	/** Height of the gmap **/
33
	protected $height = 600;
34
35
	/** Icon width of the gmarker **/
36
	protected $iconWidth = 20;
37
38
	/** Icon height of the gmarker **/
39
	protected $iconHeight = 34;
40
41
	/* array of lines to be drawn on the map */
42
	protected $lines = array();
43
44
	/* kml file to be rendered */
45
	protected $kmlFiles = array();
46
47
	/** Default zoom of the gmap **/
48
	protected $zoom = 9;
49
50
	/** Enable the zoom of the Infowindow **/
51
	protected $enableWindowZoom = false;
52
53
	/** Default zoom of the Infowindow **/
54
	protected $infoWindowZoom = 13;
55
56
	/** Lang of the gmap **/
57
	protected $lang = 'en';
58
59
	/**Center of the gmap **/
60
	protected $center = 'Paris, France';
61
62
	/*
63
	 Additional CSS classes to render as a class attribute for the div of the
64
	 map.  Use this if you want more  fine grained control over your map using
65
	 CSS.  If blank it will be ignored
66
	 */
67
	protected $additional_css_classes = '';
68
69
70
	/* Decided whether or not to show the inline map css style on div creation */
71
	protected $show_inline_map_div_style = true;
72
73
	protected $latLongCenter = null;
74
75
	protected $jsonMapStyles = '[]';
76
77
	protected $delayLoadMapFunction = false;
78
79
	/**
80
	 * Type of the gmap, can be:
81
	 *  'road' (roadmap),
82
	 *  'satellite' (sattelite/aerial photographs)
83
	 *  'hybrid' (hybrid of road and satellite)
84
	 *  'terrain' (terrain)
85
	 *  The JavaScript for the mapping service will convert this into a suitable mapping type
86
	 */
87
88
	protected $mapType = 'road';
89
90
91
	/** Content of the HTML generated **/
92
	protected $content = '';
93
94
	protected $mapService = 'google';
95
96
	/** Hide the marker by default **/
97
	protected $defaultHideMarker = false;
98
99
	/** Extra content (marker, etc...) **/
100
	protected $contentMarker = '';
101
102
	// a list of markers, markers being associative arrays
103
	protected $markers = array();
104
105
	/** Use clusterer to display a lot of markers on the gmap **/
106
	protected $useClusterer = false;
107
	protected $gridSize = 50;
108
	protected $maxZoom = 17;
109
	protected $clustererLibraryPath = "/mappable/javascript/google/markerclusterer.js";
110
111
	/** Enable automatic center/zoom **/
112
	protected $enableAutomaticCenterZoom = false;
113
114
	/** maximum longitude of all markers **/
115
	protected $maxLng = -1000000;
116
117
	/** minimum longitude of all markers **/
118
	protected $minLng = 1000000;
119
120
	/** max latitude of all markers **/
121
	protected $maxLat = -1000000;
122
123
	/** min latitude of all markers **/
124
	protected $minLat = 1000000;
125
126
	/** map center latitude (horizontal), calculated automatically as markers
127
	are added to the map **/
128
	protected $centerLat = null;
129
130
	/** map center longitude (vertical),  calculated automatically as markers
131
	are added to the map **/
132
	protected $centerLng = null;
133
134
	/** factor by which to fudge the boundaries so that when we zoom encompass,
135
	the markers aren't too close to the edge **/
136
	protected $coordCoef = 0.01;
137
138
	/* set this to true to render button to maximize / minimize a map */
139
	protected $allowFullScreen = null;
140
141
	/**
142
	 * Class constructor
143
	 *
144
	 * @param string  $googleMapKey the googleMapKey
145
	 */
146
147
	public function __construct($googleMapKey = '') {
148
		$this->googleMapKey = $googleMapKey;
149
	}
150
151
	/**
152
	 * Set the key of the gmap
153
	 *
154
	 * @param string  $googleMapKey the googleMapKey
155
	 *
156
	 * @return void
157
	 */
158
159
	public function setKey($googleMapKey) {
160
		$this->googleMapKey = $googleMapKey;
161
		return $this;
162
	}
163
164
	public function setShowInlineMapDivStyle($new_show_inline_map_div_style) {
165
		$this->show_inline_map_div_style = $new_show_inline_map_div_style;
166
		return $this;
167
	}
168
169
	public function setAdditionalCSSClasses($new_additional_css_classes) {
170
		$this->additional_css_classes = $new_additional_css_classes;
171
		return $this;
172
	}
173
174
175
	public function setMapStyle($newStyles) {
176
		$this->jsonMapStyles = $newStyles;
177
		return $this;
178
	}
179
180
181
182
	public function setDelayLoadMapFunction($newDelay) {
183
		$this->delayLoadMapFunction = $newDelay;
184
		return $this;
185
	}
186
187
	/**
188
	 * Set the useClusterer parameter (optimization to display a lot of marker)
189
	 *
190
	 * @param boolean $useClusterer     use cluster or not
191
	 * @param int     $gridSize         grid size
192
	 * @param int     $maxZoom 			max zoom to cluster at
193
	 *
194
	 * * @return MapAPI This same object, in order to enable chaining of methods
195
	 */
196
197
	public function setClusterer($useClusterer, $gridSize = 50, $maxZoom = 17,
198
		$clustererLibraryPath = '/mappable/javascript/google/markerclusterer.js') {
199
		$this->useClusterer = $useClusterer;
200
		$this->gridSize = $gridSize;
201
		$this->maxZoom = $maxZoom;
202
		$this->clustererLibraryPath = $clustererLibraryPath;
203
		return $this;
204
	}
205
206
	/**
207
	 * Set the ID of the default gmap DIV
208
	 *
209
	 * @param string  $googleMapId the google div ID
210
	 *
211
	 * @return MapAPI This same object, in order to enable chaining of methods
212
	 */
213
214
	public function setDivId($googleMapId) {
215
		$this->googleMapId = $googleMapId;
216
		return $this;
217
	}
218
219
	/**
220
	 * Set the size of the gmap.  If these values are not provided
221
	 * then CSS is used instead
222
	 *
223
	 * @param int     $width  GoogleMap  width
224
	 * @param int     $height GoogleMap  height
225
	 *
226
	 * @return MapAPI This same object, in order to enable chaining of methods
227
	 */
228
229
	public function setSize($width, $height) {
230
		$this->width = $width;
231
		$this->height = $height;
232
		return $this;
233
	}
234
235
236
	/**
237
	 * Set the size of the icon markers
238
	 *
239
	 * @param int     $iconWidth  GoogleMap  marker icon width
240
	 * @param int     $iconHeight GoogleMap  marker icon height
241
	 *
242
	 * @return MapAPI This same object, in order to enable chaining of methods
243
	 */
244
245
	public function setIconSize($iconWidth, $iconHeight) {
246
		$this->iconWidth = $iconWidth;
247
		$this->iconHeight = $iconHeight;
248
		return $this;
249
	}
250
251
	/**
252
	 * Set the lang of the gmap
253
	 *
254
	 * @param string  $lang GoogleMap  lang : fr,en,..
255
	 *
256
	 * @return MapAPI This same object, in order to enable chaining of methods
257
	 */
258
259
	public function setLang($lang) {
260
		$this->lang = $lang;
261
		return $this;
262
	}
263
264
	/**
265
	 * Set the zoom of the gmap
266
	 *
267
	 * @param int $zoom GoogleMap zoom.
268
	 *
269
	 * @return MapAPI This same object, in order to enable chaining of methods
270
	 */
271
272
	public function setZoom($zoom) {
273
		$this->zoom = $zoom;
274
		return $this;
275
	}
276
277
	/**
278
	 * Set the zoom of the infowindow
279
	 *
280
	 * @param int 	$infoWindowZoom GoogleMap information window zoom.
281
	 *
282
	 * @return MapAPI This same object, in order to enable chaining of methods
283
	 */
284
285
	public function setInfoWindowZoom($infoWindowZoom) {
286
		$this->infoWindowZoom = $infoWindowZoom;
287
		return $this;
288
	}
289
290
	/**
291
	 * Enable the zoom on the marker when you click on it
292
	 *
293
	 * @param int $enableWindowZoom info window enabled zoom.
294
	 *
295
	 * @return MapAPI This same object, in order to enable chaining of methods
296
	 */
297
298
	public function setEnableWindowZoom($enableWindowZoom) {
299
		$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...
300
		return $this;
301
	}
302
303
	/**
304
	 * Enable theautomatic center/zoom at the gmap load
305
	 *
306
	 * @param int $enableAutomaticCenterZoom enable automatic centre zoom
307
	 *
308
	 * @return MapAPI This same object, in order to enable chaining of methods
309
	 */
310
311
	public function setEnableAutomaticCenterZoom($enableAutomaticCenterZoom) {
312
		$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...
313
		return $this;
314
	}
315
316
	/**
317
	 * Set the center of the gmap (an address)
318
	 *
319
	 * @param string  $center GoogleMap  center (an address)
320
	 *
321
	 * @return MapAPI This same object, in order to enable chaining of methods
322
	 */
323
324
	public function setCenter($center) {
325
		$this->center = $center;
326
		return $this;
327
	}
328
329
	/**
330
	 * Set the type of the gmap.  Also takes into account legacy settings
331
	 *
332
	 * FIXME - allow other valid settings in config for map type
333
	 *
334
	 * @param string  $mapType  Can be one of road,satellite,hybrid or terrain. Defaults to road
335
	 *
336
	 * @return MapAPI This same object, in order to enable chaining of methods
337
	 */
338
339
	public function setMapType($mapType) {
340
		$this->mapType = $mapType;
341
342
		// deal with legacy values for backwards compatbility
343
		switch ($mapType) {
344
			case 'google.maps.MapTypeId.SATELLITE':
345
				$this->mapType = "satellite";
346
				break;
347
			case 'google.maps.MapTypeId.G_HYBRID_MAP':
348
				$this->mapType = "hybrid";
349
				break;
350
			case 'google.maps.MapTypeId.G_PHYSICAL_MAP':
351
				$this->mapType = "terrain";
352
				break;
353
			default:
354
				$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...
355
				break;
356
		}
357
358
		return $this;
359
	}
360
361
	/*
362
	Set whether or not to allow the full screen tools
363
	@return MapAPI This same object, in order to enable chaining of methods
364
	*/
365
	public function setAllowFullScreen($allowed) {
366
		$this->allowFullScreen = $allowed;
367
		return $this;
368
	}
369
370
	/**
371
	* Set the center of the gmap
372
	*
373
	* @return MapAPI This same object, in order to enable chaining of methods
374
	**/
375
	public function setLatLongCenter($center) {
376
		// error check, we want an associative array with lat,lng keys numeric
377
378
		if (!is_array($center)) {
379
			throw new InvalidArgumentException('Center must be an associative array containing lat,lng');
380
		}
381
382
		$keys = array_keys($center);
383
		sort($keys);
384
		if (implode(',', $keys) != 'lat,lng') {
385
			throw new InvalidArgumentException('Keys provided must be lat, lng');
386
		}
387
388
		$this->latLongCenter = $center;
389
		return $this;
390
	}
391
392
	/**
393
	 * Set the defaultHideMarker
394
	 *
395
	 * @param boolean $defaultHideMarker hide all the markers on the map by default
396
	 *
397
	 * @return void
398
	 */
399
400
	public function setDefaultHideMarker($defaultHideMarker) {
401
		$this->defaultHideMarker = $defaultHideMarker;
402
		return $this;
403
	}
404
405
	/**
406
	 * Get the google map content
407
	 *
408
	 * @return string the google map html code
409
	 */
410
411
	public function getGoogleMap() {
412
		return $this->content;
413
	}
414
415
416
	/**
417
	 * Get URL content using cURL.
418
	 *
419
	 * @param string  $url the url
420
	 *
421
	 * @return string the html code
422
	 *
423
	 * @todo add proxy settings
424
	 */
425
426
	public function getContent($url) {
427
		$curl = curl_init();
428
		curl_setopt($curl, CURLOPT_TIMEOUT, 10);
429
		curl_setopt($curl, CURLOPT_CONNECTTIMEOUT, 5);
430
		curl_setopt($curl, CURLOPT_RETURNTRANSFER, TRUE);
431
		curl_setopt($curl, CURLOPT_URL, $url);
432
		$data = curl_exec($curl);
433
		curl_close($curl);
434
		return $data;
435
	}
436
437
	/**
438
	 * Geocoding an address (address -> lat,lng)
439
	 *
440
	 * @param string  $address an address
441
	 *
442
	 * @return array array with precision, lat & lng
443
	 */
444
445
	public function geocoding($address) {
446
		$geocoder = new MappableGoogleGeocoder();
447
		$locations = $geocoder->getLocations($address);
448
		$result = null;
449
		if (!empty($locations)) {
450
			$place = $locations[0];
451
			$location = $place['geometry']['location'];
452
			$result = array(
453
				'lat' => $location['lat'],
454
				'lon' => $location['lng'],
455
				'geocoded' => true
456
			);
457
458
		}
459
		return $result;
460
	}
461
462
	/**
463
	 * Add marker by his coord
464
	 *
465
	 * @param string  $lat      lat
466
	 * @param string  $lng      lngs
467
	 * @param string  $html     html code display in the info window
468
	 * @param string  $category marker category
469
	 * @param string  $icon     an icon url
470
	 *
471
	 * @return void
472
	 */
473
474
	public function addMarkerByCoords($lat, $lng, $html = '', $category = '', $icon = '') {
475
		$m = array(
476
			'latitude' => $lat,
477
			'longitude' => $lng,
478
			'html' => $html,
479
			'category' => $category,
480
			'icon' => $icon
481
		);
482
		array_push($this->markers, $m);
483
		return $this;
484
	}
485
486
487
	/**
488
	 * Add marker by his address
489
	 *
490
	 * @param string  $address  an ddress
491
	 * @param string  $content  html code display in the info window
492
	 * @param string  $category marker category
493
	 * @param string  $icon     an icon url
494
	 *
495
	 * @return void
496
	 */
497
498
	public function addMarkerByAddress($address, $content = '', $category = '', $icon = '') {
499
		$point = $this->geocoding($address);
500
		if ($point !== null) {
501
			$this->addMarkerByCoords($point[2], $point[3], $content, $category, $icon);
502
		}
503
		return $this;
504
	}
505
506
	/**
507
	 * Add marker by an array of coord
508
	 *
509
	 * @param array  $coordtab an array of lat,lng,content
510
	 * @param string  $category marker category
511
	 * @param string  $icon     an icon url
512
	 *
513
	 * @return void
514
	 */
515
516
	public function addArrayMarkerByCoords($coordtab, $category = '', $icon = '') {
517
		foreach ($coordtab as $coord) {
518
			$this->addMarkerByCoords($coord[0], $coord[1], $coord[2], $category, $icon);
519
		}
520
		return $this;
521
	}
522
523
524
	/**
525
	 * Adds a {@link ViewableData} object that implements {@link Mappable}
526
	 * to the map.
527
	 * @param   $infowindowtemplateparams Optional array of extra parameters to pass to the map info window
528
	 *
529
	 * @param ViewableData $obj
530
	 */
531
	public function addMarkerAsObject(ViewableData $obj, $infowindowtemplateparams = null) {
532
		$extensionsImplementMappable = false;
533
		$extensions = Object::get_extensions(get_class($obj));
534
		if (is_array($extensions)) {
535
			foreach ($extensions as $extension) {
536
				$class = new ReflectionClass($extension);
537
				if ($class->implementsInterface('Mappable')) {
538
					$extensionsImplementMappable = true;
539
				}
540
541
			}
542
		}
543
544
		if ($extensionsImplementMappable ||
545
			($obj instanceof Mappable) ||
546
			(Object::has_extension($obj->ClassName, 'MapExtension'))
547
		) {
548
			$cat = $obj->hasMethod('getMappableMapCategory') ? $obj->getMappableMapCategory() : "default";
549
			if ($infowindowtemplateparams !== null) {
550
				foreach ($infowindowtemplateparams as $key => $value) {
551
					$obj->{$key} = $value;
552
				}
553
			}
554
			$this->addMarkerByCoords(
555
				$obj->getMappableLatitude(),
556
				$obj->getMappableLongitude(),
557
				$obj->getMappableMapContent(),
558
				$cat,
559
				$obj->getMappableMapPin()
560
			);
561
		}
562
563
		return $this;
564
	}
565
566
567
	/**
568
	 * Draws a line between two {@link ViewableData} objects
569
	 *
570
	 * @param ViewableData $one   The first point
571
	 * @param ViewableData $two   The second point
572
	 * @param string  $color The hexidecimal color of the line
573
	 */
574
	public function connectPoints(ViewableData $one, ViewableData $two, $color = "#FF3300") {
575
		$this->addLine(
576
			array($one->getMappableLatitude(), $one->getMappableLongitude()),
577
			array($two->getMappableLatitude(), $two->getMappableLongitude()),
578
			$color
579
		);
580
	}
581
582
583
	public function forTemplate() {
584
		$this->generate();
585
		return $this->getGoogleMap();
586
	}
587
588
589
	/**
590
	 * Add marker by an array of address
591
	 *
592
	 * @param array  $coordtab an array of address
593
	 * @param string  $category marker category
594
	 * @param string  $icon     an icon url
595
	 *
596
	 * @return void
597
	 */
598
599
	public function addArrayMarkerByAddress($coordtab, $category = '', $icon = '') {
600
		foreach ($coordtab as $coord) {
601
			$this->addMarkerByAddress($coord[0], $coord[1], $category, $icon);
602
		}
603
		return $this;
604
	}
605
606
	/**
607
	 * Parse a KML file and add markers to a category
608
	 *
609
	 * @param string  $url      url of the kml file compatible with gmap and gearth
610
	 *
611
	 * @return void
612
	 */
613
614
	public function addKML($url) {
615
		array_push($this->kmlFiles, $url);
616
		return $this;
617
	}
618
619
620
	/*
621
	Add a line to the map
622
623
	*/
624
	public function addLine($from = array(), $to = array(), $color = "#FF3300") {
625
		$line = array(
626
			'lat1' => $from[0],
627
			'lon1' => $from[1],
628
			'lat2' => $to[0],
629
			'lon2' => $to[1],
630
			'color' => $color
631
		);
632
633
		array_push($this->lines, $line);
634
		return $this;
635
	}
636
637
638
	/*
639
	For php 5.3
640
	*/
641
	private function jsonRemoveUnicodeSequences($struct) {
642
		 return preg_replace("/\\\\u([a-f0-9]{4})/e",
643
		 					"iconv('UCS-4LE','UTF-8',pack('V', hexdec('U$1')))",
644
		 					json_encode($struct));
645
	}
646
647
648
	/**
649
	 * Generate the gmap
650
	 *
651
	 * @return void
652
	 */
653
654
	public function generate() {
655
		// from http://stackoverflow.com/questions/3586401/cant-decode-json-string-in-php
656
		$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...
657
		$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...
658
		$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...
659
660
		// prior to PHP version 5.4, one needs to use regex
661
		if (PHP_VERSION_ID < 50400) {
662
			$jsonMarkers = stripslashes($this->jsonRemoveUnicodeSequences($this->markers));
663
			$linesJson = stripslashes($this->jsonRemoveUnicodeSequences($this->lines));
664
			$kmlJson = stripslashes($this->jsonRemoveUnicodeSequences($this->kmlFiles));
665
		} else {
666
			$jsonMarkers = stripslashes(json_encode($this->markers, JSON_UNESCAPED_UNICODE));
667
			$linesJson = stripslashes(json_encode($this->lines, JSON_UNESCAPED_UNICODE));
668
			$kmlJson = stripslashes(json_encode($this->kmlFiles, JSON_UNESCAPED_UNICODE));
669
		}
670
671
		 // Center of the GMap - text centre takes precedence
672
		$geocodeCentre = ($this->latLongCenter) ?
673
							$this->latLongCenter : $this->geocoding($this->center);
674
675
		// coordinates for centre depending on which method used
676
		if (isset($geocodeCentre['geocoded'] )) {
677
			$latlngCentre = array(
678
				'lat' => $geocodeCentre['lat'],
679
				'lng' => $geocodeCentre['lon']
680
			);
681
		} else if (is_array($this->latLongCenter)) {
682
			$latlngCentre = $this->latLongCenter;
683
		} else { // Paris
684
			$latlngCentre = array('lat'=>48.8792, 'lng' => 2.344444778);
685
		}
686
687
		$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...
688
689
		$lenLng = $this->maxLng - $this->minLng;
690
		$lenLat = $this->maxLat - $this->minLat;
691
		$this->minLng -= $lenLng * $this->coordCoef;
692
		$this->maxLng += $lenLng * $this->coordCoef;
693
		$this->minLat -= $lenLat * $this->coordCoef;
694
		$this->maxLat += $lenLat * $this->coordCoef;
695
696
		// add the css class mappable as a handle onto the map styling
697
		$this->additional_css_classes .= ' mappable';
698
699
		if (!$this->enableAutomaticCenterZoom) {
700
			$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...
701
		}
702
703
		if (!$this->useClusterer) {
704
			$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...
705
		}
706
707
		if (!$this->defaultHideMarker) {
708
			$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...
709
		}
710
711
		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...
712
			$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...
713
		}
714
715
		// initialise full screen as the config value if not already set
716
		if ($this->allowFullScreen === null) {
717
			$this->allowFullScreen = Config::inst()->get('Mappable', 'allow_full_screen');
718
		}
719
720
		if (!$this->allowFullScreen) {
721
			$this->allowFullScreen = 'false';
722
		}
723
724
		$vars = new ArrayData(array(
725
				'JsonMapStyles' => $this->jsonMapStyles,
726
				'AdditionalCssClasses' => $this->additional_css_classes,
727
				'Width' => $this->width,
728
				'Height' => $this->height,
729
				'ShowInlineMapDivStyle' => $this->show_inline_map_div_style,
730
				'InfoWindowZoom' => $this->infoWindowZoom,
731
				'EnableWindowZoom' => $this->enableWindowZoom,
732
				'MapMarkers' => $jsonMarkers,
733
				'DelayLoadMapFunction' => $this->delayLoadMapFunction,
734
				'DefaultHideMarker' => $this->defaultHideMarker,
735
				'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...
736
				'EnableAutomaticCenterZoom' => $this->enableAutomaticCenterZoom,
737
				'Zoom' => $this->zoom,
738
				'MaxZoom' => $this->maxZoom,
739
				'GridSize' => $this->gridSize,
740
				'MapType' => $this->mapType,
741
				'GoogleMapID' => $this->googleMapId,
742
				'Lang'=>$this->lang,
743
				'UseClusterer'=>$this->useClusterer,
744
				'ClustererLibraryPath' => $this->clustererLibraryPath,
745
				'ClustererMaxZoom' => $this->maxZoom,
746
				'ClustererGridSize' => $this->gridSize,
747
				'Lines' => $linesJson,
748
				'KmlFiles' => $kmlJson,
749
				'AllowFullScreen' => $this->allowFullScreen,
750
				'UseCompressedAssets' => Config::inst()->get('Mappable', 'use_compressed_assets')
751
			)
752
		);
753
754
		// HTML component of the map
755
		$this->content = $this->processTemplateHTML('Map', $vars);
756
	}
757
758
	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...
759
		if (!$templateVariables) {
760
			$templateVariables = new ArrayList();
761
		}
762
		$mappingService = Config::inst()->get('Mappable', 'mapping_service');
763
		$result = $templateVariables->renderWith($templateName.$mappingService.'HTML');
764
		return $result;
765
	}
766
}
767