Completed
Push — release-2.1 ( 0dba9a...48ac11 )
by Mert
07:06
created

Calendar.php ➔ clock()   C

Complexity

Conditions 12
Paths 24

Size

Total Lines 108
Code Lines 80

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 12
eloc 80
nc 24
nop 0
dl 0
loc 108
rs 5.034
c 0
b 0
f 0

How to fix   Long Method    Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
3
/**
4
 * This file has only one real task, showing the calendar.
5
 * Original module by Aaron O'Neil - [email protected]
6
 *
7
 * Simple Machines Forum (SMF)
8
 *
9
 * @package SMF
10
 * @author Simple Machines http://www.simplemachines.org
11
 * @copyright 2016 Simple Machines and individual contributors
12
 * @license http://www.simplemachines.org/about/smf/license.php BSD
13
 *
14
 * @version 2.1 Beta 3
15
 */
16
17
if (!defined('SMF'))
18
	die('No direct access...');
19
20
/**
21
 * Show the calendar.
22
 * It loads the specified month's events, holidays, and birthdays.
23
 * It requires the calendar_view permission.
24
 * It depends on the cal_enabled setting, and many of the other cal_ settings.
25
 * It uses the calendar_start_day theme option. (Monday/Sunday)
26
 * It uses the main sub template in the Calendar template.
27
 * It goes to the month and year passed in 'month' and 'year' by get or post.
28
 * It is accessed through ?action=calendar.
29
 * @return void
30
 */
31
function CalendarMain()
32
{
33
	global $txt, $context, $modSettings, $scripturl, $options, $sourcedir, $user_info, $smcFunc;
34
35
	// Permissions, permissions, permissions.
36
	isAllowedTo('calendar_view');
37
38
	// Some global template resources.
39
	$context['calendar_resources'] = array(
40
		'min_year' => $modSettings['cal_minyear'],
41
		'max_year' => $modSettings['cal_maxyear'],
42
	);
43
44
	// Doing something other than calendar viewing?
45
	$subActions = array(
46
		'ical' => 'iCalDownload',
47
		'post' => 'CalendarPost',
48
	);
49
50
	if (isset($_GET['sa']) && isset($subActions[$_GET['sa']]))
51
		return call_helper($subActions[$_GET['sa']]);
52
53
	// You can't do anything if the calendar is off.
54
	if (empty($modSettings['cal_enabled']))
55
		fatal_lang_error('calendar_off', false);
0 ignored issues
show
Documentation introduced by
false is of type boolean, but the function expects a string.

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...
56
57
	// This is gonna be needed...
58
	loadTemplate('Calendar');
59
	loadCSSFile('calendar.css', array('force_current' => false, 'validate' => true, 'rtl' => 'calendar.rtl.css'), 'smf_calendar');
60
61
	// Did the specify an individual event ID? If so, let's splice the year/month in to what we would otherwise be doing.
62
	if (isset($_GET['event']))
63
	{
64
		$evid = (int) $_GET['event'];
65
		if ($evid > 0)
66
		{
67
			$request = $smcFunc['db_query']('', '
68
				SELECT start_date
69
				FROM {db_prefix}calendar
70
				WHERE id_event = {int:event_id}',
71
				array(
72
					'event_id' => $evid,
73
				)
74
			);
75
			if ($row = $smcFunc['db_fetch_assoc']($request))
76
			{
77
				// We know the format is going to be in yyyy-mm-dd from the database, so let's run with that.
78
				list($_REQUEST['year'], $_REQUEST['month']) = explode('-', $row['start_date']);
79
				$_REQUEST['year'] = (int) $_REQUEST['year'];
80
				$_REQUEST['month'] = (int) $_REQUEST['month'];
81
82
				// And we definitely don't want weekly view.
83
				unset ($_GET['viewweek']);
84
85
				// We might use this later.
86
				$context['selected_event'] = $evid;
87
			}
88
			$smcFunc['db_free_result']($request);
89
		}
90
		unset ($_GET['event']);
91
	}
92
93
	// Set the page title to mention the calendar ;).
94
	$context['page_title'] = $txt['calendar'];
95
96
	// Is this a week view?
97
	$context['view_week'] = isset($_GET['viewweek']);
98
99
	// Don't let search engines index weekly calendar pages.
100
	if ($context['view_week'])
101
		$context['robot_no_index'] = true;
102
103
	// Get the current day of month...
104
	require_once($sourcedir . '/Subs-Calendar.php');
105
	$today = getTodayInfo();
106
107
	// If the month and year are not passed in, use today's date as a starting point.
108
	$curPage = array(
109
		'day' => isset($_REQUEST['day']) ? (int) $_REQUEST['day'] : $today['day'],
110
		'month' => isset($_REQUEST['month']) ? (int) $_REQUEST['month'] : $today['month'],
111
		'year' => isset($_REQUEST['year']) ? (int) $_REQUEST['year'] : $today['year']
112
	);
113
114
	// Make sure the year and month are in valid ranges.
115
	if ($curPage['month'] < 1 || $curPage['month'] > 12)
116
		fatal_lang_error('invalid_month', false);
0 ignored issues
show
Documentation introduced by
false is of type boolean, but the function expects a string.

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...
117 View Code Duplication
	if ($curPage['year'] < $modSettings['cal_minyear'] || $curPage['year'] > $modSettings['cal_maxyear'])
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
118
		fatal_lang_error('invalid_year', false);
0 ignored issues
show
Documentation introduced by
false is of type boolean, but the function expects a string.

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...
119
	// If we have a day clean that too.
120
	if ($context['view_week'])
121
	{
122
		// Note $isValid is -1 < PHP 5.1
123
		$isValid = mktime(0, 0, 0, $curPage['month'], $curPage['day'], $curPage['year']);
124
		if ($curPage['day'] > 31 || !$isValid || $isValid == -1)
125
			fatal_lang_error('invalid_day', false);
0 ignored issues
show
Documentation introduced by
false is of type boolean, but the function expects a string.

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...
126
	}
127
128
	// Load all the context information needed to show the calendar grid.
129
	$calendarOptions = array(
130
		'start_day' => !empty($options['calendar_start_day']) ? $options['calendar_start_day'] : 0,
131
		'show_birthdays' => in_array($modSettings['cal_showbdays'], array(1, 2)),
132
		'show_events' => in_array($modSettings['cal_showevents'], array(1, 2)),
133
		'show_holidays' => in_array($modSettings['cal_showholidays'], array(1, 2)),
134
		'highlight' => array(
135
			'events' => isset($modSettings['cal_highlight_events']) ? $modSettings['cal_highlight_events'] : 0,
136
			'holidays' => isset($modSettings['cal_highlight_holidays']) ? $modSettings['cal_highlight_holidays'] : 0,
137
			'birthdays' => isset($modSettings['cal_highlight_birthdays']) ? $modSettings['cal_highlight_birthdays'] : 0,
138
		),
139
		'show_week_num' => true,
140
		'short_day_titles' => !empty($modSettings['cal_short_days']),
141
		'short_month_titles' => !empty($modSettings['cal_short_months']),
142
		'show_next_prev' => !empty($modSettings['cal_prev_next_links']),
143
		'show_week_links' => isset($modSettings['cal_week_links']) ? $modSettings['cal_week_links'] : 0,
144
	);
145
146
	// Load up the main view.
147
	if ($context['view_week'])
148
		$context['calendar_grid_main'] = getCalendarWeek($curPage['month'], $curPage['year'], $curPage['day'], $calendarOptions);
149
	else
150
		$context['calendar_grid_main'] = getCalendarGrid($curPage['month'], $curPage['year'], $calendarOptions);
151
152
	// Load up the previous and next months.
153
	$context['calendar_grid_current'] = getCalendarGrid($curPage['month'], $curPage['year'], $calendarOptions);
154
155
	// Only show previous month if it isn't pre-January of the min-year
156 View Code Duplication
	if ($context['calendar_grid_current']['previous_calendar']['year'] > $modSettings['cal_minyear'] || $curPage['month'] != 1)
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
157
		$context['calendar_grid_prev'] = getCalendarGrid($context['calendar_grid_current']['previous_calendar']['month'], $context['calendar_grid_current']['previous_calendar']['year'], $calendarOptions, true);
158
159
	// Only show next month if it isn't post-December of the max-year
160 View Code Duplication
	if ($context['calendar_grid_current']['next_calendar']['year'] < $modSettings['cal_maxyear'] || $curPage['month'] != 12)
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
161
		$context['calendar_grid_next'] = getCalendarGrid($context['calendar_grid_current']['next_calendar']['month'], $context['calendar_grid_current']['next_calendar']['year'], $calendarOptions);
162
163
	// Basic template stuff.
164
	$context['allow_calendar_event'] = allowedTo('calendar_post');
165
166
	// If you don't allow events not linked to posts and you're not an admin, we have more work to do...
167 View Code Duplication
	if ($context['allow_calendar_event'] && empty($modSettings['cal_allow_unlinked']) && !$user_info['is_admin'])
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
168
	{
169
		$boards_can_post = boardsAllowedTo('post_new');
170
		$context['allow_calendar_event'] &= !empty($boards_can_post);
171
	}
172
173
	$context['can_post'] = $context['allow_calendar_event'];
174
	$context['current_day'] = $curPage['day'];
175
	$context['current_month'] = $curPage['month'];
176
	$context['current_year'] = $curPage['year'];
177
	$context['show_all_birthdays'] = isset($_GET['showbd']);
178
	$context['blocks_disabled'] = !empty($modSettings['cal_disable_prev_next']) ? 1 : 0;
179
180
	// Set the page title to mention the month or week, too
181
	$context['page_title'] .= ' - ' . ($context['view_week'] ? $context['calendar_grid_main']['week_title'] : $txt['months'][$context['current_month']] . ' ' . $context['current_year']);
182
183
	// Load up the linktree!
184
	$context['linktree'][] = array(
185
		'url' => $scripturl . '?action=calendar',
186
		'name' => $txt['calendar']
187
	);
188
	// Add the current month to the linktree.
189
	$context['linktree'][] = array(
190
		'url' => $scripturl . '?action=calendar;year=' . $context['current_year'] . ';month=' . $context['current_month'],
191
		'name' => $txt['months'][$context['current_month']] . ' ' . $context['current_year']
192
	);
193
	// If applicable, add the current week to the linktree.
194
	if ($context['view_week'])
195
		$context['linktree'][] = array(
196
			'url' => $scripturl . '?action=calendar;viewweek;year=' . $context['current_year'] . ';month=' . $context['current_month'] . ';day=' . $context['current_day'],
197
			'name' => $context['calendar_grid_main']['week_title'],
198
		);
199
200
	// Build the calendar button array.
201
	$context['calendar_buttons'] = array();
202
203
	if ($context['can_post'])
204
		$context['calendar_buttons']['post_event'] = array('text' => 'calendar_post_event', 'image' => 'calendarpe.png', 'url' => $scripturl . '?action=calendar;sa=post;month=' . $context['current_month'] . ';year=' . $context['current_year'] . ';' . $context['session_var'] . '=' . $context['session_id']);
205
206
	// Allow mods to add additional buttons here
207
	call_integration_hook('integrate_calendar_buttons');
208
}
209
210
/**
211
 * This function processes posting/editing/deleting a calendar event.
212
 *
213
 * 	- calls {@link Post.php|Post() Post()} function if event is linked to a post.
214
 *  - calls {@link Subs-Calendar.php|insertEvent() insertEvent()} to insert the event if not linked to post.
215
 *
216
 * It requires the calendar_post permission to use.
217
 * It uses the event_post sub template in the Calendar template.
218
 * It is accessed with ?action=calendar;sa=post.
219
 */
220
function CalendarPost()
221
{
222
	global $context, $txt, $user_info, $sourcedir, $scripturl;
223
	global $modSettings, $topic, $smcFunc;
224
225
	// Well - can they?
226
	isAllowedTo('calendar_post');
227
228
	// We need this for all kinds of useful functions.
229
	require_once($sourcedir . '/Subs-Calendar.php');
230
231
	// Cast this for safety...
232
	if (isset($_REQUEST['eventid']))
233
		$_REQUEST['eventid'] = (int) $_REQUEST['eventid'];
234
235
	// Submitting?
236
	if (isset($_POST[$context['session_var']], $_REQUEST['eventid']))
237
	{
238
		checkSession();
239
240
		// Validate the post...
241
		if (!isset($_POST['link_to_board']))
242
			validateEventPost();
243
244
		// If you're not allowed to edit any events, you have to be the poster.
245
		if ($_REQUEST['eventid'] > 0 && !allowedTo('calendar_edit_any'))
246
			isAllowedTo('calendar_edit_' . (!empty($user_info['id']) && getEventPoster($_REQUEST['eventid']) == $user_info['id'] ? 'own' : 'any'));
247
248
		// New - and directing?
249
		if (isset($_POST['link_to_board']) || empty($modSettings['cal_allow_unlinked']))
250
		{
251
			$_REQUEST['calendar'] = 1;
252
			require_once($sourcedir . '/Post.php');
253
			return Post();
254
		}
255
		// New...
256
		elseif ($_REQUEST['eventid'] == -1)
257
		{
258
			$eventOptions = array(
259
				'board' => 0,
260
				'topic' => 0,
261
				'title' => $smcFunc['substr']($_REQUEST['evtitle'], 0, 100),
262
				'member' => $user_info['id'],
263
				'start_date' => sprintf('%04d-%02d-%02d', $_POST['year'], $_POST['month'], $_POST['day']),
264
				'span' => isset($_POST['span']) && $_POST['span'] > 0 ? min((int) $modSettings['cal_maxspan'], (int) $_POST['span'] - 1) : 0,
265
			);
266
			insertEvent($eventOptions);
267
		}
268
269
		// Deleting...
270
		elseif (isset($_REQUEST['deleteevent']))
271
			removeEvent($_REQUEST['eventid']);
272
273
		// ... or just update it?
274
		else
275
		{
276
			$eventOptions = array(
277
				'title' => $smcFunc['substr']($_REQUEST['evtitle'], 0, 100),
278
				'span' => empty($modSettings['cal_allowspan']) || empty($_POST['span']) || $_POST['span'] == 1 || empty($modSettings['cal_maxspan']) || $_POST['span'] > $modSettings['cal_maxspan'] ? 0 : min((int) $modSettings['cal_maxspan'], (int) $_POST['span'] - 1),
279
				'start_date' => strftime('%Y-%m-%d', mktime(0, 0, 0, (int) $_REQUEST['month'], (int) $_REQUEST['day'], (int) $_REQUEST['year'])),
280
			);
281
282
			modifyEvent($_REQUEST['eventid'], $eventOptions);
283
		}
284
285
		updateSettings(array(
286
			'calendar_updated' => time(),
287
		));
288
289
		// No point hanging around here now...
290
		redirectexit($scripturl . '?action=calendar;month=' . $_POST['month'] . ';year=' . $_POST['year']);
291
	}
292
293
	// If we are not enabled... we are not enabled.
294
	if (empty($modSettings['cal_allow_unlinked']) && empty($_REQUEST['eventid']))
295
	{
296
		$_REQUEST['calendar'] = 1;
297
		require_once($sourcedir . '/Post.php');
298
		return Post();
299
	}
300
301
	// New?
302
	if (!isset($_REQUEST['eventid']))
303
	{
304
		$today = getdate();
305
306
		$context['event'] = array(
307
			'boards' => array(),
308
			'board' => 0,
309
			'new' => 1,
310
			'eventid' => -1,
311
			'year' => isset($_REQUEST['year']) ? $_REQUEST['year'] : $today['year'],
312
			'month' => isset($_REQUEST['month']) ? $_REQUEST['month'] : $today['mon'],
313
			'day' => isset($_REQUEST['day']) ? $_REQUEST['day'] : $today['mday'],
314
			'title' => '',
315
			'span' => 1,
316
		);
317
		$context['event']['last_day'] = (int) strftime('%d', mktime(0, 0, 0, $context['event']['month'] == 12 ? 1 : $context['event']['month'] + 1, 0, $context['event']['month'] == 12 ? $context['event']['year'] + 1 : $context['event']['year']));
318
	}
319
	else
320
	{
321
		$context['event'] = getEventProperties($_REQUEST['eventid']);
322
323
		if ($context['event'] === false)
324
			fatal_lang_error('no_access', false);
0 ignored issues
show
Documentation introduced by
false is of type boolean, but the function expects a string.

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...
325
326
		// If it has a board, then they should be editing it within the topic.
327
		if (!empty($context['event']['topic']['id']) && !empty($context['event']['topic']['first_msg']))
328
		{
329
			// We load the board up, for a check on the board access rights...
330
			$topic = $context['event']['topic']['id'];
331
			loadBoard();
332
		}
333
334
		// Make sure the user is allowed to edit this event.
335 View Code Duplication
		if ($context['event']['member'] != $user_info['id'])
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
336
			isAllowedTo('calendar_edit_any');
337
		elseif (!allowedTo('calendar_edit_any'))
338
			isAllowedTo('calendar_edit_own');
339
	}
340
341
	// Get list of boards that can be posted in.
342
	$boards = boardsAllowedTo('post_new');
343
	if (empty($boards))
344
	{
345
		// You can post new events but can't link them to anything...
346
		$context['event']['categories'] = array();
347
	}
348
	else
349
	{
350
		// Load the list of boards and categories in the context.
351
		require_once($sourcedir . '/Subs-MessageIndex.php');
352
		$boardListOptions = array(
353
			'included_boards' => in_array(0, $boards) ? null : $boards,
354
			'not_redirection' => true,
355
			'use_permissions' => true,
356
			'selected_board' => $modSettings['cal_defaultboard'],
357
		);
358
		$context['event']['categories'] = getBoardList($boardListOptions);
359
	}
360
361
	// Template, sub template, etc.
362
	loadTemplate('Calendar');
363
	$context['sub_template'] = 'event_post';
364
365
	$context['page_title'] = isset($_REQUEST['eventid']) ? $txt['calendar_edit'] : $txt['calendar_post_event'];
366
	$context['linktree'][] = array(
367
		'name' => $context['page_title'],
368
	);
369
}
370
371
/**
372
 * This function offers up a download of an event in iCal 2.0 format.
373
 *
374
 * Follows the conventions in {@link http://tools.ietf.org/html/rfc5546 RFC5546}
375
 * Sets events as all day events since we don't have hourly events
376
 * Will honor and set multi day events
377
 * Sets a sequence number if the event has been modified
378
 *
379
 * @todo .... allow for week or month export files as well?
380
 */
381
function iCalDownload()
382
{
383
	global $smcFunc, $sourcedir, $forum_version, $modSettings, $webmaster_email, $mbname;
384
385
	// You can't export if the calendar export feature is off.
386
	if (empty($modSettings['cal_export']))
387
		fatal_lang_error('calendar_export_off', false);
0 ignored issues
show
Documentation introduced by
false is of type boolean, but the function expects a string.

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...
388
389
	// Goes without saying that this is required.
390
	if (!isset($_REQUEST['eventid']))
391
		fatal_lang_error('no_access', false);
0 ignored issues
show
Documentation introduced by
false is of type boolean, but the function expects a string.

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...
392
393
	// This is kinda wanted.
394
	require_once($sourcedir . '/Subs-Calendar.php');
395
396
	// Load up the event in question and check it exists.
397
	$event = getEventProperties($_REQUEST['eventid']);
398
399
	if ($event === false)
400
		fatal_lang_error('no_access', false);
0 ignored issues
show
Documentation introduced by
false is of type boolean, but the function expects a string.

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...
401
402
	// Check the title isn't too long - iCal requires some formatting if so.
403
	$title = str_split($event['title'], 30);
404
	foreach ($title as $id => $line)
405
	{
406
		if ($id != 0)
407
			$title[$id] = ' ' . $title[$id];
408
		$title[$id] .= "\n";
409
	}
410
411
	// Format the dates.
412
	$datestamp = date('Ymd\THis\Z', time());
413
	$datestart = $event['year'] . ($event['month'] < 10 ? '0' . $event['month'] : $event['month']) . ($event['day'] < 10 ? '0' . $event['day'] : $event['day']);
414
415
	// Do we have a event that spans several days?
416
	if ($event['span'] > 1)
417
	{
418
		$dateend = strtotime($event['year'] . '-' . ($event['month'] < 10 ? '0' . $event['month'] : $event['month']) . '-' . ($event['day'] < 10 ? '0' . $event['day'] : $event['day']));
419
		$dateend += ($event['span'] - 1) * 86400;
420
		$dateend = date('Ymd', $dateend);
421
	}
422
423
	// This is what we will be sending later
424
	$filecontents = '';
425
	$filecontents .= 'BEGIN:VCALENDAR' . "\n";
426
	$filecontents .= 'METHOD:PUBLISH' . "\n";
427
	$filecontents .= 'PRODID:-//SimpleMachines//SMF ' . (empty($forum_version) ? 2.0 : strtr($forum_version, array('SMF ' => ''))) . '//EN' . "\n";
428
	$filecontents .= 'VERSION:2.0' . "\n";
429
	$filecontents .= 'BEGIN:VEVENT' . "\n";
430
	// @TODO - Should be the members email who created the event rather than $webmaster_email.
431
	$filecontents .= 'ORGANIZER;CN="' . $event['realname'] . '":MAILTO:' . $webmaster_email . "\n";
432
	$filecontents .= 'DTSTAMP:' . $datestamp . "\n";
433
	$filecontents .= 'DTSTART;VALUE=DATE:' . $datestart . "\n";
434
435
	// more than one day
436
	if ($event['span'] > 1)
437
		$filecontents .= 'DTEND;VALUE=DATE:' . $dateend . "\n";
0 ignored issues
show
Bug introduced by
The variable $dateend 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...
438
439
	// event has changed? advance the sequence for this UID
440
	if ($event['sequence'] > 0)
441
		$filecontents .= 'SEQUENCE:' . $event['sequence'] . "\n";
442
443
	$filecontents .= 'SUMMARY:' . implode('', $title);
444
	$filecontents .= 'UID:' . $event['eventid'] . '@' . str_replace(' ', '-', $mbname) . "\n";
445
	$filecontents .= 'END:VEVENT' . "\n";
446
	$filecontents .= 'END:VCALENDAR';
447
448
	// Send some standard headers.
449
	ob_end_clean();
450
	if (!empty($modSettings['enableCompressedOutput']))
451
		@ob_start('ob_gzhandler');
0 ignored issues
show
Security Best Practice introduced by
It seems like you do not handle an error condition here. This can introduce security issues, and is generally not recommended.

If you suppress an error, we recommend checking for the error condition explicitly:

// For example instead of
@mkdir($dir);

// Better use
if (@mkdir($dir) === false) {
    throw new \RuntimeException('The directory '.$dir.' could not be created.');
}
Loading history...
452
	else
453
		ob_start();
454
455
	// Send the file headers
456
	header('Pragma: ');
457
	header('Cache-Control: no-cache');
458
	if (!isBrowser('gecko'))
459
		header('Content-Transfer-Encoding: binary');
460
	header('Expires: ' . gmdate('D, d M Y H:i:s', time() + 525600 * 60) . ' GMT');
461
	header('Last-Modified: ' . gmdate('D, d M Y H:i:s', time()) . 'GMT');
462
	header('Accept-Ranges: bytes');
463
	header('Connection: close');
464
	header('Content-Disposition: attachment; filename="' . $event['title'] . '.ics"');
465
	if (empty($modSettings['enableCompressedOutput']))
466
		header('Content-Length: ' . $smcFunc['strlen']($filecontents));
467
468
	// This is a calendar item!
469
	header('Content-Type: text/calendar');
470
471
	// Chuck out the card.
472
	echo $filecontents;
473
474
	// Off we pop - lovely!
475
	obExit(false);
476
}
477
478
/**
479
 * Nothing to see here. Move along.
480
 */
481
function clock()
482
{
483
	global $settings, $context, $scripturl;
484
485
	$context['onimg'] = $settings['images_url'] . '/bbc/bbc_bg.png';
486
	$context['offimg'] = $settings['images_url'] . '/bbc/bbc_hoverbg.png';
487
488
	$context['page_title'] = 'Anyone know what time it is?';
489
	$context['linktree'][] = array(
490
			'url' => $scripturl . '?action=clock',
491
			'name' => 'Clock',
492
	);
493
	$context['robot_no_index'] = true;
494
495
	$omfg = isset($_REQUEST['omfg']);
496
	$bcd = !isset($_REQUEST['rb']) && !isset($_REQUEST['omfg']) && !isset($_REQUEST['time']);
497
498
	loadTemplate('Calendar');
499
500
	if ($bcd)
501
	{
502
		$context['sub_template'] = 'bcd';
503
		$context['linktree'][] = array('url' => $scripturl . '?action=clock;bcd', 'name' => 'BCD');
504
		$context['clockicons'] = safe_unserialize(base64_decode('YTo2OntzOjI6ImgxIjthOjI6e2k6MDtpOjI7aToxO2k6MTt9czoyOiJoMiI7YTo0OntpOjA7aTo4O2k6MTtpOjQ7aToyO2k6MjtpOjM7aToxO31zOjI6Im0xIjthOjM6e2k6MDtpOjQ7aToxO2k6MjtpOjI7aToxO31zOjI6Im0yIjthOjQ6e2k6MDtpOjg7aToxO2k6NDtpOjI7aToyO2k6MztpOjE7fXM6MjoiczEiO2E6Mzp7aTowO2k6NDtpOjE7aToyO2k6MjtpOjE7fXM6MjoiczIiO2E6NDp7aTowO2k6ODtpOjE7aTo0O2k6MjtpOjI7aTozO2k6MTt9fQ=='));
505
	}
506
	elseif (!$omfg && !isset($_REQUEST['time']))
507
	{
508
		$context['sub_template'] = 'hms';
509
		$context['linktree'][] = array('url' => $scripturl . '?action=clock', 'name' => 'Binary');
510
		$context['clockicons'] = safe_unserialize(base64_decode('YTozOntzOjE6ImgiO2E6NTp7aTowO2k6MTY7aToxO2k6ODtpOjI7aTo0O2k6MztpOjI7aTo0O2k6MTt9czoxOiJtIjthOjY6e2k6MDtpOjMyO2k6MTtpOjE2O2k6MjtpOjg7aTozO2k6NDtpOjQ7aToyO2k6NTtpOjE7fXM6MToicyI7YTo2OntpOjA7aTozMjtpOjE7aToxNjtpOjI7aTo4O2k6MztpOjQ7aTo0O2k6MjtpOjU7aToxO319'));
511
	}
512
	elseif ($omfg)
513
	{
514
		$context['sub_template'] = 'omfg';
515
		$context['linktree'][] = array('url' => $scripturl . '?action=clock;omfg', 'name' => 'OMFG');
516
		$context['clockicons'] = safe_unserialize(base64_decode('YTo2OntzOjQ6InllYXIiO2E6Nzp7aTowO2k6NjQ7aToxO2k6MzI7aToyO2k6MTY7aTozO2k6ODtpOjQ7aTo0O2k6NTtpOjI7aTo2O2k6MTt9czo1OiJtb250aCI7YTo0OntpOjA7aTo4O2k6MTtpOjQ7aToyO2k6MjtpOjM7aToxO31zOjM6ImRheSI7YTo1OntpOjA7aToxNjtpOjE7aTo4O2k6MjtpOjQ7aTozO2k6MjtpOjQ7aToxO31zOjQ6ImhvdXIiO2E6NTp7aTowO2k6MTY7aToxO2k6ODtpOjI7aTo0O2k6MztpOjI7aTo0O2k6MTt9czozOiJtaW4iO2E6Njp7aTowO2k6MzI7aToxO2k6MTY7aToyO2k6ODtpOjM7aTo0O2k6NDtpOjI7aTo1O2k6MTt9czozOiJzZWMiO2E6Njp7aTowO2k6MzI7aToxO2k6MTY7aToyO2k6ODtpOjM7aTo0O2k6NDtpOjI7aTo1O2k6MTt9fQ=='));
517
	}
518
	elseif (isset($_REQUEST['time']))
519
	{
520
		$context['sub_template'] = 'thetime';
521
		$time = getdate($_REQUEST['time'] == 'now' ? time() : (int) $_REQUEST['time']);
522
		$year = $time['year'] % 100;
523
		$month = $time['mon'];
524
		$day = $time['mday'];
525
		$hour = $time['hours'];
526
		$min = $time['minutes'];
527
		$sec = $time['seconds'];
528
		$context['linktree'][] = array('url' => $scripturl . '?action=clock;time=' . $_REQUEST['time'], 'name' => 'Requested Time');
529
		$context['clockicons'] = array(
530
			'year' => array(
531
				64 => false,
532
				32 => false,
533
				16 => false,
534
				8  => false,
535
				4  => false,
536
				2  => false,
537
				1  => false
538
			),
539
			'month' => array(
540
				8  => false,
541
				4  => false,
542
				2  => false,
543
				1  => false
544
			),
545
			'day' => array(
546
				16 => false,
547
				4  => false,
548
				8  => false,
549
				2  => false,
550
				1  => false
551
			),
552
			'hour' => array(
553
				32 => false,
554
				16 => false,
555
				8  => false,
556
				4  => false,
557
				2  => false,
558
				1  => false
559
			),
560
			'min' => array(
561
				32 => false,
562
				16 => false,
563
				8  => false,
564
				4  => false,
565
				2  => false,
566
				1  => false
567
			),
568
			'sec' => array(
569
				32 => false,
570
				16 => false,
571
				8  => false,
572
				4  => false,
573
				2  => false,
574
				1  => false
575
			),
576
		);
577
578
		foreach ($context['clockicons'] as $t => $vs)
579
			foreach ($vs as $v => $dumb)
580
			{
581
				if ($$t >= $v)
582
				{
583
					$$t -= $v;
584
					$context['clockicons'][$t][$v] = true;
585
				}
586
			}
587
	}
588
}
589
590
?>
0 ignored issues
show
Best Practice introduced by
It is not recommended to use PHP's closing tag ?> in files other than templates.

Using a closing tag in PHP files that only contain PHP code is not recommended as you might accidentally add whitespace after the closing tag which would then be output by PHP. This can cause severe problems, for example headers cannot be sent anymore.

A simple precaution is to leave off the closing tag as it is not required, and it also has no negative effects whatsoever.

Loading history...
591