albertlast /
SMF2.1
These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more
| 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); |
||
| 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); |
||
| 117 | View Code Duplication | if ($curPage['year'] < $modSettings['cal_minyear'] || $curPage['year'] > $modSettings['cal_maxyear']) |
|
| 118 | fatal_lang_error('invalid_year', false); |
||
| 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); |
||
| 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) |
|
| 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) |
|
| 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']) |
|
| 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, $settings; |
||
| 224 | |||
| 225 | // Well - can they? |
||
| 226 | isAllowedTo('calendar_post'); |
||
| 227 | |||
| 228 | // We need these for all kinds of useful functions. |
||
| 229 | require_once($sourcedir . '/Subs-Calendar.php'); |
||
| 230 | require_once($sourcedir . '/Subs.php'); |
||
| 231 | |||
| 232 | // Cast this for safety... |
||
| 233 | if (isset($_REQUEST['eventid'])) |
||
| 234 | $_REQUEST['eventid'] = (int) $_REQUEST['eventid']; |
||
| 235 | |||
| 236 | // We want a fairly compact version of the time, but as close as possible to the user's settings. |
||
| 237 | View Code Duplication | if (preg_match('~%[HkIlMpPrRSTX](?:[^%]*%[HkIlMpPrRSTX])*~', $user_info['time_format'], $matches) == 0 || empty($matches[0])) |
|
|
0 ignored issues
–
show
|
|||
| 238 | $time_string = '%k:%M'; |
||
| 239 | else |
||
| 240 | $time_string = str_replace(array('%I', '%H', '%S', '%r', '%R', '%T'), array('%l', '%k', '', '%l:%M %p', '%k:%M', '%l:%M'), $matches[0]); |
||
| 241 | |||
| 242 | $js_time_string = str_replace( |
||
| 243 | array('%H', '%k', '%I', '%l', '%M', '%p', '%P', '%r', '%R', '%S', '%T', '%X'), |
||
| 244 | array('H', 'G', 'h', 'g', 'i', 'A', 'a', 'h:i:s A', 'H:i', 's', 'H:i:s', 'H:i:s'), |
||
| 245 | $time_string |
||
| 246 | ); |
||
| 247 | |||
| 248 | // Submitting? |
||
| 249 | if (isset($_POST[$context['session_var']], $_REQUEST['eventid'])) |
||
| 250 | { |
||
| 251 | checkSession(); |
||
| 252 | |||
| 253 | // Validate the post... |
||
| 254 | if (!isset($_POST['link_to_board'])) |
||
| 255 | validateEventPost(); |
||
| 256 | |||
| 257 | // If you're not allowed to edit any events, you have to be the poster. |
||
| 258 | if ($_REQUEST['eventid'] > 0 && !allowedTo('calendar_edit_any')) |
||
| 259 | isAllowedTo('calendar_edit_' . (!empty($user_info['id']) && getEventPoster($_REQUEST['eventid']) == $user_info['id'] ? 'own' : 'any')); |
||
| 260 | |||
| 261 | // New - and directing? |
||
| 262 | if (isset($_POST['link_to_board']) || empty($modSettings['cal_allow_unlinked'])) |
||
| 263 | { |
||
| 264 | $_REQUEST['calendar'] = 1; |
||
| 265 | require_once($sourcedir . '/Post.php'); |
||
| 266 | return Post(); |
||
| 267 | } |
||
| 268 | // New... |
||
| 269 | elseif ($_REQUEST['eventid'] == -1) |
||
| 270 | { |
||
| 271 | $eventOptions = array( |
||
| 272 | 'board' => 0, |
||
| 273 | 'topic' => 0, |
||
| 274 | 'title' => $smcFunc['substr']($_REQUEST['evtitle'], 0, 100), |
||
| 275 | 'location' => $smcFunc['substr']($_REQUEST['event_location'], 0, 255), |
||
| 276 | 'member' => $user_info['id'], |
||
| 277 | ); |
||
| 278 | insertEvent($eventOptions); |
||
| 279 | } |
||
| 280 | |||
| 281 | // Deleting... |
||
| 282 | elseif (isset($_REQUEST['deleteevent'])) |
||
| 283 | removeEvent($_REQUEST['eventid']); |
||
| 284 | |||
| 285 | // ... or just update it? |
||
| 286 | else |
||
| 287 | { |
||
| 288 | $eventOptions = array( |
||
| 289 | 'title' => $smcFunc['substr']($_REQUEST['evtitle'], 0, 100), |
||
| 290 | 'location' => $smcFunc['substr']($_REQUEST['event_location'], 0, 255), |
||
| 291 | ); |
||
| 292 | modifyEvent($_REQUEST['eventid'], $eventOptions); |
||
| 293 | } |
||
| 294 | |||
| 295 | updateSettings(array( |
||
| 296 | 'calendar_updated' => time(), |
||
| 297 | )); |
||
| 298 | |||
| 299 | // No point hanging around here now... |
||
| 300 | if (isset($_POST['start_date'])) |
||
| 301 | { |
||
| 302 | $d = date_parse($_POST['start_date']); |
||
| 303 | $year = $d['year']; |
||
| 304 | $month = $d['month']; |
||
| 305 | } |
||
| 306 | elseif (isset($_POST['start_datetime'])) |
||
| 307 | { |
||
| 308 | $d = date_parse($_POST['start_datetime']); |
||
| 309 | $year = $d['year']; |
||
| 310 | $month = $d['month']; |
||
| 311 | } |
||
| 312 | else |
||
| 313 | { |
||
| 314 | $today = getdate(); |
||
| 315 | $year = isset($_POST['year']) ? $_POST['year'] : $today['year']; |
||
| 316 | $month = isset($_POST['month']) ? $_POST['month'] : $today['mon']; |
||
| 317 | } |
||
| 318 | redirectexit($scripturl . '?action=calendar;month=' . $month . ';year=' . $year); |
||
| 319 | } |
||
| 320 | |||
| 321 | // If we are not enabled... we are not enabled. |
||
| 322 | if (empty($modSettings['cal_allow_unlinked']) && empty($_REQUEST['eventid'])) |
||
| 323 | { |
||
| 324 | $_REQUEST['calendar'] = 1; |
||
| 325 | require_once($sourcedir . '/Post.php'); |
||
| 326 | return Post(); |
||
| 327 | } |
||
| 328 | |||
| 329 | // New? |
||
| 330 | if (!isset($_REQUEST['eventid'])) |
||
| 331 | { |
||
| 332 | $context['event'] = array( |
||
| 333 | 'boards' => array(), |
||
| 334 | 'board' => 0, |
||
| 335 | 'new' => 1, |
||
| 336 | 'eventid' => -1, |
||
| 337 | 'title' => '', |
||
| 338 | 'location' => '', |
||
| 339 | ); |
||
| 340 | |||
| 341 | $eventDatetimes = getNewEventDatetimes(); |
||
| 342 | $context['event'] = array_merge($context['event'], $eventDatetimes); |
||
| 343 | |||
| 344 | $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'])); |
||
| 345 | } |
||
| 346 | else |
||
| 347 | { |
||
| 348 | $context['event'] = getEventProperties($_REQUEST['eventid']); |
||
| 349 | |||
| 350 | if ($context['event'] === false) |
||
| 351 | fatal_lang_error('no_access', false); |
||
|
0 ignored issues
–
show
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...
|
|||
| 352 | |||
| 353 | // If it has a board, then they should be editing it within the topic. |
||
| 354 | if (!empty($context['event']['topic']['id']) && !empty($context['event']['topic']['first_msg'])) |
||
| 355 | { |
||
| 356 | // We load the board up, for a check on the board access rights... |
||
| 357 | $topic = $context['event']['topic']['id']; |
||
| 358 | loadBoard(); |
||
| 359 | } |
||
| 360 | |||
| 361 | // Make sure the user is allowed to edit this event. |
||
| 362 | if ($context['event']['member'] != $user_info['id']) |
||
| 363 | isAllowedTo('calendar_edit_any'); |
||
| 364 | elseif (!allowedTo('calendar_edit_any')) |
||
| 365 | isAllowedTo('calendar_edit_own'); |
||
| 366 | } |
||
| 367 | |||
| 368 | // An all day event? Set up some nice defaults in case the user wants to change that |
||
| 369 | View Code Duplication | if ($context['event']['allday'] == true) |
|
|
0 ignored issues
–
show
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...
|
|||
| 370 | { |
||
| 371 | $context['event']['tz'] = getUserTimezone(); |
||
| 372 | $context['event']['start_time'] = timeformat(time(), $time_string); |
||
|
0 ignored issues
–
show
$time_string is of type string, but the function expects a boolean.
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...
|
|||
| 373 | $context['event']['end_time'] = timeformat(time() + 3600, $time_string); |
||
|
0 ignored issues
–
show
$time_string is of type string, but the function expects a boolean.
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...
|
|||
| 374 | } |
||
| 375 | // Otherwise, just adjust these to look nice on the input form |
||
| 376 | else |
||
| 377 | { |
||
| 378 | $context['event']['start_time'] = timeformat(strtotime($context['event']['start_iso_gmdate']), $time_string); |
||
|
0 ignored issues
–
show
$time_string is of type string, but the function expects a boolean.
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...
|
|||
| 379 | $context['event']['end_time'] = timeformat(strtotime($context['event']['end_iso_gmdate']), $time_string); |
||
|
0 ignored issues
–
show
$time_string is of type string, but the function expects a boolean.
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...
|
|||
| 380 | } |
||
| 381 | |||
| 382 | // Need this so the user can select a timezone for the event. |
||
| 383 | $context['all_timezones'] = smf_list_timezones($context['event']['start_date']); |
||
| 384 | unset($context['all_timezones']['']); |
||
| 385 | |||
| 386 | // If the event's timezone is not in SMF's standard list of time zones, prepend it to the list |
||
| 387 | View Code Duplication | if (!in_array($context['event']['tz'], array_keys($context['all_timezones']))) |
|
|
0 ignored issues
–
show
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...
|
|||
| 388 | { |
||
| 389 | $d = date_create($context['event']['tz']); |
||
| 390 | $context['all_timezones'] = array($context['event']['tz'] => date_format($d, 'T') . ' - ' . $context['event']['tz'] . ' [UTC' . date_format($d, 'P') . ']') + $context['all_timezones']; |
||
| 391 | } |
||
| 392 | |||
| 393 | // Get list of boards that can be posted in. |
||
| 394 | $boards = boardsAllowedTo('post_new'); |
||
| 395 | if (empty($boards)) |
||
| 396 | { |
||
| 397 | // You can post new events but can't link them to anything... |
||
| 398 | $context['event']['categories'] = array(); |
||
| 399 | } |
||
| 400 | else |
||
| 401 | { |
||
| 402 | // Load the list of boards and categories in the context. |
||
| 403 | require_once($sourcedir . '/Subs-MessageIndex.php'); |
||
| 404 | $boardListOptions = array( |
||
| 405 | 'included_boards' => in_array(0, $boards) ? null : $boards, |
||
| 406 | 'not_redirection' => true, |
||
| 407 | 'use_permissions' => true, |
||
| 408 | 'selected_board' => $modSettings['cal_defaultboard'], |
||
| 409 | ); |
||
| 410 | $context['event']['categories'] = getBoardList($boardListOptions); |
||
| 411 | } |
||
| 412 | |||
| 413 | // Template, sub template, etc. |
||
| 414 | loadTemplate('Calendar'); |
||
| 415 | $context['sub_template'] = 'event_post'; |
||
| 416 | |||
| 417 | $context['page_title'] = isset($_REQUEST['eventid']) ? $txt['calendar_edit'] : $txt['calendar_post_event']; |
||
| 418 | $context['linktree'][] = array( |
||
| 419 | 'name' => $context['page_title'], |
||
| 420 | ); |
||
| 421 | |||
| 422 | loadCSSFile('jquery-ui.datepicker.css', array('defer' => false), 'smf_datepicker'); |
||
| 423 | loadCSSFile('jquery.timepicker.css', array('defer' => false), 'smf_timepicker'); |
||
| 424 | loadJavaScriptFile('jquery-ui.datepicker.min.js', array('defer' => true), 'smf_datepicker'); |
||
| 425 | loadJavaScriptFile('jquery.timepicker.min.js', array('defer' => true), 'smf_timepicker'); |
||
| 426 | loadJavaScriptFile('datepair.min.js', array('defer' => true), 'smf_datepair'); |
||
| 427 | addInlineJavaScript(' |
||
| 428 | $("#allday").click(function(){ |
||
| 429 | $("#start_time").attr("disabled", this.checked); |
||
| 430 | $("#end_time").attr("disabled", this.checked); |
||
| 431 | $("#tz").attr("disabled", this.checked); |
||
| 432 | }); |
||
| 433 | $("#event_time_input .date_input").datepicker({ |
||
| 434 | dateFormat: "yy-mm-dd", |
||
| 435 | autoSize: true, |
||
| 436 | isRTL: ' . ($context['right_to_left'] ? 'true' : 'false') . ', |
||
| 437 | constrainInput: true, |
||
| 438 | showAnim: "", |
||
| 439 | showButtonPanel: false, |
||
| 440 | minDate: "' . $modSettings['cal_minyear'] . '-01-01", |
||
| 441 | maxDate: "' . $modSettings['cal_maxyear'] . '-12-31", |
||
| 442 | yearRange: "' . $modSettings['cal_minyear'] . ':' . $modSettings['cal_maxyear'] . '", |
||
| 443 | hideIfNoPrevNext: true, |
||
| 444 | monthNames: ["' . implode('", "', $txt['months_titles']) . '"], |
||
| 445 | monthNamesShort: ["' . implode('", "', $txt['months_short']) . '"], |
||
| 446 | dayNames: ["' . implode('", "', $txt['days']) . '"], |
||
| 447 | dayNamesShort: ["' . implode('", "', $txt['days_short']) . '"], |
||
| 448 | dayNamesMin: ["' . implode('", "', $txt['days_short']) . '"], |
||
| 449 | prevText: "' . $txt['prev_month'] . '", |
||
| 450 | nextText: "' . $txt['next_month'] . '", |
||
| 451 | }); |
||
| 452 | $(".time_input").timepicker({ |
||
| 453 | timeFormat: "' . $js_time_string . '", |
||
| 454 | showDuration: true, |
||
| 455 | maxTime: "23:59:59", |
||
| 456 | }); |
||
| 457 | var date_entry = document.getElementById("event_time_input"); |
||
| 458 | var date_entry_pair = new Datepair(date_entry, { |
||
| 459 | timeClass: "time_input", |
||
| 460 | dateClass: "date_input", |
||
| 461 | parseDate: function (el) { |
||
| 462 | var utc = new Date($(el).datepicker("getDate")); |
||
| 463 | return utc && new Date(utc.getTime() + (utc.getTimezoneOffset() * 60000)); |
||
| 464 | }, |
||
| 465 | updateDate: function (el, v) { |
||
| 466 | $(el).datepicker("setDate", new Date(v.getTime() - (v.getTimezoneOffset() * 60000))); |
||
| 467 | } |
||
| 468 | }); |
||
| 469 | ', true); |
||
| 470 | } |
||
| 471 | |||
| 472 | /** |
||
| 473 | * This function offers up a download of an event in iCal 2.0 format. |
||
| 474 | * |
||
| 475 | * Follows the conventions in {@link http://tools.ietf.org/html/rfc5546 RFC5546} |
||
| 476 | * Sets events as all day events since we don't have hourly events |
||
| 477 | * Will honor and set multi day events |
||
| 478 | * Sets a sequence number if the event has been modified |
||
| 479 | * |
||
| 480 | * @todo .... allow for week or month export files as well? |
||
| 481 | */ |
||
| 482 | function iCalDownload() |
||
| 483 | { |
||
| 484 | global $smcFunc, $sourcedir, $forum_version, $modSettings, $webmaster_email, $mbname; |
||
| 485 | |||
| 486 | // You can't export if the calendar export feature is off. |
||
| 487 | if (empty($modSettings['cal_export'])) |
||
| 488 | fatal_lang_error('calendar_export_off', false); |
||
| 489 | |||
| 490 | // Goes without saying that this is required. |
||
| 491 | if (!isset($_REQUEST['eventid'])) |
||
| 492 | fatal_lang_error('no_access', false); |
||
|
0 ignored issues
–
show
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...
|
|||
| 493 | |||
| 494 | // This is kinda wanted. |
||
| 495 | require_once($sourcedir . '/Subs-Calendar.php'); |
||
| 496 | |||
| 497 | // Load up the event in question and check it exists. |
||
| 498 | $event = getEventProperties($_REQUEST['eventid']); |
||
| 499 | |||
| 500 | if ($event === false) |
||
| 501 | fatal_lang_error('no_access', false); |
||
|
0 ignored issues
–
show
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...
|
|||
| 502 | |||
| 503 | // Check the title isn't too long - iCal requires some formatting if so. |
||
| 504 | $title = str_split($event['title'], 30); |
||
| 505 | foreach ($title as $id => $line) |
||
| 506 | { |
||
| 507 | if ($id != 0) |
||
| 508 | $title[$id] = ' ' . $title[$id]; |
||
| 509 | $title[$id] .= "\n"; |
||
| 510 | } |
||
| 511 | |||
| 512 | // Format the dates. |
||
| 513 | $datestamp = date('Ymd\THis\Z', time()); |
||
| 514 | $start_date = date_create($event['start_date'] . (isset($event['start_time']) ? ' ' . $event['start_time'] : '') . (isset($event['tz']) ? ' ' . $event['tz'] : '')); |
||
| 515 | $end_date = date_create($event['end_date'] . (isset($event['end_time']) ? ' ' . $event['end_time'] : '') . (isset($event['tz']) ? ' ' . $event['tz'] : '')); |
||
| 516 | |||
| 517 | if (!empty($event['start_time'])) |
||
| 518 | { |
||
| 519 | $datestart = date_format($start_date, 'Ymd\THis'); |
||
| 520 | $dateend = date_format($end_date, 'Ymd\THis'); |
||
| 521 | } |
||
| 522 | else |
||
| 523 | { |
||
| 524 | $datestart = date_format($start_date, 'Ymd'); |
||
| 525 | |||
| 526 | date_add($end_date, date_interval_create_from_date_string('1 day')); |
||
| 527 | $dateend = date_format($end_date, 'Ymd'); |
||
| 528 | } |
||
| 529 | |||
| 530 | // This is what we will be sending later |
||
| 531 | $filecontents = ''; |
||
| 532 | $filecontents .= 'BEGIN:VCALENDAR' . "\n"; |
||
| 533 | $filecontents .= 'METHOD:PUBLISH' . "\n"; |
||
| 534 | $filecontents .= 'PRODID:-//SimpleMachines//SMF ' . (empty($forum_version) ? 2.1 : strtr($forum_version, array('SMF ' => ''))) . '//EN' . "\n"; |
||
| 535 | $filecontents .= 'VERSION:2.0' . "\n"; |
||
| 536 | $filecontents .= 'BEGIN:VEVENT' . "\n"; |
||
| 537 | // @TODO - Should be the members email who created the event rather than $webmaster_email. |
||
| 538 | $filecontents .= 'ORGANIZER;CN="' . $event['realname'] . '":MAILTO:' . $webmaster_email . "\n"; |
||
| 539 | $filecontents .= 'DTSTAMP:' . $datestamp . "\n"; |
||
| 540 | $filecontents .= 'DTSTART' . (!empty($event['start_time']) ? ';TZID=' . $event['tz'] : ';VALUE=DATE') . ':' . $datestart . "\n"; |
||
| 541 | |||
| 542 | // event has a duration |
||
| 543 | if ($event['start_iso_gmdate'] != $event['end_iso_gmdate']) |
||
| 544 | $filecontents .= 'DTEND' . (!empty($event['end_time']) ? ';TZID=' . $event['tz'] : ';VALUE=DATE') . ':' . $dateend . "\n"; |
||
| 545 | |||
| 546 | // event has changed? advance the sequence for this UID |
||
| 547 | if ($event['sequence'] > 0) |
||
| 548 | $filecontents .= 'SEQUENCE:' . $event['sequence'] . "\n"; |
||
| 549 | |||
| 550 | if (!empty($event['location'])) |
||
| 551 | $filecontents .= 'LOCATION:' . str_replace(',', '\,', $event['location']) . "\n"; |
||
| 552 | |||
| 553 | $filecontents .= 'SUMMARY:' . implode('', $title); |
||
| 554 | $filecontents .= 'UID:' . $event['eventid'] . '@' . str_replace(' ', '-', $mbname) . "\n"; |
||
| 555 | $filecontents .= 'END:VEVENT' . "\n"; |
||
| 556 | $filecontents .= 'END:VCALENDAR'; |
||
| 557 | |||
| 558 | // Send some standard headers. |
||
| 559 | ob_end_clean(); |
||
| 560 | if (!empty($modSettings['enableCompressedOutput'])) |
||
| 561 | @ob_start('ob_gzhandler'); |
||
| 562 | else |
||
| 563 | ob_start(); |
||
| 564 | |||
| 565 | // Send the file headers |
||
| 566 | header('Pragma: '); |
||
| 567 | header('Cache-Control: no-cache'); |
||
| 568 | if (!isBrowser('gecko')) |
||
| 569 | header('Content-Transfer-Encoding: binary'); |
||
| 570 | header('Expires: ' . gmdate('D, d M Y H:i:s', time() + 525600 * 60) . ' GMT'); |
||
| 571 | header('Last-Modified: ' . gmdate('D, d M Y H:i:s', time()) . 'GMT'); |
||
| 572 | header('Accept-Ranges: bytes'); |
||
| 573 | header('Connection: close'); |
||
| 574 | header('Content-Disposition: attachment; filename="' . $event['title'] . '.ics"'); |
||
| 575 | if (empty($modSettings['enableCompressedOutput'])) |
||
| 576 | header('Content-Length: ' . $smcFunc['strlen']($filecontents)); |
||
| 577 | |||
| 578 | // This is a calendar item! |
||
| 579 | header('Content-Type: text/calendar'); |
||
| 580 | |||
| 581 | // Chuck out the card. |
||
| 582 | echo $filecontents; |
||
| 583 | |||
| 584 | // Off we pop - lovely! |
||
| 585 | obExit(false); |
||
| 586 | } |
||
| 587 | |||
| 588 | /** |
||
| 589 | * Nothing to see here. Move along. |
||
| 590 | */ |
||
| 591 | function clock() |
||
| 592 | { |
||
| 593 | global $settings, $context, $scripturl; |
||
| 594 | |||
| 595 | $context['onimg'] = $settings['images_url'] . '/bbc/bbc_bg.png'; |
||
| 596 | $context['offimg'] = $settings['images_url'] . '/bbc/bbc_hoverbg.png'; |
||
| 597 | |||
| 598 | $context['page_title'] = 'Anyone know what time it is?'; |
||
| 599 | $context['linktree'][] = array( |
||
| 600 | 'url' => $scripturl . '?action=clock', |
||
| 601 | 'name' => 'Clock', |
||
| 602 | ); |
||
| 603 | $context['robot_no_index'] = true; |
||
| 604 | |||
| 605 | $omfg = isset($_REQUEST['omfg']); |
||
| 606 | $bcd = !isset($_REQUEST['rb']) && !isset($_REQUEST['omfg']) && !isset($_REQUEST['time']); |
||
| 607 | |||
| 608 | loadTemplate('Calendar'); |
||
| 609 | |||
| 610 | if ($bcd) |
||
| 611 | { |
||
| 612 | $context['sub_template'] = 'bcd'; |
||
| 613 | $context['linktree'][] = array('url' => $scripturl . '?action=clock;bcd', 'name' => 'BCD'); |
||
| 614 | $context['clockicons'] = safe_unserialize(base64_decode('YTo2OntzOjI6ImgxIjthOjI6e2k6MDtpOjI7aToxO2k6MTt9czoyOiJoMiI7YTo0OntpOjA7aTo4O2k6MTtpOjQ7aToyO2k6MjtpOjM7aToxO31zOjI6Im0xIjthOjM6e2k6MDtpOjQ7aToxO2k6MjtpOjI7aToxO31zOjI6Im0yIjthOjQ6e2k6MDtpOjg7aToxO2k6NDtpOjI7aToyO2k6MztpOjE7fXM6MjoiczEiO2E6Mzp7aTowO2k6NDtpOjE7aToyO2k6MjtpOjE7fXM6MjoiczIiO2E6NDp7aTowO2k6ODtpOjE7aTo0O2k6MjtpOjI7aTozO2k6MTt9fQ==')); |
||
| 615 | } |
||
| 616 | elseif (!$omfg && !isset($_REQUEST['time'])) |
||
| 617 | { |
||
| 618 | $context['sub_template'] = 'hms'; |
||
| 619 | $context['linktree'][] = array('url' => $scripturl . '?action=clock', 'name' => 'Binary'); |
||
| 620 | $context['clockicons'] = safe_unserialize(base64_decode('YTozOntzOjE6ImgiO2E6NTp7aTowO2k6MTY7aToxO2k6ODtpOjI7aTo0O2k6MztpOjI7aTo0O2k6MTt9czoxOiJtIjthOjY6e2k6MDtpOjMyO2k6MTtpOjE2O2k6MjtpOjg7aTozO2k6NDtpOjQ7aToyO2k6NTtpOjE7fXM6MToicyI7YTo2OntpOjA7aTozMjtpOjE7aToxNjtpOjI7aTo4O2k6MztpOjQ7aTo0O2k6MjtpOjU7aToxO319')); |
||
| 621 | } |
||
| 622 | elseif ($omfg) |
||
| 623 | { |
||
| 624 | $context['sub_template'] = 'omfg'; |
||
| 625 | $context['linktree'][] = array('url' => $scripturl . '?action=clock;omfg', 'name' => 'OMFG'); |
||
| 626 | $context['clockicons'] = safe_unserialize(base64_decode('YTo2OntzOjQ6InllYXIiO2E6Nzp7aTowO2k6NjQ7aToxO2k6MzI7aToyO2k6MTY7aTozO2k6ODtpOjQ7aTo0O2k6NTtpOjI7aTo2O2k6MTt9czo1OiJtb250aCI7YTo0OntpOjA7aTo4O2k6MTtpOjQ7aToyO2k6MjtpOjM7aToxO31zOjM6ImRheSI7YTo1OntpOjA7aToxNjtpOjE7aTo4O2k6MjtpOjQ7aTozO2k6MjtpOjQ7aToxO31zOjQ6ImhvdXIiO2E6NTp7aTowO2k6MTY7aToxO2k6ODtpOjI7aTo0O2k6MztpOjI7aTo0O2k6MTt9czozOiJtaW4iO2E6Njp7aTowO2k6MzI7aToxO2k6MTY7aToyO2k6ODtpOjM7aTo0O2k6NDtpOjI7aTo1O2k6MTt9czozOiJzZWMiO2E6Njp7aTowO2k6MzI7aToxO2k6MTY7aToyO2k6ODtpOjM7aTo0O2k6NDtpOjI7aTo1O2k6MTt9fQ==')); |
||
| 627 | } |
||
| 628 | elseif (isset($_REQUEST['time'])) |
||
| 629 | { |
||
| 630 | $context['sub_template'] = 'thetime'; |
||
| 631 | $time = getdate($_REQUEST['time'] == 'now' ? time() : (int) $_REQUEST['time']); |
||
| 632 | $year = $time['year'] % 100; |
||
| 633 | $month = $time['mon']; |
||
| 634 | $day = $time['mday']; |
||
| 635 | $hour = $time['hours']; |
||
| 636 | $min = $time['minutes']; |
||
| 637 | $sec = $time['seconds']; |
||
| 638 | $context['linktree'][] = array('url' => $scripturl . '?action=clock;time=' . $_REQUEST['time'], 'name' => 'Requested Time'); |
||
| 639 | $context['clockicons'] = array( |
||
| 640 | 'year' => array( |
||
| 641 | 64 => false, |
||
| 642 | 32 => false, |
||
| 643 | 16 => false, |
||
| 644 | 8 => false, |
||
| 645 | 4 => false, |
||
| 646 | 2 => false, |
||
| 647 | 1 => false |
||
| 648 | ), |
||
| 649 | 'month' => array( |
||
| 650 | 8 => false, |
||
| 651 | 4 => false, |
||
| 652 | 2 => false, |
||
| 653 | 1 => false |
||
| 654 | ), |
||
| 655 | 'day' => array( |
||
| 656 | 16 => false, |
||
| 657 | 4 => false, |
||
| 658 | 8 => false, |
||
| 659 | 2 => false, |
||
| 660 | 1 => false |
||
| 661 | ), |
||
| 662 | 'hour' => array( |
||
| 663 | 32 => false, |
||
| 664 | 16 => false, |
||
| 665 | 8 => false, |
||
| 666 | 4 => false, |
||
| 667 | 2 => false, |
||
| 668 | 1 => false |
||
| 669 | ), |
||
| 670 | 'min' => array( |
||
| 671 | 32 => false, |
||
| 672 | 16 => false, |
||
| 673 | 8 => false, |
||
| 674 | 4 => false, |
||
| 675 | 2 => false, |
||
| 676 | 1 => false |
||
| 677 | ), |
||
| 678 | 'sec' => array( |
||
| 679 | 32 => false, |
||
| 680 | 16 => false, |
||
| 681 | 8 => false, |
||
| 682 | 4 => false, |
||
| 683 | 2 => false, |
||
| 684 | 1 => false |
||
| 685 | ), |
||
| 686 | ); |
||
| 687 | |||
| 688 | foreach ($context['clockicons'] as $t => $vs) |
||
| 689 | foreach ($vs as $v => $dumb) |
||
| 690 | { |
||
| 691 | if ($$t >= $v) |
||
| 692 | { |
||
| 693 | $$t -= $v; |
||
| 694 | $context['clockicons'][$t][$v] = true; |
||
| 695 | } |
||
| 696 | } |
||
| 697 | } |
||
| 698 | } |
||
| 699 | |||
| 700 | ?> |
||
| 701 |
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.