This project does not seem to handle request data directly as such no vulnerable execution paths were found.
include
, or for example
via PHP's auto-loading mechanism.
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 | protected $fatalErrorMsg = false; |
||
46 | |||
47 | /** |
||
48 | * @param string $format |
||
49 | * @param bool $inline |
||
50 | */ |
||
51 | 2 | public function __construct( $format, $inline = true ) { |
|
52 | 2 | $this->service = self::$services[$format]; |
|
53 | |||
54 | 2 | parent::__construct( $format, $inline ); |
|
55 | 2 | } |
|
56 | |||
57 | /** |
||
58 | * Returns an array containing the parameter info. |
||
59 | * |
||
60 | * @since 1.0 |
||
61 | * |
||
62 | * @return array |
||
63 | */ |
||
64 | private function getParameterInfo() { |
||
65 | global $smgQPShowTitle, $smgQPTemplate, $smgQPHideNamespace; |
||
66 | |||
67 | $params = ParamDefinition::getCleanDefinitions( MapsMapper::getCommonParameters() ); |
||
0 ignored issues
–
show
|
|||
68 | |||
69 | $this->service->addParameterInfo( $params ); |
||
70 | |||
71 | $params['staticlocations'] = [ |
||
72 | 'type' => 'mapslocation', |
||
73 | 'aliases' => [ 'locations', 'points' ], |
||
74 | 'default' => [], |
||
75 | 'islist' => true, |
||
76 | 'delimiter' => ';', |
||
77 | 'message' => 'semanticmaps-par-staticlocations', |
||
78 | ]; |
||
79 | |||
80 | $params['showtitle'] = [ |
||
81 | 'type' => 'boolean', |
||
82 | 'aliases' => 'show title', |
||
83 | 'default' => $smgQPShowTitle, |
||
84 | ]; |
||
85 | |||
86 | $params['hidenamespace'] = [ |
||
87 | 'type' => 'boolean', |
||
88 | 'aliases' => 'hide namespace', |
||
89 | 'default' => $smgQPHideNamespace, |
||
90 | ]; |
||
91 | |||
92 | $params['template'] = [ |
||
93 | 'default' => $smgQPTemplate, |
||
94 | ]; |
||
95 | |||
96 | $params['userparam'] = [ |
||
97 | 'default' => '', |
||
98 | ]; |
||
99 | |||
100 | $params['activeicon'] = [ |
||
101 | 'type' => 'string', |
||
102 | 'default' => '', |
||
103 | ]; |
||
104 | |||
105 | $params['pagelabel'] = [ |
||
106 | 'type' => 'boolean', |
||
107 | 'default' => false, |
||
108 | ]; |
||
109 | |||
110 | $params['ajaxcoordproperty'] = array( |
||
111 | 'default' => '', |
||
112 | ); |
||
113 | |||
114 | $params['ajaxquery'] = array( |
||
115 | 'default' => '', |
||
116 | 'type' => 'string' |
||
117 | ); |
||
118 | |||
119 | // Messages: |
||
120 | // semanticmaps-par-staticlocations, semanticmaps-par-showtitle, semanticmaps-par-hidenamespace, |
||
121 | // semanticmaps-par-template, semanticmaps-par-userparam, semanticmaps-par-activeicon, |
||
122 | // semanticmaps-par-pagelabel, semanticmaps-par-ajaxcoordproperty semanticmaps-par-ajaxquery |
||
123 | foreach ( $params as $name => &$data ) { |
||
124 | if ( is_array( $data ) && !array_key_exists( 'message', $data ) ) { |
||
125 | $data['message'] = 'semanticmaps-par-' . $name; |
||
126 | } |
||
127 | } |
||
128 | |||
129 | $params = array_merge( $params, MapsDisplayMap::getCommonMapParams() ); |
||
0 ignored issues
–
show
|
|||
130 | |||
131 | return $params; |
||
132 | } |
||
133 | |||
134 | /** |
||
135 | * Builds up and returns the HTML for the map, with the queried coordinate data on it. |
||
136 | * |
||
137 | * @param SMWQueryResult $res |
||
138 | * @param $outputmode |
||
139 | * |
||
140 | * @return array or string |
||
141 | */ |
||
142 | public final function getResultText( SMWQueryResult $res, $outputmode ) { |
||
0 ignored issues
–
show
getResultText uses the super-global variable $GLOBALS which is generally not recommended.
Instead of super-globals, we recommend to explicitly inject the dependencies of your class. This makes your code less dependent on global state and it becomes generally more testable: // Bad
class Router
{
public function generate($path)
{
return $_SERVER['HOST'].$path;
}
}
// Better
class Router
{
private $host;
public function __construct($host)
{
$this->host = $host;
}
public function generate($path)
{
return $this->host.$path;
}
}
class Controller
{
public function myAction(Request $request)
{
// Instead of
$page = isset($_GET['page']) ? intval($_GET['page']) : 1;
// Better (assuming you use the Symfony2 request)
$page = $request->query->get('page', 1);
}
}
Loading history...
|
|||
143 | if ( $this->fatalErrorMsg !== false ) { |
||
144 | return $this->fatalErrorMsg; |
||
0 ignored issues
–
show
The return type of
return $this->fatalErrorMsg; (string|boolean ) is incompatible with the return type documented by SMMapPrinter::getResultText of type array .
If you return a value from a function or method, it should be a sub-type of the type that is given by the parent type f.e. an interface, or abstract method. This is more formally defined by the Lizkov substitution principle, and guarantees that classes that depend on the parent type can use any instance of a child type interchangably. This principle also belongs to the SOLID principles for object oriented design. Let’s take a look at an example: class Author {
private $name;
public function __construct($name) {
$this->name = $name;
}
public function getName() {
return $this->name;
}
}
abstract class Post {
public function getAuthor() {
return 'Johannes';
}
}
class BlogPost extends Post {
public function getAuthor() {
return new Author('Johannes');
}
}
class ForumPost extends Post { /* ... */ }
function my_function(Post $post) {
echo strtoupper($post->getAuthor());
}
Our function
Loading history...
|
|||
145 | } |
||
146 | |||
147 | /** |
||
148 | * @var Parser $wgParser |
||
149 | */ |
||
150 | global $wgParser; |
||
151 | |||
152 | if ( $GLOBALS['egMapsEnableCategory'] && $wgParser->getOutput() !== null ) { |
||
153 | $wgParser->addTrackingCategory( 'maps-tracking-category' ); |
||
154 | } |
||
155 | |||
156 | $params = $this->params; |
||
157 | |||
158 | $queryHandler = new SMQueryHandler( $res, $outputmode ); |
||
159 | $queryHandler->setLinkStyle($params['link']); |
||
160 | $queryHandler->setHeaderStyle($params['headers']); |
||
161 | $queryHandler->setShowSubject( $params['showtitle'] ); |
||
162 | $queryHandler->setTemplate( $params['template'] ); |
||
163 | $queryHandler->setUserParam( $params['userparam'] ); |
||
164 | $queryHandler->setHideNamespace( $params['hidenamespace'] ); |
||
165 | $queryHandler->setActiveIcon( $params['activeicon'] ); |
||
166 | |||
167 | $this->handleMarkerData( $params, $queryHandler ); |
||
168 | $locationAmount = count( $params['locations'] ); |
||
169 | |||
170 | $params['ajaxquery'] = urlencode( $params['ajaxquery'] ); |
||
171 | |||
172 | if ( $locationAmount > 0 ) { |
||
173 | // We can only take care of the zoom defaulting here, |
||
174 | // as not all locations are available in whats passed to Validator. |
||
175 | if ( $this->fullParams['zoom']->wasSetToDefault() && $locationAmount > 1 ) { |
||
176 | $params['zoom'] = false; |
||
177 | } |
||
178 | |||
179 | $mapName = $this->service->getMapId(); |
||
180 | |||
181 | SMWOutputs::requireHeadItem( |
||
182 | $mapName, |
||
183 | $this->service->getDependencyHtml() . |
||
184 | $configVars = Skin::makeVariablesScript( $this->service->getConfigVariables() ) |
||
185 | ); |
||
186 | |||
187 | foreach ( $this->service->getResourceModules() as $resourceModule ) { |
||
188 | SMWOutputs::requireResource( $resourceModule ); |
||
189 | } |
||
190 | |||
191 | if ( array_key_exists( 'source', $params ) ) { |
||
192 | unset( $params['source'] ); |
||
193 | } |
||
194 | |||
195 | return $this->getMapHTML( $params, $wgParser, $mapName ); |
||
0 ignored issues
–
show
The return type of
return $this->getMapHTML..., $wgParser, $mapName); (string ) is incompatible with the return type documented by SMMapPrinter::getResultText of type array .
If you return a value from a function or method, it should be a sub-type of the type that is given by the parent type f.e. an interface, or abstract method. This is more formally defined by the Lizkov substitution principle, and guarantees that classes that depend on the parent type can use any instance of a child type interchangably. This principle also belongs to the SOLID principles for object oriented design. Let’s take a look at an example: class Author {
private $name;
public function __construct($name) {
$this->name = $name;
}
public function getName() {
return $this->name;
}
}
abstract class Post {
public function getAuthor() {
return 'Johannes';
}
}
class BlogPost extends Post {
public function getAuthor() {
return new Author('Johannes');
}
}
class ForumPost extends Post { /* ... */ }
function my_function(Post $post) {
echo strtoupper($post->getAuthor());
}
Our function
Loading history...
|
|||
196 | } |
||
197 | else { |
||
198 | return $params['default']; |
||
199 | } |
||
200 | } |
||
201 | |||
202 | /** |
||
203 | * Returns the HTML to display the map. |
||
204 | * |
||
205 | * @since 1.1 |
||
206 | * |
||
207 | * @param array $params |
||
208 | * @param Parser $parser |
||
209 | * @param string $mapName |
||
210 | * |
||
211 | * @return string |
||
212 | */ |
||
213 | private function getMapHTML( array $params, Parser $parser, $mapName ) { |
||
214 | return Html::rawElement( |
||
215 | 'div', |
||
216 | [ |
||
217 | 'id' => $mapName, |
||
218 | 'style' => "width: {$params['width']}; height: {$params['height']}; background-color: #cccccc; overflow: hidden;", |
||
219 | 'class' => 'maps-map maps-' . $this->service->getName() |
||
220 | ], |
||
221 | wfMessage( 'maps-loading-map' )->inContentLanguage()->escaped() . |
||
222 | Html::element( |
||
223 | 'div', |
||
224 | [ 'style' => 'display:none', 'class' => 'mapdata' ], |
||
225 | FormatJson::encode( $this->getJSONObject( $params, $parser ) ) |
||
226 | ) |
||
227 | ); |
||
228 | } |
||
229 | |||
230 | /** |
||
231 | * Returns a PHP object to encode to JSON with the map data. |
||
232 | * |
||
233 | * @since 1.1 |
||
234 | * |
||
235 | * @param array $params |
||
236 | * @param Parser $parser |
||
237 | * |
||
238 | * @return mixed |
||
239 | */ |
||
240 | private function getJSONObject( array $params, Parser $parser ) { |
||
241 | return $params; |
||
242 | } |
||
243 | |||
244 | /** |
||
245 | * Converts the data in the coordinates parameter to JSON-ready objects. |
||
246 | * These get stored in the locations parameter, and the coordinates on gets deleted. |
||
247 | * |
||
248 | * @since 1.0 |
||
249 | * |
||
250 | * @param array &$params |
||
251 | * @param SMQueryHandler $queryHandler |
||
252 | */ |
||
253 | private function handleMarkerData( array &$params, SMQueryHandler $queryHandler ) { |
||
254 | if ( is_object( $params['centre'] ) ) { |
||
255 | $params['centre'] = $params['centre']->getJSONObject(); |
||
256 | } |
||
257 | |||
258 | $iconUrl = MapsMapper::getFileUrl( $params['icon'] ); |
||
0 ignored issues
–
show
|
|||
259 | $visitedIconUrl = MapsMapper::getFileUrl( $params['visitedicon'] ); |
||
0 ignored issues
–
show
|
|||
260 | |||
261 | $params['locations'] = $this->getJsonForStaticLocations( |
||
262 | $params['staticlocations'], |
||
263 | $params, |
||
264 | $iconUrl, |
||
265 | $visitedIconUrl |
||
266 | ); |
||
267 | |||
268 | unset( $params['staticlocations'] ); |
||
269 | |||
270 | $this->addShapeData( $queryHandler->getShapes(), $params, $iconUrl, $visitedIconUrl ); |
||
271 | |||
272 | if ( $params['format'] === 'openlayers' ) { |
||
273 | $params['layers'] = MapsDisplayMapRenderer::evilOpenLayersHack( $params['layers'] ); |
||
0 ignored issues
–
show
|
|||
274 | } |
||
275 | } |
||
276 | |||
277 | private function getJsonForStaticLocations( array $staticLocations, array $params, $iconUrl, $visitedIconUrl ) { |
||
0 ignored issues
–
show
getJsonForStaticLocations uses the super-global variable $GLOBALS which is generally not recommended.
Instead of super-globals, we recommend to explicitly inject the dependencies of your class. This makes your code less dependent on global state and it becomes generally more testable: // Bad
class Router
{
public function generate($path)
{
return $_SERVER['HOST'].$path;
}
}
// Better
class Router
{
private $host;
public function __construct($host)
{
$this->host = $host;
}
public function generate($path)
{
return $this->host.$path;
}
}
class Controller
{
public function myAction(Request $request)
{
// Instead of
$page = isset($_GET['page']) ? intval($_GET['page']) : 1;
// Better (assuming you use the Symfony2 request)
$page = $request->query->get('page', 1);
}
}
Loading history...
|
|||
278 | /** |
||
279 | * @var Parser $wgParser |
||
280 | */ |
||
281 | global $wgParser; |
||
282 | |||
283 | $parser = version_compare( $GLOBALS['wgVersion'], '1.18', '<' ) ? $wgParser : clone $wgParser; |
||
284 | |||
285 | $locationsJson = []; |
||
286 | |||
287 | foreach ( $staticLocations as $location ) { |
||
288 | $locationsJson[] = $this->getJsonForStaticLocation( |
||
289 | $location, |
||
290 | $params, |
||
291 | $iconUrl, |
||
292 | $visitedIconUrl, |
||
293 | $parser |
||
294 | ); |
||
295 | } |
||
296 | |||
297 | return $locationsJson; |
||
298 | } |
||
299 | |||
300 | private function getJsonForStaticLocation( Location $location, array $params, $iconUrl, $visitedIconUrl, Parser $parser ) { |
||
301 | $jsonObj = $location->getJSONObject( $params['title'], $params['label'], $iconUrl, '', '', $visitedIconUrl ); |
||
302 | |||
303 | $jsonObj['title'] = $parser->parse( $jsonObj['title'], $parser->getTitle(), new ParserOptions() )->getText(); |
||
304 | $jsonObj['text'] = $parser->parse( $jsonObj['text'], $parser->getTitle(), new ParserOptions() )->getText(); |
||
305 | |||
306 | $hasTitleAndtext = $jsonObj['title'] !== '' && $jsonObj['text'] !== ''; |
||
307 | $jsonObj['text'] = ( $hasTitleAndtext ? '<b>' . $jsonObj['title'] . '</b><hr />' : $jsonObj['title'] ) . $jsonObj['text']; |
||
308 | $jsonObj['title'] = strip_tags( $jsonObj['title'] ); |
||
309 | |||
310 | if ( $params['pagelabel'] ) { |
||
311 | $jsonObj['inlineLabel'] = Linker::link( Title::newFromText( $jsonObj['title'] ) ); |
||
312 | } |
||
313 | |||
314 | return $jsonObj; |
||
315 | } |
||
316 | |||
317 | /** |
||
318 | * @param Element[] $queryShapes |
||
319 | * @param array $params |
||
320 | * @param string $iconUrl |
||
321 | * @param string $visitedIconUrl |
||
322 | */ |
||
323 | private function addShapeData( array $queryShapes, array &$params, $iconUrl, $visitedIconUrl ) { |
||
324 | $params['locations'] = array_merge( |
||
325 | $params['locations'], |
||
326 | $this->getJsonForLocations( |
||
327 | $queryShapes['locations'], |
||
328 | $params, |
||
329 | $iconUrl, |
||
330 | $visitedIconUrl |
||
331 | ) |
||
332 | ); |
||
333 | |||
334 | $params['lines'] = $this->getElementJsonArray( $queryShapes['lines'], $params ); |
||
335 | $params['polygons'] = $this->getElementJsonArray( $queryShapes['polygons'], $params ); |
||
336 | } |
||
337 | |||
338 | /** |
||
339 | * @param Location[] $locations |
||
340 | * @param array $params |
||
341 | * @param string $iconUrl |
||
342 | * @param string $visitedIconUrl |
||
343 | * |
||
344 | * @return array |
||
345 | */ |
||
346 | private function getJsonForLocations( array $locations, array $params, $iconUrl, $visitedIconUrl ) { |
||
347 | $locationsJson = []; |
||
348 | |||
349 | foreach ( $locations as $location ) { |
||
350 | $jsonObj = $location->getJSONObject( $params['title'], $params['label'], $iconUrl, '', '', $visitedIconUrl ); |
||
351 | |||
352 | $jsonObj['title'] = strip_tags( $jsonObj['title'] ); |
||
353 | |||
354 | $locationsJson[] = $jsonObj; |
||
355 | } |
||
356 | |||
357 | return $locationsJson; |
||
358 | } |
||
359 | |||
360 | /** |
||
361 | * @param BaseElement[] $elements |
||
362 | * @param array $params |
||
363 | * |
||
364 | * @return array |
||
365 | */ |
||
366 | private function getElementJsonArray( array $elements, array $params ) { |
||
367 | $elementsJson = []; |
||
368 | |||
369 | foreach ( $elements as $element ) { |
||
370 | $jsonObj = $element->getJSONObject( $params['title'], $params['label'] ); |
||
0 ignored issues
–
show
|
|||
371 | $elementsJson[] = $jsonObj; |
||
372 | } |
||
373 | |||
374 | return $elementsJson; |
||
375 | } |
||
376 | |||
377 | /** |
||
378 | * Returns the internationalized name of the mapping service. |
||
379 | * |
||
380 | * @return string |
||
381 | */ |
||
382 | public final function getName() { |
||
383 | return wfMessage( 'maps_' . $this->service->getName() )->text(); |
||
384 | } |
||
385 | |||
386 | /** |
||
387 | * Returns a list of parameter information, for usage by Special:Ask and others. |
||
388 | * |
||
389 | * @return array |
||
390 | */ |
||
391 | public function getParameters() { |
||
392 | $params = parent::getParameters(); |
||
0 ignored issues
–
show
The method
SMW\ResultPrinter::getParameters() has been deprecated with message: since 1.8, use getParamDefinitions instead.
This method has been deprecated. The supplier of the class has supplied an explanatory message. The explanatory message should give you some clue as to whether and when the method will be removed from the class and what other method or class to use instead.
Loading history...
|
|||
393 | $paramInfo = $this->getParameterInfo(); |
||
394 | |||
395 | // Do not display this as an option, as the format already determines it |
||
396 | // TODO: this can probably be done cleaner with some changes in Maps |
||
397 | unset( $paramInfo['mappingservice'] ); |
||
398 | |||
399 | $params = array_merge( $params, $paramInfo ); |
||
400 | |||
401 | return $params; |
||
402 | } |
||
403 | } |
||
404 |
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: