Issues (1014)

Themes/default/Calendar.template.php (5 issues)

1
<?php
2
/**
3
 * Simple Machines Forum (SMF)
4
 *
5
 * @package SMF
6
 * @author Simple Machines https://www.simplemachines.org
7
 * @copyright 2022 Simple Machines and individual contributors
8
 * @license https://www.simplemachines.org/about/smf/license.php BSD
9
 *
10
 * @version 2.1.0
11
 */
12
13
/**
14
 * Our main calendar template, which encapsulates weeks and months.
15
 */
16
function template_main()
17
{
18
	global $context;
19
20
	// The main calendar wrapper.
21
	echo '
22
		<div id="calendar">';
23
24
	// Show the mini-blocks if they're enabled.
25
	if (empty($context['blocks_disabled']))
26
		echo '
27
			<div id="month_grid">
28
				', template_show_month_grid('prev', true), '
29
				', template_show_month_grid('current', true), '
30
				', template_show_month_grid('next', true), '
31
			</div>';
32
33
	// What view are we showing?
34
	if ($context['calendar_view'] == 'viewlist')
35
		echo '
36
			<div id="main_grid">
37
				', template_show_upcoming_list('main'), '
38
			</div>';
39
	elseif ($context['calendar_view'] == 'viewweek')
40
		echo '
41
			<div id="main_grid">
42
				', template_show_week_grid('main'), '
43
			</div>';
44
	else
45
		echo '
46
			<div id="main_grid">
47
				', template_show_month_grid('main'), '
48
			</div>';
49
50
	// Close our wrapper.
51
	echo '
52
		</div><!-- #calendar -->';
53
}
54
55
/**
56
 * Display a list of upcoming events, birthdays, and holidays.
57
 *
58
 * @param string $grid_name The grid name
59
 * @return void|bool Returns false if the grid doesn't exist.
60
 */
61
function template_show_upcoming_list($grid_name)
62
{
63
	global $context, $scripturl, $txt;
64
65
	// Bail out if we have nothing to work with
66
	if (!isset($context['calendar_grid_' . $grid_name]))
67
		return false;
68
69
	// Protect programmer sanity
70
	$calendar_data = &$context['calendar_grid_' . $grid_name];
71
72
	// Do we want a title?
73
	if (empty($calendar_data['disable_title']))
74
		echo '
75
			<div class="cat_bar">
76
				<h3 class="catbg centertext largetext">
77
					<a href="', $scripturl, '?action=calendar;viewlist;year=', $calendar_data['start_year'], ';month=', $calendar_data['start_month'], ';day=', $calendar_data['start_day'], '">', $txt['calendar_upcoming'], '</a>
78
				</h3>
79
			</div>';
80
81
	// Give the user some controls to work with
82
	template_calendar_top($calendar_data);
83
84
	// Output something just so people know it's not broken
85
	if (empty($calendar_data['events']) && empty($calendar_data['birthdays']) && empty($calendar_data['holidays']))
86
		echo '
87
			<div class="descbox">', $txt['calendar_empty'], '</div>';
88
89
	// First, list any events
90
	if (!empty($calendar_data['events']))
91
	{
92
		echo '
93
			<div>
94
				<div class="title_bar">
95
					<h3 class="titlebg">', str_replace(':', '', $txt['events']), '</h3>
96
				</div>
97
				<ul>';
98
99
		foreach ($calendar_data['events'] as $date => $date_events)
100
		{
101
			foreach ($date_events as $event)
102
			{
103
				echo '
104
					<li class="windowbg">
105
						<strong class="event_title">', $event['link'], '</strong>';
106
107
				if ($event['can_edit'])
108
					echo ' <a href="' . $event['modify_href'] . '"><span class="main_icons calendar_modify" title="', $txt['calendar_edit'], '"></span></a>';
109
110
				if ($event['can_export'])
111
					echo ' <a href="' . $event['export_href'] . '"><span class="main_icons calendar_export" title="', $txt['calendar_export'], '"></span></a>';
112
113
				echo '
114
						<br>';
115
116
				if (!empty($event['allday']))
117
				{
118
					echo '<time datetime="' . $event['start_iso_gmdate'] . '">', trim($event['start_date_local']), '</time>', ($event['start_date'] != $event['end_date']) ? ' &ndash; <time datetime="' . $event['end_iso_gmdate'] . '">' . trim($event['end_date_local']) . '</time>' : '';
119
				}
120
				else
121
				{
122
					// Display event info relative to user's local timezone
123
					echo '<time datetime="' . $event['start_iso_gmdate'] . '">', trim($event['start_date_local']), ', ', trim($event['start_time_local']), '</time> &ndash; <time datetime="' . $event['end_iso_gmdate'] . '">';
124
125
					if ($event['start_date_local'] != $event['end_date_local'])
126
						echo trim($event['end_date_local']) . ', ';
127
128
					echo trim($event['end_time_local']);
129
130
					// Display event info relative to original timezone
131
					if ($event['start_date_local'] . $event['start_time_local'] != $event['start_date_orig'] . $event['start_time_orig'])
132
					{
133
						echo '</time> (<time datetime="' . $event['start_iso_gmdate'] . '">';
134
135
						if ($event['start_date_orig'] != $event['start_date_local'] || $event['end_date_orig'] != $event['end_date_local'] || $event['start_date_orig'] != $event['end_date_orig'])
136
							echo trim($event['start_date_orig']), ', ';
137
138
						echo trim($event['start_time_orig']), '</time> &ndash; <time datetime="' . $event['end_iso_gmdate'] . '">';
139
140
						if ($event['start_date_orig'] != $event['end_date_orig'])
141
							echo trim($event['end_date_orig']) . ', ';
142
143
						echo trim($event['end_time_orig']), ' ', $event['tz_abbrev'], '</time>)';
144
					}
145
					// Event is scheduled in the user's own timezone? Let 'em know, just to avoid confusion
146
					else
147
						echo ' ', $event['tz_abbrev'], '</time>';
148
				}
149
150
				if (!empty($event['location']))
151
					echo '<br>', $event['location'];
152
153
				echo '
154
					</li>';
155
			}
156
		}
157
158
		echo '
159
				</ul>
160
			</div>';
161
	}
162
163
	// Next, list any birthdays
164
	if (!empty($calendar_data['birthdays']))
165
	{
166
		echo '
167
			<div>
168
				<div class="title_bar">
169
					<h3 class="titlebg">', str_replace(':', '', $txt['birthdays']), '</h3>
170
				</div>
171
				<div class="windowbg">';
172
173
		foreach ($calendar_data['birthdays'] as $date)
174
		{
175
			echo '
176
					<p class="inline">
177
						<strong>', $date['date_local'], '</strong>: ';
178
179
			unset($date['date_local']);
180
181
			$birthdays = array();
182
183
			foreach ($date as $member)
184
				$birthdays[] = '<a href="' . $scripturl . '?action=profile;u=' . $member['id'] . '">' . $member['name'] . (isset($member['age']) ? ' (' . $member['age'] . ')' : '') . '</a>';
185
186
			echo implode(', ', $birthdays);
187
188
			echo '
189
					</p>';
190
		}
191
192
		echo '
193
				</div><!-- .windowbg -->
194
			</div>';
195
	}
196
197
	// Finally, list any holidays
198
	if (!empty($calendar_data['holidays']))
199
	{
200
		echo '
201
			<div>
202
				<div class="title_bar">
203
					<h3 class="titlebg">', str_replace(':', '', $txt['calendar_prompt']), '</h3>
204
				</div>
205
				<div class="windowbg">
206
					<p class="inline holidays">';
207
208
		$holidays = array();
209
210
		foreach ($calendar_data['holidays'] as $date)
211
		{
212
			$date_local = $date['date_local'];
213
			unset($date['date_local']);
214
215
			foreach ($date as $holiday)
216
				$holidays[] = $holiday . ' (' . $date_local . ')';
217
		}
218
219
		echo implode(', ', $holidays);
220
221
		echo '
222
					</p>
223
				</div><!-- .windowbg -->
224
			</div>';
225
	}
226
}
227
228
/**
229
 * Display a monthly calendar grid.
230
 *
231
 * @param string $grid_name The grid name
232
 * @param bool $is_mini Is this a mini grid?
233
 * @return void|bool Returns false if the grid doesn't exist.
234
 */
235
function template_show_month_grid($grid_name, $is_mini = false)
236
{
237
	global $context, $txt, $scripturl, $modSettings;
238
239
	// If the grid doesn't exist, no point in proceeding.
240
	if (!isset($context['calendar_grid_' . $grid_name]))
241
		return false;
242
243
	// A handy little pointer variable.
244
	$calendar_data = &$context['calendar_grid_' . $grid_name];
245
246
	// Some conditions for whether or not we should show the week links *here*.
247
	if (isset($calendar_data['show_week_links']) && ($calendar_data['show_week_links'] == 3 || (($calendar_data['show_week_links'] == 1 && $is_mini === true) || $calendar_data['show_week_links'] == 2 && $is_mini === false)))
248
		$show_week_links = true;
249
	else
250
		$show_week_links = false;
251
252
	// Assuming that we've not disabled it, show the title block!
253
	if (empty($calendar_data['disable_title']))
254
	{
255
		echo '
256
			<div class="cat_bar">
257
				<h3 class="catbg centertext largetext">';
258
259
		// Previous Link: If we're showing prev / next and it's not a mini-calendar.
260
		if (empty($calendar_data['previous_calendar']['disabled']) && $calendar_data['show_next_prev'] && $is_mini === false)
261
			echo '
262
					<span class="floatleft">
263
						<a href="', $calendar_data['previous_calendar']['href'], '">&#171;</a>
264
					</span>';
265
266
		// Next Link: if we're showing prev / next and it's not a mini-calendar.
267
		if (empty($calendar_data['next_calendar']['disabled']) && $calendar_data['show_next_prev'] && $is_mini === false)
268
			echo '
269
					<span class="floatright">
270
						<a href="', $calendar_data['next_calendar']['href'], '">&#187;</a>
271
					</span>';
272
273
		// Arguably the most exciting part, the title!
274
		echo '
275
					<a href="', $scripturl, '?action=calendar;', $context['calendar_view'], ';year=', $calendar_data['current_year'], ';month=', $calendar_data['current_month'], ';day=', $calendar_data['current_day'], '">', $txt['months_titles'][$calendar_data['current_month']], ' ', $calendar_data['current_year'], '</a>
276
				</h3>
277
			</div><!-- .cat_bar -->';
278
	}
279
280
	// Show the controls on main grids
281
	if ($is_mini === false)
282
		template_calendar_top($calendar_data);
283
284
	// Finally, the main calendar table.
285
	echo '
286
			<table class="calendar_table">';
287
288
	// Show each day of the week.
289
	if (empty($calendar_data['disable_day_titles']))
290
	{
291
		echo '
292
				<tr>';
293
294
		// If we're showing week links, there's an extra column ahead of the week links, so let's think ahead and be prepared!
295
		if ($show_week_links === true)
296
			echo '
297
					<th></th>';
298
299
		// Now, loop through each actual day of the week.
300
		foreach ($calendar_data['week_days'] as $day)
301
			echo '
302
					<th class="days" scope="col">', !empty($calendar_data['short_day_titles']) || $is_mini === true ? $txt['days_short'][$day] : $txt['days'][$day], '</th>';
303
304
		echo '
305
				</tr>';
306
	}
307
308
	// Our looping begins on a per-week basis.
309
	foreach ($calendar_data['weeks'] as $week)
310
	{
311
		// Some useful looping variables.
312
		$current_month_started = false;
313
		$count = 1;
314
		$final_count = 1;
315
316
		echo '
317
				<tr class="days_wrapper">';
318
319
		// This is where we add the actual week link, if enabled on this location.
320
		if ($show_week_links === true)
321
			echo '
322
					<td class="windowbg weeks">
323
						<a href="', $scripturl, '?action=calendar;viewweek;year=', $calendar_data['current_year'], ';month=', $calendar_data['current_month'], ';day=', $week['days'][0]['day'], '" title="', $txt['calendar_view_week'], '">&#187;</a>
324
					</td>';
325
326
		// Now loop through each day in the week we're on.
327
		foreach ($week['days'] as $day)
328
		{
329
			// What classes should each day inherit? Day is default.
330
			$classes = array('days');
331
			if (!empty($day['day']))
332
			{
333
				$classes[] = !empty($day['is_today']) ? 'calendar_today' : 'windowbg';
334
335
				// Additional classes are given for events, holidays, and birthdays.
336
				foreach (array('events', 'holidays', 'birthdays') as $event_type)
337
					if (!empty($day[$event_type]))
338
						$classes[] = $event_type;
339
			}
340
			else
341
			{
342
				$classes[] = 'disabled';
343
			}
344
345
			// Now, implode the classes for each day.
346
			echo '
347
					<td class="', implode(' ', $classes), '">';
348
349
			// If it's within this current month, go ahead and begin.
350
			if (!empty($day['day']))
351
			{
352
				// If it's the first day of this month and not a mini-calendar, we'll add the month title - whether short or full.
353
				$title_prefix = !empty($day['is_first_of_month']) && $context['current_month'] == $calendar_data['current_month'] && $is_mini === false ? (!empty($calendar_data['short_month_titles']) ? $txt['months_short'][$calendar_data['current_month']] . ' ' : $txt['months_titles'][$calendar_data['current_month']] . ' ') : '';
354
355
				// The actual day number - be it a link, or just plain old text!
356
				if (!empty($modSettings['cal_daysaslink']) && $context['can_post'])
357
					echo '
358
						<a href="', $scripturl, '?action=calendar;sa=post;year=', $calendar_data['current_year'], ';month=', $calendar_data['current_month'], ';day=', $day['day'], ';', $context['session_var'], '=', $context['session_id'], '"><span class="day_text">', $title_prefix, $day['day'], '</span></a>';
359
				elseif ($is_mini)
360
					echo '
361
						<a href="', $scripturl, '?action=calendar;', $context['calendar_view'], ';year=', $calendar_data['current_year'], ';month=', $calendar_data['current_month'], ';day=', $day['day'], '"><span class="day_text">', $title_prefix, $day['day'], '</span></a>';
362
				else
363
					echo '
364
						<span class="day_text">', $title_prefix, $day['day'], '</span>';
365
366
				// A lot of stuff, we're not showing on mini-calendars to conserve space.
367
				if ($is_mini === false)
368
				{
369
					// Holidays are always fun, let's show them!
370
					if (!empty($day['holidays']))
371
						echo '
372
						<div class="smalltext holiday">
373
							<span>', $txt['calendar_prompt'], '</span> ', implode(', ', $day['holidays']), '
374
						</div>';
375
376
					// Happy Birthday Dear Member!
377
					if (!empty($day['birthdays']))
378
					{
379
						echo '
380
						<div class="smalltext">
381
							<span class="birthday">', $txt['birthdays'], '</span> ';
382
383
						/* Each of the birthdays has:
384
							id, name (person), age (if they have one set?), and is_last. (last in list?) */
385
						$use_js_hide = empty($context['show_all_birthdays']) && count($day['birthdays']) > 15;
386
						$birthday_count = 0;
387
						foreach ($day['birthdays'] as $member)
388
						{
389
							echo '<a href="', $scripturl, '?action=profile;u=', $member['id'], '"><span class="fix_rtl_names">', $member['name'], '</span>', isset($member['age']) ? ' (' . $member['age'] . ')' : '', '</a>', $member['is_last'] || ($count == 10 && $use_js_hide) ? '' : ', ';
390
391
							// 9...10! Let's stop there.
392
							if ($birthday_count == 10 && $use_js_hide)
393
								// !!TODO - Inline CSS and JavaScript should be moved.
394
								echo '<span class="hidelink" id="bdhidelink_', $day['day'], '">...<br><a href="', $scripturl, '?action=calendar;month=', $calendar_data['current_month'], ';year=', $calendar_data['current_year'], ';showbd" onclick="document.getElementById(\'bdhide_', $day['day'], '\').classList.remove(\'hidden\'); document.getElementById(\'bdhidelink_', $day['day'], '\').classList.add(\'hidden\'); return false;">(', sprintf($txt['calendar_click_all'], count($day['birthdays'])), ')</a></span><span id="bdhide_', $day['day'], '" class="hidden">, ';
395
396
							++$birthday_count;
397
						}
398
						if ($use_js_hide)
399
							echo '
400
							</span>';
401
402
						echo '
403
						</div><!-- .smalltext -->';
404
					}
405
406
					// Any special posted events?
407
					if (!empty($day['events']))
408
					{
409
						// Sort events by start time (all day events will be listed first)
410
						uasort(
411
							$day['events'],
412
							function($a, $b)
413
							{
414
								if ($a['start_timestamp'] == $b['start_timestamp'])
415
									return 0;
416
417
								return ($a['start_timestamp'] < $b['start_timestamp']) ? -1 : 1;
418
							}
419
						);
420
421
						echo '
422
						<div class="smalltext lefttext">
423
							<span class="event">', $txt['events'], '</span><br>';
424
425
						/* The events are made up of:
426
							title, href, is_last, can_edit (are they allowed to?), and modify_href. */
427
						foreach ($day['events'] as $event)
428
						{
429
							$event_icons_needed = ($event['can_edit'] || $event['can_export']) ? true : false;
430
431
							echo '
432
							<div class="event_wrapper', $event['starts_today'] == true ? ' event_starts_today' : '', $event['ends_today'] == true ? ' event_ends_today' : '', $event['allday'] == true ? ' allday' : '', $event['is_selected'] ? ' sel_event' : '', '">
433
								', $event['link'], '<br>
434
								<span class="event_time', empty($event_icons_needed) ? ' floatright' : '', '">';
435
436
							if (!empty($event['start_time_local']) && $event['starts_today'] == true)
437
								echo trim(str_replace(':00 ', ' ', $event['start_time_local']));
438
							elseif (!empty($event['end_time_local']) && $event['ends_today'] == true)
439
								echo strtolower($txt['ends']), ' ', trim(str_replace(':00 ', ' ', $event['end_time_local']));
440
							elseif (!empty($event['allday']))
441
								echo $txt['calendar_allday'];
442
443
							echo '
444
								</span>';
445
446
							if (!empty($event['location']))
447
								echo '
448
								<br>
449
								<span class="event_location', empty($event_icons_needed) ? ' floatright' : '', '">' . $event['location'] . '</span>';
450
451
							if ($event['can_edit'] || $event['can_export'])
452
							{
453
								echo '
454
								<span class="modify_event_links">';
455
456
								// If they can edit the event, show an icon they can click on....
457
								if ($event['can_edit'])
458
									echo '
459
									<a class="modify_event" href="', $event['modify_href'], '">
460
										<span class="main_icons calendar_modify" title="', $txt['calendar_edit'], '"></span>
461
									</a>';
462
463
								// Exporting!
464
								if ($event['can_export'])
465
									echo '
466
									<a class="modify_event" href="', $event['export_href'], '">
467
										<span class="main_icons calendar_export" title="', $txt['calendar_export'], '"></span>
468
									</a>';
469
470
								echo '
471
								</span><br class="clear">';
472
							}
473
474
							echo '
475
							</div><!-- .event_wrapper -->';
476
						}
477
478
						echo '
479
						</div><!-- .smalltext -->';
480
					}
481
				}
482
				$current_month_started = $count;
483
			}
484
			// Otherwise, assuming it's not a mini-calendar, we can show previous / next month days!
485
			elseif ($is_mini === false)
486
			{
487
				if (empty($current_month_started) && !empty($context['calendar_grid_prev']))
488
					echo '<a href="', $scripturl, '?action=calendar;year=', $context['calendar_grid_prev']['current_year'], ';month=', $context['calendar_grid_prev']['current_month'], '">', $context['calendar_grid_prev']['last_of_month'] - $calendar_data['shift']-- +1, '</a>';
489
				elseif (!empty($current_month_started) && !empty($context['calendar_grid_next']))
490
					echo '<a href="', $scripturl, '?action=calendar;year=', $context['calendar_grid_next']['current_year'], ';month=', $context['calendar_grid_next']['current_month'], '">', $current_month_started + 1 == $count ? (!empty($calendar_data['short_month_titles']) ? $txt['months_short'][$context['calendar_grid_next']['current_month']] . ' ' : $txt['months_titles'][$context['calendar_grid_next']['current_month']] . ' ') : '', $final_count++, '</a>';
491
			}
492
493
			// Close this day and increase var count.
494
			echo '
495
					</td>';
496
497
			++$count;
498
		}
499
500
		echo '
501
				</tr>';
502
	}
503
504
	// The end of our main table.
505
	echo '
506
			</table>';
507
}
508
509
/**
510
 * Shows a weekly grid
511
 *
512
 * @param string $grid_name The name of the grid
513
 * @return void|bool Returns false if the grid doesn't exist
514
 */
515
function template_show_week_grid($grid_name)
516
{
517
	global $context, $txt, $scripturl, $modSettings;
518
519
	// We might have no reason to proceed, if the variable isn't there.
520
	if (!isset($context['calendar_grid_' . $grid_name]))
521
		return false;
522
523
	// Handy pointer.
524
	$calendar_data = &$context['calendar_grid_' . $grid_name];
525
526
	// At the very least, we have one month. Possibly two, though.
527
	$iteration = 1;
528
	foreach ($calendar_data['months'] as $month_data)
529
	{
530
		// For our first iteration, we'll add a nice header!
531
		if ($iteration == 1)
532
		{
533
			echo '
534
				<div class="cat_bar">
535
					<h3 class="catbg centertext largetext">';
536
537
			// Previous Week Link...
538
			if (empty($calendar_data['previous_calendar']['disabled']) && !empty($calendar_data['show_next_prev']))
539
				echo '
540
						<span class="floatleft">
541
							<a href="', $calendar_data['previous_week']['href'], '">&#171;</a>
542
						</span>';
543
544
			// Next Week Link...
545
			if (empty($calendar_data['next_calendar']['disabled']) && !empty($calendar_data['show_next_prev']))
546
				echo '
547
						<span class="floatright">
548
							<a href="', $calendar_data['next_week']['href'], '">&#187;</a>
549
						</span>';
550
551
			// "Week beginning <date>"
552
			if (!empty($calendar_data['week_title']))
553
				echo $calendar_data['week_title'];
554
555
			echo '
556
					</h3>
557
				</div><!-- .cat_bar -->';
558
559
			// Show the controls
560
			template_calendar_top($calendar_data);
561
		}
562
563
		// Our actual month...
564
		echo '
565
				<div class="week_month_title">
566
					<a href="', $scripturl, '?action=calendar;month=', $month_data['current_month'], '">
567
						', $txt['months_titles'][$month_data['current_month']], '
568
					</a>
569
				</div>';
570
571
		// The main table grid for $this week.
572
		echo '
573
				<table class="table_grid calendar_week">
574
					<tr>
575
						<th class="days" scope="col">', $txt['calendar_day'], '</th>';
576
		if (!empty($calendar_data['show_events']))
577
			echo '
578
						<th class="days" scope="col">', $txt['events'], '</th>';
579
580
		if (!empty($calendar_data['show_holidays']))
581
			echo '
582
						<th class="days" scope="col">', $txt['calendar_prompt'], '</th>';
583
		if (!empty($calendar_data['show_birthdays']))
584
			echo '
585
						<th class="days" scope="col">', $txt['birthdays'], '</th>';
586
		echo '
587
					</tr>';
588
589
		// Each day of the week.
590
		foreach ($month_data['days'] as $day)
591
		{
592
			// How should we be highlighted or otherwise not...?
593
			$classes = array('days');
594
			$classes[] = !empty($day['is_today']) ? 'calendar_today' : 'windowbg';
595
596
			echo '
597
					<tr class="days_wrapper">
598
						<td class="', implode(' ', $classes), ' act_day">';
599
600
			// Should the day number be a link?
601
			if (!empty($modSettings['cal_daysaslink']) && $context['can_post'])
602
				echo '
603
							<a href="', $scripturl, '?action=calendar;sa=post;month=', $month_data['current_month'], ';year=', $month_data['current_year'], ';day=', $day['day'], ';', $context['session_var'], '=', $context['session_id'], '">', $txt['days'][$day['day_of_week']], ' - ', $day['day'], '</a>';
604
			else
605
				echo $txt['days'][$day['day_of_week']], ' - ', $day['day'];
606
607
			echo '
608
						</td>';
609
610
			if (!empty($calendar_data['show_events']))
611
			{
612
				echo '
613
						<td class="', implode(' ', $classes), '', empty($day['events']) ? (' disabled' . ($context['can_post'] ? ' week_post' : '')) : ' events', ' event_col" data-css-prefix="' . $txt['events'] . ' ', (empty($day['events']) && empty($context['can_post'])) ? $txt['none'] : '', '">';
614
615
				// Show any events...
616
				if (!empty($day['events']))
617
				{
618
					// Sort events by start time (all day events will be listed first)
619
					uasort(
620
						$day['events'],
621
						function($a, $b)
622
						{
623
							if ($a['start_timestamp'] == $b['start_timestamp'])
624
								return 0;
625
626
							return ($a['start_timestamp'] < $b['start_timestamp']) ? -1 : 1;
627
						}
628
					);
629
630
					foreach ($day['events'] as $event)
631
					{
632
						echo '
633
								<div class="event_wrapper">';
634
635
						$event_icons_needed = ($event['can_edit'] || $event['can_export']) ? true : false;
636
637
						echo $event['link'], '<br>
638
									<span class="event_time', empty($event_icons_needed) ? ' floatright' : '', '">';
639
640
						if (!empty($event['start_time_local']))
641
							echo trim($event['start_time_local']), !empty($event['end_time_local']) ? ' &ndash; ' . trim($event['end_time_local']) : '';
642
						else
643
							echo $txt['calendar_allday'];
644
645
						echo '
646
									</span>';
647
648
						if (!empty($event['location']))
649
							echo '<br>
650
									<span class="event_location', empty($event_icons_needed) ? ' floatright' : '', '">' . $event['location'] . '</span>';
651
652
						if (!empty($event_icons_needed))
653
						{
654
							echo ' <span class="modify_event_links">';
655
656
							// If they can edit the event, show a star they can click on....
657
							if (!empty($event['can_edit']))
658
								echo '
659
										<a class="modify_event" href="', $event['modify_href'], '">
660
											<span class="main_icons calendar_modify" title="', $txt['calendar_edit'], '"></span>
661
										</a>';
662
663
							// Can we export? Sweet.
664
							if (!empty($event['can_export']))
665
								echo '
666
										<a class="modify_event" href="', $event['export_href'], '">
667
											<span class="main_icons calendar_export" title="', $txt['calendar_export'], '"></span>
668
										</a>';
669
670
							echo '
671
									</span><br class="clear">';
672
						}
673
674
						echo '
675
								</div><!-- .event_wrapper -->';
676
					}
677
678
					if (!empty($context['can_post']))
679
					{
680
						echo '
681
								<div class="week_add_event">
682
									<a href="', $scripturl, '?action=calendar;sa=post;month=', $month_data['current_month'], ';year=', $month_data['current_year'], ';day=', $day['day'], ';', $context['session_var'], '=', $context['session_id'], '">', $txt['calendar_post_event'], '</a>
683
								</div>
684
								<br class="clear">';
685
					}
686
				}
687
				else
688
				{
689
					if (!empty($context['can_post']))
690
						echo '
691
								<div class="week_add_event">
692
									<a href="', $scripturl, '?action=calendar;sa=post;month=', $month_data['current_month'], ';year=', $month_data['current_year'], ';day=', $day['day'], ';', $context['session_var'], '=', $context['session_id'], '">', $txt['calendar_post_event'], '</a>
693
								</div>';
694
				}
695
				echo '
696
							</td>';
697
			}
698
699
			if (!empty($calendar_data['show_holidays']))
700
			{
701
				echo '
702
						<td class="', implode(' ', $classes), !empty($day['holidays']) ? ' holidays' : ' disabled', ' holiday_col" data-css-prefix="' . $txt['calendar_prompt'] . ' ">';
703
704
				// Show any holidays!
705
				if (!empty($day['holidays']))
706
					echo implode('<br>', $day['holidays']);
707
708
				echo '
709
							</td>';
710
			}
711
712
			if (!empty($calendar_data['show_birthdays']))
713
			{
714
				echo '
715
						<td class="', implode(' ', $classes), '', !empty($day['birthdays']) ? ' birthdays' : ' disabled', ' birthday_col" data-css-prefix="' . $txt['birthdays'] . ' ">';
716
717
				// Show any birthdays...
718
				if (!empty($day['birthdays']))
719
				{
720
					foreach ($day['birthdays'] as $member)
721
						echo '
722
								<a href="', $scripturl, '?action=profile;u=', $member['id'], '">', $member['name'], '</a>
723
								', isset($member['age']) ? ' (' . $member['age'] . ')' : '', '
724
								', $member['is_last'] ? '' : '<br>';
725
				}
726
				echo '
727
						</td>';
728
			}
729
			echo '
730
					</tr>';
731
		}
732
733
		// Increase iteration for loop counting.
734
		++$iteration;
735
736
		echo '
737
				</table>';
738
	}
739
}
740
741
/**
742
 * Calendar controls under the title
743
 *
744
 * Creates the view selector (list, month, week), the date selector (either a
745
 * select menu or a date range chooser, depending on the circumstances), and the
746
 * "Post Event" button.
747
 *
748
 * @param array $calendar_data The data for the calendar grid that this is for
749
 */
750
function template_calendar_top($calendar_data)
751
{
752
	global $context, $scripturl, $txt;
753
754
	echo '
755
		<div class="calendar_top roundframe', empty($calendar_data['disable_title']) ? ' noup' : '', '">
756
			<div id="calendar_viewselector" class="buttonrow floatleft">
757
				<a href="', $scripturl, '?action=calendar;viewlist;year=', $context['current_year'], ';month=', $context['current_month'], ';day=', $context['current_day'], '" class="button', $context['calendar_view'] == 'viewlist' ? ' active' : '', '">', $txt['calendar_list'], '</a>
758
				<a href="', $scripturl, '?action=calendar;viewmonth;year=', $context['current_year'], ';month=', $context['current_month'], ';day=', $context['current_day'], '" class="button', $context['calendar_view'] == 'viewmonth' ? ' active' : '', '">', $txt['calendar_month'], '</a>
759
				<a href="', $scripturl, '?action=calendar;viewweek;year=', $context['current_year'], ';month=', $context['current_month'], ';day=', $context['current_day'], '" class="button', $context['calendar_view'] == 'viewweek' ? ' active' : '', '">', $txt['calendar_week'], '</a>
760
			</div>
761
			', template_button_strip($context['calendar_buttons'], 'right');
0 ignored issues
show
Are you sure the usage of template_button_strip($c...dar_buttons'], 'right') is correct as it seems to always return null.

This check looks for function or method calls that always return null and whose return value is used.

class A
{
    function getObject()
    {
        return null;
    }

}

$a = new A();
if ($a->getObject()) {

The method getObject() can return nothing but null, so it makes no sense to use the return value.

The reason is most likely that a function or method is imcomplete or has been reduced for debug purposes.

Loading history...
762
763
	echo '
764
			<form action="', $scripturl, '?action=calendar;', $context['calendar_view'], '" id="', !empty($calendar_data['end_date']) ? 'calendar_range' : 'calendar_navigation', '" method="post" accept-charset="', $context['character_set'], '">
765
				<input type="text" name="start_date" id="start_date" value="', trim($calendar_data['start_date']), '" tabindex="', $context['tabindex']++, '" class="date_input start" data-type="date">';
766
767
	if (!empty($calendar_data['end_date']))
768
		echo '
769
				<span>', strtolower($txt['to']), '</span>
770
				<input type="text" name="end_date" id="end_date" value="', trim($calendar_data['end_date']), '" tabindex="', $context['tabindex']++, '" class="date_input end" data-type="date">';
771
772
	echo '
773
				<input type="submit" class="button" style="float:none" id="view_button" value="', $txt['view'], '">
774
			</form>
775
		</div><!-- .calendar_top -->';
776
}
777
778
/**
779
 * Template for posting a calendar event.
780
 */
781
function template_event_post()
782
{
783
	global $context, $txt, $scripturl, $modSettings;
784
785
	echo '
786
		<form action="', $scripturl, '?action=calendar;sa=post" method="post" name="postevent" accept-charset="', $context['character_set'], '" onsubmit="submitonce(this);">';
787
788
	if (!empty($context['event']['new']))
789
		echo '
790
			<input type="hidden" name="eventid" value="', $context['event']['eventid'], '">';
791
792
	// Start the main table.
793
	echo '
794
			<div id="post_event">
795
				<div class="cat_bar">
796
					<h3 class="catbg">
797
						', $context['page_title'], '
798
					</h3>
799
				</div>';
800
801
	if (!empty($context['post_error']['messages']))
802
		echo '
803
				<div class="errorbox">
804
					<dl class="event_error">
805
						<dt>
806
							', $context['error_type'] == 'serious' ? '<strong>' . $txt['error_while_submitting'] . '</strong>' : '', '
807
						</dt>
808
						<dt class="error">
809
							', implode('<br>', $context['post_error']['messages']), '
810
						</dt>
811
					</dl>
812
				</div>';
813
814
	echo '
815
				<div class="roundframe noup">
816
					<fieldset id="event_main">
817
						<legend><span', isset($context['post_error']['no_event']) ? ' class="error"' : '', '>', $txt['calendar_event_title'], '</span></legend>
818
						<input type="hidden" name="calendar" value="1">
819
						<div class="event_options_left" id="event_title">
820
							<div>
821
								<input type="text" id="evtitle" name="evtitle" maxlength="255" size="55" value="', $context['event']['title'], '" tabindex="', $context['tabindex']++, '">
822
							</div>
823
						</div>';
824
825
	// If this is a new event let the user specify which board they want the linked post to be put into.
826
	if ($context['event']['new'] && !empty($context['event']['categories']))
827
	{
828
		echo '
829
						<div class="event_options_right" id="event_board">
830
							<div>
831
								<span class="label">', $txt['calendar_post_in'], '</span>
832
								<input type="checkbox" name="link_to_board"', (!empty($context['event']['board']) ? ' checked' : ''), ' onclick="toggleLinked(this.form);">
833
								<select name="board"', empty($context['event']['board']) ? ' disabled' : '', '>';
834
835
		foreach ($context['event']['categories'] as $category)
836
		{
837
			echo '
838
									<optgroup label="', $category['name'], '">';
839
840
			foreach ($category['boards'] as $board)
841
				echo '
842
										<option value="', $board['id'], '"', $board['selected'] ? ' selected' : '', '>', $board['child_level'] > 0 ? str_repeat('==', $board['child_level'] - 1) . '=&gt;' : '', ' ', $board['name'], '</option>';
843
			echo '
844
									</optgroup>';
845
		}
846
		echo '
847
								</select>
848
							</div>
849
						</div><!-- #event_board -->';
850
	}
851
852
	// Note to theme writers: The JavaScript expects the input fields for the start and end dates & times to be contained in a wrapper element with the id "event_time_input"
853
	echo '
854
					</fieldset>
855
					<fieldset id="event_options">
856
						<legend>', $txt['calendar_event_options'], '</legend>
857
						<div class="event_options_left" id="event_time_input">
858
							<div>
859
								<span class="label">', $txt['start'], '</span>
860
								<input type="text" name="start_date" id="start_date" value="', trim($context['event']['start_date_orig']), '" tabindex="', $context['tabindex']++, '" class="date_input start" data-type="date">
861
								<input type="text" name="start_time" id="start_time" maxlength="11" value="', $context['event']['start_time_orig'], '" tabindex="', $context['tabindex']++, '" class="time_input start" data-type="time"', !empty($context['event']['allday']) ? ' disabled' : '', '>
862
							</div>
863
							<div>
864
								<span class="label">', $txt['end'], '</span>
865
								<input type="text" name="end_date" id="end_date" value="', trim($context['event']['end_date_orig']), '" tabindex="', $context['tabindex']++, '" class="date_input end" data-type="date"', $modSettings['cal_maxspan'] == 1 ? ' disabled' : '', '>
866
								<input type="text" name="end_time" id="end_time" maxlength="11" value="', $context['event']['end_time_orig'], '" tabindex="', $context['tabindex']++, '" class="time_input end" data-type="time"', !empty($context['event']['allday']) ? ' disabled' : '', '>
867
							</div>
868
						</div><!-- #event_time_input -->
869
						<div class="event_options_right" id="event_time_options">
870
							<div id="event_allday">
871
								<label for="allday"><span class="label">', $txt['calendar_allday'], '</span></label>
872
								<input type="checkbox" name="allday" id="allday"', !empty($context['event']['allday']) ? ' checked' : '', ' tabindex="', $context['tabindex']++, '">
873
							</div>
874
							<div id="event_timezone">
875
								<span class="label">', $txt['calendar_timezone'], '</span>
876
								<select name="tz" id="tz"', !empty($context['event']['allday']) ? ' disabled' : '', '>';
877
878
	foreach ($context['all_timezones'] as $tz => $tzname)
879
		echo '
880
									<option', is_numeric($tz) ? ' value="" disabled' : ' value="' . $tz . '"', $tz === $context['event']['tz'] ? ' selected' : '', '>', $tzname, '</option>';
881
882
	echo '
883
								</select>
884
							</div>
885
						</div><!-- #event_time_options -->
886
						<div>
887
							<span class="label">', $txt['location'], '</span>
888
							<input type="text" name="event_location" id="event_location" maxlength="255" value="', !empty($context['event']['location']) ? $context['event']['location'] : '', '" tabindex="', $context['tabindex']++, '">
889
						</div>
890
					</fieldset>';
891
892
	echo '
893
					<input type="submit" value="', empty($context['event']['new']) ? $txt['save'] : $txt['post'], '" class="button">';
894
895
	// Delete button?
896
	if (empty($context['event']['new']))
897
		echo '
898
					<input type="submit" name="deleteevent" value="', $txt['event_delete'], '" data-confirm="', $txt['calendar_confirm_delete'], '" class="button you_sure">';
899
900
	echo '
901
					<input type="hidden" name="', $context['session_var'], '" value="', $context['session_id'], '">
902
					<input type="hidden" name="eventid" value="', $context['event']['eventid'], '">
903
904
				</div><!-- .roundframe -->
905
			</div><!-- #post_event -->
906
		</form>';
907
}
908
909
/**
910
 * Displays a clock
911
 */
912
function template_bcd()
913
{
914
	global $context, $scripturl;
915
	$alt = false;
916
917
	echo '
918
		<table class="table_grid" style="margin: 0 auto 0 auto; border: 1px solid #ccc;">
919
			<tr>
920
				<th class="windowbg" style="font-weight: bold; text-align: center; border-bottom: 1px solid #ccc;" colspan="6">BCD Clock</th>
921
			</tr>
922
			<tr class="windowbg">';
923
924
	foreach ($context['clockicons'] as $t => $v)
925
	{
926
		echo '
927
				<td style="padding-', $alt ? 'right' : 'left', ': 1.5em;">';
928
929
		foreach ($v as $i)
930
			echo '
931
					<img src="', $context['offimg'], '" alt="" id="', $t, '_', $i, '"><br>';
932
933
		echo '
934
				</td>';
935
936
		$alt = !$alt;
0 ignored issues
show
The condition $alt is always false.
Loading history...
937
	}
938
	echo '
939
			</tr>
940
			<tr class="windowbg" style="border-top: 1px solid #ccc; text-align: center;">
941
				<td colspan="6">
942
					<a href="', $scripturl, '?action=clock;rb">Are you hardcore?</a>
943
				</td>
944
			</tr>
945
		</table>
946
947
		<script>
948
			var icons = new Object();';
949
950
	foreach ($context['clockicons'] as $t => $v)
951
	{
952
		foreach ($v as $i)
953
			echo '
954
			icons[\'', $t, '_', $i, '\'] = document.getElementById(\'', $t, '_', $i, '\');';
955
	}
956
957
	echo '
958
			function update()
959
			{
960
				// Get the current time
961
				var time = new Date();
962
				var hour = time.getHours();
963
				var min = time.getMinutes();
964
				var sec = time.getSeconds();
965
966
				// Break it up into individual digits
967
				var h1 = parseInt(hour / 10);
968
				var h2 = hour % 10;
969
				var m1 = parseInt(min / 10);
970
				var m2 = min % 10;
971
				var s1 = parseInt(sec / 10);
972
				var s2 = sec % 10;
973
974
				// For each digit figure out which ones to turn off and which ones to turn on
975
				var turnon = new Array();';
976
977
	foreach ($context['clockicons'] as $t => $v)
978
	{
979
		foreach ($v as $i)
980
			echo '
981
				if (', $t, ' >= ', $i, ')
982
				{
983
					turnon.push("', $t, '_', $i, '");
984
					', $t, ' -= ', $i, ';
985
				}';
986
	}
987
988
	echo '
989
				for (var i in icons)
990
					if (!in_array(i, turnon))
991
						icons[i].src = "', $context['offimg'], '";
992
					else
993
						icons[i].src = "', $context['onimg'], '";
994
995
				window.setTimeout("update();", 500);
996
			}
997
			// Checks for variable in theArray.
998
			function in_array(variable, theArray)
999
			{
1000
				for (var i = 0; i < theArray.length; i++)
1001
				{
1002
					if (theArray[i] == variable)
1003
						return true;
1004
				}
1005
				return false;
1006
			}
1007
1008
			update();
1009
		</script>';
1010
}
1011
1012
/**
1013
 * Displays the hours, minutes and seconds for our clock
1014
 */
1015
function template_hms()
1016
{
1017
	global $context, $scripturl;
1018
	$alt = false;
1019
1020
	echo '
1021
		<table class="table_grid" style="margin: 0 auto 0 auto; border: 1px solid #ccc;">
1022
			<tr>
1023
				<th class="windowbg" style="font-weight: bold; text-align: center; border-bottom: 1px solid #ccc;">Binary Clock</th>
1024
			</tr>';
1025
1026
	foreach ($context['clockicons'] as $t => $v)
1027
	{
1028
		echo '
1029
			<tr class="windowbg">
1030
				<td>';
1031
1032
		foreach ($v as $i)
1033
			echo '
1034
					<img src="', $context['offimg'], '" alt="" id="', $t, '_', $i, '" style="padding: 2px;">';
1035
1036
		echo '
1037
				</td>
1038
			</tr>';
1039
1040
		$alt = !$alt;
0 ignored issues
show
The condition $alt is always false.
Loading history...
1041
	}
1042
	echo '
1043
			<tr class="windowbg" style="border-top: 1px solid #ccc; text-align: center;">
1044
				<td>
1045
					<a href="', $scripturl, '?action=clock">Too tough for you?</a>
1046
				</td>
1047
			</tr>
1048
		</table>';
1049
1050
	echo '
1051
		<script>
1052
			var icons = new Object();';
1053
1054
	foreach ($context['clockicons'] as $t => $v)
1055
	{
1056
		foreach ($v as $i)
1057
			echo '
1058
			icons[\'', $t, '_', $i, '\'] = document.getElementById(\'', $t, '_', $i, '\');';
1059
	}
1060
1061
	echo '
1062
			function update()
1063
			{
1064
				// Get the current time
1065
				var time = new Date();
1066
				var h = time.getHours();
1067
				var m = time.getMinutes();
1068
				var s = time.getSeconds();
1069
1070
				// For each digit figure out which ones to turn off and which ones to turn on
1071
				var turnon = new Array();';
1072
1073
	foreach ($context['clockicons'] as $t => $v)
1074
	{
1075
		foreach ($v as $i)
1076
			echo '
1077
				if (', $t, ' >= ', $i, ')
1078
				{
1079
					turnon.push("', $t, '_', $i, '");
1080
					', $t, ' -= ', $i, ';
1081
				}';
1082
	}
1083
1084
	echo '
1085
				for (var i in icons)
1086
					if (!in_array(i, turnon))
1087
						icons[i].src = "', $context['offimg'], '";
1088
					else
1089
						icons[i].src = "', $context['onimg'], '";
1090
1091
				window.setTimeout("update();", 500);
1092
			}
1093
			// Checks for variable in theArray.
1094
			function in_array(variable, theArray)
1095
			{
1096
				for (var i = 0; i < theArray.length; i++)
1097
				{
1098
					if (theArray[i] == variable)
1099
						return true;
1100
				}
1101
				return false;
1102
			}
1103
1104
			update();
1105
		</script>';
1106
}
1107
1108
/**
1109
 * Displays a binary clock
1110
 */
1111
function template_omfg()
1112
{
1113
	global $context;
1114
	$alt = false;
1115
1116
	echo '
1117
		<table class="table_grid" style="margin: 0 auto 0 auto; border: 1px solid #ccc;">
1118
			<tr>
1119
				<th class="windowbg" style="font-weight: bold; text-align: center; border-bottom: 1px solid #ccc;">OMFG Binary Clock</th>
1120
			</tr>';
1121
1122
	foreach ($context['clockicons'] as $t => $v)
1123
	{
1124
		echo '
1125
			<tr class="windowbg">
1126
				<td>';
1127
1128
		foreach ($v as $i)
1129
			echo '
1130
					<img src="', $context['offimg'], '" alt="" id="', $t, '_', $i, '" style="padding: 2px;">';
1131
1132
		echo '
1133
				</td>
1134
			</tr>';
1135
1136
		$alt = !$alt;
0 ignored issues
show
The condition $alt is always false.
Loading history...
1137
	}
1138
1139
	echo '
1140
		</table>
1141
		<script>
1142
			var icons = new Object();';
1143
1144
	foreach ($context['clockicons'] as $t => $v)
1145
	{
1146
		foreach ($v as $i)
1147
			echo '
1148
			icons[\'', $t, '_', $i, '\'] = document.getElementById(\'', $t, '_', $i, '\');';
1149
	}
1150
1151
	echo '
1152
			function update()
1153
			{
1154
				// Get the current time
1155
				var time = new Date();
1156
				var month = time.getMonth() + 1;
1157
				var day = time.getDate();
1158
				var year = time.getFullYear();
1159
				year = year % 100;
1160
				var hour = time.getHours();
1161
				var min = time.getMinutes();
1162
				var sec = time.getSeconds();
1163
1164
				// For each digit figure out which ones to turn off and which ones to turn on
1165
				var turnon = new Array();';
1166
1167
	foreach ($context['clockicons'] as $t => $v)
1168
	{
1169
		foreach ($v as $i)
1170
			echo '
1171
				if (', $t, ' >= ', $i, ')
1172
				{
1173
					turnon.push("', $t, '_', $i, '");
1174
					', $t, ' -= ', $i, ';
1175
				}';
1176
	}
1177
1178
	echo '
1179
				for (var i in icons)
1180
					if (!in_array(i, turnon))
1181
						icons[i].src = "', $context['offimg'], '";
1182
					else
1183
						icons[i].src = "', $context['onimg'], '";
1184
1185
				window.setTimeout("update();", 500);
1186
			}
1187
			// Checks for variable in theArray.
1188
			function in_array(variable, theArray)
1189
			{
1190
				for (var i = 0; i < theArray.length; i++)
1191
				{
1192
					if (theArray[i] == variable)
1193
						return true;
1194
				}
1195
				return false;
1196
			}
1197
1198
			update();
1199
		</script>';
1200
}
1201
1202
/**
1203
 * Displays the time
1204
 */
1205
function template_thetime()
1206
{
1207
	global $context;
1208
	$alt = false;
1209
1210
	echo '
1211
		<table class="table_grid" style="margin: 0 auto 0 auto; border: 1px solid #ccc;">
1212
			<tr>
1213
				<th class="windowbg" style="font-weight: bold; text-align: center; border-bottom: 1px solid #ccc;">The time you requested</th>
1214
			</tr>';
1215
1216
	foreach ($context['clockicons'] as $v)
1217
	{
1218
		echo '
1219
			<tr class="windowbg">
1220
				<td>';
1221
1222
		foreach ($v as $i)
1223
			echo '
1224
					<img src="', $i ? $context['onimg'] : $context['offimg'], '" alt="" style="padding: 2px;">';
1225
1226
		echo '
1227
				</td>
1228
			</tr>';
1229
1230
		$alt = !$alt;
0 ignored issues
show
The condition $alt is always false.
Loading history...
1231
	}
1232
1233
	echo '
1234
		</table>';
1235
}
1236
1237
?>