Issues (141)

Security Analysis    not enabled

This project does not seem to handle request data directly as such no vulnerable execution paths were found.

  Cross-Site Scripting
Cross-Site Scripting enables an attacker to inject code into the response of a web-request that is viewed by other users. It can for example be used to bypass access controls, or even to take over other users' accounts.
  File Exposure
File Exposure allows an attacker to gain access to local files that he should not be able to access. These files can for example include database credentials, or other configuration files.
  File Manipulation
File Manipulation enables an attacker to write custom data to files. This potentially leads to injection of arbitrary code on the server.
  Object Injection
Object Injection enables an attacker to inject an object into PHP code, and can lead to arbitrary code execution, file exposure, or file manipulation attacks.
  Code Injection
Code Injection enables an attacker to execute arbitrary code on the server.
  Response Splitting
Response Splitting can be used to send arbitrary responses.
  File Inclusion
File Inclusion enables an attacker to inject custom files into PHP's file loading mechanism, either explicitly passed to include, or for example via PHP's auto-loading mechanism.
  Command Injection
Command Injection enables an attacker to inject a shell command that is execute with the privileges of the web-server. This can be used to expose sensitive data, or gain access of your server.
  SQL Injection
SQL Injection enables an attacker to execute arbitrary SQL code on your database server gaining access to user data, or manipulating user data.
  XPath Injection
XPath Injection enables an attacker to modify the parts of XML document that are read. If that XML document is for example used for authentication, this can lead to further vulnerabilities similar to SQL Injection.
  LDAP Injection
LDAP Injection enables an attacker to inject LDAP statements potentially granting permission to run unauthorized queries, or modify content inside the LDAP tree.
  Header Injection
  Other Vulnerability
This category comprises other attack vectors such as manipulating the PHP runtime, loading custom extensions, freezing the runtime, or similar.
  Regex Injection
Regex Injection enables an attacker to execute arbitrary code in your PHP process.
  XML Injection
XML Injection enables an attacker to read files on your local filesystem including configuration files, or can be abused to freeze your web-server process.
  Variable Injection
Variable Injection enables an attacker to overwrite program variables with custom data, and can lead to further vulnerabilities.
Unfortunately, the security analysis is currently not available for your project. If you are a non-commercial open-source project, please contact support to gain access.

formats/Exhibit/SRF_Exhibit.php (3 issues)

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 Exhibit to print query results.
4
 *
5
 * @author Fabian Howahl
6
 * @file
7
 * @ingroup SMWQuery
8
 */
9
10
use MediaWiki\MediaWikiServices;
11
12
/**
13
 * Result printer using Exhibit to display query results
14
 *
15
 * @ingroup SMWQuery
16
 */
17
class SRFExhibit extends SMWResultPrinter {
18
19
	// /mapping between SMW's and Exhibit's the data types
20
	protected $m_types = [ "_wpg" => "text", "_num" => "number", "_dat" => "date", "_geo" => "text", "_uri" => "url" ];
21
22
	protected static $exhibitRunningNumber = 0; // not sufficient since there might be multiple pages rendered within one PHP run; but good enough now
23
24
	// /overwrite function to allow execution of result printer even if no results are available (in case remote query yields no results in local wiki)
25
	public function getResult( $results, $params, $outputmode ) {
26
		$this->readParameters( $params, $outputmode );
27
		$result = $this->getResultText( $results, $outputmode );
28
		return $result;
29
	}
30
31
	// /function aligns the format of SMW's property names to Exhibit's format
32
	protected function encodePropertyName( $property ) {
33
		return strtolower( str_replace( " ", "_", trim( $property ) ) );
34
	}
35
36
	// /Tries to determine the namespace in the event it got lost
37
	protected function determineNamespace( $res ) {
38
		$row = $res->getNext();
39
		if ( $row != null ) {
40
			$tmp = clone $row[0];
41
			$object = $tmp->getNextDataValue();
42
43
			if ( $object instanceof SMWWikiPageValue ) {
44
				$value = $object->getPrefixedText();
45
				if ( strpos( $value, ':' ) ) {
46
					$value = explode( ':', $value, 2 );
47
					return $value[0] . ':';
48
				}
49
			}
50
		}
51
52
		return "";
53
	}
54
55
	protected function getResultText( SMWQueryResult $res, $outputmode ) {
56
57
		global $smwgIQRunningNumber, $wgScriptPath, $wgGoogleMapsKey, $srfgScriptPath;
58
59
		if ( defined( 'MW_SUPPORTS_RESOURCE_MODULES' ) ) {
60
			SMWOutputs::requireHeadItem( 'exhibit-compat', Html::linkedScript( "$wgScriptPath/common/wikibits.js" ) );
61
		}
62
63
		// //////////////////////////////
64
		// ///////REMOTE STUFF///////////
65
		// //////////////////////////////
66
67
		$remote = false;
68
69
		// in case the remote parameter is set, a link to the JSON export of the remote wiki is included in the header as data source for Exhibit
70
		// this section creates the link
71
		if ( array_key_exists( 'remote', $this->params ) && srfgExhibitRemote == true ) {
72
73
			$remote = true;
74
75
			// fetch interwiki link
76
			$dbr = &wfGetDB( DB_REPLICA );
77
			$cl = $dbr->tableName( 'interwiki' );
78
			$dbres = $dbr->select( $cl, 'iw_url', "iw_prefix='" . $this->params['remote'] . "'", __METHOD__, [] );
79
			$row = $dbr->fetchRow( $dbres );
80
			$extlinkpattern = $row[iw_url];
81
			$dbr->freeResult( $dbres );
82
83
			$newheader = '<link rel="exhibit/data" type="application/jsonp" href="';
84
			$link = $res->getQueryLink( 'JSON Link' );
85
			$link->setParameter( 'json', 'format' );
86
87
			if ( array_key_exists(
88
				'callback',
89
				$this->params
90
			) ) { // check if a special name for the callback function is set, if not stick with 'callback'
91
				$callbackfunc = $this->params['callback'];
92
			} else {
93
				$callbackfunc = 'callback';
94
			}
95
96
			if ( array_key_exists( 'limit', $this->params ) ) {
97
				$link->setParameter( $this->params['limit'], 'limit' );
98
			}
99
100
			$link->setParameter( $callbackfunc, 'callback' );
101
			$link = $link->getText( 2, $this->mLinker );
102
103
			list( $link, $trash ) = explode( '|', $link );
104
			$link = str_replace( '[[:', '', $link );
105
106
			$newheader .= str_replace( '$1', $link, $extlinkpattern );
107
			$newheader .= '" ex:jsonp-callback="' . $callbackfunc . '"';
108
			$newheader .= '/>';
109
110
			SMWOutputs::requireHeadItem( 'REMOTE', $newheader );
111
		}
112
113
		// the following variables indicate the use of special views
114
		// the variable's values define the way Exhibit is called
115
		$timeline = false;
116
		$map = false;
117
118
		/*The javascript file adopted from Wibbit uses a bunch of javascript variables in the header to store information about the Exhibit markup.
119
		 The following code sequence creates these variables*/
120
121
		// prepare sources (the sources holds information about the table which contains the information)
122
		$colstack = [];
123
		foreach ( $res->getPrintRequests() as $pr ) {
124
			$colstack[] = $this->encodePropertyName( $pr->getLabel() ) . ':' . ( array_key_exists(
125
					$pr->getTypeID(),
126
					$this->m_types
127
				) ? $this->m_types[$pr->getTypeID()] : 'text' );
128
		}
129
		array_shift( $colstack );
130
		array_unshift( $colstack, 'label' );
131
132
		if ( SRFExhibit::$exhibitRunningNumber == 0 ) {
133
			$sourcesrc = "var ex_sources = { source" . ( $smwgIQRunningNumber - 1 ) . ": { id:  'querytable" . $smwgIQRunningNumber . "' , columns: '" . implode(
134
					',',
135
					$colstack
136
				) . "'.split(','), hideTable: '1', type: 'Item', label: 'Item', pluralLabel: 'Items' } };";
137
		} else {
138
			$sourcesrc = "sources.source" . $smwgIQRunningNumber . " =  { id:  'querytable" . $smwgIQRunningNumber . "' , columns: '" . implode(
139
					',',
140
					$colstack
141
				) . "'.split(','), hideTable: '1', type: 'Item', label: 'Item', pluralLabel: 'Items' };";
142
		}
143
		$sourcesrc = "<script type=\"text/javascript\">" . $sourcesrc . "</script>";
144
145
		// prepare facets
146
		$facetcounter = 0;
147
		if ( array_key_exists( 'facets', $this->params ) ) {
148
			$facets = explode( ',', $this->params['facets'] );
149
			$facetstack = [];
150
			$params = [ 'height' ];
151
			$facparams = [];
152
			foreach ( $params as $param ) {
153
				if ( array_key_exists( $param, $this->params ) ) {
154
					$facparams[] = 'ex:' . $param . '="' . $this->encodePropertyName( $this->params[$param] ) . '" ';
155
				}
156
			}
157
			foreach ( $facets as $facet ) {
158
				$facet = trim( $facet );
159
				if ( strtolower( $facet ) == "search" ) { // special facet (text search)
160
					$facetstack[] = ' facet' . $facetcounter++ . ': { position : "right", innerHTML: \'ex:role="facet" ex:showMissing="false" ex:facetClass="TextSearch" ex:facetLabel="' . $facet . '"\'}';
161
				} else { // usual facet
162
					foreach ( $res->getPrintRequests() as $pr ) {
163
						if ( $this->encodePropertyName( $pr->getLabel() ) == $this->encodePropertyName( $facet ) ) {
164
							switch ( $pr->getTypeID() ) {
165
								case '_num':
166
									$facetstack[] = ' facet' . $facetcounter++ . ': { position : "right", innerHTML: \'ex:role="facet" ex:showMissing="false" ex:expression=".' . $this->encodePropertyName(
167
											$facet
168
										) . '" ex:facetLabel="' . $facet . '" ex:facetClass="Slider"\'}';
169
									break;
170
								default:
171
									$facetstack[] = ' facet' . $facetcounter++ . ': { position : "right", innerHTML: \'ex:role="facet" ex:showMissing="false" ' . implode(
172
											" ",
173
											$facparams
174
										) . ' ex:expression=".' . $this->encodePropertyName(
175
											$facet
176
										) . '" ex:facetLabel="' . $facet . '"\'}';
177
							}
178
						}
179
180
					}
181
				}
182
			}
183
			$facetstring = implode( ',', $facetstack );
184
		} else {
185
			$facetstring = '';
186
		}
187
		$facetsrc = "var ex_facets = {" . $facetstring . " };";
188
189
		// prepare views
190
		$stylesrc = '';
191
		if ( array_key_exists( 'views', $this->params ) ) {
192
			$views = explode( ',', $this->params['views'] );
193
		} else {
194
			$views[] = 'tiles';
195
		}
196
197
		foreach ( $views as $view ) {
198
			switch ( trim( $view ) ) {
199
				case 'tabular':// table view (the columns are automatically defined by the selected properties)
200
					$thstack = [];
201
					foreach ( $res->getPrintRequests() as $pr ) {
202
						$thstack[] = "." . $this->encodePropertyName( $pr->getLabel() );
203
					}
204
					array_shift( $thstack );
205
					array_unshift( $thstack, '.label' );
206
					$stylesrc = 'var myStyler = function(table, database) {table.className=\'smwtable\';};'; // assign SMWtable CSS to Exhibit tabular view
207
					$viewstack[] = 'ex:role=\'view\' ex:viewClass=\'Tabular\' ex:showSummary=\'false\' ex:sortAscending=\'true\' ex:tableStyler=\'myStyler\'  ex:label=\'Table\' ex:columns=\'' . implode(
208
							',',
209
							$thstack
210
						) . '\' ex:sortAscending=\'false\'';
211
					break;
212
				case 'timeline':// timeline view
213
					$timeline = true;
214
					$exparams = [
215
						'start',
216
						'end',
217
						'proxy',
218
						'colorkey' ]; // parameters expecting an Exhibit graph expression
219
					$usparams = [
220
						'timelineheight',
221
						'topbandheight',
222
						'bottombandheight',
223
						'bottombandunit',
224
						'topbandunit' ]; // parametes expecting a textual or numeric value
225
					$tlparams = [];
226
					foreach ( $exparams as $param ) {
227
						if ( array_key_exists( $param, $this->params ) ) {
228
							$tlparams[] = 'ex:' . $param . '=\'.' . $this->encodePropertyName(
229
									$this->params[$param]
230
								) . '\' ';
231
						}
232
					}
233
					foreach ( $usparams as $param ) {
234
						if ( array_key_exists( $param, $this->params ) ) {
235
							$tlparams[] = 'ex:' . $param . '=\'' . $this->encodePropertyName(
236
									$this->params[$param]
237
								) . '\' ';
238
						}
239
					}
240
					if ( !array_key_exists(
241
						'start',
242
						$this->params
243
					) ) {// find out if a start and/or end date is specified
244
						$dates = [];
245
						foreach ( $res->getPrintRequests() as $pr ) {
246
							if ( $pr->getTypeID() == '_dat' ) {
247
								$dates[] = $pr;
248
								if ( sizeof( $dates ) > 2 ) {
249
									break;
250
								}
251
							}
252
						}
253
						if ( sizeof( $dates ) == 1 ) {
254
							$tlparams[] = 'ex:start=\'.' . $this->encodePropertyName( $dates[0]->getLabel() ) . '\' ';
255
						} elseif ( sizeof( $dates ) == 2 ) {
256
							$tlparams[] = 'ex:start=\'.' . $this->encodePropertyName( $dates[0]->getLabel() ) . '\' ';
257
							$tlparams[] = 'ex:end=\'.' . $this->encodePropertyName( $dates[1]->getLabel() ) . '\' ';
258
						}
259
					}
260
					$viewstack[] = 'ex:role=\'view\' ex:viewClass=\'Timeline\' ex:label=\'Timeline\' ex:showSummary=\'false\' ' . implode(
0 ignored issues
show
The variable $viewstack does not seem to be defined for all execution paths leading up to this point.

If you define a variable conditionally, it can happen that it is not defined for all execution paths.

Let’s take a look at an example:

function myFunction($a) {
    switch ($a) {
        case 'foo':
            $x = 1;
            break;

        case 'bar':
            $x = 2;
            break;
    }

    // $x is potentially undefined here.
    echo $x;
}

In the above example, the variable $x is defined if you pass “foo” or “bar” as argument for $a. However, since the switch statement has no default case statement, if you pass any other value, the variable $x would be undefined.

Available Fixes

  1. Check for existence of the variable explicitly:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        if (isset($x)) { // Make sure it's always set.
            echo $x;
        }
    }
    
  2. Define a default value for the variable:

    function myFunction($a) {
        $x = ''; // Set a default which gets overridden for certain paths.
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        echo $x;
    }
    
  3. Add a value for the missing path:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
    
            // We add support for the missing case.
            default:
                $x = '';
                break;
        }
    
        echo $x;
    }
    
Loading history...
261
							" ",
262
							$tlparams
263
						);
264
					break;
265
				case 'map':// map view
266
					if ( isset( $wgGoogleMapsKey ) ) {
267
						$map = true;
268
						$exparams = [ 'latlng', 'colorkey' ];
269
						$usparams = [
270
							'type',
271
							'center',
272
							'zoom',
273
							'size',
274
							'scalecontrol',
275
							'overviewcontrol',
276
							'mapheight' ];
277
						$mapparams = [];
278
						foreach ( $exparams as $param ) {
279
							if ( array_key_exists( $param, $this->params ) ) {
280
								$mapparams[] = 'ex:' . $param . '=\'.' . $this->encodePropertyName(
281
										$this->params[$param]
282
									) . '\' ';
283
							}
284
						}
285
						foreach ( $usparams as $param ) {
286
							if ( array_key_exists( $param, $this->params ) ) {
287
								$mapparams[] = 'ex:' . $param . '=\'' . $this->encodePropertyName(
288
										$this->params[$param]
289
									) . '\' ';
290
							}
291
						}
292
						if ( !array_key_exists( 'start', $this->params ) && !array_key_exists(
293
								'end',
294
								$this->params
295
							) ) { // find out if a geographic coordinate is available
296
							foreach ( $res->getPrintRequests() as $pr ) {
297
								if ( $pr->getTypeID() == '_geo' ) {
298
									$mapparams[] = 'ex:latlng=\'.' . $this->encodePropertyName(
299
											$pr->getLabel()
300
										) . '\' ';
301
									break;
302
								}
303
							}
304
						}
305
						$viewstack[] .= 'ex:role=\'view\' ex:viewClass=\'Map\' ex:showSummary=\'false\' ex:label=\'Map\' ' . implode(
306
								" ",
307
								$mapparams
308
							);
309
					}
310
					break;
311
				default:
312
				case 'tiles':// tile view
313
					$sortstring = '';
314
					if ( array_key_exists( 'sort', $this->params ) ) {
315
						$sortfields = explode( ",", $this->params['sort'] );
316
						foreach ( $sortfields as $field ) {
317
							$sortkeys[] = "." . $this->encodePropertyName( trim( $field ) );
318
						}
319
						$sortstring = 'ex:orders=\'' . implode( ",", $sortkeys ) . '\' ';
320
						if ( array_key_exists( 'order', $this->params ) ) {
321
							$sortstring .= ' ex:directions=\'' . $this->encodePropertyName(
322
									$this->params['order']
323
								) . '\'';
324
						}
325
						if ( array_key_exists( 'grouped', $this->params ) ) {
326
							$sortstring .= ' ex:grouped=\'' . $this->encodePropertyName(
327
									$this->params['grouped']
328
								) . '\'';
329
						}
330
					}
331
					$viewstack[] = 'ex:role=\'view\' ex:showSummary=\'false\' ' . $sortstring;
332
					break;
333
			}
334
		}
335
336
		$viewsrc = 'var ex_views = "' . implode( "/", $viewstack ) . '".split(\'/\');;';
337
338
		// prepare automatic lenses
339
340
		$lenscounter = 0;
341
		$linkcounter = 0;
342
		$imagecounter = 0;
343
344
		if ( array_key_exists(
345
			'lens',
346
			$this->params
347
		) ) {// a customized lens is specified via the lens parameter within the query
348
			$lenstitle = Title::newFromText( "Template:" . $this->params['lens'] );
349
			$lensarticle = new Article( $lenstitle );
350
			$lenswikitext = $lensarticle->getContent();
351
352
			if ( preg_match_all(
353
				"/[\[][\[][Ii][m][a][g][e][:][{][{][{][1-9A-z\-[:space:]]*[}][}][}][\]][\]]/u",
354
				$lenswikitext,
355
				$matches
356
			) ) {
357
				foreach ( $matches as $match ) {
358
					foreach ( $match as $value ) {
359
						$strippedvalue = trim( substr( $value, 8 ), "[[{}]]" );
360
						$lenswikitext = str_replace(
361
							$value,
362
							'<div class="inlines" id="imagecontent' . $imagecounter . '">' . $this->encodePropertyName(
363
								strtolower( str_replace( "\n", "", $strippedvalue ) )
364
							) . '</div>',
365
							$lenswikitext
366
						);
367
						$imagecounter++;
368
					}
369
				}
370
			}
371
372
			if ( preg_match_all(
373
				"/[\[][\[][{][{][{][1-9A-z\-[:space:]]*[}][}][}][\]][\]]/u",
374
				$lenswikitext,
375
				$matches
376
			) ) {
377
				foreach ( $matches as $match ) {
378
					foreach ( $match as $value ) {
379
						$strippedvalue = trim( $value, "[[{}]]" );
380
						$lenswikitext = str_replace(
381
							$value,
382
							'<div class="inlines" id="linkcontent' . $linkcounter . '">' . $this->encodePropertyName(
383
								strtolower( str_replace( "\n", "", $strippedvalue ) )
384
							) . '</div>',
385
							$lenswikitext
386
						);
387
						$linkcounter++;
388
					}
389
				}
390
			}
391
392
			if ( preg_match_all( "/[{][{][{][1-9A-z\:\|\/\=\-[:space:]]*[}][}][}]/u", $lenswikitext, $matches ) ) {
393
				foreach ( $matches as $match ) {
394
					foreach ( $match as $value ) {
395
						$strippedvalue = trim( $value, "{}" );
396
						$lenswikitext = str_replace(
397
							$value,
398
							'<div class="inlines" id="lenscontent' . $lenscounter . '">' . $this->encodePropertyName(
399
								strtolower( str_replace( "\n", "", $strippedvalue ) )
400
							) . '</div>',
401
							$lenswikitext
402
						);
403
						$lenscounter++;
404
					}
405
				}
406
			}
407
408
			$parser = MediaWikiServices::getInstance()->getParser();
409
			$lenshtml = $parser->internalParse(
410
				$lenswikitext
411
			);// $parser->parse($lenswikitext, $lenstitle, new ParserOptions(), true, true)->getText();
412
413
			$lenssrc = "var ex_lens = '" . str_replace(
414
					"\n",
415
					"",
416
					$lenshtml
417
				) . "';ex_lenscounter =" . $lenscounter . ";ex_linkcounter=" . $linkcounter . ";ex_imagecounter=" . $imagecounter . ";";
418
		} else {// generic lens (creates links to further content (property-pages, pages about values)
419
			foreach ( $res->getPrintRequests() as $pr ) {
420
				if ( $remote ) {
421
					$wikiurl = str_replace( "$1", "", $extlinkpattern );
0 ignored issues
show
The variable $extlinkpattern does not seem to be defined for all execution paths leading up to this point.

If you define a variable conditionally, it can happen that it is not defined for all execution paths.

Let’s take a look at an example:

function myFunction($a) {
    switch ($a) {
        case 'foo':
            $x = 1;
            break;

        case 'bar':
            $x = 2;
            break;
    }

    // $x is potentially undefined here.
    echo $x;
}

In the above example, the variable $x is defined if you pass “foo” or “bar” as argument for $a. However, since the switch statement has no default case statement, if you pass any other value, the variable $x would be undefined.

Available Fixes

  1. Check for existence of the variable explicitly:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        if (isset($x)) { // Make sure it's always set.
            echo $x;
        }
    }
    
  2. Define a default value for the variable:

    function myFunction($a) {
        $x = ''; // Set a default which gets overridden for certain paths.
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        echo $x;
    }
    
  3. Add a value for the missing path:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
    
            // We add support for the missing case.
            default:
                $x = '';
                break;
        }
    
        echo $x;
    }
    
Loading history...
422
				} else {
423
					$wikiurl = $wgScriptPath . "/index.php?title=";
424
				}
425
				if ( $pr->getTypeID() == '_wpg' ) {
426
					$prefix = '';
427
					if ( $pr->getLabel() == 'Category' ) {
428
						$prefix = "Category:";
429
					}
430
					$lensstack[] = '<tr ex:if-exists=".' . $this->encodePropertyName(
431
							$pr->getLabel()
432
						) . '"><td width="20%">' . $pr->getText(
433
							0,
434
							$this->mLinker
435
						) . '</td><td width="80%" ex:content=".' . $this->encodePropertyName(
436
							$pr->getLabel()
437
						) . '"><a ex:href-subcontent="' . $wikiurl . $prefix . '{{urlencval(value)}}"><div ex:content="value" class="name"></div></a></td></tr>';
438
				} else {
439
					$lensstack[] = '<tr ex:if-exists=".' . $this->encodePropertyName(
440
							$pr->getLabel()
441
						) . '"><td width="20%">' . $pr->getText(
442
							0,
443
							$this->mLinker
444
						) . '</td><td width="80%"><div ex:content=".' . $this->encodePropertyName(
445
							$pr->getLabel()
446
						) . '" class="name"></div></td></tr>';
447
				}
448
			}
449
			array_shift( $lensstack );
450
			$lenssrc = 'var ex_lens = \'<table width=100% cellpadding=3><tr><th class="head" align=left bgcolor="#DDDDDD"><a ex:href-subcontent="' . $wikiurl . $this->determineNamespace(
451
					clone $res
452
				) . '{{urlenc(.label)}}" class="linkhead"><div ex:content=".label" class="name"></div></a></th></tr></table><table width="100%" cellpadding=3>' . implode(
453
					"",
454
					$lensstack
455
				) . '</table>\'; ex_lenscounter = 0; ex_linkcounter=0; ex_imagecounter=0;';
456
		}
457
458
		if ( $remote ) {
459
			$varremote = 'true';
460
		} else {
461
			$varremote = 'false';
462
		}
463
464
		// Handling special formats like date
465
		$formatssrc = 'var formats =\'\'';
466
		if ( array_key_exists( 'date', $this->params ) ) {
467
			$formatssrc = 'var formats = \'ex:formats="date { mode:' . $this->params['date'] . '; show:date }"\';';
468
		}
469
470
		// create a URL pointing to the corresponding JSON feed
471
		$label = '';
472
		$JSONlink = $res->getQueryLink( $label );
473
		if ( $this->getSearchLabel( SMW_OUTPUT_WIKI ) != '' ) { // used as a file name
474
			$link->setParameter( $this->getSearchLabel( SMW_OUTPUT_WIKI ), 'searchlabel' );
0 ignored issues
show
The variable $link does not seem to be defined for all execution paths leading up to this point.

If you define a variable conditionally, it can happen that it is not defined for all execution paths.

Let’s take a look at an example:

function myFunction($a) {
    switch ($a) {
        case 'foo':
            $x = 1;
            break;

        case 'bar':
            $x = 2;
            break;
    }

    // $x is potentially undefined here.
    echo $x;
}

In the above example, the variable $x is defined if you pass “foo” or “bar” as argument for $a. However, since the switch statement has no default case statement, if you pass any other value, the variable $x would be undefined.

Available Fixes

  1. Check for existence of the variable explicitly:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        if (isset($x)) { // Make sure it's always set.
            echo $x;
        }
    }
    
  2. Define a default value for the variable:

    function myFunction($a) {
        $x = ''; // Set a default which gets overridden for certain paths.
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        echo $x;
    }
    
  3. Add a value for the missing path:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
    
            // We add support for the missing case.
            default:
                $x = '';
                break;
        }
    
        echo $x;
    }
    
Loading history...
475
		}
476
		if ( array_key_exists( 'limit', $this->params ) ) {
477
			$JSONlink->setParameter( htmlspecialchars( $this->params['limit'] ), 'limit' );
478
		}
479
		$JSONlink->setParameter( 'json', 'format' );
480
		$stringtoedit = explode( "|", $JSONlink->getText( $outputmode, $this->mLinker ) );
481
		$stringtoedit = substr( $stringtoedit[0], 3 );
482
		$JSONlinksrc = "var JSONlink = '" . $stringtoedit . "';";
483
484
		// create script header with variables containing the Exhibit markup
485
		$headervars = "<script type='text/javascript'>\n\t\t\t" . $facetsrc . "\n\t\t\t" . $viewsrc . "\n\t\t\t" . $lenssrc . "\n\t\t\t" . $stylesrc . "\n\t\t\t" . $formatssrc . "\n\t\t\t" . $JSONlinksrc . "\n\t\t\t var remote=" . $varremote . ";</script>";
486
487
		// To run Exhibit some links to the scripts of the API need to be included in the header
488
489
		$ExhibitScriptSrc1 = '<script type="text/javascript" src="' . $srfgScriptPath . '/Exhibit/exhibit/exhibit-api.js?autoCreate=false&safe=true&bundle=false';
490
		if ( $timeline ) {
491
			$ExhibitScriptSrc1 .= '&views=timeline';
492
		}
493
		if ( $map ) {
494
			$ExhibitScriptSrc1 .= '&gmapkey=' . $wgGoogleMapsKey;
495
		}
496
		$ExhibitScriptSrc1 .= '"></script>';
497
		$ExhibitScriptSrc2 = '<script type="text/javascript" src="' . $srfgScriptPath . '/Exhibit/SRF_Exhibit.js"></script>';
498
		$CSSSrc = '<link rel="stylesheet" type="text/css" href="' . $srfgScriptPath . '/Exhibit/SRF_Exhibit.css"></link>';
499
500
		SMWOutputs::requireHeadItem( 'CSS', $CSSSrc ); // include CSS
501
		SMWOutputs::requireHeadItem( 'EXHIBIT1', $ExhibitScriptSrc1 ); // include Exhibit API
502
		SMWOutputs::requireHeadItem(
503
			'EXHIBIT2',
504
			$ExhibitScriptSrc2
505
		); // includes javascript overwriting the Exhibit start-up functions
506
		SMWOutputs::requireHeadItem( 'SOURCES' . $smwgIQRunningNumber, $sourcesrc );// include sources variable
507
		SMWOutputs::requireHeadItem( 'VIEWSFACETS', $headervars );// include views and facets variable
508
509
		if ( !$remote ) {
510
511
			// print input table
512
			// print header
513
			$result = "<table style=\"display:none\" class=\"smwtable\" id=\"querytable" . $smwgIQRunningNumber . "\">\n";
514
			if ( $this->mShowHeaders ) { // building headers
515
				$result .= "\t<tr>\n";
516
				foreach ( $res->getPrintRequests() as $pr ) {
517
					if ( $pr->getText( $outputmode, $this->getLinker( 0 ) ) == '' ) {
518
						$headerlabel = "Name";
519
					} else {
520
						$headerlabel = $pr->getText( $outputmode, $this->getLinker( 0 ) );
521
					}
522
					$result .= "\t\t<th>" . $headerlabel . "</th>\n";
523
				}
524
				$result .= "\t</tr>\n";
525
			}
526
527
			// print all result rows
528
			while ( $row = $res->getNext() ) {
529
				$result .= "\t<tr>\n";
530
				foreach ( $row as $field ) {
531
					$result .= "\t\t<td>";
532
					$textstack = [];
533
					while ( ( $object = $field->getNextDataValue() ) !== false ) {
534
						switch ( $object->getTypeID() ) {
535
							case '_wpg':
536
								$textstack[] = $object->getLongText( $outputmode, $this->getLinker( 0 ) );
537
								break;
538
							case '_geo':
539
								$c = $object->getDBKeys();
540
								$textstack[] = $c[0] . "," . $c[1];
541
								break;
542
							case '_num':
543
								if ( method_exists( $object, 'getValueKey' ) ) {
544
									$textstack[] = $object->getValueKey( $outputmode, $this->getLinker( 0 ) );
545
								} else {
546
									$textstack[] = $object->getNumericValue( $outputmode, $this->getLinker( 0 ) );
547
								}
548
								break;
549
							case '_dat':
550
								$textstack[] = $object->getYear() . "-" . str_pad(
551
										$object->getMonth(),
552
										2,
553
										'0',
554
										STR_PAD_LEFT
555
									) . "-" . str_pad(
556
										$object->getDay(),
557
										2,
558
										'0',
559
										STR_PAD_LEFT
560
									) . " " . $object->getTimeString();
561
								break;
562
							case '_ema':
563
								$textstack[] = $object->getShortWikiText( $this->getLinker( 0 ) );
564
								break;
565
							case '_tel':
566
							case '_anu':
567
							case '_uri':
568
								$textstack[] = $object->getWikiValue();
569
								break;
570
							case '__sin':
571
								$tmp = $object->getShortText( $outputmode, null );
572
								if ( strpos( $tmp, ":" ) ) {
573
									$tmp = explode( ":", $tmp, 2 );
574
									$tmp = $tmp[1];
575
								}
576
								$textstack[] = $tmp;
577
								break;
578
							case '_txt':
579
							case '_cod':
580
							case '_str':
581
								$textstack[] = $object->getWikiValue();
582
								break;
583
							default:
584
								$textstack[] = $object->getLongHTMLText( $this->getLinker( 0 ) );
585
						}
586
					}
587
588
					if ( $textstack != null ) {
589
						$result .= implode( ';', $textstack ) . "</td>\n";
590
					} else {
591
						$result .= "</td>\n";
592
					}
593
				}
594
				$result .= "\t</tr>\n";
595
			}
596
			$result .= "</table>\n";
597
		}
598
599
		if ( SRFExhibit::$exhibitRunningNumber == 0 ) {
600
			$result .= "<div id=\"exhibitLocation\"></div>";
601
		} // print placeholder (just print it one time)
602
		$this->isHTML = ( $outputmode == SMW_OUTPUT_HTML ); // yes, our code can be viewed as HTML if requested, no more parsing needed
603
		SRFExhibit::$exhibitRunningNumber++;
604
		return $result;
605
	}
606
607
	/**
608
	 * @see SMWResultPrinter::getParamDefinitions
609
	 *
610
	 * @since 1.8
611
	 *
612
	 * @param $definitions array of IParamDefinition
613
	 *
614
	 * @return array of IParamDefinition|array
615
	 */
616
	public function getParamDefinitions( array $definitions ) {
617
		$params = parent::getParamDefinitions( $definitions );
618
619
		$params[] = [
620
			'name' => 'views',
621
			'message' => 'srf_paramdesc_views',
622
			'islist' => true,
623
			'values' => [ 'tiles', 'tabular', 'timeline', 'maps' ] ];
624
		$params[] = [ 'name' => 'facets', 'message' => 'srf_paramdesc_facets' ];
625
		$params[] = [ 'name' => 'lens', 'message' => 'srf_paramdesc_lens' ];
626
627
		return $params;
628
	}
629
630
}
631