Completed
Push — master ( 76f9d5...d59f0b )
by Jeroen De
9s
created

SemanticMaps/src/queryprinters/SM_MapPrinter.php (1 issue)

mismatching argument types.

Documentation 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
3
use Maps\Elements\Location;
4
use Maps\Element;
5
use Maps\Elements\BaseElement;
6
use ParamProcessor\ParamDefinition;
7
8
/**
9
 * Query printer for maps. Is invoked via SMMapper.
10
 * Can be overridden per service to have custom output.
11
 *
12
 * @ingroup SemanticMaps
13
 *
14
 * @licence GNU GPL v2+
15
 * @author Jeroen De Dauw < [email protected] >
16
 * @author Peter Grassberger < [email protected] >
17
 */
18
class SMMapPrinter extends SMW\ResultPrinter {
19
20
	private static $services = [];
21
22
	/**
23
	 * @since 3.4
24
	 * FIXME: this is a temporary hack that should be replaced when SMW allows for dependency
25
	 * injection in query printers.
26
	 *
27
	 * @param MapsMappingService $service
28
	 */
29
	public static function registerService( MapsMappingService $service ) {
30
		self::$services[$service->getName()] = $service;
31
	}
32
33
	public static function registerDefaultService( $serviceName ) {
34
		self::$services['map'] = self::$services[$serviceName];
35
	}
36
	
37
	/**
38
	 * @var MapsMappingService
39
	 */
40
	private $service;
41
	
42
	/**
43
	 * @var string|boolean
44
	 */
45
	private $fatalErrorMsg = false;
46
	
47
	/**
48
	 * @param string $format
49
	 * @param bool $inline
50
	 */
51
	public function __construct( $format, $inline = true ) {
52
		$this->service = self::$services[$format];
53
		
54
		parent::__construct( $format, $inline );
55
	}
56
57
	/**
58
	 * Returns an array containing the parameter info.
59
	 * 
60
	 * @return array
61
	 */
62
	private function getParameterInfo() {
63
		global $smgQPShowTitle, $smgQPTemplate, $smgQPHideNamespace;
64
		
65
		$params = ParamDefinition::getCleanDefinitions( MapsMapper::getCommonParameters() );
0 ignored issues
show
\MapsMapper::getCommonParameters() is of type array<string,array<strin...efault\":\"false\"}>"}>, but the function expects a array<integer,object<Par...ssor\IParamDefinition>>.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
66
67
		$this->service->addParameterInfo( $params );
68
69
		$params['staticlocations'] = [
70
			'type' => 'mapslocation',
71
			'aliases' => [ 'locations', 'points' ],
72
			'default' => [],
73
			'islist' => true,
74
			'delimiter' => ';',
75
			'message' => 'semanticmaps-par-staticlocations',
76
		];
77
78
		$params['showtitle'] = [
79
			'type' => 'boolean',
80
			'aliases' => 'show title',
81
			'default' => $smgQPShowTitle,
82
		];
83
84
		$params['hidenamespace'] = [
85
			'type' => 'boolean',
86
			'aliases' => 'hide namespace',
87
			'default' => $smgQPHideNamespace,
88
		];
89
90
		$params['template'] = [
91
			'default' => $smgQPTemplate,
92
		];
93
94
		$params['userparam'] = [
95
			'default' => '',
96
		];
97
98
		$params['activeicon'] =  [
99
			'type' => 'string',
100
			'default' => '',
101
		];
102
103
		$params['pagelabel'] =  [
104
			'type' => 'boolean',
105
			'default' => false,
106
		];
107
108
		$params['ajaxcoordproperty'] = array(
109
			'default' => '',
110
		);
111
112
		$params['ajaxquery'] = array(
113
			'default' => '',
114
			'type' => 'string'
115
		);
116
117
		// Messages:
118
		// semanticmaps-par-staticlocations, semanticmaps-par-showtitle, semanticmaps-par-hidenamespace,
119
		// semanticmaps-par-template, semanticmaps-par-userparam, semanticmaps-par-activeicon,
120
		// semanticmaps-par-pagelabel, semanticmaps-par-ajaxcoordproperty semanticmaps-par-ajaxquery
121
		foreach ( $params as $name => &$data ) {
122
			if ( is_array( $data ) && !array_key_exists( 'message', $data ) ) {
123
				$data['message'] = 'semanticmaps-par-' . $name;
124
			}
125
		}
126
127
		return $params;
128
	}
129
	
130
	/**
131
	 * Builds up and returns the HTML for the map, with the queried coordinate data on it.
132
	 *
133
	 * @param SMWQueryResult $res
134
	 * @param $outputmode
135
	 * 
136
	 * @return array or string
137
	 */
138
	public final function getResultText( SMWQueryResult $res, $outputmode ) {
139
		if ( $this->fatalErrorMsg !== false ) {
140
			return $this->fatalErrorMsg;
141
		}
142
143
		/**
144
		 * @var Parser $wgParser
145
		 */
146
		global $wgParser;
147
148
		if ( $GLOBALS['egMapsEnableCategory'] && $wgParser->getOutput() !== null ) {
149
			$wgParser->addTrackingCategory( 'maps-tracking-category' );
150
		}
151
152
		$params = $this->params;
153
154
		$queryHandler = new SMQueryHandler( $res, $outputmode );
155
		$queryHandler->setLinkStyle($params['link']);
156
		$queryHandler->setHeaderStyle($params['headers']);
157
		$queryHandler->setShowSubject( $params['showtitle'] );
158
		$queryHandler->setTemplate( $params['template'] );
159
		$queryHandler->setUserParam( $params['userparam'] );
160
		$queryHandler->setHideNamespace( $params['hidenamespace'] );
161
		$queryHandler->setActiveIcon( $params['activeicon'] );
162
163
		$this->handleMarkerData( $params, $queryHandler );
164
		$locationAmount = count( $params['locations'] );
165
166
		$params['ajaxquery'] = urlencode( $params['ajaxquery'] );
167
168
		if ( $locationAmount > 0 ) {
169
			// We can only take care of the zoom defaulting here,
170
			// as not all locations are available in whats passed to Validator.
171
			if ( $this->fullParams['zoom']->wasSetToDefault() && $locationAmount > 1 ) {
172
				$params['zoom'] = false;
173
			}
174
175
			$mapName = $this->service->getMapId();
176
177
			SMWOutputs::requireHeadItem(
178
				$mapName,
179
				$this->service->getDependencyHtml() .
180
				$configVars = Skin::makeVariablesScript( $this->service->getConfigVariables() )
181
			);
182
183
			foreach ( $this->service->getResourceModules() as $resourceModule ) {
184
				SMWOutputs::requireResource( $resourceModule );
185
			}
186
187
			if ( array_key_exists( 'source', $params ) ) {
188
				unset( $params['source'] );
189
			}
190
191
			return $this->getMapHTML( $params, $wgParser, $mapName );
192
		}
193
		else {
194
			return $params['default'];
195
		}
196
	}
197
198
	/**
199
	 * Returns the HTML to display the map.
200
	 *
201
	 * @param array $params
202
	 * @param Parser $parser
203
	 * @param string $mapName
204
	 *
205
	 * @return string
206
	 */
207
	private function getMapHTML( array $params, Parser $parser, $mapName ) {
208
		return Html::rawElement(
209
			'div',
210
			[
211
				'id' => $mapName,
212
				'style' => "width: {$params['width']}; height: {$params['height']}; background-color: #cccccc; overflow: hidden;",
213
				'class' => 'maps-map maps-' . $this->service->getName()
214
			],
215
			wfMessage( 'maps-loading-map' )->inContentLanguage()->escaped() .
216
				Html::element(
217
					'div',
218
					[ 'style' => 'display:none', 'class' => 'mapdata' ],
219
					FormatJson::encode( $this->getJSONObject( $params, $parser ) )
220
				)
221
		);
222
	}
223
224
	/**
225
	 * Returns a PHP object to encode to JSON with the map data.
226
	 *
227
	 * @param array $params
228
	 * @param Parser $parser
229
	 *
230
	 * @return mixed
231
	 */
232
	private function getJSONObject( array $params, Parser $parser ) {
233
		return $params;
234
	}
235
	
236
	/**
237
	 * Converts the data in the coordinates parameter to JSON-ready objects.
238
	 * These get stored in the locations parameter, and the coordinates on gets deleted.
239
	 * 
240
	 * @param array &$params
241
	 * @param SMQueryHandler $queryHandler
242
	 */
243
	private function handleMarkerData( array &$params, SMQueryHandler $queryHandler ) {
244
		if ( is_object( $params['centre'] ) ) {
245
			$params['centre'] = $params['centre']->getJSONObject();
246
		}
247
248
		$iconUrl = MapsMapper::getFileUrl( $params['icon'] );
249
		$visitedIconUrl = MapsMapper::getFileUrl( $params['visitedicon'] );
250
251
		$params['locations'] = $this->getJsonForStaticLocations(
252
			$params['staticlocations'],
253
			$params,
254
			$iconUrl,
255
			$visitedIconUrl
256
		);
257
258
		unset( $params['staticlocations'] );
259
260
		$this->addShapeData( $queryHandler->getShapes(), $params, $iconUrl, $visitedIconUrl );
261
262
		if ( $params['format'] === 'openlayers' ) {
263
			$params['layers'] = MapsDisplayMapRenderer::evilOpenLayersHack( $params['layers'] );
264
		}
265
	}
266
267
	private function getJsonForStaticLocations( array $staticLocations, array $params, $iconUrl, $visitedIconUrl ) {
268
		/**
269
		 * @var Parser $wgParser
270
		 */
271
		global $wgParser;
272
273
		$parser = version_compare( $GLOBALS['wgVersion'], '1.18', '<' ) ? $wgParser : clone $wgParser;
274
275
		$locationsJson = [];
276
277
		foreach ( $staticLocations as $location ) {
278
			$locationsJson[] = $this->getJsonForStaticLocation(
279
				$location,
280
				$params,
281
				$iconUrl,
282
				$visitedIconUrl,
283
				$parser
284
			);
285
		}
286
287
		return $locationsJson;
288
	}
289
290
	private function getJsonForStaticLocation( Location $location, array $params, $iconUrl, $visitedIconUrl, Parser $parser ) {
291
		$jsonObj = $location->getJSONObject( $params['title'], $params['label'], $iconUrl, '', '', $visitedIconUrl );
292
293
		$jsonObj['title'] = $parser->parse( $jsonObj['title'], $parser->getTitle(), new ParserOptions() )->getText();
294
		$jsonObj['text'] = $parser->parse( $jsonObj['text'], $parser->getTitle(), new ParserOptions() )->getText();
295
296
		$hasTitleAndtext = $jsonObj['title'] !== '' && $jsonObj['text'] !== '';
297
		$jsonObj['text'] = ( $hasTitleAndtext ? '<b>' . $jsonObj['title'] . '</b><hr />' : $jsonObj['title'] ) . $jsonObj['text'];
298
		$jsonObj['title'] = strip_tags( $jsonObj['title'] );
299
300
		if ( $params['pagelabel'] ) {
301
			$jsonObj['inlineLabel'] = Linker::link( Title::newFromText( $jsonObj['title'] ) );
302
		}
303
304
		return $jsonObj;
305
	}
306
307
	/**
308
	 * @param Element[] $queryShapes
309
	 * @param array $params
310
	 * @param string $iconUrl
311
	 * @param string $visitedIconUrl
312
	 */
313
	private function addShapeData( array $queryShapes, array &$params, $iconUrl, $visitedIconUrl ) {
314
		$params['locations'] = array_merge(
315
			$params['locations'],
316
			$this->getJsonForLocations(
317
				$queryShapes['locations'],
318
				$params,
319
				$iconUrl,
320
				$visitedIconUrl
321
			)
322
		);
323
324
		$params['lines'] = $this->getElementJsonArray( $queryShapes['lines'], $params );
325
		$params['polygons'] = $this->getElementJsonArray( $queryShapes['polygons'], $params );
326
	}
327
328
	/**
329
	 * @param Location[] $locations
330
	 * @param array $params
331
	 * @param string $iconUrl
332
	 * @param string $visitedIconUrl
333
	 *
334
	 * @return array
335
	 */
336
	private function getJsonForLocations( array $locations, array $params, $iconUrl, $visitedIconUrl ) {
337
		$locationsJson = [];
338
339
		foreach ( $locations as $location ) {
340
			$jsonObj = $location->getJSONObject( $params['title'], $params['label'], $iconUrl, '', '', $visitedIconUrl );
341
342
			$jsonObj['title'] = strip_tags( $jsonObj['title'] );
343
344
			$locationsJson[] = $jsonObj;
345
		}
346
347
		return $locationsJson;
348
	}
349
350
	/**
351
	 * @param BaseElement[] $elements
352
	 * @param array $params
353
	 *
354
	 * @return array
355
	 */
356
	private function getElementJsonArray( array $elements, array $params ) {
357
		$elementsJson = [];
358
359
		foreach ( $elements as $element ) {
360
			$jsonObj = $element->getJSONObject( $params['title'], $params['label'] );
361
			$elementsJson[] = $jsonObj;
362
		}
363
364
		return $elementsJson;
365
	}
366
367
	/**
368
	 * Returns the internationalized name of the mapping service.
369
	 * 
370
	 * @return string
371
	 */
372
	public final function getName() {
373
		return wfMessage( 'maps_' . $this->service->getName() )->text();
374
	}
375
	
376
	/**
377
	 * Returns a list of parameter information, for usage by Special:Ask and others.
378
	 * 
379
	 * @return array
380
	 */
381
    public function getParameters() {
382
        $params = parent::getParameters();
383
        $paramInfo = $this->getParameterInfo();
384
        
385
        // Do not display this as an option, as the format already determines it
386
        // TODO: this can probably be done cleaner with some changes in Maps
387
        unset( $paramInfo['mappingservice'] );
388
        
389
        $params = array_merge( $params, $paramInfo );
390
391
		return $params;
392
    }
393
}
394