Completed
Push — master ( 684184...9a35aa )
by Jeroen De
08:07
created

includes/Maps_DisplayMapRenderer.php (1 issue)

parameters are used.

Unused Code Minor

Upgrade to new PHP Analysis Engine

These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more

1
<?php
2
use Maps\Element;
3
use Maps\Elements\Line;
4
use Maps\Elements\Location;
5
6
/**
7
 * Class handling the #display_map rendering.
8
 *
9
 * @licence GNU GPL v2+
10
 * @author Jeroen De Dauw < [email protected] >
11
 * @author Kim Eik
12
 */
13
class MapsDisplayMapRenderer {
14
15
	/**
16
	 * @since 2.0
17
	 *
18
	 * @var iMappingService
19
	 */
20
	protected $service;
21
22
	/**
23
	 * Constructor.
24
	 *
25
	 * @param iMappingService $service
26
	 */
27
	public function __construct( iMappingService $service ) {
28
		$this->service = $service;
29
	}
30
31
	/**
32
	 * Returns the HTML to display the map.
33
	 *
34
	 * @since 2.0
35
	 *
36
	 * @param array $params
37
	 * @param Parser $parser
38
	 * @param string $mapName
39
	 *
40
	 * @return string
41
	 */
42
	protected function getMapHTML( array $params, Parser $parser, $mapName ) {
43
		return Html::rawElement(
44
			'div',
45
			[
46
				'id' => $mapName,
47
				'style' => "width: {$params['width']}; height: {$params['height']}; background-color: #cccccc; overflow: hidden;",
48
				'class' => 'maps-map maps-' . $this->service->getName()
49
			],
50
			wfMessage( 'maps-loading-map' )->inContentLanguage()->escaped() .
51
				Html::element(
52
					'div',
53
					[ 'style' => 'display:none', 'class' => 'mapdata' ],
54
					FormatJson::encode( $this->getJSONObject( $params, $parser ) )
55
				)
56
		);
57
	}
58
59
	/**
60
	 * Returns a PHP object to encode to JSON with the map data.
61
	 *
62
	 * @since 2.0
63
	 *
64
	 * @param array $params
65
	 * @param Parser $parser
66
	 *
67
	 * @return mixed
68
	 */
69
	protected function getJSONObject( array $params, Parser $parser ) {
0 ignored issues
show
The parameter $parser is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
70
		return $params;
71
	}
72
73
	/**
74
	 * Handles the request from the parser hook by doing the work that's common for all
75
	 * mapping services, calling the specific methods and finally returning the resulting output.
76
	 *
77
	 * @param array $params
78
	 * @param Parser $parser
79
	 *
80
	 * @return string
81
	 */
82
	public final function renderMap( array $params, Parser $parser ) {
83
		$this->handleMarkerData( $params, $parser );
84
85
		$mapName = $this->service->getMapId();
86
87
		$output = $this->getMapHTML( $params, $parser, $mapName );
88
89
		$configVars = Skin::makeVariablesScript( $this->service->getConfigVariables() );
90
91
		$this->service->addHtmlDependencies(
92
			self::getLayerDependencies( $params['mappingservice'], $params )
93
		);
94
95
		$this->service->addDependencies( $parser );
96
		$parser->getOutput()->addHeadItem( $configVars );
97
98
		return $output;
99
	}
100
101
	/**
102
	 * Converts the data in the coordinates parameter to JSON-ready objects.
103
	 * These get stored in the locations parameter, and the coordinates on gets deleted.
104
	 *
105
	 * FIXME: complexity
106
	 *
107
	 * @since 1.0
108
	 *
109
	 * @param array &$params
110
	 * @param Parser $parser
111
	 */
112
	protected function handleMarkerData( array &$params, Parser $parser ) {
113
		if ( is_object( $params['centre'] ) ) {
114
			$params['centre'] = $params['centre']->getJSONObject();
115
		}
116
117
		$parserClone = clone $parser;
118
119
		if ( is_object( $params['wmsoverlay'] ) ) {
120
			$params['wmsoverlay'] = $params['wmsoverlay']->getJSONObject();
121
		}
122
123
		$iconUrl = MapsMapper::getFileUrl( $params['icon'] );
124
		$visitedIconUrl = MapsMapper::getFileUrl( $params['visitedicon'] );
125
		$params['locations'] = [];
126
127
		/**
128
		 * @var Location $location
129
		 */
130
		foreach ( $params['coordinates'] as $location ) {
131
			$jsonObj = $location->getJSONObject( $params['title'], $params['label'], $iconUrl, '', '',$visitedIconUrl);
132
133
			$jsonObj['title'] = $parserClone->parse( $jsonObj['title'], $parserClone->getTitle(), new ParserOptions() )->getText();
134
			$jsonObj['text'] = $parserClone->parse( $jsonObj['text'], $parserClone->getTitle(), new ParserOptions() )->getText();
135
			if ( isset( $jsonObj['inlineLabel'] ) ) {
136
				$jsonObj['inlineLabel'] = strip_tags($parserClone->parse( $jsonObj['inlineLabel'], $parserClone->getTitle(), new ParserOptions() )->getText(),'<a><img>');
137
			}
138
139
			$hasTitleAndtext = $jsonObj['title'] !== '' && $jsonObj['text'] !== '';
140
			$jsonObj['text'] = ( $hasTitleAndtext ? '<b>' . $jsonObj['title'] . '</b><hr />' : $jsonObj['title'] ) . $jsonObj['text'];
141
			$jsonObj['title'] = strip_tags( $jsonObj['title'] );
142
143
			$params['locations'][] = $jsonObj;
144
		}
145
146
		unset( $params['coordinates'] );
147
148
		$this->handleShapeData( $params, $parserClone );
149
150
		if ( $params['mappingservice'] === 'openlayers' ) {
151
			$params['layers'] = self::evilOpenLayersHack( $params['layers'] );
152
		}
153
	}
154
155
	protected function handleShapeData( array &$params, Parser $parserClone ) {
156
		$textContainers = [
157
			&$params['lines'] ,
158
			&$params['polygons'] ,
159
			&$params['circles'] ,
160
			&$params['rectangles'],
161
			&$params['imageoverlays'], // FIXME: this is Google Maps specific!!
162
		];
163
164
		foreach ( $textContainers as &$textContainer ) {
165
			if ( is_array( $textContainer ) ) {
166
				foreach ( $textContainer as &$obj ) {
167
					if ( $obj instanceof Element ) {
168
						$obj = $obj->getArrayValue();
169
					}
170
171
					$obj['title'] = $parserClone->parse( $obj['title'] , $parserClone->getTitle() , new ParserOptions() )->getText();
172
					$obj['text'] = $parserClone->parse( $obj['text'] , $parserClone->getTitle() , new ParserOptions() )->getText();
173
174
					$hasTitleAndtext = $obj['title'] !== '' && $obj['text'] !== '';
175
					$obj['text'] = ( $hasTitleAndtext ? '<b>' . $obj['title'] . '</b><hr />' : $obj['title'] ) . $obj['text'];
176
					$obj['title'] = strip_tags( $obj['title'] );
177
				}
178
			}
179
		}
180
	}
181
182
	/**
183
	 * FIXME
184
	 *
185
	 * Temporary hack until the mapping service handling gets a proper refactor
186
	 * This kind of JS construction is also rather evil and should not be done at this point
187
	 *
188
	 * @since 3.0
189
	 * @deprecated
190
	 *
191
	 * @param string[] $layers
192
	 *
193
	 * @return string[]
194
	 */
195
	public static function evilOpenLayersHack( $layers ) {
196
		global $egMapsOLLayerGroups, $egMapsOLAvailableLayers;
197
198
		$layerDefs = [];
199
		$layerNames = [];
200
201
		foreach ( $layers as $layerOrGroup ) {
202
			$lcLayerOrGroup = strtolower( $layerOrGroup );
203
204
			// Layer groups. Loop over all items and add them if not present yet:
205
			if ( array_key_exists( $lcLayerOrGroup, $egMapsOLLayerGroups ) ) {
206
				foreach ( $egMapsOLLayerGroups[$lcLayerOrGroup] as $layerName ) {
207
					if ( !in_array( $layerName, $layerNames ) ) {
208
						if ( is_array( $egMapsOLAvailableLayers[$layerName] ) ) {
209
							$layerDefs[] = 'new ' . $egMapsOLAvailableLayers[$layerName][0];
210
						}
211
						else {
212
							$layerDefs[] = 'new ' . $egMapsOLAvailableLayers[$layerName];
213
						}
214
						$layerNames[] = $layerName;
215
					}
216
				}
217
			}
218
			// Single layers. Add them if not present yet:
219
			elseif ( array_key_exists( $lcLayerOrGroup, $egMapsOLAvailableLayers ) ) {
220
				if ( !in_array( $lcLayerOrGroup, $layerNames ) ) {
221
					if ( is_array( $egMapsOLAvailableLayers[$lcLayerOrGroup] ) ) {
222
						$layerDefs[] = 'new ' . $egMapsOLAvailableLayers[$lcLayerOrGroup][0];
223
					}
224
					else {
225
						$layerDefs[] = 'new ' . $egMapsOLAvailableLayers[$lcLayerOrGroup];
226
					}
227
228
					$layerNames[] = $lcLayerOrGroup;
229
				}
230
			}
231
		}
232
		return $layerDefs;
233
	}
234
235
	public static function getLayerDependencies( $service, $params ) {
236
		global $egMapsOLLayerDependencies, $egMapsOLAvailableLayers,
237
			   $egMapsLeafletLayerDependencies, $egMapsLeafletAvailableLayers,
238
			   $egMapsLeafletLayersApiKeys;
239
240
		$layerDependencies = [];
241
242
		if ( $service === 'leaflet' ) {
243
			$layerName = $params['layer'];
244
			if ( array_key_exists( $layerName, $egMapsLeafletAvailableLayers )
245
					&& $egMapsLeafletAvailableLayers[$layerName]
246
					&& array_key_exists( $layerName, $egMapsLeafletLayersApiKeys )
247
					&& array_key_exists( $layerName, $egMapsLeafletLayerDependencies ) ) {
248
				$layerDependencies[] = '<script src="' . $egMapsLeafletLayerDependencies[$layerName] .
249
					$egMapsLeafletLayersApiKeys[$layerName] . '"></script>';
250
			}
251
		} else if ( $service === 'openlayers' ) {
252
			$layerNames = $params['layers'];
253
			foreach ( $layerNames as $layerName ) {
254
				if ( array_key_exists( $layerName, $egMapsOLAvailableLayers ) // The layer must be defined in php
255
						&& is_array( $egMapsOLAvailableLayers[$layerName] ) // The layer must be an array...
256
						&& count( $egMapsOLAvailableLayers[$layerName] ) > 1 // ...with a second element...
257
						&& array_key_exists( $egMapsOLAvailableLayers[$layerName][1], $egMapsOLLayerDependencies ) ) { //...that is a dependency.
258
					$layerDependencies[] = $egMapsOLLayerDependencies[$egMapsOLAvailableLayers[$layerName][1]];
259
				}
260
			}
261
262
		}
263
264
		return array_unique( $layerDependencies );
265
	}
266
267
}
268