MDL-12627 - when visiting the gradebook for the first time, we don't sort
[moodle.git] / calendar / lib.php
CommitLineData
7423f116 1<?php // $Id$
2
3/////////////////////////////////////////////////////////////////////////////
4// //
5// NOTICE OF COPYRIGHT //
6// //
7// Moodle - Calendar extension //
8// //
9// Copyright (C) 2003-2004 Greek School Network www.sch.gr //
10// //
11// Designed by: //
bdcb26b7 12// Avgoustos Tsinakos (tsinakos@teikav.edu.gr) //
13// Jon Papaioannou (pj@moodle.org) //
7423f116 14// //
15// Programming and development: //
bdcb26b7 16// Jon Papaioannou (pj@moodle.org) //
7423f116 17// //
18// For bugs, suggestions, etc contact: //
bdcb26b7 19// Jon Papaioannou (pj@moodle.org) //
7423f116 20// //
21// The current module was developed at the University of Macedonia //
22// (www.uom.gr) under the funding of the Greek School Network (www.sch.gr) //
23// The aim of this project is to provide additional and improved //
24// functionality to the Asynchronous Distance Education service that the //
25// Greek School Network deploys. //
26// //
27// This program is free software; you can redistribute it and/or modify //
28// it under the terms of the GNU General Public License as published by //
29// the Free Software Foundation; either version 2 of the License, or //
30// (at your option) any later version. //
31// //
32// This program is distributed in the hope that it will be useful, //
33// but WITHOUT ANY WARRANTY; without even the implied warranty of //
34// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the //
35// GNU General Public License for more details: //
36// //
37// http://www.gnu.org/copyleft/gpl.html //
38// //
39/////////////////////////////////////////////////////////////////////////////
40
bb4a2e85 41// These are read by the administration component to provide default values
42define('CALENDAR_DEFAULT_UPCOMING_LOOKAHEAD', 21);
43define('CALENDAR_DEFAULT_UPCOMING_MAXEVENTS', 10);
44define('CALENDAR_DEFAULT_STARTING_WEEKDAY', 1);
45// This is a packed bitfield: day X is "weekend" if $field & (1 << X) is true
46// Default value = 65 = 64 + 1 = 2^6 + 2^0 = Saturday & Sunday
47define('CALENDAR_DEFAULT_WEEKEND', 65);
48
49// Fetch the correct values from admin settings/lang pack
50// If no such settings found, use the above defaults
51$firstday = isset($CFG->calendar_startwday) ? $CFG->calendar_startwday : get_string('firstdayofweek');
e295df44 52if(!is_numeric($firstday)) {
bb4a2e85 53 define ('CALENDAR_STARTING_WEEKDAY', CALENDAR_DEFAULT_STARTING_WEEKDAY);
ed151929 54}
55else {
56 define ('CALENDAR_STARTING_WEEKDAY', intval($firstday) % 7);
57}
bb4a2e85 58define ('CALENDAR_UPCOMING_DAYS', isset($CFG->calendar_lookahead) ? intval($CFG->calendar_lookahead) : CALENDAR_DEFAULT_UPCOMING_LOOKAHEAD);
59define ('CALENDAR_UPCOMING_MAXEVENTS', isset($CFG->calendar_maxevents) ? intval($CFG->calendar_maxevents) : CALENDAR_DEFAULT_UPCOMING_MAXEVENTS);
60define ('CALENDAR_WEEKEND', isset($CFG->calendar_weekend) ? intval($CFG->calendar_weekend) : CALENDAR_DEFAULT_WEEKEND);
7423f116 61define ('CALENDAR_URL', $CFG->wwwroot.'/calendar/');
1b0ebe79 62define ('CALENDAR_TF_24', '%H:%M');
63define ('CALENDAR_TF_12', '%I:%M %p');
7423f116 64
f2bffd9e 65$CALENDARDAYS = array('sunday','monday','tuesday','wednesday','thursday','friday','saturday');
66
37d87d11 67
bd119567 68
7423f116 69function calendar_get_mini($courses, $groups, $users, $cal_month = false, $cal_year = false) {
70 global $CFG, $USER;
71
4e17c6f3 72 $display = &New stdClass;
7423f116 73 $display->minwday = get_user_preferences('calendar_startwday', CALENDAR_STARTING_WEEKDAY);
74 $display->maxwday = $display->minwday + 6;
75
76 $content = '';
77
78 if(!empty($cal_month) && !empty($cal_year)) {
79 $thisdate = usergetdate(time()); // Date and time the user sees at his location
80 if($cal_month == $thisdate['mon'] && $cal_year == $thisdate['year']) {
81 // Navigated to this month
82 $date = $thisdate;
83 $display->thismonth = true;
84 }
85 else {
86 // Navigated to other month, let's do a nice trick and save us a lot of work...
87 if(!checkdate($cal_month, 1, $cal_year)) {
88 $date = array('mday' => 1, 'mon' => $thisdate['mon'], 'year' => $thisdate['year']);
89 $display->thismonth = true;
90 }
91 else {
92 $date = array('mday' => 1, 'mon' => $cal_month, 'year' => $cal_year);
93 $display->thismonth = false;
94 }
95 }
96 }
97 else {
98 $date = usergetdate(time()); // Date and time the user sees at his location
99 $display->thismonth = true;
100 }
101
102 // Fill in the variables we 're going to use, nice and tidy
103 list($d, $m, $y) = array($date['mday'], $date['mon'], $date['year']); // This is what we want to display
104 $display->maxdays = calendar_days_in_month($m, $y);
105
d6198903 106 if (get_user_timezone_offset() < 99) {
107 // We 'll keep these values as GMT here, and offset them when the time comes to query the db
61240489 108 $display->tstart = gmmktime(0, 0, 0, $m, 1, $y); // This is GMT
109 $display->tend = gmmktime(23, 59, 59, $m, $display->maxdays, $y); // GMT
d6198903 110 } else {
111 // no timezone info specified
61240489 112 $display->tstart = mktime(0, 0, 0, $m, 1, $y);
113 $display->tend = mktime(23, 59, 59, $m, $display->maxdays, $y);
d6198903 114 }
7423f116 115
69244b91 116 $startwday = dayofweek(1, $m, $y);
7423f116 117
118 // Align the starting weekday to fall in our display range
119 // This is simple, not foolproof.
120 if($startwday < $display->minwday) {
121 $startwday += 7;
122 }
123
c0b507d1 124 // TODO: THIS IS TEMPORARY CODE!
125 // [pj] I was just reading through this and realized that I when writing this code I was probably
126 // asking for trouble, as all these time manipulations seem to be unnecessary and a simple
127 // make_timestamp would accomplish the same thing. So here goes a test:
1747ee05 128 //$test_start = make_timestamp($y, $m, 1);
129 //$test_end = make_timestamp($y, $m, $display->maxdays, 23, 59, 59);
130 //if($test_start != usertime($display->tstart) - dst_offset_on($display->tstart)) {
131 //notify('Failed assertion in calendar/lib.php line 126; display->tstart = '.$display->tstart.', dst_offset = '.dst_offset_on($display->tstart).', usertime = '.usertime($display->tstart).', make_t = '.$test_start);
132 //}
133 //if($test_end != usertime($display->tend) - dst_offset_on($display->tend)) {
134 //notify('Failed assertion in calendar/lib.php line 130; display->tend = '.$display->tend.', dst_offset = '.dst_offset_on($display->tend).', usertime = '.usertime($display->tend).', make_t = '.$test_end);
135 //}
c0b507d1 136
137
7423f116 138 // Get the events matching our criteria. Don't forget to offset the timestamps for the user's TZ!
8263f802 139 $events = calendar_get_events(
d3555a2f 140 usertime($display->tstart) - dst_offset_on($display->tstart),
141 usertime($display->tend) - dst_offset_on($display->tend),
142 $users, $groups, $courses);
7423f116 143
b4892fa2 144 // Set event course class for course events
145 if (!empty($events)) {
13534ef7 146 foreach ($events as $eventid => $event) {
13534ef7
ML
147 if (!empty($event->modulename)) {
148 $cm = get_coursemodule_from_instance($event->modulename, $event->instance);
149 if (!groups_course_module_visible($cm)) {
150 unset($events[$eventid]);
151 }
152 }
b4892fa2 153 }
154 }
6619eba4 155
c635dcda 156 // This is either a genius idea or an idiot idea: in order to not complicate things, we use this rule: if, after
9064751b 157 // possibly removing SITEID from $courses, there is only one course left, then clicking on a day in the month
c635dcda 158 // will also set the $SESSION->cal_courses_shown variable to that one course. Otherwise, we 'd need to add extra
159 // arguments to this function.
160
7bd1677c 161 $morehref = '';
162 if(!empty($courses)) {
e749554e 163 $courses = array_diff($courses, array(SITEID));
7bd1677c 164 if(count($courses) == 1) {
165 $morehref = '&amp;course='.reset($courses);
166 }
c635dcda 167 }
168
7423f116 169 // We want to have easy access by day, since the display is on a per-day basis.
170 // Arguments passed by reference.
7b38bfa6 171 //calendar_events_by_day($events, $display->tstart, $eventsbyday, $durationbyday, $typesbyday);
7c50db30 172 calendar_events_by_day($events, $m, $y, $eventsbyday, $durationbyday, $typesbyday, $courses);
7423f116 173
f20c4d02 174 //Accessibility: added summary and <abbr> elements.
175 ///global $CALENDARDAYS; appears to be broken.
176 $days_title = array('sunday','monday','tuesday','wednesday','thursday','friday','saturday');
177
2a06efcc 178 $summary = get_string('calendarheading', 'calendar', userdate(make_timestamp($y, $m), get_string('strftimemonthyear')));
179 $summary = get_string('tabledata', 'access', $summary);
180 $content .= '<table class="minicalendar" summary="'.$summary.'">'; // Begin table
f136e4c5 181 $content .= '<tr class="weekdays">'; // Header row: day names
7423f116 182
183 // Print out the names of the weekdays
184 $days = array('sun', 'mon', 'tue', 'wed', 'thu', 'fri', 'sat');
185 for($i = $display->minwday; $i <= $display->maxwday; ++$i) {
186 // This uses the % operator to get the correct weekday no matter what shift we have
187 // applied to the $display->minwday : $display->maxwday range from the default 0 : 6
f20c4d02 188 $content .= '<th scope="col"><abbr title="'. get_string($days_title[$i % 7], 'calendar') .'">'.
189 get_string($days[$i % 7], 'calendar') ."</abbr></th>\n";
7423f116 190 }
191
f136e4c5 192 $content .= '</tr><tr>'; // End of day names; prepare for day numbers
7423f116 193
194 // For the table display. $week is the row; $dayweek is the column.
7423f116 195 $dayweek = $startwday;
196
197 // Paddding (the first week may have blank days in the beginning)
198 for($i = $display->minwday; $i < $startwday; ++$i) {
3bfd8bc8 199 $content .= '<td class="dayblank">&nbsp;</td>'."\n";
7423f116 200 }
201
202 // Now display all the calendar
203 for($day = 1; $day <= $display->maxdays; ++$day, ++$dayweek) {
204 if($dayweek > $display->maxwday) {
205 // We need to change week (table row)
d56d4e23 206 $content .= '</tr><tr>';
7423f116 207 $dayweek = $display->minwday;
7423f116 208 }
92668ad2 209
7423f116 210 // Reset vars
7423f116 211 $cell = '';
bb4a2e85 212 if(CALENDAR_WEEKEND & (1 << ($dayweek % 7))) {
7423f116 213 // Weekend. This is true no matter what the exact range is.
e2aa618b 214 $class = 'weekend day';
7423f116 215 }
216 else {
217 // Normal working day.
e2aa618b 218 $class = 'day';
7423f116 219 }
220
221 // Special visual fx if an event is defined
222 if(isset($eventsbyday[$day])) {
c635dcda 223 $dayhref = calendar_get_link_href(CALENDAR_URL.'view.php?view=day'.$morehref.'&amp;', $day, $m, $y);
f434283f 224
7423f116 225 // OverLib popup
226 $popupcontent = '';
227 foreach($eventsbyday[$day] as $eventid) {
41d30a8e 228 if (!isset($events[$eventid])) {
229 continue;
4e17c6f3 230 }
41d30a8e 231 $event = $events[$eventid];
41d30a8e 232 if(!empty($event->modulename)) {
233 $popupicon = $CFG->modpixpath.'/'.$event->modulename.'/icon.gif';
234 $popupalt = $event->modulename;
235
9064751b 236 } else if ($event->courseid == SITEID) { // Site event
41d30a8e 237 $popupicon = $CFG->pixpath.'/c/site.gif';
238 $popupalt = '';
c3d3b6d4 239 } else if ($event->courseid != 0 && $event->courseid != SITEID && $event->groupid == 0) { // Course event
41d30a8e 240 $popupicon = $CFG->pixpath.'/c/course.gif';
c9b05b32 241 $popupalt = '';
41d30a8e 242 } else if ($event->groupid) { // Group event
243 $popupicon = $CFG->pixpath.'/c/group.gif';
244 $popupalt = '';
245 } else if ($event->userid) { // User event
246 $popupicon = $CFG->pixpath.'/c/user.gif';
247 $popupalt = '';
4e17c6f3 248 }
53d8fac0 249 $popupcontent .= '<div><img class="icon" src="'.$popupicon.'" alt="'.$popupalt.'" /><a href="'.$dayhref.'#event_'.$event->id.'">'.format_string($event->name, true).'</a></div>';
7423f116 250 }
e295df44 251
b5c42e70 252 //Accessibility: functionality moved to calendar_get_popup.
253 if($display->thismonth && $day == $d) {
450a0a7d 254 $popup = calendar_get_popup(true, $events[$eventid]->timestart, $popupcontent);
b5c42e70 255 } else {
450a0a7d 256 $popup = calendar_get_popup(false, $events[$eventid]->timestart, $popupcontent);
e295df44 257 }
f20c4d02 258
7423f116 259 // Class and cell content
260 if(isset($typesbyday[$day]['startglobal'])) {
edbe6c1b 261 $class .= ' event_global';
7423f116 262 }
263 else if(isset($typesbyday[$day]['startcourse'])) {
edbe6c1b 264 $class .= ' event_course';
7423f116 265 }
266 else if(isset($typesbyday[$day]['startgroup'])) {
edbe6c1b 267 $class .= ' event_group';
7423f116 268 }
269 else if(isset($typesbyday[$day]['startuser'])) {
edbe6c1b 270 $class .= ' event_user';
7423f116 271 }
05fcc5fd 272 $cell = '<a href="'.$dayhref.'" '.$popup.'>'.$day.'</a>';
7423f116 273 }
274 else {
05fcc5fd 275 $cell = $day;
7423f116 276 }
277
278 if(isset($typesbyday[$day]['durationglobal'])) {
edbe6c1b 279 $class .= ' duration_global';
7423f116 280 }
281 else if(isset($typesbyday[$day]['durationcourse'])) {
edbe6c1b 282 $class .= ' duration_course';
7423f116 283 }
284 else if(isset($typesbyday[$day]['durationgroup'])) {
edbe6c1b 285 $class .= ' duration_group';
7423f116 286 }
287 else if(isset($typesbyday[$day]['durationuser'])) {
edbe6c1b 288 $class .= ' duration_user';
7423f116 289 }
290
b4892fa2 291 // If event has a class set then add it to the table day <td> tag
292 // Note: only one colour for minicalendar
293 if(isset($eventsbyday[$day])) {
294 foreach($eventsbyday[$day] as $eventid) {
295 if (!isset($events[$eventid])) {
296 continue;
297 }
298 $event = $events[$eventid];
299 if (!empty($event->class)) {
300 $class .= ' '.$event->class;
301 }
302 break;
303 }
304 }
305
7423f116 306 // Special visual fx for today
450a0a7d 307 //Accessibility: hidden text for today, and popup.
7423f116 308 if($display->thismonth && $day == $d) {
edbe6c1b 309 $class .= ' today';
b5c42e70 310 $today = get_string('today', 'calendar').' '.userdate(time(), get_string('strftimedayshort'));
e295df44 311
b5c42e70 312 if(! isset($eventsbyday[$day])) {
450a0a7d 313 $class .= ' eventnone';
314 $popup = calendar_get_popup(true, false);
315 $cell = '<a href="#" '.$popup.'>'.$day.'</a>';
b5c42e70 316 }
f79f2494 317 $cell = get_accesshide($today.' ').$cell;
7423f116 318 }
319
320 // Just display it
92668ad2 321 if(!empty($class)) {
d56d4e23 322 $class = ' class="'.$class.'"';
92668ad2 323 }
324 $content .= '<td'.$class.'>'.$cell."</td>\n";
7423f116 325 }
326
327 // Paddding (the last week may have blank days at the end)
328 for($i = $dayweek; $i <= $display->maxwday; ++$i) {
3bfd8bc8 329 $content .= '<td class="dayblank">&nbsp;</td>';
7423f116 330 }
331 $content .= '</tr>'; // Last row ends
332
f136e4c5 333 $content .= '</table>'; // Tabular display of days ends
7423f116 334
335 return $content;
336}
337
b5c42e70 338/**
339 * calendar_get_popup, called at multiple points in from calendar_get_mini.
340 * Copied and modified from calendar_get_mini.
341 * @uses OverLib popup.
342 * @param $is_today bool, false except when called on the current day.
343 * @param $event_timestart mixed, $events[$eventid]->timestart, OR false if there are no events.
344 * @param $popupcontent string.
e295df44 345 * @return $popup string, contains onmousover and onmouseout events.
b5c42e70 346 */
347function calendar_get_popup($is_today, $event_timestart, $popupcontent='') {
348 $popupcaption = '';
349 if($is_today) {
350 $popupcaption = get_string('today', 'calendar').' ';
351 }
352 if (false === $event_timestart) {
353 $popupcaption .= userdate(time(), get_string('strftimedayshort'));
354 $popupcontent = get_string('eventnone', 'calendar');
450a0a7d 355
b5c42e70 356 } else {
357 $popupcaption .= get_string('eventsfor', 'calendar', userdate($event_timestart, get_string('strftimedayshort')));
358 }
359 $popupcontent = str_replace("'", "\'", htmlspecialchars($popupcontent));
e295df44 360 $popupcaption = str_replace("'", "\'", htmlspecialchars($popupcaption));
b5c42e70 361 $popup = 'onmouseover="return overlib(\''.$popupcontent.'\', CAPTION, \''.$popupcaption.'\');" onmouseout="return nd();"';
450a0a7d 362 return $popup;
b5c42e70 363}
364
9958a08c 365function calendar_get_upcoming($courses, $groups, $users, $daysinfuture, $maxevents, $fromtime=0) {
7423f116 366 global $CFG;
367
1f473774 368 $display = &new stdClass;
7423f116 369 $display->range = $daysinfuture; // How many days in the future we 'll look
370 $display->maxevents = $maxevents;
371
372 $output = array();
373
374 // Prepare "course caching", since it may save us a lot of queries
375 $coursecache = array();
376
377 $processed = 0;
378 $now = time(); // We 'll need this later
9d567178 379 $usermidnighttoday = usergetmidnight($now);
7423f116 380
9958a08c 381 if ($fromtime) {
382 $display->tstart = $fromtime;
383 } else {
9d567178 384 $display->tstart = $usermidnighttoday;
9958a08c 385 }
7423f116 386
1f473774 387 // This works correctly with respect to the user's DST, but it is accurate
388 // only because $fromtime is always the exact midnight of some day!
389 $display->tend = usergetmidnight($display->tstart + DAYSECS * $display->range + 3 * HOURSECS) - 1;
7423f116 390
391 // Get the events matching our criteria
8263f802 392 $events = calendar_get_events($display->tstart, $display->tend, $users, $groups, $courses);
7423f116 393
c635dcda 394 // This is either a genius idea or an idiot idea: in order to not complicate things, we use this rule: if, after
9064751b 395 // possibly removing SITEID from $courses, there is only one course left, then clicking on a day in the month
c635dcda 396 // will also set the $SESSION->cal_courses_shown variable to that one course. Otherwise, we 'd need to add extra
397 // arguments to this function.
398
7bd1677c 399 $morehref = '';
400 if(!empty($courses)) {
e749554e 401 $courses = array_diff($courses, array(SITEID));
7bd1677c 402 if(count($courses) == 1) {
403 $morehref = '&amp;course='.reset($courses);
404 }
c635dcda 405 }
406
7423f116 407 if($events !== false) {
fa22fd5f 408
7423f116 409 foreach($events as $event) {
dc6cb74e 410
13534ef7
ML
411 if(!empty($event->modulename)) {
412 $mod = get_coursemodule_from_instance($event->modulename, $event->instance);
413 if (!groups_course_module_visible($mod)) {
414 continue;
415 }
416 }
dc6cb74e 417
418
419 if ($event->modulename == 'assignment'){
420 if(!calendar_edit_event_allowed($event)){ // cannot manage entries, eg. student
421 if(!$assignment = get_record('assignment','id',$event->instance)){
422 // error("assignment ID was incorrect");
423 continue;
424 }
425 // assign assignment to assignment object to use hidden_is_hidden method
426 require_once($CFG->dirroot.'/mod/assignment/lib.php');
427
428 if (!file_exists($CFG->dirroot.'/mod/assignment/type/'.$assignment->assignmenttype.'/assignment.class.php')) {
429 continue;
430 }
431 require_once ($CFG->dirroot.'/mod/assignment/type/'.$assignment->assignmenttype.'/assignment.class.php');
432
433 $assignmentclass = 'assignment_'.$assignment->assignmenttype;
434 $assignmentinstance = new $assignmentclass($mod->id,$assignment);
435
436 if ($assignmentinstance->description_is_hidden()){//force not to show description before availability
437 $event->description = get_string('notavailableyet', 'assignment');
438 }
439 }
440 }
9d567178 441
442 if($processed >= $display->maxevents) {
443 break;
444 }
7423f116 445
3c134875 446 $event->time = calendar_format_event_time($event, $now, $morehref);
447 $output[] = $event;
448 ++$processed;
449 }
450 }
451 return $output;
452}
7423f116 453
9df8ff44 454function calendar_add_event_metadata($event) {
455 global $CFG;
fb73f3b3 456
e295df44 457 //Support multilang in event->name
fb73f3b3 458 $event->name = format_string($event->name,true);
e295df44 459
3c134875 460 if(!empty($event->modulename)) { // Activity event
461 // The module name is set. I will assume that it has to be displayed, and
462 // also that it is an automatically-generated event. And of course that the
463 // fields for get_coursemodule_from_instance are set correctly.
464 $module = calendar_get_module_cached($coursecache, $event->modulename, $event->instance);
7423f116 465
3c134875 466 if ($module === false) {
467 return;
468 }
9958a08c 469
3c134875 470 $modulename = get_string('modulename', $event->modulename);
471 $eventtype = get_string($event->eventtype, $event->modulename);
472 $icon = $CFG->modpixpath.'/'.$event->modulename.'/icon.gif';
9958a08c 473
10daca92 474 $event->icon = '<img height="16" width="16" src="'.$icon.'" alt="'.$eventtype.'" title="'.$modulename.'" style="vertical-align: middle;" />';
fb73f3b3 475 $event->referer = '<a href="'.$CFG->wwwroot.'/mod/'.$event->modulename.'/view.php?id='.$module->id.'">'.$event->name.'</a>';
3c134875 476 $event->courselink = '<a href="'.$CFG->wwwroot.'/course/view.php?id='.$module->course.'">'.$coursecache[$module->course]->fullname.'</a>';
477 $event->cmid = $module->id;
9958a08c 478
9958a08c 479
3c134875 480 } else if($event->courseid == SITEID) { // Site event
10daca92 481 $event->icon = '<img height="16" width="16" src="'.$CFG->pixpath.'/c/site.gif" alt="'.get_string('globalevent', 'calendar').'" style="vertical-align: middle;" />';
3c49918a 482 $event->cssclass = 'event_global';
3c134875 483 } else if($event->courseid != 0 && $event->courseid != SITEID && $event->groupid == 0) { // Course event
484 calendar_get_course_cached($coursecache, $event->courseid);
10daca92 485 $event->icon = '<img height="16" width="16" src="'.$CFG->pixpath.'/c/course.gif" alt="'.get_string('courseevent', 'calendar').'" style="vertical-align: middle;" />';
3c134875 486 $event->courselink = '<a href="'.$CFG->wwwroot.'/course/view.php?id='.$event->courseid.'">'.$coursecache[$event->courseid]->fullname.'</a>';
3c49918a 487 $event->cssclass = 'event_course';
3c134875 488 } else if ($event->groupid) { // Group event
10daca92 489 $event->icon = '<img height="16" width="16" src="'.$CFG->pixpath.'/c/group.gif" alt="'.get_string('groupevent', 'calendar').'" style="vertical-align: middle;" />';
3c49918a 490 $event->cssclass = 'event_group';
3c134875 491 } else if($event->userid) { // User event
10daca92 492 $event->icon = '<img height="16" width="16" src="'.$CFG->pixpath.'/c/user.gif" alt="'.get_string('userevent', 'calendar').'" style="vertical-align: middle;" />';
3c49918a 493 $event->cssclass = 'event_user';
3c134875 494 }
9df8ff44 495 return $event;
e295df44 496}
9df8ff44 497
498function calendar_print_event($event) {
499 global $CFG, $USER;
500
501 static $strftimetime;
502
503 $event = calendar_add_event_metadata($event);
53d8fac0 504 echo '<a name="event_'.$event->id.'"></a><table class="event" cellspacing="0">';
ed8ea92b 505 echo '<tr><td class="picture">';
3c134875 506 if (!empty($event->icon)) {
507 echo $event->icon;
508 } else {
509 print_spacer(16,16);
510 }
511 echo '</td>';
df349d1d 512 echo '<td class="topic">';
9958a08c 513
3c134875 514 if (!empty($event->referer)) {
e96ba29d 515 echo '<div class="referer">'.$event->referer.'</div>';
3c134875 516 } else {
ed8ea92b 517 echo '<div class="name">'.$event->name."</div>";
3c134875 518 }
519 if (!empty($event->courselink)) {
ed8ea92b 520 echo '<div class="course">'.$event->courselink.' </div>';
3c134875 521 }
522 if (!empty($event->time)) {
ed8ea92b 523 echo '<span class="date">'.$event->time.'</span>';
3c134875 524 } else {
ed8ea92b 525 echo '<span class="date">'.calendar_time_representation($event->timestart).'</span>';
3c134875 526 }
9958a08c 527
ed8ea92b 528 echo '</td></tr>';
529 echo '<tr><td class="side">&nbsp;</td>';
9ba76792 530 if (isset($event->cssclass)) {
531 echo '<td class="description '.$event->cssclass.'">';
532 } else {
533 echo '<td class="description">';
534 }
3c134875 535 echo format_text($event->description, FORMAT_HTML);
536 if (calendar_edit_event_allowed($event)) {
ed8ea92b 537 echo '<div class="commands">';
54052a7a 538 $calendarcourseid = '';
539 if (!empty($event->calendarcourseid)) {
540 $calendarcourseid = '&amp;course='.$event->calendarcourseid;
541 }
3c134875 542 if (empty($event->cmid)) {
54052a7a 543 $editlink = CALENDAR_URL.'event.php?action=edit&amp;id='.$event->id.$calendarcourseid;
544 $deletelink = CALENDAR_URL.'event.php?action=delete&amp;id='.$event->id.$calendarcourseid;
3c134875 545 } else {
546 $editlink = $CFG->wwwroot.'/course/mod.php?update='.$event->cmid.'&amp;return=true&amp;sesskey='.$USER->sesskey;
547 $deletelink = $CFG->wwwroot.'/course/mod.php?delete='.$event->cmid.'&amp;sesskey='.$USER->sesskey;;
7423f116 548 }
3c134875 549 echo ' <a href="'.$editlink.'"><img
550 src="'.$CFG->pixpath.'/t/edit.gif" alt="'.get_string('tt_editevent', 'calendar').'"
551 title="'.get_string('tt_editevent', 'calendar').'" /></a>';
552 echo ' <a href="'.$deletelink.'"><img
553 src="'.$CFG->pixpath.'/t/delete.gif" alt="'.get_string('tt_deleteevent', 'calendar').'"
554 title="'.get_string('tt_deleteevent', 'calendar').'" /></a>';
555 echo '</div>';
7423f116 556 }
3c134875 557 echo '</td></tr></table>';
558
7423f116 559}
560
8263f802 561/**
562 * Get calendar events
563 * @param int $tstart Start time of time range for events
564 * @param int $tend End time of time range for events
565 * @param array/int/boolean $users array of users, user id or boolean for all/no user events
566 * @param array/int/boolean $groups array of groups, group id or boolean for all/no group events
567 * @param array/int/boolean $courses array of courses, course id or boolean for all/no course events
568 * @param boolean $withduration whether only events starting within time range selected
569 * or events in progress/already started selected as well
570 * @param boolean $ignorehidden whether to select only visible events or all events
571 * @return array of selected events or an empty array if there aren't any (or there was an error)
572 */
573function calendar_get_events($tstart, $tend, $users, $groups, $courses, $withduration=true, $ignorehidden=true) {
7423f116 574 $whereclause = '';
575 // Quick test
576 if(is_bool($users) && is_bool($groups) && is_bool($courses)) {
8263f802 577 return array();
7423f116 578 }
482dbe0c 579
7423f116 580 if(is_array($users) && !empty($users)) {
581 // Events from a number of users
582 if(!empty($whereclause)) $whereclause .= ' OR';
6e957c41 583 $whereclause .= ' (userid IN ('.implode(',', $users).') AND courseid = 0 AND groupid = 0)';
7423f116 584 }
585 else if(is_numeric($users)) {
586 // Events from one user
587 if(!empty($whereclause)) $whereclause .= ' OR';
6e957c41 588 $whereclause .= ' (userid = '.$users.' AND courseid = 0 AND groupid = 0)';
7423f116 589 }
590 else if($users === true) {
591 // Events from ALL users
592 if(!empty($whereclause)) $whereclause .= ' OR';
6e957c41 593 $whereclause .= ' (userid != 0 AND courseid = 0 AND groupid = 0)';
7423f116 594 }
f52f7413 595 else if($users === false) {
6e957c41 596 // No user at all, do nothing
f52f7413 597 }
482dbe0c 598
7423f116 599 if(is_array($groups) && !empty($groups)) {
600 // Events from a number of groups
601 if(!empty($whereclause)) $whereclause .= ' OR';
602 $whereclause .= ' groupid IN ('.implode(',', $groups).')';
603 }
604 else if(is_numeric($groups)) {
605 // Events from one group
606 if(!empty($whereclause)) $whereclause .= ' OR ';
607 $whereclause .= ' groupid = '.$groups;
608 }
609 else if($groups === true) {
610 // Events from ALL groups
611 if(!empty($whereclause)) $whereclause .= ' OR ';
612 $whereclause .= ' groupid != 0';
613 }
482dbe0c 614 // boolean false (no groups at all): we don't need to do anything
615
f52f7413 616 if(is_array($courses)) {
617 // A number of courses (maybe none at all!)
618 if(!empty($courses)) {
619 if(!empty($whereclause)) {
620 $whereclause .= ' OR';
621 }
6e957c41 622 $whereclause .= ' (groupid = 0 AND courseid IN ('.implode(',', $courses).'))';
f52f7413 623 }
624 else {
625 // This means NO courses, not that we don't care!
09d36284 626 // No need to do anything
f52f7413 627 }
7423f116 628 }
629 else if(is_numeric($courses)) {
630 // One course
631 if(!empty($whereclause)) $whereclause .= ' OR';
6e957c41 632 $whereclause .= ' (groupid = 0 AND courseid = '.$courses.')';
7423f116 633 }
634 else if($courses === true) {
635 // Events from ALL courses
636 if(!empty($whereclause)) $whereclause .= ' OR';
6e957c41 637 $whereclause .= ' (groupid = 0 AND courseid != 0)';
7423f116 638 }
8c165fe9 639
482dbe0c 640 // Security check: if, by now, we have NOTHING in $whereclause, then it means
641 // that NO event-selecting clauses were defined. Thus, we won't be returning ANY
642 // events no matter what. Allowing the code to proceed might return a completely
643 // valid query with only time constraints, thus selecting ALL events in that time frame!
644 if(empty($whereclause)) {
8263f802 645 return array();
482dbe0c 646 }
647
7423f116 648 if($withduration) {
b4892fa2 649 $timeclause = '(timestart >= '.$tstart.' OR timestart + timeduration > '.$tstart.') AND timestart <= '.$tend;
7423f116 650 }
651 else {
652 $timeclause = 'timestart >= '.$tstart.' AND timestart <= '.$tend;
653 }
654 if(!empty($whereclause)) {
655 // We have additional constraints
656 $whereclause = $timeclause.' AND ('.$whereclause.')';
657 }
658 else {
659 // Just basic time filtering
660 $whereclause = $timeclause;
661 }
f52f7413 662
0ad072de 663 if ($ignorehidden) {
664 $whereclause .= ' AND visible = 1';
665 }
666
8263f802 667 $events = get_records_select('event', $whereclause, 'timestart');
668 if ($events === false) {
669 $events = array();
670 }
671 return $events;
7423f116 672}
673
674function calendar_top_controls($type, $data) {
57100a90 675 global $CFG, $CALENDARDAYS, $THEME;
7423f116 676 $content = '';
677 if(!isset($data['d'])) {
678 $data['d'] = 1;
679 }
5147ad48 680
f21ed0f3 681 // Ensure course id passed if relevant
682 // Required due to changes in view/lib.php mainly (calendar_session_vars())
683 $courseid = '';
684 if (!empty($data['id'])) {
685 $courseid = '&amp;course='.$data['id'];
686 }
687
5147ad48 688 if(!checkdate($data['m'], $data['d'], $data['y'])) {
689 $time = time();
690 }
691 else {
692 $time = make_timestamp($data['y'], $data['m'], $data['d']);
693 }
694 $date = usergetdate($time);
e295df44 695
7423f116 696 $data['m'] = $date['mon'];
697 $data['y'] = $date['year'];
7423f116 698
2a06efcc 699 //Accessibility: calendar block controls, replaced <table> with <div>.
a84dea2c 700 //$nexttext = link_arrow_right(get_string('monthnext', 'access'), $url='', $accesshide=true);
701 //$prevtext = link_arrow_left(get_string('monthprev', 'access'), $url='', $accesshide=true);
2a06efcc 702
7423f116 703 switch($type) {
704 case 'frontpage':
705 list($prevmonth, $prevyear) = calendar_sub_month($data['m'], $data['y']);
706 list($nextmonth, $nextyear) = calendar_add_month($data['m'], $data['y']);
a84dea2c 707 $nextlink = calendar_get_link_next(get_string('monthnext', 'access'), 'index.php?', 0, $nextmonth, $nextyear, $accesshide=true);
708 $prevlink = calendar_get_link_previous(get_string('monthprev', 'access'), 'index.php?', 0, $prevmonth, $prevyear, true);
709 $content .= "\n".'<div class="calendar-controls">'. $prevlink;
54052a7a 710 $content .= '<span class="hide"> | </span><span class="current"><a href="'.calendar_get_link_href(CALENDAR_URL.'view.php?view=month'.$courseid.'&amp;', 1, $data['m'], $data['y']).'">'.userdate($time, get_string('strftimemonthyear')).'</a></span>';
a84dea2c 711 $content .= '<span class="hide"> | </span>'. $nextlink ."\n";
f2de62da 712 $content .= "<span class=\"clearer\"><!-- --></span></div>\n";
7423f116 713 break;
714 case 'course':
715 list($prevmonth, $prevyear) = calendar_sub_month($data['m'], $data['y']);
716 list($nextmonth, $nextyear) = calendar_add_month($data['m'], $data['y']);
a84dea2c 717 $nextlink = calendar_get_link_next(get_string('monthnext', 'access'), 'view.php?id='.$data['id'].'&amp;', 0, $nextmonth, $nextyear, $accesshide=true);
718 $prevlink = calendar_get_link_previous(get_string('monthprev', 'access'), 'view.php?id='.$data['id'].'&amp;', 0, $prevmonth, $prevyear, true);
719 $content .= "\n".'<div class="calendar-controls">'. $prevlink;
54052a7a 720 $content .= '<span class="hide"> | </span><span class="current"><a href="'.calendar_get_link_href(CALENDAR_URL.'view.php?view=month'.$courseid.'&amp;', 1, $data['m'], $data['y']).'">'.userdate($time, get_string('strftimemonthyear')).'</a></span>';
a84dea2c 721 $content .= '<span class="hide"> | </span>'. $nextlink ."\n";
f2de62da 722 $content .= "<span class=\"clearer\"><!-- --></span></div>\n";
7423f116 723 break;
724 case 'upcoming':
f21ed0f3 725 $content .= '<div style="text-align: center;"><a href="'.CALENDAR_URL.'view.php?view=upcoming"'.$courseid.'>'.userdate($time, get_string('strftimemonthyear'))."</a></div>\n";
7423f116 726 break;
727 case 'display':
f21ed0f3 728 $content .= '<div style="text-align: center;"><a href="'.calendar_get_link_href(CALENDAR_URL.'view.php?view=month'.$courseid.'&amp;', 1, $data['m'], $data['y']).'">'.userdate($time, get_string('strftimemonthyear'))."</a></div>\n";
7423f116 729 break;
730 case 'month':
731 list($prevmonth, $prevyear) = calendar_sub_month($data['m'], $data['y']);
732 list($nextmonth, $nextyear) = calendar_add_month($data['m'], $data['y']);
5147ad48 733 $prevdate = make_timestamp($prevyear, $prevmonth, 1);
734 $nextdate = make_timestamp($nextyear, $nextmonth, 1);
a84dea2c 735 $content .= "\n".'<div class="calendar-controls">';
f21ed0f3 736 $content .= calendar_get_link_previous(userdate($prevdate, get_string('strftimemonthyear')), 'view.php?view=month'.$courseid.'&amp;', 1, $prevmonth, $prevyear);
a7c385e6 737 $content .= '<span class="hide"> | </span><span class="current">'.userdate($time, get_string('strftimemonthyear'))."</span>\n";
f21ed0f3 738 $content .= '<span class="hide"> | </span>'.calendar_get_link_next(userdate($nextdate, get_string('strftimemonthyear')), 'view.php?view=month'.$courseid.'&amp;', 1, $nextmonth, $nextyear);
f2de62da 739 $content .= "<span class=\"clearer\"><!-- --></span></div>\n";
7423f116 740 break;
741 case 'day':
742 $data['d'] = $date['mday']; // Just for convenience
5147ad48 743 $prevdate = usergetdate(make_timestamp($data['y'], $data['m'], $data['d'] - 1));
744 $nextdate = usergetdate(make_timestamp($data['y'], $data['m'], $data['d'] + 1));
f2bffd9e 745 $prevname = calendar_wday_name($CALENDARDAYS[$prevdate['wday']]);
746 $nextname = calendar_wday_name($CALENDARDAYS[$nextdate['wday']]);
a84dea2c 747 $content .= "\n".'<div class="calendar-controls">';
f21ed0f3 748 $content .= calendar_get_link_previous($prevname, 'view.php?view=day'.$courseid.'&amp;', $prevdate['mday'], $prevdate['mon'], $prevdate['year']);
e295df44 749
6e8e8ec6 750 // Get the format string
751 $text = get_string('strftimedaydate');
3477a900 752 /*
6e8e8ec6 753 // Regexp hackery to make a link out of the month/year part
754 $text = ereg_replace('(%B.+%Y|%Y.+%B|%Y.+%m[^ ]+)', '<a href="'.calendar_get_link_href('view.php?view=month&amp;', 1, $data['m'], $data['y']).'">\\1</a>', $text);
5147ad48 755 $text = ereg_replace('(F.+Y|Y.+F|Y.+m[^ ]+)', '<a href="'.calendar_get_link_href('view.php?view=month&amp;', 1, $data['m'], $data['y']).'">\\1</a>', $text);
3477a900 756 */
6e8e8ec6 757 // Replace with actual values and lose any day leading zero
3477a900 758 $text = userdate($time, $text);
6e8e8ec6 759 // Print the actual thing
a7c385e6 760 $content .= '<span class="hide"> | </span><span class="current">'.$text.'</span>';
6e8e8ec6 761
f21ed0f3 762 $content .= '<span class="hide"> | </span>'. calendar_get_link_next($nextname, 'view.php?view=day'.$courseid.'&amp;', $nextdate['mday'], $nextdate['mon'], $nextdate['year']);
f2de62da 763 $content .= "<span class=\"clearer\"><!-- --></span></div>\n";
7423f116 764 break;
765 }
766 return $content;
767}
768
b4892fa2 769function calendar_filter_controls($type, $vars = NULL, $course = NULL, $courses = NULL) {
43c3ffbe 770 global $CFG, $SESSION, $USER;
7423f116 771
48f508ab 772 $groupevents = true;
3cb9ee39 773 $getvars = '';
e295df44 774
7f4d18fc 775 $id = optional_param( 'id',0,PARAM_INT );
d715f7c4 776
34bf3ad4 777 switch($type) {
eb15f829 778 case 'event':
34bf3ad4 779 case 'upcoming':
34bf3ad4 780 case 'day':
c3f463ca 781 case 'month':
eb15f829 782 $getvars = '&amp;from='.$type;
34bf3ad4 783 break;
784 case 'course':
fac01360 785 if ($id > 0) {
7f4d18fc 786 $getvars = '&amp;from=course&amp;id='.$id;
2eb68e6f 787 } else {
788 $getvars = '&amp;from=course';
789 }
5a74ffd3 790 if (isset($course->groupmode) and $course->groupmode == NOGROUPS and $course->groupmodeforce) {
34bf3ad4 791 $groupevents = false;
792 }
793 break;
d715f7c4 794 }
34bf3ad4 795
3cb9ee39 796 if (!empty($vars)) {
34bf3ad4 797 $getvars .= '&amp;'.$vars;
48f508ab 798 }
7423f116 799
2ad2cbc3 800 $content = '<table>';
7423f116 801
48f508ab 802 $content .= '<tr>';
803 if($SESSION->cal_show_global) {
365cec3c 804 $content .= '<td class="eventskey event_global" style="width: 11px;"><img src="'.$CFG->pixpath.'/t/hide.gif" class="iconsmall" alt="'.get_string('hide').'" title="'.get_string('tt_hideglobal', 'calendar').'" style="cursor:pointer" onclick="location.href='."'".CALENDAR_URL.'set.php?var=showglobal'.$getvars."'".'" /></td>';
b4892fa2 805 $content .= '<td><a href="'.CALENDAR_URL.'set.php?var=showglobal'.$getvars.'" title="'.get_string('tt_hideglobal', 'calendar').'">'.get_string('global', 'calendar').'</a></td>'."\n";
fdbffa54 806 } else {
10b1d598 807 $content .= '<td style="width: 11px;"><img src="'.$CFG->pixpath.'/t/show.gif" class="iconsmall" alt="'.get_string('show').'" title="'.get_string('tt_showglobal', 'calendar').'" style="cursor:pointer" onclick="location.href='."'".CALENDAR_URL.'set.php?var=showglobal'.$getvars."'".'" /></td>';
b4892fa2 808 $content .= '<td><a href="'.CALENDAR_URL.'set.php?var=showglobal'.$getvars.'" title="'.get_string('tt_showglobal', 'calendar').'">'.get_string('global', 'calendar').'</a></td>'."\n";
48f508ab 809 }
e3bb6401 810 if($SESSION->cal_show_course) {
fdbffa54 811 $content .= '<td class="eventskey event_course" style="width: 11px;"><img src="'.$CFG->pixpath.'/t/hide.gif" class="iconsmall" alt="'.get_string('hide').'" title="'.get_string('tt_hidecourse', 'calendar').'" style="cursor:pointer" onclick="location.href='."'".CALENDAR_URL.'set.php?var=showcourses'.$getvars."'".'" /></td>';
812 $content .= '<td><a href="'.CALENDAR_URL.'set.php?var=showcourses'.$getvars.'" title="'.get_string('tt_hidecourse', 'calendar').'">'.get_string('course', 'calendar').'</a></td>'."\n";
813 } else {
814 $content .= '<td style="width: 11px;"><img src="'.$CFG->pixpath.'/t/show.gif" class="iconsmall" alt="'.get_string('hide').'" title="'.get_string('tt_showcourse', 'calendar').'" style="cursor:pointer" onclick="location.href='."'".CALENDAR_URL.'set.php?var=showcourses'.$getvars."'".'" /></td>';
815 $content .= '<td><a href="'.CALENDAR_URL.'set.php?var=showcourses'.$getvars.'" title="'.get_string('tt_showcourse', 'calendar').'">'.get_string('course', 'calendar').'</a></td>'."\n";
816
e3bb6401 817 }
48f508ab 818
b4892fa2 819
e3bb6401 820 if(!empty($USER->id) && !isguest()) {
821 $content .= "</tr>\n<tr>";
10b1d598 822
823 if($groupevents) {
43c3ffbe 824 // This course MIGHT have group events defined, so show the filter
825 if($SESSION->cal_show_groups) {
fdbffa54 826 $content .= '<td class="eventskey event_group" style="width: 11px;"><img src="'.$CFG->pixpath.'/t/hide.gif" class="iconsmall" alt="'.get_string('hide').'" title="'.get_string('tt_hidegroups', 'calendar').'" style="cursor:pointer" onclick="location.href='."'".CALENDAR_URL.'set.php?var=showgroups'.$getvars."'".'" /></td>';
827 $content .= '<td><a href="'.CALENDAR_URL.'set.php?var=showgroups'.$getvars.'" title="'.get_string('tt_hidegroups', 'calendar').'">'.get_string('group', 'calendar').'</a></td>'."\n";
e3bb6401 828 } else {
fdbffa54 829 $content .= '<td style="width: 11px;"><img src="'.$CFG->pixpath.'/t/show.gif" class="iconsmall" alt="'.get_string('show').'" title="'.get_string('tt_showgroups', 'calendar').'" style="cursor:pointer" onclick="location.href='."'".CALENDAR_URL.'set.php?var=showgroups'.$getvars."'".'" /></td>';
830 $content .= '<td><a href="'.CALENDAR_URL.'set.php?var=showgroups'.$getvars.'" title="'.get_string('tt_showgroups', 'calendar').'">'.get_string('group', 'calendar').'</a></td>'."\n";
43c3ffbe 831 }
e3bb6401 832 } else {
43c3ffbe 833 // This course CANNOT have group events, so lose the filter
5c53988f 834 $content .= '<td style="width: 11px;"></td><td>&nbsp;</td>'."\n";
fdbffa54 835 }
836 if($SESSION->cal_show_user) {
837 $content .= '<td class="eventskey event_user" style="width: 11px;"><img src="'.$CFG->pixpath.'/t/hide.gif" class="iconsmall" alt="'.get_string('hide').'" title="'.get_string('tt_hideuser', 'calendar').'" style="cursor:pointer" onclick="location.href='."'".CALENDAR_URL.'set.php?var=showuser'.$getvars."'".'" /></td>';
838 $content .= '<td><a href="'.CALENDAR_URL.'set.php?var=showuser'.$getvars.'" title="'.get_string('tt_hideuser', 'calendar').'">'.get_string('user', 'calendar').'</a></td>'."\n";
839 } else {
840 $content .= '<td style="width: 11px;"><img src="'.$CFG->pixpath.'/t/show.gif" class="iconsmall" alt="'.get_string('show').'" title="'.get_string('tt_showuser', 'calendar').'" style="cursor:pointer" onclick="location.href='."'".CALENDAR_URL.'set.php?var=showuser'.$getvars."'".'" /></td>';
841 $content .= '<td><a href="'.CALENDAR_URL.'set.php?var=showuser'.$getvars.'" title="'.get_string('tt_showuser', 'calendar').'">'.get_string('user', 'calendar').'</a></td>'."\n";
48f508ab 842 }
843 }
844 $content .= "</tr>\n</table>\n";
845
7423f116 846 return $content;
847}
848
849function calendar_day_representation($tstamp, $now = false, $usecommonwords = true) {
850
0ef7c973 851 static $shortformat;
852 if(empty($shortformat)) {
e70fdac0 853 $shortformat = get_string('strftimedayshort');
0ef7c973 854 }
855
7423f116 856 if($now === false) {
857 $now = time();
858 }
859
860 // To have it in one place, if a change is needed
e70fdac0 861 $formal = userdate($tstamp, $shortformat);
7423f116 862
7b38bfa6 863 $datestamp = usergetdate($tstamp);
864 $datenow = usergetdate($now);
7423f116 865
866 if($usecommonwords == false) {
867 // We don't want words, just a date
868 return $formal;
869 }
7b38bfa6 870 else if($datestamp['year'] == $datenow['year'] && $datestamp['yday'] == $datenow['yday']) {
7423f116 871 // Today
872 return get_string('today', 'calendar');
873 }
7b38bfa6 874 else if(
875 ($datestamp['year'] == $datenow['year'] && $datestamp['yday'] == $datenow['yday'] - 1 ) ||
876 ($datestamp['year'] == $datenow['year'] - 1 && $datestamp['mday'] == 31 && $datestamp['mon'] == 12 && $datenow['yday'] == 1)
877 ) {
7423f116 878 // Yesterday
879 return get_string('yesterday', 'calendar');
880 }
7b38bfa6 881 else if(
882 ($datestamp['year'] == $datenow['year'] && $datestamp['yday'] == $datenow['yday'] + 1 ) ||
883 ($datestamp['year'] == $datenow['year'] + 1 && $datenow['mday'] == 31 && $datenow['mon'] == 12 && $datestamp['yday'] == 1)
884 ) {
7423f116 885 // Tomorrow
886 return get_string('tomorrow', 'calendar');
887 }
888 else {
889 return $formal;
890 }
891}
892
893function calendar_time_representation($time) {
1b0ebe79 894 static $langtimeformat = NULL;
895 if($langtimeformat === NULL) {
896 $langtimeformat = get_string('strftimetime');
897 }
898 $timeformat = get_user_preferences('calendar_timeformat');
c7dd2550 899 if(empty($timeformat)){
900 $timeformat = get_config(NULL,'calendar_site_timeformat');
901 }
1b0ebe79 902 // The ? is needed because the preference might be present, but empty
903 return userdate($time, empty($timeformat) ? $langtimeformat : $timeformat);
7423f116 904}
905
e295df44 906/**
907 * TODO document
908 */
7423f116 909function calendar_get_link_href($linkbase, $d, $m, $y) {
910 if(empty($linkbase)) return '';
911 $paramstr = '';
912 if(!empty($d)) $paramstr .= '&amp;cal_d='.$d;
913 if(!empty($m)) $paramstr .= '&amp;cal_m='.$m;
914 if(!empty($y)) $paramstr .= '&amp;cal_y='.$y;
915 if(!empty($paramstr)) $paramstr = substr($paramstr, 5);
916 return $linkbase.$paramstr;
917}
918
e295df44 919/**
920 * TODO document
921 */
7423f116 922function calendar_get_link_tag($text, $linkbase, $d, $m, $y) {
923 $href = calendar_get_link_href($linkbase, $d, $m, $y);
924 if(empty($href)) return $text;
925 return '<a href="'.$href.'">'.$text.'</a>';
926}
927
a84dea2c 928/**
929 * Build and return a previous month HTML link, with an arrow.
930 * @param string $text The text label.
931 * @param string $linkbase The URL stub.
932 * @param int $d $m $y Day of month, month and year numbers.
933 * @param bool $accesshide Default visible, or hide from all except screenreaders.
934 * @return string HTML string.
935 */
936function calendar_get_link_previous($text, $linkbase, $d, $m, $y, $accesshide=false) {
937 $href = calendar_get_link_href($linkbase, $d, $m, $y);
938 if(empty($href)) return $text;
939 return link_arrow_left($text, $href, $accesshide, 'previous');
940}
941
942/**
943 * Build and return a next month HTML link, with an arrow.
944 * @param string $text The text label.
945 * @param string $linkbase The URL stub.
946 * @param int $d $m $y Day of month, month and year numbers.
947 * @param bool $accesshide Default visible, or hide from all except screenreaders.
948 * @return string HTML string.
949 */
950function calendar_get_link_next($text, $linkbase, $d, $m, $y, $accesshide=false) {
951 $href = calendar_get_link_href($linkbase, $d, $m, $y);
952 if(empty($href)) return $text;
953 return link_arrow_right($text, $href, $accesshide, 'next');
954}
955
7423f116 956function calendar_wday_name($englishname) {
957 return get_string(strtolower($englishname), 'calendar');
958}
959
960function calendar_days_in_month($month, $year) {
7b38bfa6 961 return intval(date('t', mktime(0, 0, 0, $month, 1, $year)));
7423f116 962}
963
e749554e 964function calendar_get_sideblock_upcoming($events, $linkhref = NULL) {
7423f116 965 $content = '';
966 $lines = count($events);
396b61f0 967 if (!$lines) {
968 return $content;
969 }
7423f116 970
396b61f0 971 for ($i = 0; $i < $lines; ++$i) {
b0ac9180 972 if (!isset($events[$i]->time)) { // Just for robustness
973 continue;
974 }
9df8ff44 975 $events[$i] = calendar_add_event_metadata($events[$i]);
ea21c1f4 976 $content .= '<div class="event"><span class="icon c0">'.$events[$i]->icon.'</span> ';
43c3ffbe 977 if (!empty($events[$i]->referer)) {
7423f116 978 // That's an activity event, so let's provide the hyperlink
396b61f0 979 $content .= $events[$i]->referer;
980 } else {
e749554e 981 if(!empty($linkhref)) {
982 $ed = usergetdate($events[$i]->timestart);
983 $href = calendar_get_link_href(CALENDAR_URL.$linkhref, $ed['mday'], $ed['mon'], $ed['year']);
53d8fac0 984 $content .= '<a href="'.$href.'#event_'.$events[$i]->id.'">'.$events[$i]->name.'</a>';
e749554e 985 }
986 else {
987 $content .= $events[$i]->name;
988 }
7423f116 989 }
9ecf051d 990 $events[$i]->time = str_replace('&raquo;', '<br />&raquo;', $events[$i]->time);
991 $content .= '<div class="date">'.$events[$i]->time.'</div></div>';
396b61f0 992 if ($i < $lines - 1) $content .= '<hr />';
7423f116 993 }
994
995 return $content;
7423f116 996}
997
998function calendar_add_month($month, $year) {
999 if($month == 12) {
1000 return array(1, $year + 1);
1001 }
1002 else {
1003 return array($month + 1, $year);
1004 }
1005}
1006
1007function calendar_sub_month($month, $year) {
1008 if($month == 1) {
1009 return array(12, $year - 1);
1010 }
1011 else {
1012 return array($month - 1, $year);
1013 }
1014}
1015
7c50db30 1016function calendar_events_by_day($events, $month, $year, &$eventsbyday, &$durationbyday, &$typesbyday, &$courses) {
7423f116 1017 $eventsbyday = array();
1018 $typesbyday = array();
1019 $durationbyday = array();
1020
1021 if($events === false) {
1022 return;
1023 }
1024
7423f116 1025 foreach($events as $event) {
7423f116 1026
7b38bfa6 1027 $startdate = usergetdate($event->timestart);
b4892fa2 1028 // Set end date = start date if no duration
1029 if ($event->timeduration) {
1030 $enddate = usergetdate($event->timestart + $event->timeduration - 1);
1031 } else {
1032 $enddate = $startdate;
1033 }
7423f116 1034
7b38bfa6 1035 // Simple arithmetic: $year * 13 + $month is a distinct integer for each distinct ($year, $month) pair
ef618501 1036 if(!($startdate['year'] * 13 + $startdate['mon'] <= $year * 13 + $month) && ($enddate['year'] * 13 + $enddate['mon'] >= $year * 13 + $month)) {
7b38bfa6 1037 // Out of bounds
1038 continue;
7423f116 1039 }
1040
7b38bfa6 1041 $eventdaystart = intval($startdate['mday']);
7423f116 1042
7b38bfa6 1043 if($startdate['mon'] == $month && $startdate['year'] == $year) {
1044 // Give the event to its day
1045 $eventsbyday[$eventdaystart][] = $event->id;
7423f116 1046
7b38bfa6 1047 // Mark the day as having such an event
9064751b 1048 if($event->courseid == SITEID && $event->groupid == 0) {
7b38bfa6 1049 $typesbyday[$eventdaystart]['startglobal'] = true;
b4892fa2 1050 // Set event class for global event
1051 $events[$event->id]->class = 'event_global';
7b38bfa6 1052 }
c3d3b6d4 1053 else if($event->courseid != 0 && $event->courseid != SITEID && $event->groupid == 0) {
7b38bfa6 1054 $typesbyday[$eventdaystart]['startcourse'] = true;
b4892fa2 1055 // Set event class for course event
9b50bd46 1056 $events[$event->id]->class = 'event_course';
7b38bfa6 1057 }
1058 else if($event->groupid) {
1059 $typesbyday[$eventdaystart]['startgroup'] = true;
b4892fa2 1060 // Set event class for group event
1061 $events[$event->id]->class = 'event_group';
7b38bfa6 1062 }
1063 else if($event->userid) {
1064 $typesbyday[$eventdaystart]['startuser'] = true;
b4892fa2 1065 // Set event class for user event
1066 $events[$event->id]->class = 'event_user';
7b38bfa6 1067 }
1068 }
7423f116 1069
7b38bfa6 1070 if($event->timeduration == 0) {
1071 // Proceed with the next
1072 continue;
1073 }
7423f116 1074
7b38bfa6 1075 // The event starts on $month $year or before. So...
ef618501 1076 $lowerbound = $startdate['mon'] == $month && $startdate['year'] == $year ? intval($startdate['mday']) : 0;
7b38bfa6 1077
1078 // Also, it ends on $month $year or later...
1079 $upperbound = $enddate['mon'] == $month && $enddate['year'] == $year ? intval($enddate['mday']) : calendar_days_in_month($month, $year);
1080
1081 // Mark all days between $lowerbound and $upperbound (inclusive) as duration
1082 for($i = $lowerbound + 1; $i <= $upperbound; ++$i) {
1083 $durationbyday[$i][] = $event->id;
9064751b 1084 if($event->courseid == SITEID && $event->groupid == 0) {
7b38bfa6 1085 $typesbyday[$i]['durationglobal'] = true;
1086 }
c3d3b6d4 1087 else if($event->courseid != 0 && $event->courseid != SITEID && $event->groupid == 0) {
7b38bfa6 1088 $typesbyday[$i]['durationcourse'] = true;
1089 }
1090 else if($event->groupid) {
1091 $typesbyday[$i]['durationgroup'] = true;
1092 }
1093 else if($event->userid) {
1094 $typesbyday[$i]['durationuser'] = true;
7423f116 1095 }
1096 }
7b38bfa6 1097
7423f116 1098 }
1099 return;
1100}
1101
b63c0ee5 1102function calendar_get_module_cached(&$coursecache, $modulename, $instance) {
1103 $module = get_coursemodule_from_instance($modulename, $instance);
7423f116 1104
1105 if($module === false) return false;
b63c0ee5 1106 if(!calendar_get_course_cached($coursecache, $module->course)) {
7423f116 1107 return false;
1108 }
1109 return $module;
1110}
1111
1112function calendar_get_course_cached(&$coursecache, $courseid) {
b571c6b3 1113 global $COURSE;
1114 if (!isset($coursecache[$courseid])) {
1115 if ($courseid == $COURSE->id) {
1116 $coursecache[$courseid] = $COURSE;
1117 } else {
1118 $coursecache[$courseid] = get_record('course', 'id', $courseid);
1119 }
7423f116 1120 }
1121 return $coursecache[$courseid];
1122}
1123
1124function calendar_session_vars() {
1125 global $SESSION, $USER;
1126
1066e0dc 1127 if(!empty($USER->id) && isset($USER->realuser) && !isset($SESSION->cal_loggedinas)) {
02ce3848 1128 // We just logged in as someone else, update the filtering
1129 unset($SESSION->cal_users_shown);
1130 unset($SESSION->cal_courses_shown);
1131 $SESSION->cal_loggedinas = true;
054193be 1132 if(intval(get_user_preferences('calendar_persistflt', 0))) {
1133 calendar_set_filters_status(get_user_preferences('calendar_savedflt', 0xff));
1134 }
02ce3848 1135 }
1066e0dc 1136 else if(!empty($USER->id) && !isset($USER->realuser) && isset($SESSION->cal_loggedinas)) {
02ce3848 1137 // We just logged back to our real self, update again
1138 unset($SESSION->cal_users_shown);
1139 unset($SESSION->cal_courses_shown);
1140 unset($SESSION->cal_loggedinas);
054193be 1141 if(intval(get_user_preferences('calendar_persistflt', 0))) {
1142 calendar_set_filters_status(get_user_preferences('calendar_savedflt', 0xff));
1143 }
02ce3848 1144 }
1145
7423f116 1146 if(!isset($SESSION->cal_course_referer)) {
1147 $SESSION->cal_course_referer = 0;
1148 }
1149 if(!isset($SESSION->cal_show_global)) {
1150 $SESSION->cal_show_global = true;
1151 }
1152 if(!isset($SESSION->cal_show_groups)) {
1153 $SESSION->cal_show_groups = true;
1154 }
1155 if(!isset($SESSION->cal_show_course)) {
1156 $SESSION->cal_show_course = true;
1157 }
1158 if(!isset($SESSION->cal_show_user)) {
89adb174 1159 $SESSION->cal_show_user = true;
7423f116 1160 }
f21ed0f3 1161 // if(empty($SESSION->cal_courses_shown)) {
43c3ffbe 1162 $SESSION->cal_courses_shown = calendar_get_default_courses(true);
f21ed0f3 1163 //}
89adb174 1164 if(empty($SESSION->cal_users_shown)) {
1165 // The empty() instead of !isset() here makes a whole world of difference,
1166 // as it will automatically change to the user's id when the user first logs
1167 // in. With !isset(), it would never do that.
86a1ba04 1168 $SESSION->cal_users_shown = !empty($USER->id) ? $USER->id : false;
89adb174 1169 }
1170 else if(is_numeric($SESSION->cal_users_shown) && !empty($USER->id) && $SESSION->cal_users_shown != $USER->id) {
1171 // Follow the white rabbit, for example if a teacher logs in as a student
1172 $SESSION->cal_users_shown = $USER->id;
1173 }
7423f116 1174}
1175
1176function calendar_overlib_html() {
9c6bf80e 1177 return '<div id="overDiv" style="position: absolute; visibility: hidden; z-index:1000;"></div>'
1178 .'<script type="text/javascript" src="'.CALENDAR_URL.'overlib.cfg.php"></script>';
7423f116 1179}
1180
7423f116 1181function calendar_set_referring_course($courseid) {
1182 global $SESSION;
1183 $SESSION->cal_course_referer = intval($courseid);
1184}
1185
43c3ffbe 1186function calendar_set_filters(&$courses, &$group, &$user, $courseeventsfrom = NULL, $groupeventsfrom = NULL, $ignorefilters = false) {
257e3f4c 1187 global $SESSION, $USER, $CFG;
1188
43c3ffbe 1189 // Insidious bug-wannabe: setting $SESSION->cal_courses_shown to $course->id would cause
51f8a12f 1190 // the code to function incorrectly UNLESS we convert it to an integer. One case where
1191 // PHP's loose type system works against us.
43c3ffbe 1192 if(is_string($SESSION->cal_courses_shown)) {
1193 $SESSION->cal_courses_shown = intval($SESSION->cal_courses_shown);
51f8a12f 1194 }
43c3ffbe 1195 if($courseeventsfrom === NULL) {
d12e3ff2 1196 $courseeventsfrom = $SESSION->cal_courses_shown;
1197 }
1198
1199 // MDL-9059, $courseeventsfrom can be an int, or an array of ints, or an array of course objects
1200 // convert all to array of objects
1201 // we probably should do some clean up and make sure that session is set to use the proper form
1202 if (is_int($courseeventsfrom)) { // case of an int, e.g. calendar view page
1203 $c = array();
1204 $c[$courseeventsfrom] = get_record('course', 'id', $courseeventsfrom);
1205 $courseeventsfrom = $c;
1206 } else if (is_array($courseeventsfrom)) { // case of an array of ints, e.g. course home page
1207 foreach ($courseeventsfrom as $i=>$courseid) {
1208 if (is_int($courseid)) {
1209 $courseeventsfrom[$i] = get_record('course', 'id', $courseid);
1210 }
1211 }
7423f116 1212 }
d12e3ff2 1213
43c3ffbe 1214 if($groupeventsfrom === NULL) {
1215 $groupeventsfrom = $SESSION->cal_courses_shown;
7423f116 1216 }
1217
43c3ffbe 1218 if(($SESSION->cal_show_course && $SESSION->cal_show_global) || $ignorefilters) {
1219 if(is_int($courseeventsfrom)) {
9064751b 1220 $courses = array(SITEID, $courseeventsfrom);
7423f116 1221 }
43c3ffbe 1222 else if(is_array($courseeventsfrom)) {
1223 $courses = array_keys($courseeventsfrom);
9064751b 1224 $courses[] = SITEID;
7423f116 1225 }
1226 }
43c3ffbe 1227 else if($SESSION->cal_show_course) {
1228 if(is_int($courseeventsfrom)) {
1229 $courses = array($courseeventsfrom);
7423f116 1230 }
43c3ffbe 1231 else if(is_array($courseeventsfrom)) {
1232 $courses = array_keys($courseeventsfrom);
7423f116 1233 }
e749554e 1234 $courses = array_diff($courses, array(SITEID));
7423f116 1235 }
1236 else if($SESSION->cal_show_global) {
e749554e 1237 $courses = array(SITEID);
7423f116 1238 }
1239 else {
1240 $courses = false;
1241 }
e295df44 1242 //BUG 6130 clean $courses array as SESSION has bad entries.
0e6a8f4b 1243 // [pj] TODO: See if this has to do with my new change in get_default_courses and can be taken out
1384da1e 1244 if (is_array($courses)) {
1245 foreach ($courses as $index => $value) {
1246 if (empty($value)) unset($courses[$index]);
1247 }
7c50db30 1248
1249 // Sort courses for consistent colour highlighting
1250 // Effectively ignoring SITEID as setting as last course id
1251 $key = array_search(SITEID, $courses);
1252 if ($key !== false) {
1253 unset($courses[$key]);
1254 sort($courses);
1255 $courses[] = SITEID;
1256 } else {
1257 sort($courses);
1258 }
0e6a8f4b 1259 }
7423f116 1260
43c3ffbe 1261 if($SESSION->cal_show_user || $ignorefilters) {
89adb174 1262 // This doesn't work for arrays yet (maybe someday it will)
1263 $user = $SESSION->cal_users_shown;
7423f116 1264 }
1265 else {
1266 $user = false;
1267 }
43c3ffbe 1268 if($SESSION->cal_show_groups || $ignorefilters) {
1269 if(is_int($groupeventsfrom)) {
1270 $groupcourses = array($groupeventsfrom);
7423f116 1271 }
43c3ffbe 1272 else if(is_array($groupeventsfrom)) {
1273 $groupcourses = array_keys($groupeventsfrom);
1274 }
257e3f4c 1275
9c37662f 1276 // XXX TODO: not sure how to replace $CFG->calendar_adminseesall
1277 if(has_capability('moodle/calendar:manageentries', get_context_instance(CONTEXT_SYSTEM, SITEID)) && !empty($CFG->calendar_adminseesall)) {
257e3f4c 1278 $group = true;
1279 }
1280 else {
1281 $grouparray = array();
69762501 1282
257e3f4c 1283 // We already have the courses to examine in $courses
1284 // For each course...
37d87d11 1285
257e3f4c 1286 foreach($groupcourses as $courseid) {
69762501 1287
37875ac5 1288 if (!isset($courseeventsfrom[$courseid]->context)) { // SHOULD be set MDL-11221
8397874d 1289 if (is_object($courseeventsfrom[$courseid])) {
1290 $courseeventsfrom[$courseid]->context = get_context_instance(CONTEXT_COURSE, $courseid);
1291 }
37875ac5 1292 }
1293
257e3f4c 1294 // If the user is an editing teacher in there,
edeed697 1295 if (!empty($USER->id) && isset($courseeventsfrom[$courseid]->context) && has_capability('moodle/calendar:manageentries', $courseeventsfrom[$courseid]->context)) {
69762501 1296 // If this course has groups, show events from all of them
b8227b88 1297 if(is_int($groupeventsfrom)) {
37875ac5 1298 if (is_object($courseeventsfrom[$courseid])) { // SHOULD be set MDL-11221
1299 $courserecord = $courseeventsfrom[$courseid];
1300 } else {
1301 $courserecord = get_record('course', 'id', $courseid);
1302 }
b8227b88 1303 $courserecord = get_record('course', 'id', $courseid);
1304 if ($courserecord->groupmode != NOGROUPS || !$courserecord->groupmodeforce) {
1305 $groupids[] = $courseid;
1306 }
1307 }
1308 else if(isset($SESSION->cal_courses_shown[$courseid]) && ($SESSION->cal_courses_shown[$courseid]->groupmode != NOGROUPS || !$SESSION->cal_courses_shown[$courseid]->groupmodeforce)) {
37d87d11 1309 $groupids[] = $courseid;
257e3f4c 1310 }
1311 }
69762501 1312
1313 // Otherwise (not editing teacher) show events from the group he is a member of
257e3f4c 1314 else if(isset($USER->groupmember[$courseid])) {
fa22fd5f 1315 //changed to 2D array
1316 foreach ($USER->groupmember[$courseid] as $groupid){
1317 $grouparray[] = $groupid;
1318 }
7423f116 1319 }
1320 }
e295df44 1321
6b4aeb31 1322 if (!empty($groupids)) {
f6ee5e04 1323 $sql = "SELECT *
2524b0f2 1324 FROM {$CFG->prefix}groups
6b4aeb31 1325 WHERE courseid IN (".implode(',', $groupids).')';
e295df44 1326
6b4aeb31 1327 if ($grouprecords= get_records_sql($sql)) {
f6ee5e04 1328 foreach ($grouprecords as $grouprecord) {
1329 $grouparray[] = $grouprecord->id;
1330 }
6b4aeb31 1331 }
1332 }
e295df44 1333
257e3f4c 1334 if(empty($grouparray)) {
1335 $group = false;
1336 }
1337 else {
1338 $group = $grouparray;
6c9584d1 1339 }
7423f116 1340 }
e295df44 1341
7423f116 1342 }
1343 else {
1344 $group = false;
1345 }
1346}
1347
1348function calendar_edit_event_allowed($event) {
e295df44 1349
7423f116 1350 global $USER;
1351
89491dbd 1352 // can not be using guest account
1353 if ($USER->username == "guest") {
e295df44 1354 return false;
89491dbd 1355 }
e295df44 1356
89491dbd 1357 $sitecontext = get_context_instance(CONTEXT_SYSTEM, SITEID);
1358 // if user has manageentries at site level, return true
28ee98c5 1359 if (has_capability('moodle/calendar:manageentries', $sitecontext)) {
89491dbd 1360 return true;
f52f7413 1361 }
e295df44 1362
c0a2c361 1363 // if groupid is set, it's definitely a group event
1364 if ($event->groupid) {
f63d2922 1365 // Allow users to add/edit group events if:
1366 // 1) They have manageentries (= entries for whole course)
1367 // 2) They have managegroupentries AND are in the group
1368 $group = get_record('groups', 'id', $event->groupid);
1369 return $group && (
1370 has_capability('moodle/calendar:manageentries', get_context_instance(CONTEXT_COURSE, $group->courseid)) ||
1371 (has_capability('moodle/calendar:managegroupentries', get_context_instance(CONTEXT_COURSE, $group->courseid))
1372 && groups_is_member($event->groupid)));
89491dbd 1373 } else if ($event->courseid) {
c0a2c361 1374 // if groupid is not set, but course is set,
1375 // it's definiely a course event
e295df44 1376 return has_capability('moodle/calendar:manageentries', get_context_instance(CONTEXT_COURSE, $event->courseid));
1377 } else if ($event->userid && $event->userid == $USER->id) {
c0a2c361 1378 // if course is not set, but userid id set, it's a user event
1379 return (has_capability('moodle/calendar:manageownentries', $sitecontext));
e295df44 1380 }
7423f116 1381 return false;
1382}
1383
8c54cec6 1384function calendar_get_default_courses($ignoreref = false) {
9ff136e5 1385 global $USER, $CFG, $SESSION;
1386
8c54cec6 1387 if(!empty($SESSION->cal_course_referer) && !$ignoreref) {
4c7d1137 1388 return array($SESSION->cal_course_referer => 1);
9ff136e5 1389 }
7423f116 1390
1066e0dc 1391 if(empty($USER->id)) {
2ef75eee 1392 return array();
1393 }
1394
7423f116 1395 $courses = array();
03bb25e1 1396 if (has_capability('moodle/calendar:manageentries', get_context_instance(CONTEXT_SYSTEM, SITEID))) {
1397 if (!empty($CFG->calendar_adminseesall)) {
86f092d2 1398 $courses = get_records_sql('SELECT id, 1 FROM '.$CFG->prefix.'course');
1399 return $courses;
1400 }
95a89225 1401 }
e295df44 1402
daaf61f4 1403 if (isset($CFG->adminseesall)) {
e3fc108e 1404 $courses = get_my_courses($USER->id, null, null, $CFG->adminseesall);
daaf61f4 1405 }
1406 else {
e3fc108e 1407 $courses = get_my_courses($USER->id, null, null, false);
7423f116 1408 }
37d87d11 1409
1410 return $courses;
7423f116 1411}
1412
1e1ff33b 1413function calendar_preferences_button() {
1414 global $CFG, $USER;
7423f116 1415
1416 // Guests have no preferences
f52f7413 1417 if (empty($USER->id) || isguest()) {
7423f116 1418 return '';
1419 }
1420
fa738731 1421 return "<form $CFG->frametarget method=\"get\" ".
1e1ff33b 1422 " action=\"$CFG->wwwroot/calendar/preferences.php\">".
2aab6488 1423 "<div><input type=\"submit\" value=\"".get_string("preferences", "calendar")." ...\" /></div></form>";
7423f116 1424}
1425
b4892fa2 1426function calendar_format_event_time($event, $now, $morehref, $usecommonwords = true, $showtime=0) {
8f896582 1427 $startdate = usergetdate($event->timestart);
1428 $enddate = usergetdate($event->timestart + $event->timeduration);
1429 $usermidnightstart = usergetmidnight($event->timestart);
1430
1431 if($event->timeduration) {
1432 // To avoid doing the math if one IF is enough :)
1433 $usermidnightend = usergetmidnight($event->timestart + $event->timeduration);
1434 }
1435 else {
1436 $usermidnightend = $usermidnightstart;
1437 }
1438
1439 // OK, now to get a meaningful display...
1440 // First of all we have to construct a human-readable date/time representation
1441
b4892fa2 1442 if($event->timeduration) {
8f896582 1443 // It has a duration
b4892fa2 1444 if($usermidnightstart == $usermidnightend ||
1445 ($event->timestart == $usermidnightstart) && ($event->timeduration == 86400 || $event->timeduration == 86399) ||
1446 ($event->timestart + $event->timeduration <= $usermidnightstart + 86400)) {
8f896582 1447 // But it's all on the same day
8f896582 1448 $timestart = calendar_time_representation($event->timestart);
1449 $timeend = calendar_time_representation($event->timestart + $event->timeduration);
b4892fa2 1450 $time = $timestart.' <strong>&raquo;</strong> '.$timeend;
1451
1452 if ($event->timestart == $usermidnightstart && ($event->timeduration == 86400 || $event->timeduration == 86399)) {
1453 $time = get_string('allday', 'calendar');
1454 }
8f896582 1455
1456 // Set printable representation
b4892fa2 1457 if (!$showtime) {
1458 $day = calendar_day_representation($event->timestart, $now, $usecommonwords);
1459 $eventtime = calendar_get_link_tag($day, CALENDAR_URL.'view.php?view=day'.$morehref.'&amp;', $enddate['mday'], $enddate['mon'], $enddate['year']).', '.$time;
1460 } else {
1461 $eventtime = $time;
1462 }
1463 } else {
8f896582 1464 // It spans two or more days
b4892fa2 1465 $daystart = calendar_day_representation($event->timestart, $now, $usecommonwords).', ';
1466 if ($showtime == $usermidnightstart) {
1467 $daystart = '';
1468 }
8f896582 1469 $timestart = calendar_time_representation($event->timestart);
b4892fa2 1470 $dayend = calendar_day_representation($event->timestart + $event->timeduration, $now, $usecommonwords).', ';
1471 if ($showtime == $usermidnightend) {
1472 $dayend = '';
1473 }
8f896582 1474 $timeend = calendar_time_representation($event->timestart + $event->timeduration);
1475
1476 // Set printable representation
b4892fa2 1477 if ($now >= $usermidnightstart && $now < ($usermidnightstart + 86400)) {
1478 $eventtime = $timestart.' <strong>&raquo;</strong> '.calendar_get_link_tag($dayend, CALENDAR_URL.'view.php?view=day'.$morehref.'&amp;', $enddate['mday'], $enddate['mon'], $enddate['year']).
1479 $timeend;
1480 } else {
1481 $eventtime = calendar_get_link_tag($daystart, CALENDAR_URL.'view.php?view=day'.$morehref.'&amp;', $startdate['mday'], $startdate['mon'], $startdate['year']).
1482 $timestart.' <strong>&raquo;</strong> '.calendar_get_link_tag($dayend, CALENDAR_URL.'view.php?view=day'.$morehref.'&amp;', $enddate['mday'], $enddate['mon'], $enddate['year']).
1483 $timeend;
1484 }
8f896582 1485 }
b4892fa2 1486 } else {
1c4bedd7 1487 $time = ' ';
8f896582 1488
1489 // Set printable representation
b4892fa2 1490 if (!$showtime) {
1491 $day = calendar_day_representation($event->timestart, $now, $usecommonwords);
1492 $eventtime = calendar_get_link_tag($day, CALENDAR_URL.'view.php?view=day'.$morehref.'&amp;', $startdate['mday'], $startdate['mon'], $startdate['year']).trim($time);
1493 } else {
1494 $eventtime = $time;
1495 }
1496 }
1497
1498 if($event->timestart + $event->timeduration < $now) {
1499 // It has expired
1500 $eventtime = '<span class="dimmed_text">'.str_replace(' href=', ' class="dimmed" href=', $eventtime).'</span>';
8f896582 1501 }
09d36284 1502
8f896582 1503 return $eventtime;
1504}
054193be 1505
86f092d2 1506function calendar_print_month_selector($name, $selected) {
e295df44 1507
86f092d2 1508 $months = array();
1509
1510 for ($i=1; $i<=12; $i++) {
76ab1c33 1511 $months[$i] = userdate(gmmktime(12, 0, 0, $i, 15, 2000), '%B');
86f092d2 1512 }
1513
1514 choose_from_menu($months, $name, $selected, '');
1515}
1516
054193be 1517function calendar_get_filters_status() {
1518 global $SESSION;
1519
1520 $status = 0;
1521 if($SESSION->cal_show_global) {
1522 $status += 1;
1523 }
1524 if($SESSION->cal_show_course) {
1525 $status += 2;
1526 }
1527 if($SESSION->cal_show_groups) {
1528 $status += 4;
1529 }
1530 if($SESSION->cal_show_user) {
1531 $status += 8;
1532 }
1533 return $status;
1534}
1535
1536function calendar_set_filters_status($packed_bitfield) {
1537 global $SESSION, $USER;
1538
1539 if(!isset($USER) || empty($USER->id)) {
1540 return false;
1541 }
1542
1543 $SESSION->cal_show_global = ($packed_bitfield & 1);
1544 $SESSION->cal_show_course = ($packed_bitfield & 2);
e295df44 1545 $SESSION->cal_show_groups = ($packed_bitfield & 4);
054193be 1546 $SESSION->cal_show_user = ($packed_bitfield & 8);
1547
1548 return true;
1549}
1550
86ac8b24 1551function calendar_get_allowed_types(&$allowed) {
1552 global $USER, $CFG, $SESSION;
1553 $sitecontext = get_context_instance(CONTEXT_SYSTEM);
1554 $allowed->user = has_capability('moodle/calendar:manageownentries', $sitecontext);
1555 $allowed->groups = false; // This may change just below
1556 $allowed->courses = false; // This may change just below
1557 $allowed->site = has_capability('moodle/calendar:manageentries', get_context_instance(CONTEXT_COURSE, SITEID));
1558
f63d2922 1559 if(!empty($SESSION->cal_course_referer) && $SESSION->cal_course_referer != SITEID) {
86ac8b24 1560 $course = get_record('course', 'id', $SESSION->cal_course_referer);
f63d2922 1561 $coursecontext = get_context_instance(CONTEXT_COURSE, $SESSION->cal_course_referer);
86ac8b24 1562
f63d2922 1563 if(has_capability('moodle/calendar:manageentries', $coursecontext)) {
1564 $allowed->courses = array($course->id => 1);
1565
1566 if($course->groupmode != NOGROUPS || !$course->groupmodeforce) {
1567 $allowed->groups = groups_get_all_groups($SESSION->cal_course_referer);
1568 }
1569 } else if(has_capability('moodle/calendar:managegroupentries', $coursecontext)) {
1570 if($course->groupmode != NOGROUPS || !$course->groupmodeforce) {
1571 $allowed->groups = groups_get_all_groups($SESSION->cal_course_referer, $USER->id);
1572 }
86ac8b24 1573 }
1574 }
1575}
1576
1577/**
1578 * see if user can add calendar entries at all
1579 * used to print the "New Event" button
1580 * @return bool
1581 */
1582function calendar_user_can_add_event() {
1583 calendar_get_allowed_types($allowed);
e295df44 1584 return (bool)($allowed->user || $allowed->groups || $allowed->courses || $allowed->site);
86ac8b24 1585}
d0a32914 1586?>