GoogleMapsService   A
last analyzed

Complexity

Total Complexity 24

Size/Duplication

Total Lines 353
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 4

Test Coverage

Coverage 97.92%

Importance

Changes 0
Metric Value
wmc 24
lcom 1
cbo 4
dl 0
loc 353
ccs 141
cts 144
cp 0.9792
rs 10
c 0
b 0
f 0

13 Methods

Rating   Name   Duplication   Size   Complexity  
A getMappedLanguageCode() 0 13 2
A getName() 0 3 1
A getAliases() 0 3 1
B getParameterInfo() 0 212 2
A getTypeNames() 0 3 1
A newMapId() 0 7 1
A getResourceModules() 0 3 1
A getApiScript() 0 16 3
A getDependencyHtml() 0 13 3
A getDependencies() 0 8 2
A getParameterWithValue() 0 9 1
A newMapDataFromProcessingResult() 0 17 5
A newMapDataFromParameters() 0 3 1
1
<?php
2
3
declare( strict_types = 1 );
4
5
namespace Maps;
6
7
use Html;
8
use Maps\Map\MapData;
9
use ParamProcessor\ProcessedParam;
10
use ParamProcessor\ProcessingResult;
11
12
/**
13
 * @licence GNU GPL v2+
14
 * @author Jeroen De Dauw < [email protected] >
15
 * @author Peter Grassberger < [email protected] >
16
 */
17
class GoogleMapsService implements MappingService {
18
19
	/**
20
	 * Maps user input map types to the Google Maps names for the map types.
21
	 */
22
	private const MAP_TYPES = [
23
		'normal' => 'ROADMAP',
24
		'roadmap' => 'ROADMAP',
25
		'satellite' => 'SATELLITE',
26
		'hybrid' => 'HYBRID',
27
		'terrain' => 'TERRAIN',
28
		'physical' => 'TERRAIN'
29
	];
30
31
	private const TYPE_CONTROL_STYLES = [
32
		'default' => 'DEFAULT',
33
		'horizontal' => 'HORIZONTAL_BAR',
34
		'dropdown' => 'DROPDOWN_MENU'
35
	];
36
37
	private $addedDependencies = [];
38
39
	public function getName(): string {
40 27
		return 'googlemaps3';
41 27
	}
42
43
	public function getAliases(): array {
44 27
		return [ 'googlemaps', 'google' ];
45 27
	}
46
47
	public function getParameterInfo(): array {
48 8
		global $egMapsGMaps3Type, $egMapsGMaps3Types, $egMapsGMaps3Controls, $egMapsGMaps3Layers;
49 8
		global $egMapsGMaps3DefTypeStyle, $egMapsGMaps3DefZoomStyle, $egMapsGMaps3AutoInfoWindows;
50 8
		global $egMapsResizableByDefault;
51 8
52
		$params = MapsFunctions::getCommonParameters();
53 8
54
		$params['visitedicon'] = [
55 8
			'default' => '',
56
			'message' => 'maps-displaymap-par-visitedicon',
57
		];
58
59
		$params['wmsoverlay'] = [
60 8
			'type' => 'wmsoverlay',
61
			'default' => false,
62
			'delimiter' => ' ',
63
			'message' => 'maps-displaymap-par-wmsoverlay',
64
		];
65
66
		$params['zoom'] = [
67 8
			'type' => 'integer',
68 8
			'range' => [ 0, 20 ],
69
			'default' => $GLOBALS['egMapsGMaps3Zoom'],
70 8
			'message' => 'maps-par-zoom',
71 8
		];
72
73
		$params['type'] = [
74 8
			'default' => $egMapsGMaps3Type,
75 8
			'values' => self::getTypeNames(),
76 8
			'message' => 'maps-googlemaps3-par-type',
77 8
			'post-format' => function ( $value ) {
78 8
				return GoogleMapsService::MAP_TYPES[strtolower( $value )];
79 8
			},
80 8
		];
81
82
		$params['types'] = [
83 8
			'dependencies' => 'type',
84 8
			'default' => $egMapsGMaps3Types,
85 8
			'values' => self::getTypeNames(),
86 8
			'message' => 'maps-googlemaps3-par-types',
87 8
			'islist' => true,
88
			'post-format' => function ( array $value ) {
89 8
				foreach ( $value as &$part ) {
90 8
					$part = self::MAP_TYPES[strtolower( $part )];
91 8
				}
92
93
				return $value;
94 8
			},
95 8
		];
96
97
		$params['layers'] = [
98 8
			'default' => $egMapsGMaps3Layers,
99 8
			'values' => [
100
				'traffic',
101
				'bicycling',
102
				'transit'
103
			],
104
			'message' => 'maps-googlemaps3-par-layers',
105 8
			'islist' => true,
106
		];
107
108
		$params['controls'] = [
109 8
			'default' => $egMapsGMaps3Controls,
110 8
			'values' => [
111
				'pan',
112
				'zoom',
113
				'type',
114
				'scale',
115
				'streetview',
116
				'rotate'
117
			],
118
			'message' => 'maps-googlemaps3-par-controls',
119 8
			'islist' => true,
120
			'post-format' => function ( $value ) {
121 8
				return array_map( 'strtolower', $value );
122 8
			},
123 8
		];
124
125
		$params['zoomstyle'] = [
126 8
			'default' => $egMapsGMaps3DefZoomStyle,
127 8
			'values' => [ 'default', 'small', 'large' ],
128
			'message' => 'maps-googlemaps3-par-zoomstyle',
129 8
			'post-format' => 'strtoupper',
130 8
		];
131
132
		$params['typestyle'] = [
133 8
			'default' => $egMapsGMaps3DefTypeStyle,
134 8
			'values' => array_keys( self::TYPE_CONTROL_STYLES ),
135 8
			'message' => 'maps-googlemaps3-par-typestyle',
136 8
			'post-format' => function ( $value ) {
137 8
				return self::TYPE_CONTROL_STYLES[strtolower( $value )];
138 8
			},
139 8
		];
140
141
		$params['autoinfowindows'] = [
142 8
			'type' => 'boolean',
143 8
			'default' => $egMapsGMaps3AutoInfoWindows,
144 8
			'message' => 'maps-googlemaps3-par-autoinfowindows',
145 8
		];
146
147
		$params['resizable'] = [
148 8
			'type' => 'boolean',
149 8
			'default' => $egMapsResizableByDefault,
150 8
			'message' => 'maps-par-resizable',
151 8
		];
152
153
		$params['kmlrezoom'] = [
154 8
			'type' => 'boolean',
155 8
			'default' => $GLOBALS['egMapsRezoomForKML'],
156 8
			'message' => 'maps-googlemaps3-par-kmlrezoom',
157 8
		];
158
159
		$params['poi'] = [
160 8
			'type' => 'boolean',
161 8
			'default' => $GLOBALS['egMapsShowPOI'],
162 8
			'message' => 'maps-googlemaps3-par-poi',
163 8
		];
164
165
		$params['cluster'] = [
166 8
			'aliases' => [ 'markercluster' ],
167
			'type' => 'boolean',
168
			'default' => false,
169
			'message' => 'maps-par-markercluster',
170
		];
171
172
		$params['clustergridsize'] = [
173 8
			'type' => 'integer',
174
			'default' => 60,
175
			'message' => 'maps-googlemaps3-par-clustergridsize',
176
		];
177
178
		$params['clustermaxzoom'] = [
179 8
			'type' => 'integer',
180
			'default' => 20,
181
			'message' => 'maps-par-clustermaxzoom',
182
		];
183
184
		$params['clusterzoomonclick'] = [
185 8
			'type' => 'boolean',
186
			'default' => true,
187
			'message' => 'maps-par-clusterzoomonclick',
188
		];
189
190
		$params['clusteraveragecenter'] = [
191 8
			'type' => 'boolean',
192
			'default' => true,
193
			'message' => 'maps-googlemaps3-par-clusteraveragecenter',
194
		];
195
196
		$params['clusterminsize'] = [
197 8
			'type' => 'integer',
198
			'default' => 2,
199
			'message' => 'maps-googlemaps3-par-clusterminsize',
200
		];
201
202
		$params['imageoverlays'] = [
203 8
			'type' => 'mapsimageoverlay',
204
			'default' => [],
205
			'delimiter' => ';',
206
			'islist' => true,
207
			'message' => 'maps-googlemaps3-par-imageoverlays',
208
		];
209
210
		$params['kml'] = [
211 8
			'default' => [],
212 8
			'message' => 'maps-par-kml',
213 8
			'islist' => true,
214
			'post-format' => function( array $kmlFileNames ) {
215 8
				return array_values(
216 8
					array_filter(
217 8
						array_map(
218 8
							function( string $fileName ) {
219 8
								return wfExpandUrl( MapsFunctions::getFileUrl( $fileName ) );
0 ignored issues
show
Deprecated Code introduced by
The method Maps\MapsFunctions::getFileUrl() has been deprecated.

This method has been deprecated.

Loading history...
220 1
							},
221 8
							$kmlFileNames
222
						),
223
						function( string $fileName ) {
224 8
							return $fileName !== '';
225 1
						}
226 8
					)
227
				);
228
			}
229 8
		];
230
231
		$params['gkml'] = [
232 8
			'default' => [],
233
			'message' => 'maps-googlemaps3-par-gkml',
234
			'islist' => true,
235
		];
236
237
		$params['searchmarkers'] = [
238 8
			'default' => '',
239
			'message' => 'maps-par-searchmarkers',
240
			// new CriterionSearchMarkers() FIXME
241
		];
242
243
		$params['fullscreen'] = [
244 8
			'aliases' => [ 'enablefullscreen' ],
245
			'type' => 'boolean',
246
			'default' => false,
247
			'message' => 'maps-par-enable-fullscreen',
248
		];
249
250
		$params['scrollwheelzoom'] = [
251 8
			'aliases' => [ 'scrollzoom' ],
252
			'type' => 'boolean',
253
			'default' => false,
254
			'message' => 'maps-par-scrollwheelzoom',
255
		];
256
257
		return $params;
258 8
	}
259
260
	/**
261
	 * Returns the names of all supported map types.
262
	 */
263
	private function getTypeNames(): array {
264 8
		return array_keys( self::MAP_TYPES );
265 8
	}
266
267
	public function newMapId(): string {
268 8
		static $mapsOnThisPage = 0;
269 8
270
		$mapsOnThisPage++;
271 8
272
		return 'map_google3_' . $mapsOnThisPage;
273 8
	}
274
275
	public function getResourceModules( array $params ): array {
276 8
		return [ 'ext.maps.googlemaps3', 'ext.maps.googlemaps3ajax' ];
277 8
	}
278
279
	public static function getApiScript( $langCode, array $urlArgs = [] ) {
280 8
		$urlArgs = array_merge(
281 8
			[
282
				'language' => self::getMappedLanguageCode( $langCode )
283 8
			],
284
			$urlArgs
285
		);
286
		if ( $GLOBALS['egMapsGMaps3ApiKey'] !== '' ) {
287 8
			$urlArgs['key'] = $GLOBALS['egMapsGMaps3ApiKey'];
288
		}
289
		if ( $GLOBALS['egMapsGMaps3ApiVersion'] !== '' ) {
290 8
			$urlArgs['v'] = $GLOBALS['egMapsGMaps3ApiVersion'];
291
		}
292
293
		return Html::linkedScript( '//maps.googleapis.com/maps/api/js?' . wfArrayToCgi( $urlArgs ) );
294 8
	}
295
296
	/**
297
	 * Maps language codes to Google Maps API v3 compatible values.
298
	 */
299
	private static function getMappedLanguageCode( string $code ): string {
300 8
		$mappings = [
301
			'en_gb' => 'en-gb',// v3 supports en_gb - but wants us to call it en-gb
302 8
			'he' => 'iw',      // iw is googlish for hebrew
303
			'fj' => 'fil',     // google does not support Fijian - use Filipino as close(?) supported relative
304
		];
305
306
		if ( array_key_exists( $code, $mappings ) ) {
307 8
			return $mappings[$code];
308
		}
309
310
		return $code;
311 8
	}
312
313
	public function getDependencyHtml( array $params ): string {
314 8
		$dependencies = [];
315 8
316
		// Only add dependencies that have not yet been added.
317
		foreach ( $this->getDependencies() as $dependency ) {
318 8
			if ( !in_array( $dependency, $this->addedDependencies ) ) {
319 8
				$dependencies[] = $dependency;
320 1
				$this->addedDependencies[] = $dependency;
321 1
			}
322
		}
323
324
		return implode( '', $dependencies );
325 8
	}
326
327
	private function getDependencies(): array {
328 8
		return [
329
			self::getApiScript(
330 8
				is_string( $GLOBALS['egMapsGMaps3Language'] ) ?
331 8
					$GLOBALS['egMapsGMaps3Language'] : $GLOBALS['egMapsGMaps3Language']->getCode()
332 8
			)
333
		];
334
	}
335
336
	public function newMapDataFromProcessingResult( ProcessingResult $processingResult ): MapData {
337 8
		$parameters = $processingResult->getParameters();
338 8
339
		if ( array_key_exists( 'zoom', $parameters ) && $parameters['zoom']->wasSetToDefault() && count(
340 8
				$parameters['coordinates']->getValue()
341 7
			) > 1 ) {
342 8
			$parameters['zoom'] = $this->getParameterWithValue( $parameters['zoom'], false );
343 1
		}
344
345
		$mapParams = [];
346 8
347
		foreach ( $parameters as $parameter ) {
348 8
			$mapParams[$parameter->getName()] = $parameter->getValue();
349 8
		}
350
351
		return $this->newMapDataFromParameters( $mapParams );
352 8
	}
353
354
355
	private function getParameterWithValue( ProcessedParam $param, $value ) {
356 1
		return new ProcessedParam(
357 1
			$param->getName(),
358 1
			$value,
359
			$param->wasSetToDefault(),
360 1
			$param->getOriginalName(),
361 1
			$param->getOriginalValue()
362 1
		);
363
	}
364
365
	public function newMapDataFromParameters( array $params ): MapData {
366 8
		return new MapData( $params );
367 8
	}
368
369
}
370