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 https://www.simplemachines.org |
||||
11 | * @copyright 2022 Simple Machines and individual contributors |
||||
12 | * @license https://www.simplemachines.org/about/smf/license.php BSD |
||||
13 | * |
||||
14 | * @version 2.1.2 |
||||
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 | * |
||||
30 | * @return void |
||||
31 | */ |
||||
32 | function CalendarMain() |
||||
33 | { |
||||
34 | global $txt, $context, $modSettings, $scripturl, $options, $sourcedir, $user_info, $smcFunc; |
||||
35 | |||||
36 | // Permissions, permissions, permissions. |
||||
37 | isAllowedTo('calendar_view'); |
||||
38 | |||||
39 | // Some global template resources. |
||||
40 | $context['calendar_resources'] = array( |
||||
41 | 'min_year' => $modSettings['cal_minyear'], |
||||
42 | 'max_year' => $modSettings['cal_maxyear'], |
||||
43 | ); |
||||
44 | |||||
45 | // Doing something other than calendar viewing? |
||||
46 | $subActions = array( |
||||
47 | 'ical' => 'iCalDownload', |
||||
48 | 'post' => 'CalendarPost', |
||||
49 | ); |
||||
50 | |||||
51 | if (isset($_GET['sa']) && isset($subActions[$_GET['sa']])) |
||||
52 | return call_helper($subActions[$_GET['sa']]); |
||||
53 | |||||
54 | // You can't do anything if the calendar is off. |
||||
55 | if (empty($modSettings['cal_enabled'])) |
||||
56 | fatal_lang_error('calendar_off', false); |
||||
57 | |||||
58 | // This is gonna be needed... |
||||
59 | loadTemplate('Calendar'); |
||||
60 | loadCSSFile('calendar.css', array('force_current' => false, 'validate' => true, 'rtl' => 'calendar.rtl.css'), 'smf_calendar'); |
||||
61 | |||||
62 | // Did the specify an individual event ID? If so, let's splice the year/month in to what we would otherwise be doing. |
||||
63 | if (isset($_GET['event'])) |
||||
64 | { |
||||
65 | $evid = (int) $_GET['event']; |
||||
66 | if ($evid > 0) |
||||
67 | { |
||||
68 | $request = $smcFunc['db_query']('', ' |
||||
69 | SELECT start_date |
||||
70 | FROM {db_prefix}calendar |
||||
71 | WHERE id_event = {int:event_id}', |
||||
72 | array( |
||||
73 | 'event_id' => $evid, |
||||
74 | ) |
||||
75 | ); |
||||
76 | if ($row = $smcFunc['db_fetch_assoc']($request)) |
||||
77 | { |
||||
78 | $_REQUEST['start_date'] = $row['start_date']; |
||||
79 | |||||
80 | // We might use this later. |
||||
81 | $context['selected_event'] = $evid; |
||||
82 | } |
||||
83 | $smcFunc['db_free_result']($request); |
||||
84 | } |
||||
85 | unset ($_GET['event']); |
||||
86 | } |
||||
87 | |||||
88 | // Set the page title to mention the calendar ;). |
||||
89 | $context['page_title'] = $txt['calendar']; |
||||
90 | |||||
91 | // Ensure a default view is defined |
||||
92 | if (empty($options['calendar_default_view'])) |
||||
93 | $options['calendar_default_view'] = 'viewlist'; |
||||
94 | |||||
95 | // What view do we want? |
||||
96 | if (isset($_GET['viewweek'])) |
||||
97 | $context['calendar_view'] = 'viewweek'; |
||||
98 | elseif (isset($_GET['viewmonth'])) |
||||
99 | $context['calendar_view'] = 'viewmonth'; |
||||
100 | elseif (isset($_GET['viewlist'])) |
||||
101 | $context['calendar_view'] = 'viewlist'; |
||||
102 | else |
||||
103 | $context['calendar_view'] = $options['calendar_default_view']; |
||||
104 | |||||
105 | // Don't let search engines index the non-default calendar pages |
||||
106 | if ($context['calendar_view'] !== $options['calendar_default_view']) |
||||
107 | $context['robot_no_index'] = true; |
||||
108 | |||||
109 | // Get the current day of month... |
||||
110 | require_once($sourcedir . '/Subs-Calendar.php'); |
||||
111 | $today = getTodayInfo(); |
||||
112 | |||||
113 | // Need a start date for all views |
||||
114 | if (!empty($_REQUEST['start_date'])) |
||||
115 | { |
||||
116 | $start_parsed = date_parse(str_replace(',', '', convertDateToEnglish($_REQUEST['start_date']))); |
||||
117 | if (empty($start_parsed['error_count']) && empty($start_parsed['warning_count'])) |
||||
118 | { |
||||
119 | $_REQUEST['year'] = $start_parsed['year']; |
||||
120 | $_REQUEST['month'] = $start_parsed['month']; |
||||
121 | $_REQUEST['day'] = $start_parsed['day']; |
||||
122 | } |
||||
123 | } |
||||
124 | $year = !empty($_REQUEST['year']) ? (int) $_REQUEST['year'] : $today['year']; |
||||
125 | $month = !empty($_REQUEST['month']) ? (int) $_REQUEST['month'] : $today['month']; |
||||
126 | $day = !empty($_REQUEST['day']) ? (int) $_REQUEST['day'] : (!empty($_REQUEST['month']) ? 1 : $today['day']); |
||||
127 | |||||
128 | $start_object = checkdate($month, $day, $year) === true ? date_create(implode('-', array($year, $month, $day)) . ' ' . getUserTimezone()) : date_create(implode('-', array($today['year'], $today['month'], $today['day'])) . ' ' . getUserTimezone()); |
||||
129 | |||||
130 | // Need an end date for the list view |
||||
131 | if (!empty($_REQUEST['end_date'])) |
||||
132 | { |
||||
133 | $end_parsed = date_parse(str_replace(',', '', convertDateToEnglish($_REQUEST['end_date']))); |
||||
134 | if (empty($end_parsed['error_count']) && empty($end_parsed['warning_count'])) |
||||
135 | { |
||||
136 | $_REQUEST['end_year'] = $end_parsed['year']; |
||||
137 | $_REQUEST['end_month'] = $end_parsed['month']; |
||||
138 | $_REQUEST['end_day'] = $end_parsed['day']; |
||||
139 | } |
||||
140 | } |
||||
141 | $end_year = !empty($_REQUEST['end_year']) ? (int) $_REQUEST['end_year'] : null; |
||||
142 | $end_month = !empty($_REQUEST['end_month']) ? (int) $_REQUEST['end_month'] : null; |
||||
143 | $end_day = !empty($_REQUEST['end_day']) ? (int) $_REQUEST['end_day'] : null; |
||||
144 | |||||
145 | $end_object = null; |
||||
146 | |||||
147 | if (isset($end_month, $end_day, $end_year) && checkdate($end_month, $end_day, $end_year)) |
||||
148 | { |
||||
149 | $end_object = date_create(implode('-', array($end_year, $end_month, $end_day)) . ' ' . getUserTimezone()); |
||||
150 | } |
||||
151 | |||||
152 | if (empty($end_object) || $start_object >= $end_object) |
||||
153 | { |
||||
154 | $num_days_shown = empty($modSettings['cal_days_for_index']) || $modSettings['cal_days_for_index'] < 1 ? 1 : $modSettings['cal_days_for_index']; |
||||
155 | |||||
156 | $end_object = date_create(date_format($start_object, 'Y-m-d') . ' ' . getUserTimezone()); |
||||
157 | |||||
158 | date_add($end_object, date_interval_create_from_date_string($num_days_shown . ' days')); |
||||
159 | } |
||||
160 | |||||
161 | $curPage = array( |
||||
162 | 'year' => date_format($start_object, 'Y'), |
||||
163 | 'month' => date_format($start_object, 'n'), |
||||
164 | 'day' => date_format($start_object, 'j'), |
||||
165 | 'start_date' => date_format($start_object, 'Y-m-d'), |
||||
166 | 'end_year' => date_format($end_object, 'Y'), |
||||
167 | 'end_month' => date_format($end_object, 'n'), |
||||
168 | 'end_day' => date_format($end_object, 'j'), |
||||
169 | 'end_date' => date_format($end_object, 'Y-m-d'), |
||||
170 | ); |
||||
171 | |||||
172 | // Make sure the year and month are in valid ranges. |
||||
173 | if ($curPage['month'] < 1 || $curPage['month'] > 12) |
||||
174 | fatal_lang_error('invalid_month', false); |
||||
175 | if ($curPage['year'] < $modSettings['cal_minyear'] || $curPage['year'] > $modSettings['cal_maxyear']) |
||||
176 | fatal_lang_error('invalid_year', false); |
||||
177 | // If we have a day clean that too. |
||||
178 | if ($context['calendar_view'] != 'viewmonth') |
||||
179 | { |
||||
180 | $isValid = checkdate($curPage['month'], $curPage['day'], $curPage['year']); |
||||
181 | if (!$isValid) |
||||
182 | fatal_lang_error('invalid_day', false); |
||||
183 | } |
||||
184 | |||||
185 | // Load all the context information needed to show the calendar grid. |
||||
186 | $calendarOptions = array( |
||||
187 | 'start_day' => !empty($options['calendar_start_day']) ? $options['calendar_start_day'] : 0, |
||||
188 | 'show_birthdays' => in_array($modSettings['cal_showbdays'], array(1, 2)), |
||||
189 | 'show_events' => in_array($modSettings['cal_showevents'], array(1, 2)), |
||||
190 | 'show_holidays' => in_array($modSettings['cal_showholidays'], array(1, 2)), |
||||
191 | 'show_week_num' => true, |
||||
192 | 'short_day_titles' => !empty($modSettings['cal_short_days']), |
||||
193 | 'short_month_titles' => !empty($modSettings['cal_short_months']), |
||||
194 | 'show_next_prev' => !empty($modSettings['cal_prev_next_links']), |
||||
195 | 'show_week_links' => isset($modSettings['cal_week_links']) ? $modSettings['cal_week_links'] : 0, |
||||
196 | ); |
||||
197 | |||||
198 | // Load up the main view. |
||||
199 | if ($context['calendar_view'] == 'viewlist') |
||||
200 | $context['calendar_grid_main'] = getCalendarList($curPage['start_date'], $curPage['end_date'], $calendarOptions); |
||||
201 | elseif ($context['calendar_view'] == 'viewweek') |
||||
202 | $context['calendar_grid_main'] = getCalendarWeek($curPage['start_date'], $calendarOptions); |
||||
203 | else |
||||
204 | $context['calendar_grid_main'] = getCalendarGrid($curPage['start_date'], $calendarOptions); |
||||
205 | |||||
206 | // Load up the previous and next months. |
||||
207 | $context['calendar_grid_current'] = getCalendarGrid($curPage['start_date'], $calendarOptions, false, false); |
||||
208 | |||||
209 | // Only show previous month if it isn't pre-January of the min-year |
||||
210 | if ($context['calendar_grid_current']['previous_calendar']['year'] > $modSettings['cal_minyear'] || $curPage['month'] != 1) |
||||
211 | $context['calendar_grid_prev'] = getCalendarGrid($context['calendar_grid_current']['previous_calendar']['start_date'], $calendarOptions, true, false); |
||||
212 | |||||
213 | // Only show next month if it isn't post-December of the max-year |
||||
214 | if ($context['calendar_grid_current']['next_calendar']['year'] < $modSettings['cal_maxyear'] || $curPage['month'] != 12) |
||||
215 | $context['calendar_grid_next'] = getCalendarGrid($context['calendar_grid_current']['next_calendar']['start_date'], $calendarOptions, false, false); |
||||
216 | |||||
217 | // Basic template stuff. |
||||
218 | $context['allow_calendar_event'] = allowedTo('calendar_post'); |
||||
219 | |||||
220 | // If you don't allow events not linked to posts and you're not an admin, we have more work to do... |
||||
221 | if ($context['allow_calendar_event'] && empty($modSettings['cal_allow_unlinked']) && !$user_info['is_admin']) |
||||
222 | { |
||||
223 | $boards_can_post = boardsAllowedTo('post_new'); |
||||
224 | $context['allow_calendar_event'] &= !empty($boards_can_post); |
||||
225 | } |
||||
226 | |||||
227 | $context['can_post'] = $context['allow_calendar_event']; |
||||
228 | $context['current_day'] = $curPage['day']; |
||||
229 | $context['current_month'] = $curPage['month']; |
||||
230 | $context['current_year'] = $curPage['year']; |
||||
231 | $context['show_all_birthdays'] = isset($_GET['showbd']); |
||||
232 | $context['blocks_disabled'] = !empty($modSettings['cal_disable_prev_next']) ? 1 : 0; |
||||
233 | |||||
234 | // Set the page title to mention the month or week, too |
||||
235 | if ($context['calendar_view'] != 'viewlist') |
||||
236 | $context['page_title'] .= ' - ' . ($context['calendar_view'] == 'viewweek' ? $context['calendar_grid_main']['week_title'] : $txt['months_titles'][$context['current_month']] . ' ' . $context['current_year']); |
||||
237 | |||||
238 | // Load up the linktree! |
||||
239 | $context['linktree'][] = array( |
||||
240 | 'url' => $scripturl . '?action=calendar', |
||||
241 | 'name' => $txt['calendar'] |
||||
242 | ); |
||||
243 | // Add the current month to the linktree. |
||||
244 | $context['linktree'][] = array( |
||||
245 | 'url' => $scripturl . '?action=calendar;year=' . $context['current_year'] . ';month=' . $context['current_month'], |
||||
246 | 'name' => $txt['months_titles'][$context['current_month']] . ' ' . $context['current_year'] |
||||
247 | ); |
||||
248 | // If applicable, add the current week to the linktree. |
||||
249 | if ($context['calendar_view'] == 'viewweek') |
||||
250 | $context['linktree'][] = array( |
||||
251 | 'url' => $scripturl . '?action=calendar;viewweek;year=' . $context['current_year'] . ';month=' . $context['current_month'] . ';day=' . $context['current_day'], |
||||
252 | 'name' => $context['calendar_grid_main']['week_title'], |
||||
253 | ); |
||||
254 | |||||
255 | // Build the calendar button array. |
||||
256 | $context['calendar_buttons'] = array(); |
||||
257 | |||||
258 | if ($context['can_post']) |
||||
259 | $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']); |
||||
260 | |||||
261 | // Allow mods to add additional buttons here |
||||
262 | call_integration_hook('integrate_calendar_buttons'); |
||||
263 | } |
||||
264 | |||||
265 | /** |
||||
266 | * This function processes posting/editing/deleting a calendar event. |
||||
267 | * |
||||
268 | * - calls {@link Post.php|Post() Post()} function if event is linked to a post. |
||||
269 | * - calls {@link Subs-Calendar.php|insertEvent() insertEvent()} to insert the event if not linked to post. |
||||
270 | * |
||||
271 | * It requires the calendar_post permission to use. |
||||
272 | * It uses the event_post sub template in the Calendar template. |
||||
273 | * It is accessed with ?action=calendar;sa=post. |
||||
274 | */ |
||||
275 | function CalendarPost() |
||||
276 | { |
||||
277 | global $context, $txt, $user_info, $sourcedir, $scripturl; |
||||
278 | global $modSettings, $topic, $smcFunc; |
||||
279 | |||||
280 | // Well - can they? |
||||
281 | isAllowedTo('calendar_post'); |
||||
282 | |||||
283 | // We need these for all kinds of useful functions. |
||||
284 | require_once($sourcedir . '/Subs-Calendar.php'); |
||||
285 | require_once($sourcedir . '/Subs.php'); |
||||
286 | |||||
287 | // Cast this for safety... |
||||
288 | if (isset($_REQUEST['eventid'])) |
||||
289 | $_REQUEST['eventid'] = (int) $_REQUEST['eventid']; |
||||
290 | |||||
291 | // We want a fairly compact version of the time, but as close as possible to the user's settings. |
||||
292 | $time_string = strtr(get_date_or_time_format('time'), array( |
||||
293 | '%I' => '%l', |
||||
294 | '%H' => '%k', |
||||
295 | '%S' => '', |
||||
296 | '%r' => '%l:%M %p', |
||||
297 | '%R' => '%k:%M', |
||||
298 | '%T' => '%l:%M', |
||||
299 | )); |
||||
300 | |||||
301 | $time_string = preg_replace('~:(?=\s|$|%[pPzZ])~', '', $time_string); |
||||
302 | |||||
303 | // Submitting? |
||||
304 | if (isset($_POST[$context['session_var']], $_REQUEST['eventid'])) |
||||
305 | { |
||||
306 | checkSession(); |
||||
307 | |||||
308 | // Validate the post... |
||||
309 | if (!isset($_POST['link_to_board'])) |
||||
310 | validateEventPost(); |
||||
311 | |||||
312 | // If you're not allowed to edit any events, you have to be the poster. |
||||
313 | if ($_REQUEST['eventid'] > 0 && !allowedTo('calendar_edit_any')) |
||||
314 | isAllowedTo('calendar_edit_' . (!empty($user_info['id']) && getEventPoster($_REQUEST['eventid']) == $user_info['id'] ? 'own' : 'any')); |
||||
315 | |||||
316 | // New - and directing? |
||||
317 | if (isset($_POST['link_to_board']) || empty($modSettings['cal_allow_unlinked'])) |
||||
318 | { |
||||
319 | $_REQUEST['calendar'] = 1; |
||||
320 | require_once($sourcedir . '/Post.php'); |
||||
321 | return Post(); |
||||
322 | } |
||||
323 | // New... |
||||
324 | elseif ($_REQUEST['eventid'] == -1) |
||||
325 | { |
||||
326 | $eventOptions = array( |
||||
327 | 'board' => 0, |
||||
328 | 'topic' => 0, |
||||
329 | 'title' => $smcFunc['substr']($_REQUEST['evtitle'], 0, 100), |
||||
330 | 'location' => $smcFunc['substr']($_REQUEST['event_location'], 0, 255), |
||||
331 | 'member' => $user_info['id'], |
||||
332 | ); |
||||
333 | insertEvent($eventOptions); |
||||
334 | } |
||||
335 | |||||
336 | // Deleting... |
||||
337 | elseif (isset($_REQUEST['deleteevent'])) |
||||
338 | removeEvent($_REQUEST['eventid']); |
||||
339 | |||||
340 | // ... or just update it? |
||||
341 | else |
||||
342 | { |
||||
343 | $eventOptions = array( |
||||
344 | 'title' => $smcFunc['substr']($_REQUEST['evtitle'], 0, 100), |
||||
345 | 'location' => $smcFunc['substr']($_REQUEST['event_location'], 0, 255), |
||||
346 | ); |
||||
347 | modifyEvent($_REQUEST['eventid'], $eventOptions); |
||||
348 | } |
||||
349 | |||||
350 | updateSettings(array( |
||||
351 | 'calendar_updated' => time(), |
||||
352 | )); |
||||
353 | |||||
354 | // No point hanging around here now... |
||||
355 | if (isset($_POST['start_date'])) |
||||
356 | { |
||||
357 | $d = date_parse($_POST['start_date']); |
||||
358 | $year = $d['year']; |
||||
359 | $month = $d['month']; |
||||
360 | $day = $d['day']; |
||||
361 | } |
||||
362 | elseif (isset($_POST['start_datetime'])) |
||||
363 | { |
||||
364 | $d = date_parse($_POST['start_datetime']); |
||||
365 | $year = $d['year']; |
||||
366 | $month = $d['month']; |
||||
367 | $day = $d['day']; |
||||
368 | } |
||||
369 | else |
||||
370 | { |
||||
371 | $today = getdate(); |
||||
372 | $year = isset($_POST['year']) ? $_POST['year'] : $today['year']; |
||||
373 | $month = isset($_POST['month']) ? $_POST['month'] : $today['mon']; |
||||
374 | $day = isset($_POST['day']) ? $_POST['day'] : $today['mday']; |
||||
375 | } |
||||
376 | redirectexit($scripturl . '?action=calendar;month=' . $month . ';year=' . $year . ';day=' . $day); |
||||
377 | } |
||||
378 | |||||
379 | // If we are not enabled... we are not enabled. |
||||
380 | if (empty($modSettings['cal_allow_unlinked']) && empty($_REQUEST['eventid'])) |
||||
381 | { |
||||
382 | $_REQUEST['calendar'] = 1; |
||||
383 | require_once($sourcedir . '/Post.php'); |
||||
384 | return Post(); |
||||
0 ignored issues
–
show
|
|||||
385 | } |
||||
386 | |||||
387 | // New? |
||||
388 | if (!isset($_REQUEST['eventid'])) |
||||
389 | { |
||||
390 | $context['event'] = array( |
||||
391 | 'boards' => array(), |
||||
392 | 'board' => 0, |
||||
393 | 'new' => 1, |
||||
394 | 'eventid' => -1, |
||||
395 | 'title' => '', |
||||
396 | 'location' => '', |
||||
397 | ); |
||||
398 | |||||
399 | $eventDatetimes = getNewEventDatetimes(); |
||||
400 | $context['event'] = array_merge($context['event'], $eventDatetimes); |
||||
401 | |||||
402 | $context['event']['last_day'] = (int) smf_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'])); |
||||
403 | } |
||||
404 | else |
||||
405 | { |
||||
406 | $context['event'] = getEventProperties($_REQUEST['eventid']); |
||||
407 | |||||
408 | if ($context['event'] === false) |
||||
409 | fatal_lang_error('no_access', false); |
||||
410 | |||||
411 | // If it has a board, then they should be editing it within the topic. |
||||
412 | if (!empty($context['event']['topic']['id']) && !empty($context['event']['topic']['first_msg'])) |
||||
413 | { |
||||
414 | // We load the board up, for a check on the board access rights... |
||||
415 | $topic = $context['event']['topic']['id']; |
||||
416 | loadBoard(); |
||||
417 | } |
||||
418 | |||||
419 | // Make sure the user is allowed to edit this event. |
||||
420 | if ($context['event']['member'] != $user_info['id']) |
||||
421 | isAllowedTo('calendar_edit_any'); |
||||
422 | elseif (!allowedTo('calendar_edit_any')) |
||||
423 | isAllowedTo('calendar_edit_own'); |
||||
424 | } |
||||
425 | |||||
426 | // An all day event? Set up some nice defaults in case the user wants to change that |
||||
427 | if ($context['event']['allday'] == true) |
||||
428 | { |
||||
429 | $context['event']['tz'] = getUserTimezone(); |
||||
430 | $context['event']['start_time'] = timeformat(time(), $time_string); |
||||
431 | $context['event']['end_time'] = timeformat(time() + 3600, $time_string); |
||||
432 | } |
||||
433 | // Otherwise, just adjust these to look nice on the input form |
||||
434 | else |
||||
435 | { |
||||
436 | $context['event']['start_time'] = $context['event']['start_time_orig']; |
||||
437 | $context['event']['end_time'] = $context['event']['end_time_orig']; |
||||
438 | } |
||||
439 | |||||
440 | // Need this so the user can select a timezone for the event. |
||||
441 | $context['all_timezones'] = smf_list_timezones($context['event']['start_date']); |
||||
442 | |||||
443 | // If the event's timezone is not in SMF's standard list of time zones, try to fix it. |
||||
444 | if (!isset($context['all_timezones'][$context['event']['tz']])) |
||||
445 | { |
||||
446 | $later = strtotime('@' . $context['event']['start_timestamp'] . ' + 1 year'); |
||||
447 | $tzinfo = timezone_transitions_get(timezone_open($context['event']['tz']), $context['event']['start_timestamp'], $later); |
||||
448 | |||||
449 | $found = false; |
||||
450 | foreach ($context['all_timezones'] as $possible_tzid => $dummy) |
||||
451 | { |
||||
452 | // Ignore the "-----" option |
||||
453 | if (empty($possible_tzid)) |
||||
454 | continue; |
||||
455 | |||||
456 | $possible_tzinfo = timezone_transitions_get(timezone_open($possible_tzid), $context['event']['start_timestamp'], $later); |
||||
457 | |||||
458 | if ($tzinfo === $possible_tzinfo) |
||||
459 | { |
||||
460 | $context['event']['tz'] = $possible_tzid; |
||||
461 | $found = true; |
||||
462 | break; |
||||
463 | } |
||||
464 | } |
||||
465 | |||||
466 | // Hm. That's weird. Well, just prepend it to the list and let the user deal with it. |
||||
467 | if (!$found) |
||||
468 | { |
||||
469 | $d = date_create($context['event']['start_datetime'] . ' ' . $context['event']['tz']); |
||||
470 | $context['all_timezones'] = array($context['event']['tz'] => '[UTC' . date_format($d, 'P') . '] - ' . $context['event']['tz']) + $context['all_timezones']; |
||||
471 | } |
||||
472 | } |
||||
473 | |||||
474 | // Get list of boards that can be posted in. |
||||
475 | $boards = boardsAllowedTo('post_new'); |
||||
476 | if (empty($boards)) |
||||
477 | { |
||||
478 | // You can post new events but can't link them to anything... |
||||
479 | $context['event']['categories'] = array(); |
||||
480 | } |
||||
481 | else |
||||
482 | { |
||||
483 | // Load the list of boards and categories in the context. |
||||
484 | require_once($sourcedir . '/Subs-MessageIndex.php'); |
||||
485 | $boardListOptions = array( |
||||
486 | 'included_boards' => in_array(0, $boards) ? null : $boards, |
||||
487 | 'not_redirection' => true, |
||||
488 | 'use_permissions' => true, |
||||
489 | 'selected_board' => $modSettings['cal_defaultboard'], |
||||
490 | ); |
||||
491 | $context['event']['categories'] = getBoardList($boardListOptions); |
||||
492 | } |
||||
493 | |||||
494 | // Template, sub template, etc. |
||||
495 | loadTemplate('Calendar'); |
||||
496 | $context['sub_template'] = 'event_post'; |
||||
497 | |||||
498 | $context['page_title'] = isset($_REQUEST['eventid']) ? $txt['calendar_edit'] : $txt['calendar_post_event']; |
||||
499 | $context['linktree'][] = array( |
||||
500 | 'name' => $context['page_title'], |
||||
501 | ); |
||||
502 | |||||
503 | loadDatePicker('#event_time_input .date_input'); |
||||
504 | loadTimePicker('#event_time_input .time_input', $time_string); |
||||
505 | loadDatePair('#event_time_input', 'date_input', 'time_input'); |
||||
506 | addInlineJavaScript(' |
||||
507 | $("#allday").click(function(){ |
||||
508 | $("#start_time").attr("disabled", this.checked); |
||||
509 | $("#end_time").attr("disabled", this.checked); |
||||
510 | $("#tz").attr("disabled", this.checked); |
||||
511 | });', true); |
||||
512 | } |
||||
513 | |||||
514 | /** |
||||
515 | * This function offers up a download of an event in iCal 2.0 format. |
||||
516 | * |
||||
517 | * Follows the conventions in {@link https://tools.ietf.org/html/rfc5546 RFC5546} |
||||
518 | * Sets events as all day events since we don't have hourly events |
||||
519 | * Will honor and set multi day events |
||||
520 | * Sets a sequence number if the event has been modified |
||||
521 | * |
||||
522 | * @todo .... allow for week or month export files as well? |
||||
523 | */ |
||||
524 | function iCalDownload() |
||||
525 | { |
||||
526 | global $smcFunc, $sourcedir, $modSettings, $webmaster_email, $mbname; |
||||
527 | |||||
528 | // You can't export if the calendar export feature is off. |
||||
529 | if (empty($modSettings['cal_export'])) |
||||
530 | fatal_lang_error('calendar_export_off', false); |
||||
531 | |||||
532 | // Goes without saying that this is required. |
||||
533 | if (!isset($_REQUEST['eventid'])) |
||||
534 | fatal_lang_error('no_access', false); |
||||
535 | |||||
536 | // This is kinda wanted. |
||||
537 | require_once($sourcedir . '/Subs-Calendar.php'); |
||||
538 | |||||
539 | // Load up the event in question and check it exists. |
||||
540 | $event = getEventProperties($_REQUEST['eventid']); |
||||
541 | |||||
542 | if ($event === false) |
||||
0 ignored issues
–
show
|
|||||
543 | fatal_lang_error('no_access', false); |
||||
544 | |||||
545 | // Check the title isn't too long - iCal requires some formatting if so. |
||||
546 | $title = str_split($event['title'], 30); |
||||
547 | foreach ($title as $id => $line) |
||||
548 | { |
||||
549 | if ($id != 0) |
||||
550 | $title[$id] = ' ' . $title[$id]; |
||||
551 | $title[$id] .= "\n"; |
||||
552 | } |
||||
553 | |||||
554 | // Format the dates. |
||||
555 | $datestamp = date('Ymd\THis\Z', time()); |
||||
556 | $start_date = date_create($event['start_date'] . (isset($event['start_time']) ? ' ' . $event['start_time'] : '') . (isset($event['tz']) ? ' ' . $event['tz'] : '')); |
||||
557 | $end_date = date_create($event['end_date'] . (isset($event['end_time']) ? ' ' . $event['end_time'] : '') . (isset($event['tz']) ? ' ' . $event['tz'] : '')); |
||||
558 | |||||
559 | if (!empty($event['start_time'])) |
||||
560 | { |
||||
561 | $datestart = date_format($start_date, 'Ymd\THis'); |
||||
562 | $dateend = date_format($end_date, 'Ymd\THis'); |
||||
563 | } |
||||
564 | else |
||||
565 | { |
||||
566 | $datestart = date_format($start_date, 'Ymd'); |
||||
567 | |||||
568 | date_add($end_date, date_interval_create_from_date_string('1 day')); |
||||
569 | $dateend = date_format($end_date, 'Ymd'); |
||||
570 | } |
||||
571 | |||||
572 | // This is what we will be sending later |
||||
573 | $filecontents = ''; |
||||
574 | $filecontents .= 'BEGIN:VCALENDAR' . "\n"; |
||||
575 | $filecontents .= 'METHOD:PUBLISH' . "\n"; |
||||
576 | $filecontents .= 'PRODID:-//SimpleMachines//' . SMF_FULL_VERSION . '//EN' . "\n"; |
||||
577 | $filecontents .= 'VERSION:2.0' . "\n"; |
||||
578 | $filecontents .= 'BEGIN:VEVENT' . "\n"; |
||||
579 | // @TODO - Should be the members email who created the event rather than $webmaster_email. |
||||
580 | $filecontents .= 'ORGANIZER;CN="' . $event['realname'] . '":MAILTO:' . $webmaster_email . "\n"; |
||||
581 | $filecontents .= 'DTSTAMP:' . $datestamp . "\n"; |
||||
582 | $filecontents .= 'DTSTART' . (!empty($event['start_time']) ? ';TZID=' . $event['tz'] : ';VALUE=DATE') . ':' . $datestart . "\n"; |
||||
583 | |||||
584 | // event has a duration |
||||
585 | if ($event['start_iso_gmdate'] != $event['end_iso_gmdate']) |
||||
586 | $filecontents .= 'DTEND' . (!empty($event['end_time']) ? ';TZID=' . $event['tz'] : ';VALUE=DATE') . ':' . $dateend . "\n"; |
||||
587 | |||||
588 | // event has changed? advance the sequence for this UID |
||||
589 | if ($event['sequence'] > 0) |
||||
590 | $filecontents .= 'SEQUENCE:' . $event['sequence'] . "\n"; |
||||
591 | |||||
592 | if (!empty($event['location'])) |
||||
593 | $filecontents .= 'LOCATION:' . str_replace(',', '\,', $event['location']) . "\n"; |
||||
594 | |||||
595 | $filecontents .= 'SUMMARY:' . implode('', $title); |
||||
0 ignored issues
–
show
It seems like
$title can also be of type true ; however, parameter $pieces of implode() does only seem to accept array , maybe add an additional type check?
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
Loading history...
|
|||||
596 | $filecontents .= 'UID:' . $event['eventid'] . '@' . str_replace(' ', '-', $mbname) . "\n"; |
||||
597 | $filecontents .= 'END:VEVENT' . "\n"; |
||||
598 | $filecontents .= 'END:VCALENDAR'; |
||||
599 | |||||
600 | // Send some standard headers. |
||||
601 | ob_end_clean(); |
||||
602 | if (!empty($modSettings['enableCompressedOutput'])) |
||||
603 | @ob_start('ob_gzhandler'); |
||||
604 | else |
||||
605 | ob_start(); |
||||
606 | |||||
607 | // Send the file headers |
||||
608 | header('pragma: '); |
||||
609 | header('cache-control: no-cache'); |
||||
610 | if (!isBrowser('gecko')) |
||||
611 | header('content-transfer-encoding: binary'); |
||||
612 | header('expires: ' . gmdate('D, d M Y H:i:s', time() + 525600 * 60) . ' GMT'); |
||||
613 | header('last-modified: ' . gmdate('D, d M Y H:i:s', time()) . 'GMT'); |
||||
614 | header('accept-ranges: bytes'); |
||||
615 | header('connection: close'); |
||||
616 | header('content-disposition: attachment; filename="' . $event['title'] . '.ics"'); |
||||
617 | if (empty($modSettings['enableCompressedOutput'])) |
||||
618 | header('content-length: ' . $smcFunc['strlen']($filecontents)); |
||||
619 | |||||
620 | // This is a calendar item! |
||||
621 | header('content-type: text/calendar'); |
||||
622 | |||||
623 | // Chuck out the card. |
||||
624 | echo $filecontents; |
||||
625 | |||||
626 | // Off we pop - lovely! |
||||
627 | obExit(false); |
||||
628 | } |
||||
629 | |||||
630 | /** |
||||
631 | * Nothing to see here. Move along. |
||||
632 | */ |
||||
633 | function clock() |
||||
634 | { |
||||
635 | global $smcFunc, $settings, $context, $scripturl; |
||||
636 | |||||
637 | $context['onimg'] = $settings['images_url'] . '/bbc/bbc_hoverbg.png'; |
||||
638 | $context['offimg'] = $settings['images_url'] . '/bbc/bbc_bg.png'; |
||||
639 | |||||
640 | $context['page_title'] = 'Anyone know what time it is?'; |
||||
641 | $context['linktree'][] = array( |
||||
642 | 'url' => $scripturl . '?action=clock', |
||||
643 | 'name' => 'Clock', |
||||
644 | ); |
||||
645 | $context['robot_no_index'] = true; |
||||
646 | |||||
647 | $omfg = isset($_REQUEST['omfg']); |
||||
648 | $bcd = !isset($_REQUEST['rb']) && !isset($_REQUEST['omfg']) && !isset($_REQUEST['time']); |
||||
649 | |||||
650 | loadTemplate('Calendar'); |
||||
651 | |||||
652 | if ($bcd) |
||||
653 | { |
||||
654 | $context['sub_template'] = 'bcd'; |
||||
655 | $context['linktree'][] = array('url' => $scripturl . '?action=clock;bcd', 'name' => 'BCD'); |
||||
656 | $context['clockicons'] = $smcFunc['json_decode'](base64_decode('eyJoMSI6WzIsMV0sImgyIjpbOCw0LDIsMV0sIm0xIjpbNCwyLDFdLCJtMiI6WzgsNCwyLDFdLCJzMSI6WzQsMiwxXSwiczIiOls4LDQsMiwxXX0='), true); |
||||
657 | } |
||||
658 | elseif (!$omfg && !isset($_REQUEST['time'])) |
||||
659 | { |
||||
660 | $context['sub_template'] = 'hms'; |
||||
661 | $context['linktree'][] = array('url' => $scripturl . '?action=clock', 'name' => 'Binary'); |
||||
662 | $context['clockicons'] = $smcFunc['json_decode'](base64_decode('eyJoIjpbMTYsOCw0LDIsMV0sIm0iOlszMiwxNiw4LDQsMiwxXSwicyI6WzMyLDE2LDgsNCwyLDFdfQ'), true); |
||||
663 | } |
||||
664 | elseif ($omfg) |
||||
665 | { |
||||
666 | $context['sub_template'] = 'omfg'; |
||||
667 | $context['linktree'][] = array('url' => $scripturl . '?action=clock;omfg', 'name' => 'OMFG'); |
||||
668 | $context['clockicons'] = $smcFunc['json_decode'](base64_decode('eyJ5ZWFyIjpbNjQsMzIsMTYsOCw0LDIsMV0sIm1vbnRoIjpbOCw0LDIsMV0sImRheSI6WzE2LDgsNCwyLDFdLCJob3VyIjpbMTYsOCw0LDIsMV0sIm1pbiI6WzMyLDE2LDgsNCwyLDFdLCJzZWMiOlszMiwxNiw4LDQsMiwxXX0='), true); |
||||
669 | } |
||||
670 | elseif (isset($_REQUEST['time'])) |
||||
671 | { |
||||
672 | $context['sub_template'] = 'thetime'; |
||||
673 | $time = getdate($_REQUEST['time'] == 'now' ? time() : (int) $_REQUEST['time']); |
||||
674 | $context['linktree'][] = array('url' => $scripturl . '?action=clock;time=' . $_REQUEST['time'], 'name' => 'Requested Time'); |
||||
675 | $context['clockicons'] = array( |
||||
676 | 'year' => array( |
||||
677 | 64 => false, |
||||
678 | 32 => false, |
||||
679 | 16 => false, |
||||
680 | 8 => false, |
||||
681 | 4 => false, |
||||
682 | 2 => false, |
||||
683 | 1 => false |
||||
684 | ), |
||||
685 | 'month' => array( |
||||
686 | 8 => false, |
||||
687 | 4 => false, |
||||
688 | 2 => false, |
||||
689 | 1 => false |
||||
690 | ), |
||||
691 | 'day' => array( |
||||
692 | 16 => false, |
||||
693 | 4 => false, |
||||
694 | 8 => false, |
||||
695 | 2 => false, |
||||
696 | 1 => false |
||||
697 | ), |
||||
698 | 'hour' => array( |
||||
699 | 32 => false, |
||||
700 | 16 => false, |
||||
701 | 8 => false, |
||||
702 | 4 => false, |
||||
703 | 2 => false, |
||||
704 | 1 => false |
||||
705 | ), |
||||
706 | 'min' => array( |
||||
707 | 32 => false, |
||||
708 | 16 => false, |
||||
709 | 8 => false, |
||||
710 | 4 => false, |
||||
711 | 2 => false, |
||||
712 | 1 => false |
||||
713 | ), |
||||
714 | 'sec' => array( |
||||
715 | 32 => false, |
||||
716 | 16 => false, |
||||
717 | 8 => false, |
||||
718 | 4 => false, |
||||
719 | 2 => false, |
||||
720 | 1 => false |
||||
721 | ), |
||||
722 | ); |
||||
723 | |||||
724 | foreach ($context['clockicons'] as $t => $vs) |
||||
725 | foreach ($vs as $v => $dumb) |
||||
726 | { |
||||
727 | if ($$t >= $v) |
||||
728 | { |
||||
729 | $$t -= $v; |
||||
730 | $context['clockicons'][$t][$v] = true; |
||||
731 | } |
||||
732 | } |
||||
733 | } |
||||
734 | } |
||||
735 | |||||
736 | ?> |
This check looks for function or method calls that always return null and whose return value is used.
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.