Completed
Push — master ( 6dc7d8...407c40 )
by Karsten
15:45
created

formats/calendar/SRF_Calendar.php (10 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
0 ignored issues
show
Coding Style Compatibility introduced by
For compatibility and reusability of your code, PSR1 recommends that a file should introduce either new symbols (like classes, functions, etc.) or have side-effects (like outputting something, or including other files), but not both at the same time. The first symbol is defined on line 14 and the first side effect is on line 3.

The PSR-1: Basic Coding Standard recommends that a file should either introduce new symbols, that is classes, functions, constants or similar, or have side effects. Side effects are anything that executes logic, like for example printing output, changing ini settings or writing to a file.

The idea behind this recommendation is that merely auto-loading a class should not change the state of an application. It also promotes a cleaner style of programming and makes your code less prone to errors, because the logic is not spread out all over the place.

To learn more about the PSR-1, please see the PHP-FIG site on the PSR-1.

Loading history...
2
3
$wgAutoloadClasses['SRFCHistoricalDate'] = dirname( __FILE__ )
4
	. '/SRFC_HistoricalDate.php';
5
6
/**
7
 * Result printer that prints query results as a monthly calendar.
8
 *
9
 * @file SRF_Calendar.php
10
 * @ingroup SemanticResultFormats
11
 *
12
 * @author Yaron Koren
13
 */
14
class SRFCalendar extends SMWResultPrinter {
15
16
	protected $mTemplate;
17
	protected $mUserParam;
18
	protected $mRealUserLang = null;
19
	protected $mStartMonth;
20
	protected $mStartYear;
21
22
	protected function setColors( $colorsText ) {
23
		$colors = [];
24
		$colorElements = explode( ',', $colorsText );
25
		foreach ( $colorElements as $colorElem ) {
26
			$propAndColor = explode( '=>', $colorElem );
27
			if ( count( $propAndColor ) == 2 ) {
28
				$colors[$propAndColor[0]] = $propAndColor[1];
29
			}
30
		}
31
		$this->mColors = $colors;
32
	}
33
34
	protected function handleParameters( array $params, $outputmode ) {
35
		parent::handleParameters( $params, $outputmode );
36
37
		$this->mTemplate = trim( $params['template'] );
38
		$this->mUserParam = trim( $params['userparam'] );
39
		// startmonth is initialized with current month by default
40
		$this->mStartMonth = trim( $params['startmonth'] );
41
		// startyear is initialized with current year by default
42
		$this->mStartYear = trim( $params['startyear'] );
43
44
		if ( $params['lang'] !== false ) {
45
			global $wgLang;
46
			// Store the actual user's language, so we can revert
47
			// back to it after printing the calendar.
48
			$this->mRealUserLang = clone ( $wgLang );
49
			$wgLang = Language::factory( trim( $params['lang'] ) );
50
		}
51
52
		$this->setColors( $params['colors'] );
53
	}
54
55
	public function getName() {
56
		return wfMessage( 'srf_printername_calendar' )->text();
57
	}
58
59
	/**
60
	 * @see SMWResultPrinter::buildResult
61
	 *
62
	 * @since 1.8
63
	 *
64
	 * @param SMWQueryResult $results
65
	 *
66
	 * @return string
67
	 */
68
	protected function buildResult( SMWQueryResult $results ) {
69
		$this->isHTML = false;
70
		$this->hasTemplates = false;
71
72
		// Skip checks - results with 0 entries are normal.
73
		return $this->getResultText( $results, SMW_OUTPUT_HTML );
74
	}
75
76
	/**
77
	 * (non-PHPdoc)
78
	 * @see SMWResultPrinter::getResultText()
79
	 *
80
	 * @todo Split up megamoth
81
	 */
82
	protected function getResultText( SMWQueryResult $res, $outputmode ) {
83
		$events = [];
84
85
		// Print all result rows.
86
		while ( $row = $res->getNext() ) {
87
			$dates = [];
88
			$title = $text = $color = '';
89
90
			if ( $this->mTemplate != '' ) {
91
				// Build template code
92
				$this->hasTemplates = true;
93
94
				if ( $this->mUserParam ) {
95
					$text = "|userparam=$this->mUserParam";
96
				}
97
98
				foreach ( $row as $i => $field ) {
99
					$pr = $field->getPrintRequest();
100
					$text .= '|' . ( $i + 1 ) . '=';
101
102
					while (
103
						( $object = $field->getNextDataValue() ) !== false
104
					) {
105
						if ( $object->getTypeID() == '_dat' ) {
106
							$text .= $object->getLongWikiText();
107
108
							// use shorter "LongText" for wikipage
109
						} elseif ( $object->getTypeID() == '_wpg' ) {
110
							// handling of "link=" param
111
							if ( $this->mLinkOthers ) {
112
								$text .=
113
									$object->getLongText( $outputmode, null );
114
							} else {
115
								$text .= $object->getWikiValue();
116
							}
117
						} else {
118
							$text .= $object->getShortText( $outputmode, null );
119
						}
120
121
						if (
122
							$pr->getMode() == SMWPrintRequest::PRINT_PROP &&
123
							$pr->getTypeID() == '_dat'
124
						) {
125
							$datePropLabel = $pr->getLabel();
126
							if ( !array_key_exists( $datePropLabel, $dates ) ) {
127
								$dates[$datePropLabel] = [];
128
							}
129
							$dates[$datePropLabel][] =
130
								$this->formatDateStr( $object );
131
						}
132
					}
133
				}
134
			} else {
135
				// Build simple text.
136
				$numNonDateProperties = 0;
137
				// Cycle through a 'row', which is the page
138
				// name (the first field) plus all its
139
				// properties.
140
				foreach ( $row as $i => $field ) {
141
					$pr = $field->getPrintRequest();
142
					// A property can have more than one
143
					// value - cycle through all the values
144
					// for this property.
145
					$textForProperty = '';
146
147
					while (
148
						( $object = $field->getNextDataValue() ) !== false
149
					) {
150
						if ( $object->getTypeID() == '_dat' ) {
0 ignored issues
show
This if statement is empty and can be removed.

This check looks for the bodies of if statements that have no statements or where all statements have been commented out. This may be the result of changes for debugging or the code may simply be obsolete.

These if bodies can be removed. If you have an empty if but statements in the else branch, consider inverting the condition.

if (rand(1, 6) > 3) {
//print "Check failed";
} else {
    print "Check succeeded";
}

could be turned into

if (rand(1, 6) <= 3) {
    print "Check succeeded";
}

This is much more concise to read.

Loading history...
151
							// Don't add date values to the display.
152
153
							// use shorter "LongText" for wikipage
154
						} elseif ( $object->getTypeID() == '_wpg' ) {
155
							if ( $i == 0 ) {
156
								$title = Title::newFromText(
157
									$object->getShortWikiText( false )
158
								);
159
							} else {
160
								$numNonDateProperties++;
161
162
								// handling of "headers=" param
163
								if ( $this->mShowHeaders == SMW_HEADERS_SHOW ) {
164
									$textForProperty .= $pr->getHTMLText(
165
											smwfGetLinker()
166
										) . ' ';
167
								} elseif (
168
									$this->mShowHeaders == SMW_HEADERS_PLAIN
169
								) {
170
									$textForProperty .= $pr->getLabel() . ' ';
171
								}
172
173
								// If $this->mShowHeaders == SMW_HEADERS_HIDE,
174
								//	print nothing.
175
								// handling of "link=" param
176
								if ( $this->mLinkOthers ) {
177
									$textForProperty .= $object->getLongText(
178
										$outputmode,
179
										smwfGetLinker()
180
									);
181
								} else {
182
									$textForProperty .= $object->getWikiValue();
183
								}
184
							}
185
						} else {
186
							$numNonDateProperties++;
187
							$textForProperty .=
188
								$pr->getHTMLText( smwfGetLinker() )
189
								. ' ' . $object->getShortText(
190
									$outputmode,
191
									smwfGetLinker()
192
								);
193
						}
194
						if (
195
							$pr->getMode() == SMWPrintRequest::PRINT_PROP &&
196
							$pr->getTypeID() == '_dat'
197
						) {
198
							$datePropLabel = $pr->getLabel();
199
							if ( !array_key_exists( $datePropLabel, $dates ) ) {
200
								$dates[$datePropLabel] = [];
201
							}
202
							$dates[$datePropLabel][] =
203
								$this->formatDateStr( $object );
204
						}
205
					}
206
207
					// Add the text for this property to
208
					// the main text, adding on parentheses
209
					// or commas as needed.
210
					if ( $numNonDateProperties == 1 ) {
211
						$text .= ' (';
212
					} elseif ( $numNonDateProperties > 1 ) {
213
						$text .= ', ';
214
					}
215
					$text .= $textForProperty;
216
				}
217
				if ( $numNonDateProperties > 0 ) {
218
					$text .= ')';
219
				}
220
			}
221
222
			if ( count( $dates ) > 0 ) {
223
				// Handle the 'color=' value, whether it came
224
				// from a compound query or a regular one.
225
				$resSubject = $field->getResultSubject();
0 ignored issues
show
The variable $field 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...
226
				if ( isset( $resSubject->display_options )
227
					&& is_array( $resSubject->display_options ) ) {
228
					if ( array_key_exists(
229
						'color',
230
						$resSubject->display_options
231
					)
232
					) {
233
						$color = $resSubject->display_options['color'];
234
					}
235
					if (
236
					array_key_exists(
237
						'colors',
238
						$resSubject->display_options
239
					)
240
					) {
241
						$this->setColors(
242
							$resSubject->display_options['colors']
243
						);
244
					}
245
				}
246
247
				foreach ( $dates as $label => $datesForLabel ) {
248
					foreach ( $datesForLabel as $date ) {
249
						$curText = $text;
250
						// If there's more than one
251
						// label, i.e. more than one
252
						// date property being displayed,
253
						// show the name of the current
254
						// property in parentheses.
255
						if ( count( $dates ) > 1 ) {
256
							$curText = "($label) " . $curText;
257
						}
258
						$curColor = $color;
259
						if ( array_key_exists( $label, $this->mColors ) ) {
260
							$curColor = $this->mColors[$label];
261
						}
262
						$events[] = [ $title, $curText, $date, $curColor ];
263
					}
264
				}
265
			}
266
		}
267
268
		$result = $this->displayCalendar( $events );
269
270
		// Go back to the actual user's language, in case a different
271
		// language had been specified for this calendar.
272
		if ( !is_null( $this->mRealUserLang ) ) {
273
			global $wgLang;
274
			$wgLang = $this->mRealUserLang;
275
		}
276
277
		global $wgParser;
278
279
		if ( is_null( $wgParser->getTitle() ) ) {
280
			return $result;
281
		} else {
282
			return [ $result, 'noparse' => 'true', 'isHTML' => 'true' ];
283
		}
284
	}
285
286
	protected static function intToMonth( $int ) {
287
		$months = [
288
			'1' => 'january',
289
			'2' => 'february',
290
			'3' => 'march',
291
			'4' => 'april',
292
			'5' => 'may_long',
293
			'6' => 'june',
294
			'7' => 'july',
295
			'8' => 'august',
296
			'9' => 'september',
297
			'10' => 'october',
298
			'11' => 'november',
299
			'12' => 'december',
300
		];
301
302
		return wfMessage(
303
			array_key_exists( $int, $months )
304
				? $months[$int]
305
				: 'january'
306
		)->inContentLanguage()->text();
307
	}
308
309
	function formatDateStr( $object ) {
0 ignored issues
show
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
Comprehensibility Best Practice introduced by
It is recommend to declare an explicit visibility for formatDateStr.

Generally, we recommend to declare visibility for all methods in your source code. This has the advantage of clearly communication to other developers, and also yourself, how this method should be consumed.

If you are not sure which visibility to choose, it is a good idea to start with the most restrictive visibility, and then raise visibility as needed, i.e. start with private, and only raise it to protected if a sub-class needs to have access, or public if an external class needs access.

Loading history...
310
		// For some reason, getMonth() and getDay() sometimes return a
311
		// number with a leading zero - get rid of it using (int)
312
		return $object->getYear()
313
			. '-' . (int)$object->getMonth() . '-' . (int)$object->getDay();
314
	}
315
316
	function displayCalendar( $events ) {
0 ignored issues
show
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
displayCalendar uses the super-global variable $_REQUEST 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...
Comprehensibility Best Practice introduced by
It is recommend to declare an explicit visibility for displayCalendar.

Generally, we recommend to declare visibility for all methods in your source code. This has the advantage of clearly communication to other developers, and also yourself, how this method should be consumed.

If you are not sure which visibility to choose, it is a good idea to start with the most restrictive visibility, and then raise visibility as needed, i.e. start with private, and only raise it to protected if a sub-class needs to have access, or public if an external class needs access.

Loading history...
317
		global $wgParser;
318
		global $srfgFirstDayOfWeek;
319
		global $srfgScriptPath;
320
321
		$context = RequestContext::getMain();
322
		$request = $context->getRequest();
323
		if ( !$wgParser->mFirstCall ) {
324
			$wgParser->disableCache();
325
		}
326
327
		$context->getOutput()->addLink(
328
			[
329
				'rel' => 'stylesheet',
330
				'type' => 'text/css',
331
				'media' => 'screen, print',
332
				'href' => $srfgScriptPath
333
					. '/formats/calendar/resources/ext.srf.calendar.css'
334
			]
335
		);
336
337
		// Set variables differently depending on whether this is
338
		// being called from a regular page, via #ask, or from a
339
		// special page: most likely either Special:Ask or
340
		// Special:RunQuery.
341
		$pageTitle = $context->getTitle();
342
		if ( !$pageTitle ) {
343
			$pageTitle = $wgParser->getTitle();
344
		}
345
		$additionalQueryString = '';
346
		$hiddenInputs = '';
347
348
		if ( $pageTitle->isSpecialPage() ) {
349
			$requestValues = $request->getValues();
350
			// Also go through the predefined PHP variable
351
			// $_REQUEST, because $request->getValues() for
352
			// some reason doesn't return array values - is
353
			// there a better (less hacky) way to do this?
354
			foreach ( $_REQUEST as $key => $value ) {
355
				if ( is_array( $value ) ) {
356
					foreach ( $value as $k2 => $v2 ) {
357
						$newKey = $key . '[' . $k2 . ']';
358
						$requestValues[$newKey] = $v2;
359
					}
360
				}
361
			}
362
363
			foreach ( $requestValues as $key => $value ) {
364
				if ( $key != 'month' && $key != 'year'
365
					// values from 'RunQuery'
366
					&& $key != 'query' && $key != 'free_text'
367
				) {
368
					$additionalQueryString .= "&$key=$value";
369
					$hiddenInputs .= "<input type=\"hidden\" " .
370
						"name=\"$key\" value=\"$value\" />";
371
				}
372
			}
373
		}
374
375
		// Set days of the week.
376
		$weekDayNames = [
377
			1 => wfMessage( 'sunday' )->text(),
378
			2 => wfMessage( 'monday' )->text(),
379
			3 => wfMessage( 'tuesday' )->text(),
380
			4 => wfMessage( 'wednesday' )->text(),
381
			5 => wfMessage( 'thursday' )->text(),
382
			6 => wfMessage( 'friday' )->text(),
383
			7 => wfMessage( 'saturday' )->text()
384
		];
385
		if ( empty( $srfgFirstDayOfWeek ) ) {
386
			$firstDayOfWeek = 1;
387
			$lastDayOfWeek = 7;
388
		} else {
389
			$firstDayOfWeek =
390
				array_search( $srfgFirstDayOfWeek, $weekDayNames );
391
			if ( $firstDayOfWeek === false ) {
392
				// Bad value for $srfgFirstDayOfWeek!
393
				print 'Warning: Bad value for $srfgFirstDayOfWeek "' .
394
					'(' . $srfgFirstDayOfWeek . '")';
395
				$firstDayOfWeek = 1;
396
			}
397
			if ( $firstDayOfWeek == 1 ) {
398
				$lastDayOfWeek = 7;
399
			} else {
400
				$lastDayOfWeek = $firstDayOfWeek - 1;
401
			}
402
		}
403
404
		// Now create the actual array of days of the week, based on
405
		// the start day
406
		$weekDays = [];
407
		for ( $i = 1; $i <= 7; $i++ ) {
408
			$curDay = ( ( $firstDayOfWeek + $i - 2 ) % 7 ) + 1;
409
			$weekDays[$i] = $weekDayNames[$curDay];
410
		}
411
412
		// Get all the date-based values we need - the current month
413
		// and year (i.e., the one the user is looking at - not
414
		// necessarily the "current" ones), the previous and next months
415
		// and years (same - note that the previous or next month could
416
		// be in a different year), the number of days in the current,
417
		// previous and next months, etc.
418
419
		if ( is_numeric( $this->mStartMonth ) &&
420
			( intval( $this->mStartMonth ) == $this->mStartMonth ) &&
421
			$this->mStartMonth >= 1 && $this->mStartMonth <= 12
422
		) {
423
			$curMonthNum = $this->mStartMonth;
424
		} else {
425
			$curMonthNum = date( 'n' );
426
		}
427
		if ( $request->getCheck( 'month' ) ) {
428
			$queryMonth = $request->getVal( 'month' );
429
			if ( is_numeric( $queryMonth ) &&
430
				( intval( $queryMonth ) == $queryMonth ) &&
431
				$queryMonth >= 1 && $queryMonth <= 12
432
			) {
433
				$curMonthNum = $request->getVal( 'month' );
434
			}
435
		}
436
437
		$curMonth = self::intToMonth( $curMonthNum );
438
439
		if ( is_numeric( $this->mStartYear ) &&
440
			( intval( $this->mStartYear ) == $this->mStartYear )
441
		) {
442
			$curYear = $this->mStartYear;
443
		} else {
444
			$curYear = date( 'Y' );
445
		}
446
		if ( $request->getCheck( 'year' ) ) {
447
			$queryYear = $request->getVal( 'year' );
448
			if ( is_numeric( $queryYear ) &&
449
				intval( $queryYear ) == $queryYear
450
			) {
451
				$curYear = $request->getVal( 'year' );
452
			}
453
		}
454
455
		if ( $curMonthNum == '1' ) {
456
			$prevMonthNum = '12';
457
			$prevYear = $curYear - 1;
458
		} else {
459
			$prevMonthNum = $curMonthNum - 1;
460
			$prevYear = $curYear;
461
		}
462
463
		if ( $curMonthNum == '12' ) {
464
			$nextMonthNum = '1';
465
			$nextYear = $curYear + 1;
466
		} else {
467
			$nextMonthNum = $curMonthNum + 1;
468
			$nextYear = $curYear;
469
		}
470
471
		// There's no year '0' - change it to '1' or '-1'.
472
		if ( $curYear == '0' ) {
473
			$curYear = '1';
474
		}
475
		if ( $nextYear == '0' ) {
476
			$nextYear = '1';
477
		}
478
		if ( $prevYear == '0' ) {
479
			$prevYear = '-1';
480
		}
481
482
		$prevMonthUrl = $pageTitle->getLocalURL(
483
			"month=$prevMonthNum&year=$prevYear" .
484
			$additionalQueryString
485
		);
486
		$nextMonthUrl = $pageTitle->getLocalURL(
487
			"month=$nextMonthNum&year=$nextYear" .
488
			$additionalQueryString
489
		);
490
		$todayUrl = $pageTitle->getLocalURL( $additionalQueryString );
491
492
		$todayText = wfMessage( 'srfc_today' )->text();
493
		$prevMonthText = wfMessage( 'srfc_previousmonth' )->text();
494
		$nextMonthText = wfMessage( 'srfc_nextmonth' )->text();
495
		$goToMonthText = wfMessage( 'srfc_gotomonth' )->text();
496
497
		// Get day of the week that the first of this month falls on.
498
		$firstDay = new SRFCHistoricalDate();
499
		$firstDay->create( $curYear, $curMonthNum, 1 );
500
		$startDay = $firstDayOfWeek - $firstDay->getDayOfWeek();
501
		if ( $startDay > 0 ) {
502
			$startDay -= 7;
503
		}
504
		$daysInPrevMonth =
505
			SRFCHistoricalDate::daysInMonth( $prevYear, $prevMonthNum );
506
		$daysInCurMonth =
507
			SRFCHistoricalDate::daysInMonth( $curYear, $curMonthNum );
508
		$todayString = date( 'Y n j', time() );
509
		$pageName = $pageTitle->getPrefixedDbKey();
510
511
		// Create table for holding title and navigation information.
512
		$text = <<<END
513
<table class="navigation_table">
514
<tr><td class="month_name">$curMonth $curYear</td>
515
<td class="nav_links"><a href="$prevMonthUrl" title="$prevMonthText">
516
<img src="{$srfgScriptPath}/formats/calendar/resources/images/left-arrow.png" border="0" />
517
</a>&#160;<a href="$todayUrl">$todayText</a>&#160;
518
<a href="$nextMonthUrl" title="$nextMonthText">
519
<img src="{$srfgScriptPath}/formats/calendar/resources/images/right-arrow.png" border="0" />
520
</a></td><td class="nav_form"><form>
521
<input type="hidden" name="title" value="$pageName">
522
<select name="month">
523
524
END;
525
		for ( $i = 1; $i <= 12; $i++ ) {
526
			$monthName = self::intToMonth( $i );
527
			$selectedStr = ( $i == $curMonthNum ) ? "selected" : "";
528
			$text .= "<option value=\"$i\" $selectedStr>
529
				$monthName</option>\n";
530
		}
531
		$text .= <<<END
532
</select>
533
<input name="year" type="text" value="$curYear" size="4">
534
$hiddenInputs
535
<input type="submit" value="$goToMonthText">
536
</form>
537
</td>
538
</tr>
539
</table>
540
541
<table class="month_calendar">
542
<tr class="weekdays">
543
544
END;
545
		// First row of the main table holds the days of the week
546
		foreach ( $weekDays as $weekDay ) {
547
			$text .= "<td>$weekDay</td>";
548
		}
549
		$text .= "</tr>\n";
550
551
		// Now, create the calendar itself -
552
		// loop through a set of weeks, from a "Sunday" (which might be
553
		// before the beginning of the month) to a "Saturday" (which
554
		// might be after the end of the month).
555
		// "Sunday" and "Saturday" are in quotes because the actual
556
		// start and end days of the week can be set by the admin.
557
		$dayOfTheWeek = $firstDayOfWeek;
558
		$isLastWeek = false;
559
		for ( $day = $startDay;
560
		( !$isLastWeek || $dayOfTheWeek != $firstDayOfWeek );
561
			  $day++ ) {
562
			if ( $dayOfTheWeek == $firstDayOfWeek ) {
563
				$text .= "<tr>\n";
564
			}
565
			if ( "$curYear $curMonthNum $day" == $todayString ) {
566
				$text .= "<td class=\"today\">\n";
567
			} elseif ( $dayOfTheWeek == 1 || $dayOfTheWeek == 7 ) {
568
				$text .= "<td class=\"weekend_day\">\n";
569
			} else {
570
				$text .= "<td>\n";
571
			}
572
			if ( $day == $daysInCurMonth || $day > 50 ) {
573
				$isLastWeek = true;
574
			}
575
			// If this day is before or after the current month,
576
			// set a "display day" to show on the calendar, and
577
			// use a different CSS style for it.
578
			if ( $day > $daysInCurMonth || $day < 1 ) {
579
				if ( $day < 1 ) {
580
					$displayDay = $day + $daysInPrevMonth;
581
					$dateStr =
582
						$prevYear . '-' . $prevMonthNum . '-' . $displayDay;
583
				}
584
				if ( $day > $daysInCurMonth ) {
585
					$displayDay = $day - $daysInCurMonth;
586
					$dateStr =
587
						$nextYear . '-' . $nextMonthNum . '-' . $displayDay;
588
				}
589
				$text .=
590
					"<div class=\"day day_other_month\">$displayDay</div>\n";
0 ignored issues
show
The variable $displayDay 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...
591
			} else {
592
				$dateStr = $curYear . '-' . $curMonthNum . '-' . $day;
593
				$text .= "<div class=\"day\">$day</div>\n";
594
			}
595
			// Finally, the most important step - get the events
596
			// that match this date, and the given set of criteria,
597
			// and display them in this date's box.
598
			$text .= "<div class=\"main\">\n";
599
			if ( $events == null ) {
600
				$events = [];
601
			}
602
			foreach ( $events as $event ) {
603
				list( $eventTitle, $otherText, $eventDate, $color ) = $event;
604
				if ( $eventDate == $dateStr ) {
605
					if ( $this->mTemplate != '' ) {
606
						$templatetext = '{{' . $this->mTemplate . $otherText .
607
							'|thisdate=' . $dateStr . '}}';
0 ignored issues
show
The variable $dateStr 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...
608
						$templatetext =
609
							$wgParser->replaceVariables( $templatetext );
610
						$templatetext =
611
							$wgParser->recursiveTagParse( $templatetext );
612
						$text .= $templatetext;
613
					} else {
614
						$eventStr = Linker::link( $eventTitle );
615
						if ( $color != '' ) {
616
							$text .= "<div class=\"colored-entry\">
617
								<p style=\"border-left: 7px $color solid;\">
618
								$eventStr $otherText</p></div>\n";
619
						} else {
620
							$text .= "$eventStr $otherText\n\n";
621
						}
622
					}
623
				}
624
			}
625
			$text .= <<<END
626
</div>
627
</td>
628
629
END;
630
			if ( $dayOfTheWeek == $lastDayOfWeek ) {
631
				$text .= "</tr>\n";
632
			}
633
			if ( $dayOfTheWeek == 7 ) {
634
				$dayOfTheWeek = 1;
635
			} else {
636
				$dayOfTheWeek++;
637
			}
638
		}
639
		$text .= "</table>\n";
640
641
		return $text;
642
	}
643
644
	/**
645
	 * @see SMWResultPrinter::getParamDefinitions
646
	 *
647
	 * @since 1.8
648
	 *
649
	 * @param $definitions array of IParamDefinition
650
	 *
651
	 * @return array of IParamDefinition|array
652
	 */
653
	public function getParamDefinitions( array $definitions ) {
654
		$params = parent::getParamDefinitions( $definitions );
655
656
		$params['lang'] = [
657
			'message' => 'srf_paramdesc_calendarlang',
658
			'default' => false,
659
			'manipulatedefault' => false,
660
		];
661
662
		$params['template'] = [
663
			'message' => 'smw-paramdesc-template',
664
			'default' => '',
665
		];
666
667
		$params['userparam'] = [
668
			'message' => 'smw-paramdesc-userparam',
669
			'default' => '',
670
		];
671
672
		$params['color'] = [
673
			'message' => 'srf-paramdesc-color',
674
			'default' => '',
675
		];
676
677
		$params['colors'] = [
678
			'message' => 'srf_paramdesc_calendarcolors',
679
			'default' => '',
680
		];
681
682
		$params['startmonth'] = [
683
			'message' => 'srf-paramdesc-calendar-startmonth',
684
			'default' => date( 'n' ),
685
		];
686
687
		$params['startyear'] = [
688
			'message' => 'srf-paramdesc-calendar-startyear',
689
			'default' => date( 'Y' ),
690
		];
691
692
		return $params;
693
	}
694
}
695