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