]> git.mjollnir.org Git - moodle.git/commitdiff
Checking in latest calendar code! Looking great, Jon!
authormoodler <moodler>
Mon, 29 Mar 2004 15:28:15 +0000 (15:28 +0000)
committermoodler <moodler>
Mon, 29 Mar 2004 15:28:15 +0000 (15:28 +0000)
calendar/event.php [new file with mode: 0644]
calendar/event_delete.html [new file with mode: 0644]
calendar/event_edit.html [new file with mode: 0644]
calendar/event_new.html [new file with mode: 0644]
calendar/event_select.html [new file with mode: 0644]
calendar/lib.php [new file with mode: 0644]
calendar/overlib.cfg.php [new file with mode: 0644]
calendar/preferences.php [new file with mode: 0644]
calendar/set.php [new file with mode: 0644]
calendar/view.php [new file with mode: 0644]

diff --git a/calendar/event.php b/calendar/event.php
new file mode 100644 (file)
index 0000000..4fa0a14
--- /dev/null
@@ -0,0 +1,479 @@
+<?php // $Id$
+
+/////////////////////////////////////////////////////////////////////////////
+//                                                                         //
+// NOTICE OF COPYRIGHT                                                     //
+//                                                                         //
+// Moodle - Calendar extension                                             //
+//                                                                         //
+// Copyright (C) 2003-2004  Greek School Network            www.sch.gr     //
+//                                                                         //
+// Designed by:                                                            //
+//     Avgoustos Tsinakos (tsinakos@uom.gr)                                //
+//     Jon Papaioannou (pj@uom.gr)                                         //
+//                                                                         //
+// Programming and development:                                            //
+//     Jon Papaioannou (pj@uom.gr)                                         //
+//                                                                         //
+// For bugs, suggestions, etc contact:                                     //
+//     Jon Papaioannou (pj@uom.gr)                                         //
+//                                                                         //
+// The current module was developed at the University of Macedonia         //
+// (www.uom.gr) under the funding of the Greek School Network (www.sch.gr) //
+// The aim of this project is to provide additional and improved           //
+// functionality to the Asynchronous Distance Education service that the   //
+// Greek School Network deploys.                                           //
+//                                                                         //
+// This program is free software; you can redistribute it and/or modify    //
+// it under the terms of the GNU General Public License as published by    //
+// the Free Software Foundation; either version 2 of the License, or       //
+// (at your option) any later version.                                     //
+//                                                                         //
+// This program is distributed in the hope that it will be useful,         //
+// but WITHOUT ANY WARRANTY; without even the implied warranty of          //
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the           //
+// GNU General Public License for more details:                            //
+//                                                                         //
+//          http://www.gnu.org/copyleft/gpl.html                           //
+//                                                                         //
+/////////////////////////////////////////////////////////////////////////////
+
+    require_once('../config.php');
+    require_once('lib.php');
+    require_once('../course/lib.php');
+    require_once('../mod/forum/lib.php');
+
+    require_login();
+
+    if(isguest()) {
+        // Guests cannot do anything with events
+        redirect(CALENDAR_URL.'view.php?view=upcoming');
+    }
+
+    require_variable($_REQUEST['action']);
+    optional_variable($_REQUEST['id']);
+    $_REQUEST['id'] = intval($_REQUEST['id']); // Always a good idea, against SQL injections
+
+    if(!$site = get_site()) {
+        redirect($CFG->wwwroot.'/'.$CFG->admin.'/index.php');
+    }
+
+    $firstcolumn = false;  // for now
+    $side = 175;
+
+    calendar_session_vars();
+    $now = usergetdate(time());
+    $nav = calendar_get_link_tag(get_string('calendar', 'calendar'), CALENDAR_URL.'view.php?view=upcoming&amp;', $now['mday'], $now['mon'], $now['year']);
+
+    // Minor hack to default to FORMAT_MOODLE and no html editor for now
+    // maybe in the future...
+
+    if ($usehtmleditor = can_use_richtext_editor() && false) {
+        $defaultformat = FORMAT_HTML;
+    } else {
+        $defaultformat = FORMAT_MOODLE;
+    }
+
+    switch($_REQUEST['action']) {
+        case 'delete':
+            $title = get_string('deleteevent', 'calendar');
+            $event = get_record('event', 'id', $_REQUEST['id']);
+            if($event === false) {
+                error('Invalid event');
+            }
+            if(!calendar_edit_event_allowed($event)) {
+                error('You are not authorized to do this');
+            }
+        break;
+
+        case 'edit':
+            $title = get_string('editevent', 'calendar');
+            $event = get_record('event', 'id', $_REQUEST['id']);
+            if($event === false) {
+                error('Invalid event');
+            }
+            if(!calendar_edit_event_allowed($event)) {
+                error('You are not authorized to do this');
+            }
+
+            if($form = data_submitted()) {
+
+                $form->name = strip_tags($form->name);  // Strip all tags
+                $form->description = strip_tags($form->description);  // Strip all tags
+                //$form->description = clean_text($form->description , $form->format);   // Clean up any bad tags
+
+                $form->timestart = make_timestamp($form->startyr, $form->startmon, $form->startday, $form->starthr, $form->startmin);
+                if($form->duration == 1) {
+                    $form->timeduration = make_timestamp($form->endyr, $form->endmon, $form->endday, $form->endhr, $form->endmin) - $form->timestart;
+                    if($form->timeduration < 0) {
+                        $form->timeduration = 0;
+                    }
+                }
+                else {
+                    $form->timeduration = 0;
+                }
+                validate_form($form, $err);
+                if (count($err) == 0) {
+                    $form->timemodified = time();
+                    update_record('event', $form);
+
+                    /// Log the event update.
+                    add_to_log($form->courseid, 'calendar', 'edit', 'event.php?action=edit&amp;id='.$form->id, $form->name);
+
+                    // OK, now redirect to day view
+                    redirect(CALENDAR_URL.'view.php?view=day&cal_d='.$form->startday.'&cal_m='.$form->startmon.'&cal_y='.$form->startyr);
+                }
+                else {
+                    foreach ($err as $key => $value) {
+                        $focus = "form.$key";
+                    }
+                }
+            }
+        break;
+
+        case 'new':
+            $title = get_string('newevent', 'calendar');
+            $form = data_submitted();
+            if(!empty($form) && $form->type == 'defined') {
+
+                $form->name = strip_tags($form->name);  // Strip all tags
+                $form->description = strip_tags($form->description);  // Strip all tags
+                //$form->description = clean_text($form->description , $form->format);   // Clean up any bad tags
+
+                $form->timestart = make_timestamp($form->startyr, $form->startmon, $form->startday, $form->starthr, $form->startmin);
+                if($form->duration == 1) {
+                    $form->timeduration = make_timestamp($form->endyr, $form->endmon, $form->endday, $form->endhr, $form->endmin) - $form->timestart;
+                    if($form->timeduration < 0) {
+                        $form->timeduration = 0;
+                    }
+                }
+                else {
+                    $form->timeduration = 0;
+                }
+                if(!calendar_add_event_allowed($form->courseid, $form->groupid, $form->userid)) {
+                    error('You are not authorized to do this');
+                }
+                validate_form($form, $err);
+                if (count($err) == 0) {
+                    $form->timemodified = time();
+
+                    /// Get the event id for the log record.
+                    $eventid = insert_record('event', $form, true);
+
+                    /// Log the event entry.
+                    add_to_log($form->courseid, 'calendar', 'add', 'event.php?action=edit&amp;id='.$eventid, $form->name);
+
+                    // OK, now redirect to day view
+                    redirect(CALENDAR_URL.'view.php?view=day&cal_d='.$form->startday.'&cal_m='.$form->startmon.'&cal_y='.$form->startyr);
+                }
+                else {
+                    foreach ($err as $key => $value) {
+                        $focus = "form.$key";
+                    }
+                }
+            }
+        break;
+    }
+    if(empty($focus)) $focus = '';
+
+    // Let's see if we are supposed to provide a referring course link
+    // but NOT for the front page
+    if($SESSION->cal_course_referer > 1 &&
+      ($shortname = get_field('course', 'shortname', 'id', $SESSION->cal_course_referer)) !== false) {
+        // If we know about the referring course, show a return link
+        $nav = '<a href="'.$CFG->wwwroot.'/course/view.php?id='.$SESSION->cal_course_referer.'">'.$shortname.'</a> -> '.$nav;
+    }
+
+    print_header(get_string('calendar', 'calendar').': '.$title, $site->fullname, $nav.' -> '.$title,
+                 $focus, '', true, '', '<p class="logininfo">'.user_login_string($site).'</p>');
+
+    /// Layout the whole page as three big columns.
+    echo '<table border="0" cellpadding="3" cellspacing="0" width="100%"><tr valign="top">';
+
+    $sections = get_all_sections($site->id);
+
+    if ($site->newsitems > 0 or $sections[0]->sequence or isediting($site->id) or isadmin()) {
+        echo "<td width=\"$side\" valign='top nowrap'>";
+        $firstcolumn=true;
+
+        if ($sections[0]->sequence or isediting($site->id)) {
+            get_all_mods($site->id, $mods, $modnames, $modnamesplural, $modnamesused);
+            print_section_block(get_string("mainmenu"), $site, $sections[0],
+                                 $mods, $modnames, $modnamesused, true, $side);
+        }
+
+    print_courses_sideblock(0, $side);
+        if ($site->newsitems) {
+            if ($news = forum_get_course_forum($site->id, "news")) {
+                print_side_block_start(get_string("latestnews"), $side, "sideblocklatestnews");
+                echo "<font size=\"-2\">";
+                forum_print_latest_discussions($news->id, $site->newsitems, "minimal", "", false);
+                echo "</font>";
+                print_side_block_end();
+            }
+        }
+        print_spacer(1,$side);
+    }
+
+    if (iscreator()) {
+        if (!$firstcolumn) {
+            echo "<td width=\"$side\" valign=top nowrap>";
+            $firstcolumn=true;
+        }
+        print_admin_links($site->id, $side);
+    }
+
+    if ($firstcolumn) {
+        echo '</td>';
+        echo '<td valign="top\">';
+    }
+    else {
+        echo '<td valign="top">';
+    }
+
+    $text = '<div style="float: left;">'.get_string('calendarheading', 'calendar', strip_tags($site->shortname)).'</div><div style="float: right;">';
+    $text.= calendar_get_preferences_menu();
+    $text.= '</div>';
+    print_heading_block($text);
+    print_spacer(8, 1);
+
+    switch($_REQUEST['action']) {
+        case 'delete':
+            if($_REQUEST['confirm'] == 1) {
+                // Kill it and redirect to day view
+                if(($event = get_record('event', 'id', $_REQUEST['id'])) !== false) {
+                    /// Log the event delete.
+
+                    delete_records('event', 'id', $_REQUEST['id']);
+
+                    // pj - fixed the course id problem, but now we have another one:
+                    // what to do with the URL?
+                    add_to_log($event->courseid, 'calendar', 'delete', '', $event->name);
+                }
+
+                if(checkdate($_REQUEST['m'], $_REQUEST['d'], $_REQUEST['y'])) {
+                    // Being a bit paranoid to check this, but it doesn't hurt
+                    redirect(CALENDAR_URL.'view.php?view=day&cal_d='.$_REQUEST['d'].'&cal_m='.$_REQUEST['m'].'&cal_y='.$_REQUEST['y']);
+                }
+                else {
+                    // Redirect to now
+                    redirect(CALENDAR_URL.'view.php?view=day&cal_d='.$now['mday'].'&cal_m='.$now['mon'].'&cal_y='.$now['year']);
+                }
+            }
+            else {
+                $eventtime = usergetdate($event->timestart);
+                $m = $eventtime['mon'];
+                $d = $eventtime['mday'];
+                $y = $eventtime['year'];
+                // Display confirmation form
+                print_side_block_start(get_string('deleteevent', 'calendar').': '.$event->name, '', 'mycalendar');
+                include('event_delete.html');
+                print_side_block_end();
+            }
+        break;
+
+        case 'edit':
+            if(empty($form)) {
+                $form->name = $event->name;
+                $form->courseid = $event->courseid; // Not to update, but for date validation
+                $form->description = $event->description;
+                $form->timestart = $event->timestart;
+                $form->timeduration = $event->timeduration;
+                $form->id = $event->id;
+                $form->format = $defaultformat;
+                if($event->timeduration) {
+                    $form->duration = 1;
+                }
+                else {
+                    $form->duration = 0;
+                }
+            }
+            print_side_block_start(get_string('editevent', 'calendar'), '', 'mycalendar');
+            include('event_edit.html');
+            print_side_block_end();
+        break;
+
+        case 'new':
+            optional_variable($_GET['cal_y']);
+            optional_variable($_GET['cal_m']);
+            optional_variable($_GET['cal_d']);
+            optional_variable($form->timestart, -1);
+
+            if($_GET['cal_y'] && $_GET['cal_m'] && $_GET['cal_d'] && checkdate($_GET['cal_m'], $_GET['cal_d'], $_GET['cal_y'])) {
+                $form->timestart = make_timestamp($_GET['cal_y'], $_GET['cal_m'], $_GET['cal_d'], 0, 0, 0);
+            }
+            else if($_GET['cal_y'] && $_GET['cal_m'] && checkdate($_GET['cal_m'], 1, $_GET['cal_y'])) {
+                if($_GET['cal_y'] == $now['year'] && $_GET['cal_m'] == $now['mon']) {
+                    $form->timestart = make_timestamp($_GET['cal_y'], $_GET['cal_m'], $now['mday'], 0, 0, 0);
+                }
+                else {
+                    $form->timestart = make_timestamp($_GET['cal_y'], $_GET['cal_m'], 1, 0, 0, 0);
+                }
+            }
+            if($form->timestart < 0) {
+                $form->timestart = time();
+            }
+
+            if(!isset($_REQUEST['type'])) {
+                // We don't know what kind of event we want
+                calendar_get_allowed_types($allowed);
+                if(!$allowed->groups && !$allowed->courses && !$allowed->site) {
+                    // Take the shortcut
+                    $_REQUEST['type'] = 'user';
+                }
+                else {
+                    $_REQUEST['type'] = 'select';
+                }
+            }
+
+            $header = '';
+
+            switch($_REQUEST['type']) {
+                case 'user':
+                    $form->courseid = 0;
+                    $form->groupid = 0;
+                    $form->userid = $USER->id;
+                    $form->modulename = '';
+                    $form->eventtype = '';
+                    $form->instance = 0;
+                    $form->timeduration = 0;
+                    $form->duration = 0;
+                    $header = get_string('typeuser', 'calendar');
+                break;
+                case 'group':
+                    optional_variable($_REQUEST['groupid']);
+                    $groupid = $_REQUEST['groupid'];
+                    if(!($group = get_record('groups', 'id', $groupid) )) {
+                        calendar_get_allowed_types($allowed);
+                        $_REQUEST['type'] = 'select';
+                    }
+                    else {
+                        $form->courseid = $group->courseid;
+                        $form->groupid = $group->id;
+                        $form->userid = $USER->id;
+                        $form->modulename = '';
+                        $form->eventtype = '';
+                        $form->instance = 0;
+                        $form->timeduration = 0;
+                        $form->duration = 0;
+                        $header = get_string('typegroup', 'calendar');
+                    }
+                break;
+                case 'course':
+                    optional_variable($_REQUEST['courseid']);
+                    $courseid = $_REQUEST['courseid'];
+                    if(!record_exists('course', 'id', $courseid)) {
+                        calendar_get_allowed_types($allowed);
+                        $_REQUEST['type'] = 'select';
+                    }
+                    else {
+                        $form->courseid = $courseid;
+                        $form->groupid = 0;
+                        $form->userid = $USER->id;
+                        $form->modulename = '';
+                        $form->eventtype = '';
+                        $form->instance = 0;
+                        $form->timeduration = 0;
+                        $form->duration = 0;
+                        $header = get_string('typecourse', 'calendar');
+                    }
+                break;
+                case 'site':
+                    $form->courseid = 1;
+                    $form->groupid = 0;
+                    $form->userid = $USER->id;
+                    $form->modulename = '';
+                    $form->eventtype = '';
+                    $form->instance = 0;
+                    $form->timeduration = 0;
+                    $form->duration = 0;
+                    $header = get_string('typesite', 'calendar');
+                break;
+                case 'defined':
+                case 'select':
+                break;
+                default:
+                    error('Unsupported event type');
+            }
+
+            $form->format = $defaultformat;
+            if(!empty($header)) {
+                $header = ' ('.$header.')';
+            }
+
+            print_side_block_start(get_string('newevent', 'calendar').$header, '', 'mycalendar');
+            if($_REQUEST['type'] == 'select') {
+                include('event_select.html');
+            }
+            else {
+                include('event_new.html');
+            }
+            print_side_block_end();
+        break;
+    }
+
+
+    echo '</td></table>';
+
+    if ($usehtmleditor) {
+        use_html_editor();
+    }
+
+    print_footer();
+
+
+function validate_form(&$form, &$err) {
+    if(empty($form->name)) {
+        $err['name'] = get_string('errornoeventname', 'calendar');
+    }
+    if(empty($form->description)) {
+        $err['description'] = get_string('errornodescription', 'calendar');
+    }
+    if(!checkdate($form->startmon, $form->startday, $form->startyr)) {
+        $err['timestart'] = get_string('errorinvaliddate', 'calendar');
+    }
+    if(!checkdate($form->endmon, $form->endday, $form->endyr)) {
+        $err['timeduration'] = get_string('errorinvaliddate', 'calendar');
+    }
+    if(!empty($form->courseid)) {
+        // Timestamps must be >= course startdate
+        $course = get_record('course', 'id', $form->courseid);
+        if($course === false) {
+            error('Event belongs to invalid course');
+        }
+        else if($form->timestart < $form->startdate) {
+            $err['timestart'] = get_string('errorbeforecoursestart', 'calendar');
+        }
+    }
+}
+
+function calendar_add_event_allowed($courseid, $groupid, $userid) {
+    global $USER;
+
+    if(isadmin()) {
+        return true;
+    }
+    else if($courseid == 0 && $groupid == 0 && $userid == $USER->id) {
+        return true;
+    }
+    else if($courseid != 0 && isteacheredit($courseid)) {
+        return true;
+    }
+
+    return false;
+}
+
+function calendar_get_allowed_types(&$allowed) {
+    global $USER, $CFG;
+
+    $allowed->user = true; // User events always allowed
+    $allowed->groups = false; // This may change just below
+    $allowed->courses = false; // This may change just below
+    $allowed->site = isadmin();
+    if(!empty($USER->teacheredit)) {
+        $allowed->courses = get_records_select('course', 'id != 1 AND id IN ('.implode(',', array_keys($USER->teacheredit)).')');
+        $allowed->groups = get_records_sql('SELECT g.*, c.fullname FROM '.$CFG->prefix.'groups g LEFT JOIN '.$CFG->prefix.'course c ON g.courseid = c.id WHERE g.courseid IN ('.implode(',', array_keys($USER->teacheredit)).')');
+    }
+}
+
+?>
diff --git a/calendar/event_delete.html b/calendar/event_delete.html
new file mode 100644 (file)
index 0000000..7a55051
--- /dev/null
@@ -0,0 +1,27 @@
+<p style="text-align: center;"><?php print_string('confirmeventdelete', 'calendar'); ?></p>\r
+<div style="text-align: center; width: 100%;">\r
+<table style="margin: auto;" >\r
+  <tr>\r
+    <td>\r
+    <form method="get" action="event.php" name="delete">\r
+      <input type="submit" value=" <?php print_string('ok') ?> ">\r
+      <input type="hidden" name="id" value="<?php echo $event->id?>" />\r
+      <input type="hidden" name="action" value="delete" />\r
+      <input type="hidden" name="m" value="<?php echo $m; ?>" />\r
+      <input type="hidden" name="d" value="<?php echo $d; ?>" />\r
+      <input type="hidden" name="y" value="<?php echo $y; ?>" />\r
+      <input type="hidden" name="confirm" value="1" />\r
+      </form>\r
+    </td>\r
+    <td>\r
+      <form method="get" action="view.php" name="cancel">\r
+      <input type="submit" value=" <?php print_string('cancel') ?> ">\r
+      <input type="hidden" name="view" value="day" />\r
+      <input type="hidden" name="cal_m" value="<?php echo $m; ?>" />\r
+      <input type="hidden" name="cal_d" value="<?php echo $d; ?>" />\r
+      <input type="hidden" name="cal_y" value="<?php echo $y; ?>" />\r
+      </form>\r
+    </td>\r
+  </tr>\r
+</table>\r
+</div>\r
diff --git a/calendar/event_edit.html b/calendar/event_edit.html
new file mode 100644 (file)
index 0000000..4560b2c
--- /dev/null
@@ -0,0 +1,38 @@
+<form method="post" action="event.php" name="edit">\r
+<table class="formtable">\r
+  <tr>\r
+    <td style="vertical-align: top; text-align: right;"><?php print_string('eventname', 'calendar'); ?>:</td>\r
+    <td><input type="text" name="name" size="67" value="<?php p($form->name); ?>" /> <?php if (isset($err['name'])) formerr($err['name']); ?></td>\r
+  </tr>\r
+  <tr>\r
+    <td style="vertical-align: top; text-align: right;"><?php print_string('eventdescription', 'calendar'); ?>:</td>\r
+    <td>\r
+      <textarea name="description" rows="10" cols="50" wrap="virtual"><?php p($form->description); ?></textarea><br />\r
+      <?php if (isset($err['description'])) formerr($err['description']); ?>\r
+    </td>\r
+  </tr>\r
+  <tr>\r
+    <td style="vertical-align: top; text-align: right;"><?php print_string('eventdate', 'calendar'); ?>:</td>\r
+    <td><?php print_date_selector('startday', 'startmon', 'startyr', $form->timestart);?> <?php print_string('eventtime', 'calendar');?> <?php print_time_selector('starthr', 'startmin', $form->timestart) ?>  <?php if (isset($err['timestart'])) formerr($err['timestart']); ?></td>\r
+  </tr>\r
+  <tr>\r
+    <td style="vertical-align: top; text-align: right;"><?php print_string('eventduration', 'calendar'); ?>:</td>\r
+    <td>\r
+      <div><input type="radio" name="duration" value="0" id="duration_none" <?php if($form->duration == 0) echo 'checked="checked"'; ?>/><label for="duration_none"><?php print_string('durationnone', 'calendar'); ?></label></div>\r
+      <div><input type="radio" name="duration" value="1" id="duration_yes" <?php if($form->duration == 1) echo 'checked="checked"'; ?>/><label for="duration_yes"><?php print_string('durationuntil', 'calendar'); ?></label>\r
+        <?php print_date_selector('endday', 'endmon', 'endyr', $form->timestart + $form->timeduration);?> <?php print_string('eventtime', 'calendar');?> <?php print_time_selector('endhr', 'endmin', $form->timestart + $form->timeduration) ?>  <?php if (isset($err['timeduration'])) formerr($err['timeduration']); ?>\r
+      </div>\r
+    </td>\r
+  </tr>\r
+  <tr>\r
+    <td>&nbsp;</td>\r
+    <td><p><input type="submit" value=" <?php print_string('ok') ?> "></p></td>\r
+  </tr>\r
+</table>\r
+<p>\r
+<input type="hidden" name="id" value="<?php echo $form->id; ?>" />\r
+<input type="hidden" name="courseid" value="<?php echo $form->courseid; ?>" />\r
+<!--<input type="hidden" name="format" value="<?php echo $form->format; ?>" />-->\r
+<input type="hidden" name="action" value="edit" />\r
+</p>\r
+</form>\r
diff --git a/calendar/event_new.html b/calendar/event_new.html
new file mode 100644 (file)
index 0000000..bc6222e
--- /dev/null
@@ -0,0 +1,43 @@
+<form method="post" action="event.php" name="new">\r
+<table class="formtable">\r
+  <tr>\r
+    <td style="vertical-align: top; text-align: right;"><?php print_string('eventname', 'calendar'); ?>:</td>\r
+    <td><input type="text" name="name" size="67" value="<?php p($form->name); ?>" /> <?php if (isset($err['name'])) formerr($err['name']); ?></td>\r
+  </tr>\r
+  <tr>\r
+    <td style="vertical-align: top; text-align: right;"><?php print_string('eventdescription', 'calendar'); ?>:</td>\r
+    <td>\r
+      <textarea name="description" rows="10" cols="50" wrap="virtual"><?php p($form->description); ?></textarea><br />\r
+      <?php if (isset($err['description'])) formerr($err['description']); ?>\r
+    </td>\r
+  </tr>\r
+  <tr>\r
+    <td style="vertical-align: top; text-align: right;"><?php print_string('eventdate', 'calendar'); ?>:</td>\r
+    <td><?php print_date_selector('startday', 'startmon', 'startyr', $form->timestart);?> <?php print_string('eventtime', 'calendar');?> <?php print_time_selector('starthr', 'startmin', $form->timestart) ?>  <?php if (isset($err['timestart'])) formerr($err['timestart']); ?></td>\r
+  </tr>\r
+  <tr>\r
+    <td style="vertical-align: top; text-align: right;"><?php print_string('eventduration', 'calendar'); ?>:</td>\r
+    <td>\r
+      <div><input type="radio" name="duration" value="0" id="duration_none" <?php if($form->duration == 0) echo 'checked="checked"'; ?>/><label for="duration_none"><?php print_string('durationnone', 'calendar'); ?></label></div>\r
+      <div><input type="radio" name="duration" value="1" id="duration_yes" <?php if($form->duration == 1) echo 'checked="checked"'; ?>/><label for="duration_yes"><?php print_string('durationuntil', 'calendar'); ?></label>\r
+        <?php print_date_selector('endday', 'endmon', 'endyr', $form->timestart + $form->timeduration);?> <?php print_string('eventtime', 'calendar');?> <?php print_time_selector('endhr', 'endmin', $form->timestart + $form->timeduration) ?>  <?php if (isset($err['timeduration'])) formerr($err['timeduration']); ?>\r
+      </div>\r
+    </td>\r
+  </tr>\r
+  <tr>\r
+    <td>&nbsp;</td>\r
+    <td><p><input type="submit" value="<?php print_string('ok') ?>"></p></td>\r
+  </tr>\r
+</table>\r
+<p>\r
+<input type="hidden" name="courseid" value="<?php echo $form->courseid?>" />\r
+<input type="hidden" name="groupid" value="<?php echo $form->groupid?>" />\r
+<input type="hidden" name="userid" value="<?php echo $form->userid?>" />\r
+<input type="hidden" name="modulename" value="<?php echo $form->modulename?>" />\r
+<input type="hidden" name="eventtype" value="<?php echo $form->eventtype?>" />\r
+<input type="hidden" name="instance" value="<?php echo $form->instance?>" />\r
+<!--<input type="hidden" name="format" value="<?php echo $form->format; ?>" />-->\r
+<input type="hidden" name="action" value="new" />\r
+<input type="hidden" name="type" value="defined" />\r
+</p>\r
+</form>\r
diff --git a/calendar/event_select.html b/calendar/event_select.html
new file mode 100644 (file)
index 0000000..076c482
--- /dev/null
@@ -0,0 +1,47 @@
+<table class="formtable">\r
+  <form method="post" action="event.php" name="edit">\r
+  <p>\r
+  <input type="hidden" name="action" value="new" />\r
+  <input type="hidden" name="timestart" value="<?php echo $form->timestart; ?>" />\r
+  </p>\r
+  <tr>\r
+    <td style="vertical-align: top; text-align: right;"><?php print_string('eventkind', 'calendar'); ?>:</td>\r
+    <td>\r
+    <?php if(!empty($allowed->user)) { ?><p><input type='radio' name='type' value='user' id='type_user' checked='checked' /><label for='type_user'><?php print_string('typeuser', 'calendar') ?></label></p>\r
+    <?php } ?>\r
+    <?php if(!empty($allowed->groups)) { ?><p><input type='radio' name='type' value='group' id='type_group' /><label for='type_group'><?php print_string('typegroup', 'calendar') ?></label></p>\r
+      <div style="padding-left: 1.5em;">\r
+      <?php print_string('course'); echo ' / '; print_string('group'); ?>:\r
+      <select name='groupid'>\r
+        <option value=''></option>\r
+      <?php foreach($allowed->groups as $group) {?>\r
+        <option value='<?php echo $group->id?>' <?php if($group->id == $groupid) echo 'selected="selected"';?>><?php echo $group->fullname.' - '.$group->name?></option>\r
+      <?php }?>\r
+      </select>\r
+      </div>\r
+    <?php } ?>\r
+    <?php if(!empty($allowed->courses)) { ?><p><input type='radio' name='type' value='course' id='type_course' /><label for='type_course'><?php print_string('typecourse', 'calendar') ?></label></p>\r
+      <div style="padding-left: 1.5em;">\r
+      <?php print_string('course'); ?>:\r
+      <select name='courseid'>\r
+        <option value=''></option>\r
+      <?php foreach($allowed->courses as $course) {?>\r
+        <option value='<?php echo $course->id?>' <?php if($course->id == $courseid) echo 'selected="selected"';?>><?php echo $course->fullname?></option>\r
+      <?php }?>\r
+      </select>\r
+      </div>\r
+    <?php } ?>\r
+    <?php if(!empty($allowed->site)) { ?><p><input type='radio' name='type' value='site' id='type_site' /><label for='type_site'><?php print_string('typesite', 'calendar') ?></label></p>\r
+    <?php } ?>\r
+    </td>\r
+  </tr>\r
+  <tr>\r
+    <td>&nbsp;</td>\r
+    <td>\r
+      <p><input type="submit" value=" <?php print_string('ok') ?> ">\r
+      <input type="button" onclick="document.location.href='view.php?view=upcoming';" value=" <?php print_string('cancel') ?> ">\r
+      </p>\r
+    </td>\r
+  </tr>\r
+  </form>\r
+</table>\r
diff --git a/calendar/lib.php b/calendar/lib.php
new file mode 100644 (file)
index 0000000..9810e2c
--- /dev/null
@@ -0,0 +1,1195 @@
+<?php // $Id$
+
+/////////////////////////////////////////////////////////////////////////////
+//                                                                         //
+// NOTICE OF COPYRIGHT                                                     //
+//                                                                         //
+// Moodle - Calendar extension                                             //
+//                                                                         //
+// Copyright (C) 2003-2004  Greek School Network            www.sch.gr     //
+//                                                                         //
+// Designed by:                                                            //
+//     Avgoustos Tsinakos (tsinakos@uom.gr)                                //
+//     Jon Papaioannou (pj@uom.gr)                                         //
+//                                                                         //
+// Programming and development:                                            //
+//     Jon Papaioannou (pj@uom.gr)                                         //
+//                                                                         //
+// For bugs, suggestions, etc contact:                                     //
+//     Jon Papaioannou (pj@uom.gr)                                         //
+//                                                                         //
+// The current module was developed at the University of Macedonia         //
+// (www.uom.gr) under the funding of the Greek School Network (www.sch.gr) //
+// The aim of this project is to provide additional and improved           //
+// functionality to the Asynchronous Distance Education service that the   //
+// Greek School Network deploys.                                           //
+//                                                                         //
+// This program is free software; you can redistribute it and/or modify    //
+// it under the terms of the GNU General Public License as published by    //
+// the Free Software Foundation; either version 2 of the License, or       //
+// (at your option) any later version.                                     //
+//                                                                         //
+// This program is distributed in the hope that it will be useful,         //
+// but WITHOUT ANY WARRANTY; without even the implied warranty of          //
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the           //
+// GNU General Public License for more details:                            //
+//                                                                         //
+//          http://www.gnu.org/copyleft/gpl.html                           //
+//                                                                         //
+/////////////////////////////////////////////////////////////////////////////
+
+define ('SECS_IN_DAY', 86400);
+define ('CALENDAR_UPCOMING_DAYS', 14);
+define ('CALENDAR_UPCOMING_MAXEVENTS', 10);
+define ('CALENDAR_STARTING_WEEKDAY', 1);
+define ('CALENDAR_URL', $CFG->wwwroot.'/calendar/');
+
+function calendar_get_mini($courses, $groups, $users, $cal_month = false, $cal_year = false) {
+    global $CFG, $USER;
+
+    $display = &New object;
+    $display->minwday = get_user_preferences('calendar_startwday', CALENDAR_STARTING_WEEKDAY);
+    $display->maxwday = $display->minwday + 6;
+
+    $content = '';
+
+    if(!empty($cal_month) && !empty($cal_year)) {
+        $thisdate = usergetdate(time()); // Date and time the user sees at his location
+        if($cal_month == $thisdate['mon'] && $cal_year == $thisdate['year']) {
+            // Navigated to this month
+            $date = $thisdate;
+            $display->thismonth = true;
+        }
+        else {
+            // Navigated to other month, let's do a nice trick and save us a lot of work...
+            if(!checkdate($cal_month, 1, $cal_year)) {
+                $date = array('mday' => 1, 'mon' => $thisdate['mon'], 'year' => $thisdate['year']);
+                $display->thismonth = true;
+            }
+            else {
+                $date = array('mday' => 1, 'mon' => $cal_month, 'year' => $cal_year);
+                $display->thismonth = false;
+            }
+        }
+    }
+    else {
+        $date = usergetdate(time()); // Date and time the user sees at his location
+        $display->thismonth = true;
+    }
+
+    // Fill in the variables we 're going to use, nice and tidy
+    list($d, $m, $y) = array($date['mday'], $date['mon'], $date['year']); // This is what we want to display
+    $display->maxdays = calendar_days_in_month($m, $y);
+
+    // We 'll keep these values as GMT here, and offset them when the time comes to query the db
+    $display->tstart = gmmktime(0, 0, 0, $m, 1, $y); // This is GMT
+    $display->tend = gmmktime(23, 59, 59, $m, $display->maxdays, $y); // GMT
+
+    $startwday = gmdate('w', $display->tstart); // $display->tstart is already GMT, so don't use date(): messes with server's TZ
+
+    // Align the starting weekday to fall in our display range
+    // This is simple, not foolproof.
+    if($startwday < $display->minwday) {
+        $startwday += 7;
+    }
+
+    // Get the events matching our criteria. Don't forget to offset the timestamps for the user's TZ!
+    $whereclause = calendar_sql_where(usertime($display->tstart), usertime($display->tend), $users, $groups, $courses);
+
+    if($whereclause === false) {
+        $events = array();
+    }
+    else {
+        $events = get_records_select('event', $whereclause);
+    }
+
+    // We want to have easy access by day, since the display is on a per-day basis.
+    // Arguments passed by reference.
+    calendar_events_by_day($events, $display->tstart, $eventsbyday, $durationbyday, $typesbyday);
+
+    $content .= '<table class="calendarmini"><tr>'; // Begin table. First row: day names
+
+    // Print out the names of the weekdays
+    $days = array('sun', 'mon', 'tue', 'wed', 'thu', 'fri', 'sat');
+    for($i = $display->minwday; $i <= $display->maxwday; ++$i) {
+        // This uses the % operator to get the correct weekday no matter what shift we have
+        // applied to the $display->minwday : $display->maxwday range from the default 0 : 6
+        $content .= '<td class="calendarheader">'.get_string($days[$i % 7], 'calendar')."</td>\n";
+    }
+
+    $content .= '</tr><tr>'; // End of day names; prepare for day numbers
+
+    // For the table display. $week is the row; $dayweek is the column.
+    $week = 1;
+    $dayweek = $startwday;
+
+    // Paddding (the first week may have blank days in the beginning)
+    for($i = $display->minwday; $i < $startwday; ++$i) {
+        $content .= '<td class="calendardaymini">&nbsp;</td>'."\n";
+    }
+
+    // Now display all the calendar
+    for($day = 1; $day <= $display->maxdays; ++$day, ++$dayweek) {
+        if($dayweek > $display->maxwday) {
+            // We need to change week (table row)
+            $content .= "</tr>\n<tr>";
+            $dayweek = $display->minwday;
+            ++$week;
+        }
+        // Reset vars
+        $class = '';
+        $cell = '';
+        if($dayweek % 7 == 0 || $dayweek % 7 == 6) {
+            // Weekend. This is true no matter what the exact range is.
+            $class = 'cal_day_mini calendarweekend';
+        }
+        else {
+            // Normal working day.
+            $class = 'cal_day_mini';
+        }
+
+        // Special visual fx if an event is defined
+        if(isset($eventsbyday[$day])) {
+            // OverLib popup
+            $popupcontent = '';
+            foreach($eventsbyday[$day] as $eventid) {
+                $popupcontent .= '<div><a href=\\\''.CALENDAR_URL.'view.php?view=event&amp;id='.$events[$eventid]->id.'\\\'>'.addslashes(htmlspecialchars($events[$eventid]->name)).'</a></div>';
+            }
+
+            $popupcaption = get_string('eventsfor', 'calendar', calendar_month_name(intval($date['mon'])).' '.$day);
+            $popup = 'onmouseover="return overlib(\''.$popupcontent.'\', CAPTION, \''.$popupcaption.'\');" onmouseout="return nd();"';
+
+            // Class and cell content
+            if(isset($typesbyday[$day]['startglobal'])) {
+                $class .= ' cal_event_global';
+            }
+            else if(isset($typesbyday[$day]['startcourse'])) {
+                $class .= ' cal_event_course';
+            }
+            else if(isset($typesbyday[$day]['startgroup'])) {
+                $class .= ' cal_event_group';
+            }
+            else if(isset($typesbyday[$day]['startuser'])) {
+                $class .= ' cal_event_user';
+            }
+            if(count($eventsbyday[$day]) == 1) {
+                $title = get_string('oneevent', 'calendar');
+            }
+            else {
+                $title = get_string('manyevents', 'calendar', count($eventsbyday[$day]));
+            }
+            $cell = '<strong><a href="'.calendar_get_link_href(CALENDAR_URL.'view.php?view=day&amp;', $day, $m, $y).'" '.$popup.'">'.$day.'</a></strong>';
+        }
+        else {
+            $cell = $day;
+        }
+
+        if(isset($typesbyday[$day]['durationglobal'])) {
+            $class .= ' cal_duration_global';
+        }
+        else if(isset($typesbyday[$day]['durationcourse'])) {
+            $class .= ' cal_duration_course';
+        }
+        else if(isset($typesbyday[$day]['durationgroup'])) {
+            $class .= ' cal_duration_group';
+        }
+        else if(isset($typesbyday[$day]['durationuser'])) {
+            $class .= ' cal_duration_user';
+        }
+
+        // Special visual fx for today
+        if($display->thismonth && $day == $d) {
+            $class .= ' cal_today';
+        }
+
+        // Just display it
+        $content .= '<td class="'.$class.'">'.$cell."</td>\n";
+    }
+
+    // Paddding (the last week may have blank days at the end)
+    for($i = $dayweek; $i <= $display->maxwday; ++$i) {
+        $content .= '<td class="calendardaymini">&nbsp;</td>';
+    }
+    $content .= '</tr>'; // Last row ends
+
+    $content .= '</table>'; // Tabular display of days ends
+
+    return $content;
+}
+
+function calendar_get_upcoming($courses, $groups, $users, $daysinfuture, $maxevents) {
+
+    global $CFG;
+
+    $display = &New object;
+    $display->range = $daysinfuture; // How many days in the future we 'll look
+    $display->maxevents = $maxevents;
+
+    $output = array();
+
+    // Prepare "course caching", since it may save us a lot of queries
+    $coursecache = array();
+
+    $processed = 0;
+    $now = time(); // We 'll need this later
+    $nowsecs = $now % SECS_IN_DAY; // this too
+    $nowdays = $now - $nowsecs; // and this
+    $date = usergetdate($now); // Nominal datetime
+
+    // Fill in the variables we 're going to use, nice and tidy
+    list($d, $m, $y) = array($date['mday'], $date['mon'], $date['year']);
+    $display->tstart = gmmktime(0, 0, 0, $m, $d, $y);
+
+    // This effectively adds as many days as needed, and the final SECS_IN_DAY - 1
+    // serves to cover the duration until the end of the final day. We could
+    // just do another gmmktime() and an addition, but this is "faster" :)
+    $display->tend = $display->tstart + (SECS_IN_DAY * $display->range) - 1;
+
+    // Get the events matching our criteria
+    $whereclause = calendar_sql_where($display->tstart, $display->tend, $users, $groups, $courses);
+    if($whereclause === false) {
+        $events = false;
+    }
+    else {
+        $whereclause .= ' ORDER BY timestart'; // We want them this way
+        $events = get_records_select('event', $whereclause);
+    }
+
+    if($events !== false) {
+        foreach($events as $event) {
+            if($processed >= $display->maxevents) break;
+
+            // Important note: these timestamps will receive an offset before being converted
+            // to human-readable form in the calendar_get_XXX_representation() functions.
+            $startdate = usergetdate($event->timestart);
+            $enddate = usergetdate($event->timestart + $event->timeduration);
+
+            // It is equally important that we offset them manually to get the correct dates
+            // for the link URL parameters before creating the links!
+            $tzfix = calendar_get_tz_offset();
+            $linkstartdate = usergetdate($event->timestart + $tzfix);
+            $linkenddate = usergetdate($event->timestart + $event->timeduration + $tzfix);
+
+            $starttimesecs = $event->timestart % SECS_IN_DAY; // Seconds after that day's midnight
+            $starttimedays = $event->timestart - $starttimesecs; // Timestamp of midnight of that day
+
+            if($event->timeduration) {
+                // To avoid doing the math if one IF is enough :)
+                $endtimesecs = ($event->timestart + $event->timeduration) % SECS_IN_DAY; // Seconds after that day's midnight
+                $endtimedays = ($event->timestart + $event->timeduration) - $endtimesecs; // Timestamp of midnight of that day
+            }
+            else {
+                $endtimesecs = $starttimesecs;
+                $endtimedays = $starttimedays;
+            }
+
+            // Keep in mind: $starttimeXXX, $endtimeXXX and $nowXXX are all in GMT-based
+            // OK, now to get a meaningful display...
+
+            // First of all we have to construct a human-readable date/time representation
+            if($endtimedays < $nowdays || $endtimedays == $nowdays && $endtimesecs <= $nowsecs) {
+                // It has expired, so we don't care about duration
+                $day = calendar_day_representation($event->timestart + $event->timeduration, $now);
+                $time = calendar_time_representation($event->timestart + $event->timeduration);
+
+                // This var always has the printable time representation
+                $eventtime = '<span class="calendarexpired">'.get_string('expired', 'calendar').' '.
+                    calendar_get_link_tag($day, CALENDAR_URL.'view.php?view=day&amp;', $linkenddate['mday'], $linkenddate['mon'], $linkenddate['year']).'</span> ('.$time.')';
+            }
+            else if($event->timeduration) {
+                // It has a duration
+                if($starttimedays == $endtimedays) {
+                    // But it's all on one day
+                    $day = calendar_day_representation($event->timestart, $now);
+                    $timestart = calendar_time_representation($event->timestart);
+                    $timeend = calendar_time_representation($event->timestart + $event->timeduration);
+
+                    // Set printable representation
+                    $eventtime = calendar_get_link_tag($day, CALENDAR_URL.'view.php?view=day&amp;', $linkenddate['mday'], $linkenddate['mon'], $linkenddate['year']).
+                        ' ('.$timestart.' - '.$timeend.')';
+                }
+                else {
+                    // It spans two or more days
+                    $daystart = calendar_day_representation($event->timestart, $now);
+                    $dayend = calendar_day_representation($event->timestart + $event->timeduration, $now);
+                    $timestart = calendar_time_representation($event->timestart);
+                    $timeend = calendar_time_representation($event->timestart + $event->timeduration);
+
+                    // Set printable representation
+                    $eventtime = calendar_get_link_tag($daystart, CALENDAR_URL.'view.php?view=day&amp;', $linkstartdate['mday'], $linkstartdate['mon'], $linkstartdate['year']).
+                        ' ('.$timestart.') - '.calendar_get_link_tag($dayend, CALENDAR_URL.'view.php?view=day&amp;', $linkenddate['mday'], $linkenddate['mon'], $linkenddate['year']).
+                        ' ('.$timeend.')';
+                }
+            }
+            else {
+                // It's an "instantaneous" event
+                $day = calendar_day_representation($event->timestart, $now);
+                $time = calendar_time_representation($event->timestart);
+
+                // Set printable representation
+                $eventtime = calendar_get_link_tag($day, CALENDAR_URL.'view.php?view=day&amp;', $linkstartdate['mday'], $linkstartdate['mon'], $linkstartdate['year']).' ('.$time.')';
+            }
+
+            $outkey = count($output);
+
+            // Now we know how to display the time, we have to see how to display the event
+            if(!empty($event->modulename)) {
+
+                // The module name is set. I will assume that it has to be displayed, and
+                // also that it is an automatically-generated event. And of course that the
+                // three fields for get_coursemodule_from_instance are set correctly.
+
+                $module = calendar_get_module_cached($coursecache, $event->modulename, $event->instance, $event->courseid);
+
+                if($module === false) {
+                    // This shouldn't have happened. What to do now?
+                    // Just ignore it
+                    continue;
+                }
+
+                $modulename = get_string('modulename', $event->modulename);
+                $eventtype = get_string($event->eventtype, $event->modulename);
+                $icon = $CFG->modpixpath.'/'.$event->modulename.'/icon.gif';
+                $output[$outkey]->referer = '<a href="'.$CFG->wwwroot.'/mod/'.$event->modulename.'/view.php?id='.$module->id.'">'.$module->name.'</a>';
+                $output[$outkey]->icon = '<img src="'.$icon.'" title="'.$modulename.'" style="vertical-align: middle;" />';
+                $output[$outkey]->name = $event->name;
+                $output[$outkey]->time = $eventtime;
+                $output[$outkey]->description = $event->description;
+            }
+            else if($event->courseid == 1) {
+                // Global event
+                global $site;
+                $output[$outkey]->referer = '<a href="'.$CFG->wwwroot.'">'.$site->shortname.'</a>';
+                $output[$outkey]->icon = '';
+                $output[$outkey]->name = $event->name;
+                $output[$outkey]->time = $eventtime;
+                $output[$outkey]->description = $event->description;
+            }
+            else if($event->courseid > 1) {
+                // Course event
+                calendar_get_course_cached($coursecache, $event->courseid);
+
+                $output[$outkey]->referer = '<a href="'.$CFG->wwwroot.'/course/view.php?id='.$coursecache[$event->courseid]->id.'">'.$coursecache[$event->courseid]->fullname.'</a>';
+                $output[$outkey]->icon = '';
+                $output[$outkey]->name = $event->name;
+                $output[$outkey]->time = $eventtime;
+                $output[$outkey]->description = $event->description;
+            }
+            else if($event->groupid) {
+                // Group event
+                $output[$outkey]->icon = '';
+                $output[$outkey]->name = $event->name;
+                $output[$outkey]->time = $eventtime;
+                $output[$outkey]->description = $event->description;
+        }
+            else if($event->userid) {
+                // User event
+                $output[$outkey]->icon = '';
+                $output[$outkey]->name = $event->name;
+                $output[$outkey]->time = $eventtime;
+                $output[$outkey]->description = $event->description;
+            }
+            ++$processed;
+        }
+    }
+    return $output;
+}
+
+function calendar_sql_where($tstart, $tend, $users, $groups, $courses, $withduration = true) {
+    $whereclause = '';
+    // Quick test
+    if(is_bool($users) && is_bool($groups) && is_bool($courses)) {
+        return false;
+    }
+
+    if(is_array($users) && !empty($users)) {
+        // Events from a number of users
+        if(!empty($whereclause)) $whereclause .= ' OR';
+        $whereclause .= ' userid IN ('.implode(',', $users).') AND courseid = 0 AND groupid = 0';
+    }
+    else if(is_numeric($users)) {
+        // Events from one user
+        if(!empty($whereclause)) $whereclause .= ' OR';
+        $whereclause .= ' userid = '.$users.' AND courseid = 0 AND groupid = 0';
+    }
+    else if($users === true) {
+        // Events from ALL users
+        if(!empty($whereclause)) $whereclause .= ' OR';
+        $whereclause .= ' userid != 0 AND courseid = 0 AND groupid = 0';
+    }
+    if(is_array($groups) && !empty($groups)) {
+        // Events from a number of groups
+        if(!empty($whereclause)) $whereclause .= ' OR';
+        $whereclause .= ' groupid IN ('.implode(',', $groups).')';
+    }
+    else if(is_numeric($groups)) {
+        // Events from one group
+        if(!empty($whereclause)) $whereclause .= ' OR ';
+        $whereclause .= ' groupid = '.$groups;
+    }
+    else if($groups === true) {
+        // Events from ALL groups
+        if(!empty($whereclause)) $whereclause .= ' OR ';
+        $whereclause .= ' groupid != 0';
+    }
+    if(is_array($courses) && !empty($courses)) {
+        // A number of courses
+        if(!empty($whereclause)) $whereclause .= ' OR';
+        $whereclause .= ' groupid = 0 AND courseid IN ('.implode(',', $courses).')';
+    }
+    else if(is_numeric($courses)) {
+        // One course
+        if(!empty($whereclause)) $whereclause .= ' OR';
+        $whereclause .= ' groupid = 0 AND courseid = '.$courses;
+    }
+    else if($courses === true) {
+        // Events from ALL courses
+        if(!empty($whereclause)) $whereclause .= ' OR';
+        $whereclause .= ' groupid = 0 AND courseid != 0';
+    }
+    if($withduration) {
+        $timeclause = 'timestart + timeduration >= '.$tstart.' AND timestart <= '.$tend;
+    }
+    else {
+        $timeclause = 'timestart >= '.$tstart.' AND timestart <= '.$tend;
+    }
+    if(!empty($whereclause)) {
+        // We have additional constraints
+        $whereclause = $timeclause.' AND ('.$whereclause.')';
+    }
+    else {
+        // Just basic time filtering
+        $whereclause = $timeclause;
+    }
+    return $whereclause;
+}
+
+function calendar_top_controls($type, $data) {
+    global $CFG;
+    $content = '';
+    if(!isset($data['d'])) {
+        $data['d'] = 1;
+    }
+    $time = calendar_mktime_check($data['m'], $data['d'], $data['y']);
+    $date = getdate($time);
+    $data['m'] = $date['mon'];
+    $data['y'] = $date['year'];
+    $monthname = calendar_month_name($date['month']);
+
+    switch($type) {
+        case 'frontpage':
+            list($prevmonth, $prevyear) = calendar_sub_month($data['m'], $data['y']);
+            list($nextmonth, $nextyear) = calendar_add_month($data['m'], $data['y']);
+            $nextlink = calendar_get_link_tag('&gt;&gt;', 'index.php?id='.$data['id'].'&amp;', 0, $nextmonth, $nextyear);
+            $prevlink = calendar_get_link_tag('&lt;&lt;', 'index.php?id='.$data['id'].'&amp;', 0, $prevmonth, $prevyear);
+            $content .= '<table class="generaltable" style="width: 100%;"><tr>';
+            $content .= '<td style="text-align: left; width: 12%;">'.$prevlink."</td>\n";
+            $content .= '<td style="text-align: center;"><a href="'.calendar_get_link_href(CALENDAR_URL.'view.php?view=month&amp;', 1, $data['m'], $data['y']).'">'.$monthname.' '.$data['y']."</a></td>\n";
+            $content .= '<td style="text-align: right; width: 12%;">'.$nextlink."</td>\n";
+            $content .= '</tr></table>';
+        break;
+        case 'course':
+            list($prevmonth, $prevyear) = calendar_sub_month($data['m'], $data['y']);
+            list($nextmonth, $nextyear) = calendar_add_month($data['m'], $data['y']);
+            $nextlink = calendar_get_link_tag('&gt;&gt;', 'view.php?id='.$data['id'].'&amp;', 0, $nextmonth, $nextyear);
+            $prevlink = calendar_get_link_tag('&lt;&lt;', 'view.php?id='.$data['id'].'&amp;', 0, $prevmonth, $prevyear);
+            $content .= '<table class="generaltable" style="width: 100%;"><tr>';
+            $content .= '<td style="text-align: left; width: 12%;">'.$prevlink."</td>\n";
+            $content .= '<td style="text-align: center;"><a href="'.calendar_get_link_href(CALENDAR_URL.'view.php?view=month&amp;', 1, $data['m'], $data['y']).'">'.$monthname.' '.$data['y']."</a></td>\n";
+            $content .= '<td style="text-align: right; width: 12%;">'.$nextlink."</td>\n";
+            $content .= '</tr></table>';
+        break;
+        case 'upcoming':
+            // A quick check reveals that this is not used at all
+            /*
+            list($prevmonth, $prevyear) = calendar_sub_month($data['m'], $data['y']);
+            list($nextmonth, $nextyear) = calendar_add_month($data['m'], $data['y']);
+            $prevdate = getdate(calendar_mktime_check($prevmonth, 1, $prevyear));
+            $nextdate = getdate(calendar_mktime_check($nextmonth, 1, $nextyear));
+            $prevname = calendar_month_name($prevdate['month']);
+            $nextname = calendar_month_name($nextdate['month']);
+            $content .= "<tr>\n";
+            $content .= '<td style="text-align: center"><a href="'.calendar_get_link_href(CALENDAR_URL.'view.php?view=month&amp;', 1, $prevmonth, $prevyear).'">'.$prevname.' '.$prevyear."</a></td>\n";
+            $content .= '<td style="text-align: center"><a href="'.calendar_get_link_href(CALENDAR_URL.'view.php?view=month&amp;', 1, $data['m'], $data['y']).'">'.$monthname.' '.$data['y']."</a></td>\n";
+            $content .= '<td style="text-align: center"><a href="'.calendar_get_link_href(CALENDAR_URL.'view.php?view=month&amp;', 1, $nextmonth, $nextyear).'">'.$nextname.' '.$nextyear."</a></td>\n";
+            $content .= "</tr>\n";
+            */
+        break;
+        case 'display':
+            $content .= '<div style="text-align: center;"><a href="'.calendar_get_link_href(CALENDAR_URL.'view.php?view=month&amp;', 1, $data['m'], $data['y']).'">'.$monthname.' '.$data['y']."</a></div>\n";
+        break;
+        case 'month':
+            list($prevmonth, $prevyear) = calendar_sub_month($data['m'], $data['y']);
+            list($nextmonth, $nextyear) = calendar_add_month($data['m'], $data['y']);
+            $prevdate = getdate(calendar_mktime_check($prevmonth, 1, $prevyear));
+            $nextdate = getdate(calendar_mktime_check($nextmonth, 1, $nextyear));
+            $prevname = calendar_month_name($prevdate['month']);
+            $nextname = calendar_month_name($nextdate['month']);
+            $content .= "<table style='width: 100%;'><tr>\n";
+            $content .= '<td style="text-align: left; width: 30%;"><a href="'.calendar_get_link_href('view.php?view=month&amp;', 1, $prevmonth, $prevyear).'">&lt;&lt; '.$prevname.' '.$prevyear."</a></td>\n";
+            $content .= '<td style="text-align: center"><strong>'.$monthname.' '.$data['y']."</strong></td>\n";
+            $content .= '<td style="text-align: right; width: 30%;"><a href="'.calendar_get_link_href('view.php?view=month&amp;', 1, $nextmonth, $nextyear).'">'.$nextname.' '.$nextyear." &gt;&gt;</a></td>\n";
+            $content .= "</tr></table>\n";
+        break;
+        case 'day':
+            $data['d'] = $date['mday']; // Just for convenience
+            $dayname = calendar_wday_name($date['weekday']);
+            $prevdate = getdate($time - SECS_IN_DAY);
+            $nextdate = getdate($time + SECS_IN_DAY);
+            $prevname = calendar_wday_name($prevdate['weekday']);
+            $nextname = calendar_wday_name($nextdate['weekday']);
+            $content .= "<table style='width: 100%;'><tr>\n";
+            $content .= '<td style="text-align: left; width: 20%;"><a href="'.calendar_get_link_href('view.php?view=day&amp;', $prevdate['mday'], $prevdate['mon'], $prevdate['year']).'">&lt;&lt; '.$prevname.' '.$prevyear."</a></td>\n";
+            $content .= '<td style="text-align: center"><strong>'.$dayname.', '.$data['d'].' <a href="'.calendar_get_link_href('view.php?view=month&amp;', 1, $data['m'], $data['y']).'">'.$monthname.' '.$data['y']."</a></strong></td>\n";
+            $content .= '<td style="text-align: right; width: 20%;"><a href="'.calendar_get_link_href('view.php?view=day&amp;', $nextdate['mday'], $nextdate['mon'], $nextdate['year']).'">'.$nextname.' '.$nextyear." &gt;&gt;</a></td>\n";
+            $content .= "</tr></table>\n";
+        break;
+    }
+    return $content;
+}
+
+function calendar_filter_controls($type) {
+    global $CFG, $SESSION;
+
+    $content = '';
+    switch($type) {
+        // A quick check reveals this is not used at all
+        // case 'upcoming':
+        //     if(!isset($getvars)) {
+        //         global $day, $mon, $yr;
+        //         $getvars = 'from=upcoming&amp;cal_d='.$day.'&amp;cal_m='.$mon.'&amp;cal_y='.$yr;
+        //     }
+
+        case 'event':
+            if(!isset($getvars)) {
+                global $day, $mon, $yr;
+                $getvars = 'from=event&amp;id='.$_GET['id'];
+            }
+
+        case 'day':
+            if(!isset($getvars)) {
+                global $day, $mon, $yr;
+                $getvars = 'from=day&amp;cal_d='.$day.'&amp;cal_m='.$mon.'&amp;cal_y='.$yr;
+            }
+
+        case 'course':
+            if(!isset($getvars)) {
+                global $course;
+                $getvars = 'from=course&amp;id='.$course->id;
+            }
+
+            $content .= '<table class="cal_controls" style="width: 98%;">';
+
+            $content .= '<tr>';
+            if($SESSION->cal_show_global) {
+                $content .= '<td class="cal_event_global" style="width: 8px;"></td><td><a href="'.CALENDAR_URL.'set.php?var=showglobal&amp;'.$getvars.'" title="'.get_string('tt_hideglobal', 'calendar').'">'.get_string('globalevents', 'calendar').'</a></td>'."\n";
+            }
+            else {
+                $content .= '<td style="width: 8px;"></td><td><a href="'.CALENDAR_URL.'set.php?var=showglobal&amp;'.$getvars.'" title="'.get_string('tt_showglobal', 'calendar').'">'.get_string('globalevents', 'calendar').'</a></td>'."\n";
+            }
+            if($SESSION->cal_show_course) {
+                $content .= '<td class="cal_event_course" style="width: 8px;"></td><td><a href="'.CALENDAR_URL.'set.php?var=showcourses&amp;'.$getvars.'" title="'.get_string('tt_hidecourse', 'calendar').'">'.get_string('courseevents', 'calendar').'</a></td>'."\n";
+            }
+            else {
+                $content .= '<td style="width: 8px;"></td><td><a href="'.CALENDAR_URL.'set.php?var=showcourses&amp;'.$getvars.'" title="'.get_string('tt_showcourse', 'calendar').'">'.get_string('courseevents', 'calendar').'</a></td>'."\n";
+            }
+            $content .= "</tr>\n";
+            $content .= '<tr>';
+            if($SESSION->cal_show_groups) {
+                $content .= '<td class="cal_event_group" style="width: 8px;"></td><td><a href="'.CALENDAR_URL.'set.php?var=showgroups&amp;'.$getvars.'" title="'.get_string('tt_hidegroups', 'calendar').'">'.get_string('groupevents', 'calendar').'</a></td>'."\n";
+            }
+            else {
+                $content .= '<td style="width: 8px;"></td><td><a href="'.CALENDAR_URL.'set.php?var=showgroups&amp;'.$getvars.'" title="'.get_string('clickshowgroups', 'calendar').'">'.get_string('groupevents', 'calendar').'</a></td>'."\n";
+            }
+            if($SESSION->cal_show_user) {
+                $content .= '<td class="cal_event_user" style="width: 8px;"></td><td><a href="'.CALENDAR_URL.'set.php?var=showuser&amp;'.$getvars.'" title="'.get_string('tt_hideuser', 'calendar').'">'.get_string('userevents', 'calendar').'</a></td>'."\n";
+            }
+            else {
+                $content .= '<td style="width: 8px;"></td><td><a href="'.CALENDAR_URL.'set.php?var=showuser&amp;'.$getvars.'" title="'.get_string('clickshowuser', 'calendar').'">'.get_string('userevents', 'calendar').'</a></td>'."\n";
+            }
+            $content .= "</tr>\n</table>\n";
+        break;
+    }
+    return $content;
+}
+
+function calendar_day_representation($tstamp, $now = false, $usecommonwords = true) {
+
+    $days = array('sunday', 'monday', 'tuesday', 'wednesday', 'thursday', 'friday', 'saturday');
+    if($now === false) {
+        $now = time();
+    }
+
+    // To have it in one place, if a change is needed
+    $formal = get_string($days[userdate($tstamp, '%w')], 'calendar') . userdate($tstamp,' %d %b');
+
+    // Reverse TZ compensation: make GMT stamps correspond to user's TZ
+    $tzfix = calendar_get_tz_offset();
+    $tstamp += $tzfix;
+    $now += $tzfix;
+
+    $eventdays = intval($tstamp / SECS_IN_DAY);
+    $nowdays = intval($now / SECS_IN_DAY);
+
+    if($usecommonwords == false) {
+        // We don't want words, just a date
+        return $formal;
+    }
+    else if($eventdays == $nowdays) {
+        // Today
+        return get_string('today', 'calendar');
+    }
+    else if($eventdays == $nowdays - 1) {
+        // Yesterday
+        return get_string('yesterday', 'calendar');
+    }
+    else if($eventdays == $nowdays + 1) {
+        // Tomorrow
+        return get_string('tomorrow', 'calendar');
+    }
+    else {
+        return $formal;
+    }
+}
+
+function calendar_time_representation($time) {
+    return userdate($time, '%H:%M');
+}
+
+function calendar_get_link_href($linkbase, $d, $m, $y) {
+    if(empty($linkbase)) return '';
+    $paramstr = '';
+    if(!empty($d)) $paramstr .= '&amp;cal_d='.$d;
+    if(!empty($m)) $paramstr .= '&amp;cal_m='.$m;
+    if(!empty($y)) $paramstr .= '&amp;cal_y='.$y;
+    if(!empty($paramstr)) $paramstr = substr($paramstr, 5);
+    return $linkbase.$paramstr;
+}
+
+function calendar_get_link_tag($text, $linkbase, $d, $m, $y) {
+    $href = calendar_get_link_href($linkbase, $d, $m, $y);
+    if(empty($href)) return $text;
+    return '<a href="'.$href.'">'.$text.'</a>';
+}
+
+function calendar_gmmktime_check($m, $d, $y, $default = false) {
+    if($default === false) $default = time();
+    if(!checkdate($m, $d, $y)) {
+        return $default;
+    }
+    else {
+        return gmmktime(0, 0, 0, $m, $d, $y);
+    }
+}
+
+function calendar_mktime_check($m, $d, $y, $default = false) {
+    if($default === false) $default = time();
+    if(!checkdate($m, $d, $y)) {
+        return $default;
+    }
+    else {
+        return mktime(0, 0, 0, $m, $d, $y);
+    }
+}
+
+function calendar_month_name($month) {
+    if(is_int($month)) {
+        // 1 ... 12 integer converted to month name
+        $months = array('january', 'february', 'march', 'april', 'may', 'june', 'july', 'august', 'september', 'october', 'november', 'december');
+        return get_string($months[$month - 1], 'calendar');
+    }
+    else {
+        return get_string(strtolower($month), 'calendar');
+    }
+}
+
+function calendar_wday_name($englishname) {
+    return get_string(strtolower($englishname), 'calendar');
+}
+
+function calendar_days_in_month($month, $year) {
+   return date('t', mktime(0, 0, 0, $month, 1, $year));
+}
+
+function calendar_get_sideblock_upcoming($courses, $groups, $users, $daysinfuture, $maxevents) {
+    $events = calendar_get_upcoming($courses, $groups, $users, $daysinfuture, $maxevents);
+
+    $content = '';
+    $lines = count($events);
+    if(!$lines) return $content;
+
+    for($i = 0; $i < $lines; ++$i) {
+        $content .= '<div class="cal_event">'.$events[$i]->icon.' ';
+        $content .= $events[$i]->name.':';
+        if(!empty($events[$i]->icon)) {
+            // That's an activity event, so let's provide the hyperlink
+            $content .= ' '.$events[$i]->referer;
+        }
+        $content .= '</div><div class="cal_event_date">'.$events[$i]->time.'</div>';
+        if($i < $lines - 1) $content .= '<hr />';
+    }
+
+    return $content;
+
+}
+
+function calendar_add_month($month, $year) {
+    if($month == 12) {
+        return array(1, $year + 1);
+    }
+    else {
+        return array($month + 1, $year);
+    }
+}
+
+function calendar_sub_month($month, $year) {
+    if($month == 1) {
+        return array(12, $year - 1);
+    }
+    else {
+        return array($month - 1, $year);
+    }
+}
+
+function calendar_events_by_day($events, $starttime, &$eventsbyday, &$durationbyday, &$typesbyday) {
+    $eventsbyday = array();
+    $typesbyday = array();
+    $durationbyday = array();
+
+    if($events === false) {
+        return;
+    }
+
+    // Reverse TZ compensation: make GMT stamps (from event table) correspond to user's TZ
+    $tzfix = calendar_get_tz_offset();
+
+    foreach($events as $event) {
+        $eventdaystart = 1 + floor(($event->timestart + $tzfix - $starttime) / SECS_IN_DAY);
+        $eventdayend = 1 + floor(($event->timestart + $event->timeduration + $tzfix - $starttime) / SECS_IN_DAY);
+
+        // Give the event to its day
+        $eventsbyday[$eventdaystart][] = $event->id;
+
+        // Mark the day as having such an event
+        if($event->courseid == 1 && $event->groupid == 0) {
+            $typesbyday[$eventdaystart]['startglobal'] = true;
+        }
+        else if($event->courseid > 1 && $event->groupid == 0) {
+            $typesbyday[$eventdaystart]['startcourse'] = true;
+        }
+        else if($event->groupid) {
+            $typesbyday[$eventdaystart]['startgroup'] = true;
+        }
+        else if($event->userid) {
+            $typesbyday[$eventdaystart]['startuser'] = true;
+        }
+
+        // Mark all days up to and including ending day as duration
+        if($eventdaystart < $eventdayend) {
+
+            // Normally this should be
+
+            // $bound = min($eventdayend, $display->maxdays);
+            // for($i = $eventdaystart + 1; $i <= $bound; ++$i) {
+
+            // So that we don't go on marking days after the end of
+            // the month if the event continues. However, this code
+            // has moved and now we don't have access to $display->maxdays.
+            // In order to save the overhead of recomputing it, we just
+            // use this "dumb" approach. Anyway, the function that called
+            // us already knows up to what day it should display.
+
+            for($i = $eventdaystart + 1; $i <= $eventdayend; ++$i) {
+                $durationbyday[$i][] = $event->id;
+                if($event->courseid == 1 && $event->groupid == 0) {
+                    $typesbyday[$i]['durationglobal'] = true;
+                }
+                else if($event->courseid > 1 && $event->groupid == 0) {
+                    $typesbyday[$i]['durationcourse'] = true;
+                }
+                else if($event->groupid) {
+                    $typesbyday[$i]['durationgroup'] = true;
+                }
+                else if($event->userid) {
+                    $typesbyday[$i]['durationuser'] = true;
+                }
+            }
+        }
+    }
+    return;
+}
+
+function calendar_get_module_cached(&$coursecache, $modulename, $instance, $courseid) {
+    $module = get_coursemodule_from_instance($modulename, $instance, $courseid);
+
+    if($module === false) return false;
+    if(!calendar_get_course_cached($coursecache, $courseid)) {
+        return false;
+    }
+    return $module;
+}
+
+function calendar_get_course_cached(&$coursecache, $courseid) {
+    if(!isset($coursecache[$courseid])) {
+        $coursecache[$courseid] = get_record('course', 'id', $courseid);
+    }
+    return $coursecache[$courseid];
+}
+
+function calendar_session_vars() {
+    global $SESSION, $USER;
+
+    if(!isset($SESSION->cal_course_referer)) {
+        $SESSION->cal_course_referer = 0;
+    }
+    if(!isset($SESSION->cal_show_global)) {
+        $SESSION->cal_show_global = true;
+    }
+    if(!isset($SESSION->cal_show_groups)) {
+        $SESSION->cal_show_groups = true;
+    }
+    if(!isset($SESSION->cal_show_course)) {
+        $SESSION->cal_show_course = true;
+    }
+    if(!isset($SESSION->cal_show_user)) {
+        $SESSION->cal_show_user = $USER->id;
+    }
+}
+
+function calendar_overlib_html() {
+    global $CFG;
+
+    $html = '';
+    $html .= '<div id="overDiv" style="position: absolute; visibility: hidden; z-index:1000;"></div>';
+    $html .= '<script type="text/javascript" src="'.CALENDAR_URL.'overlib.cfg.php"></script>';
+
+    return $html;
+}
+
+function calendar_print_side_blocks($forcecourse = NULL) {
+    // WARNING: Keep in mind that using $forcecourse will override the $SESSION
+    // filters, and thus not respect the user's filter settings. Use it sparingly.
+
+    global $USER, $CFG, $SESSION, $course;
+    optional_variable($_GET['cal_m']);
+    optional_variable($_GET['cal_y']);
+
+    calendar_session_vars();
+
+    if(is_int($forcecourse)) {
+        // Overrides the course to use
+        $courseshown = $forcecourse;
+        $defaultcourses = array($courseshown => 1);
+    }
+    else if($forcecourse === false) {
+        // Overrides: use no course at all
+        $courseshown = false;
+        $defaultcourses = NULL;
+    }
+    else {
+        // Normal behavior: use displayed course, or front page if no course
+        $courseshown = ($course === NULL) ? 1 : $course->id;
+        $defaultcourses = array($courseshown => 1);
+    }
+
+    // I 'm not really sure if this belongs here...
+    calendar_set_referring_course($courseshown);
+
+    if($courseshown !== false && is_int($SESSION->cal_show_course) && $SESSION->cal_show_course != $courseshown) {
+        // There is a filter in action that shows events from a course other than the current
+        // Obviously we have to cut it out
+        $SESSION->cal_show_course = true;
+    }
+   else if($courseshown !== false && is_array($SESSION->cal_show_course) && !in_array($courseshown, $SESSION->cal_show_course)) {
+        // Same as above, only there are many courses being shown. Unfortunately, not this one.
+        $SESSION->cal_show_course = true;
+    }
+
+    // Be VERY careful with the format for default courses arguments!
+    // Correct formatting is [courseid] => 1 to be concise with moodlelib.php functions.
+
+    calendar_set_filters($courses, $group, $user, $defaultcourses, $defaultcourses);
+
+    if(get_user_preferences('calendar_showmonth', true)) {
+        if($courseshown == 1) {
+            // For the front page
+            echo calendar_overlib_html();
+            print_side_block_start(get_string('calendar', 'calendar'));
+            echo calendar_top_controls('frontpage', array('m' => $_GET['cal_m'], 'y' => $_GET['cal_y']));
+            echo calendar_get_mini($courses, $group, $user, $_GET['cal_m'], $_GET['cal_y']);
+            // No filters for now
+            print_side_block_end();
+        }
+        else {
+            // For any other course
+            echo calendar_overlib_html();
+            print_side_block_start(get_string('calendar', 'calendar'));
+            echo calendar_top_controls('course', array('id' => $courseshown, 'm' => $_GET['cal_m'], 'y' => $_GET['cal_y']));
+            echo calendar_get_mini($courses, $group, $user, $_GET['cal_m'], $_GET['cal_y']);
+            echo calendar_filter_controls('course');
+            print_side_block_end();
+        }
+    }
+    if(get_user_preferences('calendar_showupcoming', true)) {
+        $block = calendar_get_sideblock_upcoming($courses, $group, $user, get_user_preferences('calendar_lookahead', CALENDAR_UPCOMING_DAYS), get_user_preferences('calendar_maxevents', CALENDAR_UPCOMING_MAXEVENTS));
+        if(!empty($block)) {
+            print_side_block_start(get_string('upcomingevents', 'calendar'));
+            echo $block;
+            print_side_block_end();
+        }
+    }
+}
+
+function calendar_set_referring_course($courseid) {
+    global $SESSION;
+    $SESSION->cal_course_referer = intval($courseid);
+}
+
+function calendar_set_filters(&$courses, &$group, &$user, $defaultcourses = NULL, $groupcourses = NULL) {
+    global $SESSION, $USER;
+
+    // WARNING: When calling this function, be VERY careful with the format for default courses arguments!
+    // Correct formatting is [courseid] => 1 to be concise with moodlelib.php functions.
+
+    $showcourse = (
+        (is_int($SESSION->cal_show_course) && $SESSION->cal_show_course) ||
+        (is_array($SESSION->cal_show_course) && count($SESSION->cal_show_course)) ||
+        ($SESSION->cal_show_course === true)
+    );
+    if($defaultcourses === NULL) {
+        $defaultcourses = array();
+    }
+    if($groupcourses === NULL) {
+        $groupcourses = array();
+    }
+
+    if(is_array($defaultcourses) && array_key_exists(1, $defaultcourses)) {
+        // This should never happen, so let's be sure just in case
+        $defaultcourses = array_diff_assoc($defaultcourses, array(1 => 1));
+    }
+
+    if($showcourse && $SESSION->cal_show_global) {
+        if(is_int($SESSION->cal_show_course)) {
+            $courses = array(1, $SESSION->cal_show_course);
+        }
+        else if(is_array($SESSION->cal_show_course)) {
+            $courses = array(1) + $SESSION->cal_show_course;
+
+        }
+        else {
+            $courses = array_keys($defaultcourses);
+            $courses[] = 1;
+        }
+    }
+    else if($showcourse) {
+        if(is_int($SESSION->cal_show_course)) {
+            $courses = array($SESSION->cal_show_course);
+        }
+        else if(is_array($SESSION->cal_show_course)) {
+            $courses = $SESSION->cal_show_course;
+        }
+        else {
+            $courses = array_keys($defaultcourses);
+            if(empty($courses)) $courses = false;
+        }
+    }
+    else if($SESSION->cal_show_global) {
+        $courses = array(1);
+    }
+    else {
+        $courses = false;
+    }
+
+    if($SESSION->cal_show_user) {
+        $user = $SESSION->cal_show_user;
+    }
+    else {
+        $user = false;
+    }
+    if($SESSION->cal_show_groups) {
+        if(is_int($groupcourses)) {
+            // One course, whatever group the user is in that course
+            if(mygroupid($groupcourses)) {
+                $group = mygroupid($groupcourses);
+            }
+            else {
+                $group = false;
+            }
+        }
+        else if(is_array($groupcourses)) {
+            // Many courses, we want all of them
+            if(empty($USER->groupmember)) {
+                $group = false;
+            }
+            else {
+                $grouparray = array();
+                foreach ($USER->groupmember as $courseid => $mgroupid) {
+                    if (in_array($courseid, $groupcourses)) {
+                        $grouparray[] = $mgroupid;
+                    }
+                }
+                if(!empty($grouparray)) {
+                    // We got some groups at the least
+                    $group = $grouparray;
+                }
+                else {
+                    // No groups in these courses
+                    $group = false;
+                }
+            }
+        }
+        else if(is_bool($groupcourses)) {
+            // Override
+            $group = $groupcourses;
+        }
+        else {
+            // Sanity
+            $group = false;
+        }
+    }
+    else {
+        $group = false;
+    }
+}
+
+function calendar_edit_event_allowed($event) {
+    global $USER;
+
+    if(isadmin($USER->id)) return true; // Admins are allowed anything
+
+    if($event->courseid > 1) {
+        // Course event, only editing teachers may... edit :P
+        if(isteacheredit($event->courseid)) {
+            return true;
+        }
+    }
+    else if($event->courseid == 0 && $event->groupid != 0) {
+        // Group event
+        $group = get_record('groups', 'id', $event->groupid);
+        if($group === false) return false;
+        if(isteacheredit($group->courseid)) {
+            return true;
+        }
+    }
+    else if($event->courseid == 0 && $event->groupid == 0 && $event->userid == $USER->id) {
+        // User event, owned by this user
+        return true;
+    }
+
+    return false;
+}
+
+function calendar_get_default_courses() {
+    global $USER;
+
+    $courses = array();
+    if(is_array($USER->student)) {
+        $courses = $USER->student + $courses;
+    }
+    if(is_array($USER->teacher)) {
+        $courses = $USER->teacher + $courses;
+    }
+    return $courses;
+}
+
+// NOTE: This function is obsolete. But let's not kill it just yet.
+/*
+function calendar_print_preferences_menu() {
+
+    // Guests have no preferences
+    if(isguest()) {
+        return;
+    }
+
+    print_side_block_start(get_string('preferences', 'calendar'), '', 'mycalendar');
+    echo '<div style="text-align: center;"><table style="margin: auto; text-align: center;"><tr>';
+    $prefs = array(
+        'startwday' => get_string('pref_startwday', 'calendar'),
+        'maxevents' => get_string('pref_maxevents', 'calendar'),
+        'lookahead' => get_string('pref_lookahead', 'calendar'),
+    );
+    foreach($prefs as $name => $description) {
+        echo '<td style="padding: 0px 20px;"><a href="preferences.php?edit='.$name.'"><img src="images/'.$name.'.gif" alt="'.$description.'" title="'.$description.'" /><div style="font-size: 0.6em;">'.$description.'</div></a></td>';
+    }
+    echo '</tr></table></div>';
+    print_side_block_end();
+}
+*/
+
+function calendar_get_tz_offset() {
+    global $USER, $CFG;
+    static $tzfix;
+
+    // Caching
+    if(isset($tzfix)) {
+        return $tzfix;
+    }
+
+    if(empty($USER)) {
+        // Don't forget that there are users which have NOT logged in, even as guests
+        $timezone = $CFG->timezone;
+    }
+    else {
+        // If, on the other hand, we do have a user...
+        $timezone = $USER->timezone;
+        if(abs($timezone > 13)) {
+            // But if the user has specified 'server default' time,
+            // don't get the server's; get the Moodle $CFG setting
+            // (Martin's help text on site cfg implies this)
+            $timezone = $CFG->timezone;
+        }
+    }
+
+    if(abs($timezone) <= 13) {
+        $tzfix = $timezone * 3600;
+    }
+    else {
+        $tzfix = date('Z', $starttime);
+    }
+
+    return $tzfix;
+}
+
+function calendar_preferences_array() {
+    return array(
+        'startwday' => get_string('pref_startwday', 'calendar'),
+        'maxevents' => get_string('pref_maxevents', 'calendar'),
+        'lookahead' => get_string('pref_lookahead', 'calendar'),
+    );
+}
+
+function calendar_get_preferences_menu() {
+
+    // Guests have no preferences
+    if(isguest()) {
+        return '';
+    }
+
+    $str = '<form style="display: inline;" name="cal_pref_form" method="get" action="preferences.php">';
+    $str .= '<select id="cal_pref" name="edit" onchange="self.location=\'preferences.php?edit=\'+document.cal_pref_form.cal_pref.options[document.cal_pref_form.cal_pref.options.selectedIndex].value; ">';
+    $str .= '<option value="" selected="selected">'.get_string('preferences', 'calendar').'...</option>';
+    $prefs = calendar_preferences_array();
+
+    foreach($prefs as $name => $description) {
+        $str .= '<option value="'.$name.'">'.$description.'</option>';
+    }
+    $str .= '</select>';
+    $str .= '<noscript id="cal_noscript" style="display: inline;"> <input type="submit" value=" &gt; " /></noscript>';
+    $str .= '<script type="text/javascript">document.getElementById("cal_noscript").style.display = "none";</script>';
+    $str .= '</form>';
+
+    return $str;
+}
+
+if(!function_exists('array_diff_assoc')) {
+    // PHP < 4.3.0
+    function array_diff_assoc($source, $diff) {
+        $res = $source;
+        foreach ($diff as $key=>$data) {
+            unset($res[$key]);
+        }
+        return $res;
+    }
+}
+
+?>
diff --git a/calendar/overlib.cfg.php b/calendar/overlib.cfg.php
new file mode 100644 (file)
index 0000000..b4cbb39
--- /dev/null
@@ -0,0 +1,10 @@
+ol_delay = 1000;\r
+ol_css = CSSCLASS;\r
+ol_fgclass = 'cal_popup_fg';\r
+ol_bgclass = 'cal_popup_bg';\r
+ol_captionfontclass = 'cal_popup_caption';\r
+ol_closefontclass = 'cal_popup_close';\r
+ol_closeclick = true;\r
+ol_sticky = true;\r
+ol_close = 'X';\r
+ol_offsety = -20;\r
diff --git a/calendar/preferences.php b/calendar/preferences.php
new file mode 100644 (file)
index 0000000..5cc3d5f
--- /dev/null
@@ -0,0 +1,280 @@
+<?php // $Id$
+
+/////////////////////////////////////////////////////////////////////////////
+//                                                                         //
+// NOTICE OF COPYRIGHT                                                     //
+//                                                                         //
+// Moodle - Calendar extension                                             //
+//                                                                         //
+// Copyright (C) 2003-2004  Greek School Network            www.sch.gr     //
+//                                                                         //
+// Designed by:                                                            //
+//     Avgoustos Tsinakos (tsinakos@uom.gr)                                //
+//     Jon Papaioannou (pj@uom.gr)                                         //
+//                                                                         //
+// Programming and development:                                            //
+//     Jon Papaioannou (pj@uom.gr)                                         //
+//                                                                         //
+// For bugs, suggestions, etc contact:                                     //
+//     Jon Papaioannou (pj@uom.gr)                                         //
+//                                                                         //
+// The current module was developed at the University of Macedonia         //
+// (www.uom.gr) under the funding of the Greek School Network (www.sch.gr) //
+// The aim of this project is to provide additional and improved           //
+// functionality to the Asynchronous Distance Education service that the   //
+// Greek School Network deploys.                                           //
+//                                                                         //
+// This program is free software; you can redistribute it and/or modify    //
+// it under the terms of the GNU General Public License as published by    //
+// the Free Software Foundation; either version 2 of the License, or       //
+// (at your option) any later version.                                     //
+//                                                                         //
+// This program is distributed in the hope that it will be useful,         //
+// but WITHOUT ANY WARRANTY; without even the implied warranty of          //
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the           //
+// GNU General Public License for more details:                            //
+//                                                                         //
+//          http://www.gnu.org/copyleft/gpl.html                           //
+//                                                                         //
+/////////////////////////////////////////////////////////////////////////////
+
+    //  Edit calendar preferences
+
+    require_once('../config.php');
+    require_once('lib.php');
+    require_once('../course/lib.php');
+    require_once('../mod/forum/lib.php');
+
+    require_login();
+
+    if(!$site = get_site()) {
+        redirect($CFG->wwwroot.'/'.$CFG->admin.'/index.php');
+    }
+    if(isguest()) {
+        redirect($CFG->wwwroot.'/index.php');
+    }
+
+    optional_variable($_GET['edit'], '');
+    optional_variable($_GET['commit'], 0);
+    $knownpreference = false; // Defensive coding: let's be suspicious from the beginning
+    $prefs = calendar_preferences_array(); // Get this now, we 'll be using it all the time
+
+    if(in_array($_GET['edit'], array_keys($prefs))) {
+        // If we know this preference, you 'll get to see the setting page
+        $knownpreference = true;
+    }
+
+    if($_GET['commit']) {
+        switch($_GET['edit']) {
+            case 'startwday':
+                $day = intval($_GET[$_GET['edit']]);
+                if($day < 0 || $day > 6) {
+                    $day = abs($day % 7);
+                }
+                set_user_preference('calendar_'.$_GET['edit'], $day);
+            break;
+            case 'maxevents':
+                $events = intval($_GET[$_GET['edit']]);
+                if($events >= 1) {
+                    set_user_preference('calendar_'.$_GET['edit'], $events);
+                }
+            break;
+            case 'lookahead':
+                $days = intval($_GET[$_GET['edit']]);
+                if($days >= 1) {
+                    set_user_preference('calendar_'.$_GET['edit'], $days);
+                }
+            break;
+        }
+        // Use this trick to get back to the preferences list after editing one
+        $knownpreference = false;
+        $_GET['edit'] = '';
+    }
+
+    $firstcolumn = false;  // for now
+    $side = 175;
+
+    calendar_session_vars();
+
+    $now = usergetdate(time());
+    $pagetitle = get_string('preferences', 'calendar');
+    $nav = calendar_get_link_tag(get_string('calendar', 'calendar'), $CFG->wwwroot.'/calendar/view.php?view=upcoming&amp;', $now['mday'], $now['mon'], $now['year']);
+    if($knownpreference) {
+        $nav .= ' -> <a href="'.$CFG->wwwroot.'/calendar/preferences.php">'.$pagetitle.'</a> -> '.$prefs[$_GET['edit']];
+    }
+    else {
+        $nav .= ' -> '.$pagetitle;
+    }
+
+    // Let's see if we are supposed to provide a referring course link
+    // but NOT for the front page
+    if($SESSION->cal_course_referer > 1 &&
+      ($shortname = get_field('course', 'shortname', 'id', $SESSION->cal_course_referer)) !== false) {
+        // If we know about the referring course, show a return link
+        $nav = '<a href="'.$CFG->wwwroot.'/course/view.php?id='.$SESSION->cal_course_referer.'">'.$shortname.'</a> -> '.$nav;
+    }
+
+    print_header(get_string('calendar', 'calendar').': '.$pagetitle, $site->fullname, $nav,
+                 '', '', true, '', '<p class="logininfo">'.user_login_string($site).'</p>');
+
+    echo calendar_overlib_html();
+
+    // Layout the whole page as three big columns.
+    echo '<table border="0" cellpadding="3" cellspacing="0" width="100%">';
+
+    // START: The left column
+    echo '<tr valign="top"><td valign="top" width="180">';
+
+    $sections = get_all_sections($site->id);
+
+    if ($site->newsitems > 0 or $sections[0]->sequence or isediting($site->id) or isadmin()) {
+        echo "<td width=\"$side\" valign=top nowrap>";
+        $firstcolumn=true;
+
+        if ($sections[0]->sequence or isediting($site->id)) {
+            get_all_mods($site->id, $mods, $modnames, $modnamesplural, $modnamesused);
+            print_section_block(get_string("mainmenu"), $site, $sections[0],
+                                 $mods, $modnames, $modnamesused, true, $side);
+        }
+
+        print_courses_sideblock(0, $side);
+        if ($site->newsitems) {
+            if ($news = forum_get_course_forum($site->id, "news")) {
+                print_side_block_start(get_string("latestnews"), $side, "sideblocklatestnews");
+                echo "<font size=\"-2\">";
+                forum_print_latest_discussions($news->id, $site->newsitems, "minimal", "", false);
+                echo "</font>";
+                print_side_block_end();
+            }
+        }
+        print_spacer(1,$side);
+    }
+
+    if (iscreator()) {
+        if (!$firstcolumn) {
+            echo "<td width=\"$side\" valign=top nowrap>";
+            $firstcolumn=true;
+        }
+        print_admin_links($site->id, $side);
+    }
+
+    if ($firstcolumn) {
+        echo '</td>';
+    }
+    // END: The left column
+
+    // START: Middle column
+    echo '<td width="70%" valign="top\">';
+
+    $text = '<div style="float: left;">'.get_string('calendarheading', 'calendar', strip_tags($site->shortname)).'</div><div style="float: right;">';
+    $text.= calendar_get_preferences_menu();
+    $text.= '</div>';
+
+    print_heading_block($text);
+    print_spacer(8,1);
+
+    $defaultcourses = calendar_get_default_courses();
+
+    $courses = array();
+
+    calendar_set_filters($courses, $groups, $users, $defaultcourses, $defaultcourses);
+
+    $day = $now['mday'];
+    $mon = $now['mon'];
+    $yr = $now['year'];
+
+    if($knownpreference) {
+        print_side_block_start($prefs[$_GET['edit']], '', 'mycalendar');
+        echo '<form name="preference" method="get" action="preferences.php"><p style="text-align: justify;">';
+        print_string('explain_'.$_GET['edit'], 'calendar');
+        echo '</p><div style="text-align: center;"><table style="margin: auto;"><tr>';
+        echo '<td><strong>'.$prefs[$_GET['edit']].':</strong></td>';
+    }
+
+    switch($_GET['edit']) {
+        case 'startwday':
+            echo '<td>';
+            $days = array(
+                get_string('sunday', 'calendar'), get_string('monday', 'calendar'),
+                get_string('tuesday', 'calendar'), get_string('wednesday', 'calendar'),
+                get_string('thursday', 'calendar'), get_string('friday', 'calendar'),
+                get_string('saturday', 'calendar'));
+            choose_from_menu($days, 'startwday', get_user_preferences('calendar_startwday', CALENDAR_STARTING_WEEKDAY), '');
+            echo '</td>';
+        break;
+        case 'maxevents':
+            echo '<td><input type="text" name="maxevents" size="5" value="'.get_user_preferences('calendar_maxevents', CALENDAR_UPCOMING_MAXEVENTS).'" /></td>';
+        break;
+        case 'lookahead':
+            echo '<td><input type="text" name="lookahead" size="5" value="'.get_user_preferences('calendar_lookahead', CALENDAR_UPCOMING_DAYS).'" /></td>';
+        break;
+        default:
+            // Print a form displaying all the preferences and their values
+            print_side_block_start(get_string('preferences', 'calendar'), '', 'mycalendar');
+            echo '<div style="text-align: center; font-weight: bold;">'.get_string('preferences_available', 'calendar').'</div>';
+            echo '<p style="text-align: center;"><table style="width: 100%">';
+
+            // Get the actual values of all preferences
+            $values = array();
+            foreach($prefs as $name => $description) {
+                $values[$name] = get_user_preferences('calendar_'.$name);
+            }
+
+            // Fix 'display-friendly' values now
+            $days = array(
+                get_string('sunday', 'calendar'), get_string('monday', 'calendar'),
+                get_string('tuesday', 'calendar'), get_string('wednesday', 'calendar'),
+                get_string('thursday', 'calendar'), get_string('friday', 'calendar'),
+                get_string('saturday', 'calendar'));
+            $values['startwday'] = $days[$values['startwday']];
+
+            // OK, display them
+            foreach($prefs as $name => $description) {
+                echo '<tr><td style="text-align: right; width: 50%;"><a href="preferences.php?edit='.$name.'">'.$description.'</a>:</td>';
+                echo '<td>'.($values[$name] === NULL?get_string('default', 'calendar'):$values[$name]) .'</td></tr>';
+            }
+
+            // Done
+            echo '</table></p>';
+            print_side_block_end();
+        break;
+    }
+
+    if($knownpreference) {
+        echo '</tr></table>';
+        echo '<p><input type="submit" value=" '.get_string('ok').' "/></p>';
+        echo '</div>';
+        echo '<p><input type="hidden" name="commit" value="1" /><input type="hidden" name="edit" value="'.$_GET['edit'].'" />';
+        echo '</form>';
+        print_side_block_end();
+    }
+
+    echo '</td>';
+    // END: Middle column
+
+    // START: Last column (3-month display)
+    echo '<td valign="top">';
+    print_side_block_start(get_string('monthlyview', 'calendar'), '', 'sideblockmain');
+    list($prevmon, $prevyr) = calendar_sub_month($mon, $yr);
+    list($nextmon, $nextyr) = calendar_add_month($mon, $yr);
+
+    echo calendar_filter_controls($_GET['view']);
+    echo '<p>';
+    echo calendar_top_controls('display', array('m' => $prevmon, 'y' => $prevyr));
+    echo calendar_get_mini($courses, $groups, $users, $prevmon, $prevyr);
+    echo '</p><p>';
+    echo calendar_top_controls('display', array('m' => $mon, 'y' => $yr));
+    echo calendar_get_mini($courses, $groups, $users, $mon, $yr);
+    echo '</p><p>';
+    echo calendar_top_controls('display', array('m' => $nextmon, 'y' => $nextyr));
+    echo calendar_get_mini($courses, $groups, $users, $nextmon, $nextyr);
+    echo '</p>';
+    print_side_block_end();
+    print_spacer(1, $side);
+    echo '</td>';
+    // START: Last column (3-month display)
+
+    echo '</tr></table>';
+    print_footer();
+
+?>
diff --git a/calendar/set.php b/calendar/set.php
new file mode 100644 (file)
index 0000000..bf4af68
--- /dev/null
@@ -0,0 +1,110 @@
+<?php // $Id$
+
+/////////////////////////////////////////////////////////////////////////////
+//                                                                         //
+// NOTICE OF COPYRIGHT                                                     //
+//                                                                         //
+// Moodle - Calendar extension                                             //
+//                                                                         //
+// Copyright (C) 2003-2004  Greek School Network            www.sch.gr     //
+//                                                                         //
+// Designed by:                                                            //
+//     Avgoustos Tsinakos (tsinakos@uom.gr)                                //
+//     Jon Papaioannou (pj@uom.gr)                                         //
+//                                                                         //
+// Programming and development:                                            //
+//     Jon Papaioannou (pj@uom.gr)                                         //
+//                                                                         //
+// For bugs, suggestions, etc contact:                                     //
+//     Jon Papaioannou (pj@uom.gr)                                         //
+//                                                                         //
+// The current module was developed at the University of Macedonia         //
+// (www.uom.gr) under the funding of the Greek School Network (www.sch.gr) //
+// The aim of this project is to provide additional and improved           //
+// functionality to the Asynchronous Distance Education service that the   //
+// Greek School Network deploys.                                           //
+//                                                                         //
+// This program is free software; you can redistribute it and/or modify    //
+// it under the terms of the GNU General Public License as published by    //
+// the Free Software Foundation; either version 2 of the License, or       //
+// (at your option) any later version.                                     //
+//                                                                         //
+// This program is distributed in the hope that it will be useful,         //
+// but WITHOUT ANY WARRANTY; without even the implied warranty of          //
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the           //
+// GNU General Public License for more details:                            //
+//                                                                         //
+//          http://www.gnu.org/copyleft/gpl.html                           //
+//                                                                         //
+/////////////////////////////////////////////////////////////////////////////
+
+       require_once('../config.php');
+       require_once('lib.php');
+
+       require_login();
+
+       require_variable($_GET['from']);
+       require_variable($_GET['var']);
+       optional_variable($_GET['value']);
+       optional_variable($_GET['id']);
+       optional_variable($_GET['cal_d']);
+       optional_variable($_GET['cal_m']);
+       optional_variable($_GET['cal_y']);
+
+       switch($_GET['var']) {
+               case 'setcourse':
+                       $id = intval($_GET['id']);
+                       if($id == 0) {
+                               $SESSION->cal_show_course = false;
+                       }
+                       else if($id == 1) {
+                               $SESSION->cal_show_course = true;
+                       }
+                       else if(isstudent($id, $USER->id) || isteacher($id, $USER->id)) {
+                               $SESSION->cal_show_course = $id;
+                       }
+               break;
+               case 'showgroups':
+                       $SESSION->cal_show_groups = !$SESSION->cal_show_groups;
+               break;
+               case 'showcourses':
+                       if($SESSION->cal_show_course) {
+                               $SESSION->cal_show_course = false;
+                       }
+                       else {
+                               $SESSION->cal_show_course = true;
+                       }
+               break;
+               case 'showglobal':
+                       $SESSION->cal_show_global = !$SESSION->cal_show_global;
+               break;
+               case 'showuser':
+                       if($SESSION->cal_show_user) {
+                               $SESSION->cal_show_user = false;
+                       }
+                       else {
+                               $SESSION->cal_show_user = $USER->id;
+                       }
+               break;
+       }
+
+       switch($_GET['from']) {
+               case 'month':
+       redirect($CFG->wwwroot.'/calendar/view.php?view=month&cal_d='.$_GET['cal_d'].'&cal_m='.$_GET['cal_m'].'&cal_y='.$_GET['cal_y']);
+               break;
+               case 'upcoming':
+               redirect($CFG->wwwroot.'/calendar/view.php?view=upcoming&cal_d='.$_GET['cal_d'].'&cal_m='.$_GET['cal_m'].'&cal_y='.$_GET['cal_y']);
+               break;
+               case 'event':
+               redirect($CFG->wwwroot.'/calendar/view.php?view=event&id='.$_GET['id']);
+               break;
+               case 'day':
+               redirect($CFG->wwwroot.'/calendar/view.php?view=day&cal_d='.$_GET['cal_d'].'&cal_m='.$_GET['cal_m'].'&cal_y='.$_GET['cal_y']);
+               break;
+               case 'course':
+               redirect($CFG->wwwroot.'/course/view.php?id='.intval($_GET['id']));
+               break;
+               default:
+
+       }
+?>
diff --git a/calendar/view.php b/calendar/view.php
new file mode 100644 (file)
index 0000000..786c138
--- /dev/null
@@ -0,0 +1,719 @@
+<?php // $Id$
+
+/////////////////////////////////////////////////////////////////////////////
+//                                                                         //
+// NOTICE OF COPYRIGHT                                                     //
+//                                                                         //
+// Moodle - Calendar extension                                             //
+//                                                                         //
+// Copyright (C) 2003-2004  Greek School Network            www.sch.gr     //
+//                                                                         //
+// Designed by:                                                            //
+//     Avgoustos Tsinakos (tsinakos@uom.gr)                                //
+//     Jon Papaioannou (pj@uom.gr)                                         //
+//                                                                         //
+// Programming and development:                                            //
+//     Jon Papaioannou (pj@uom.gr)                                         //
+//                                                                         //
+// For bugs, suggestions, etc contact:                                     //
+//     Jon Papaioannou (pj@uom.gr)                                         //
+//                                                                         //
+// The current module was developed at the University of Macedonia         //
+// (www.uom.gr) under the funding of the Greek School Network (www.sch.gr) //
+// The aim of this project is to provide additional and improved           //
+// functionality to the Asynchronous Distance Education service that the   //
+// Greek School Network deploys.                                           //
+//                                                                         //
+// This program is free software; you can redistribute it and/or modify    //
+// it under the terms of the GNU General Public License as published by    //
+// the Free Software Foundation; either version 2 of the License, or       //
+// (at your option) any later version.                                     //
+//                                                                         //
+// This program is distributed in the hope that it will be useful,         //
+// but WITHOUT ANY WARRANTY; without even the implied warranty of          //
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the           //
+// GNU General Public License for more details:                            //
+//                                                                         //
+//          http://www.gnu.org/copyleft/gpl.html                           //
+//                                                                         //
+/////////////////////////////////////////////////////////////////////////////
+
+//  Display the calendar page.
+
+    require_once('../config.php');
+    require_once('lib.php');
+    require_once('../course/lib.php');
+    require_once('../mod/forum/lib.php');
+
+    require_variable($_GET['view']);
+    optional_variable($_GET['cal_d']);
+    optional_variable($_GET['cal_m']);
+    optional_variable($_GET['cal_y']);
+
+    if(!$site = get_site()) {
+        redirect($CFG->wwwroot.'/'.$CFG->admin.'/index.php');
+    }
+
+    //add_to_log($course->id, "course", "view", "view.php?id=$course->id", "$course->id");
+
+    $firstcolumn = false;  // for now
+    $lastcolumn = true;   // for now
+    $side = 175;
+
+    $prefmenu = true; // By default, display it
+    calendar_session_vars();
+    $now = usergetdate(time());
+    $pagetitle = '';
+
+    $nav = calendar_get_link_tag(get_string('calendar', 'calendar'), CALENDAR_URL.'view.php?view=upcoming&amp;', $now['mday'], $now['mon'], $now['year']);
+
+    // Make sure that the GET variables are correct
+    $day = intval($_GET['cal_d']);
+    $mon = intval($_GET['cal_m']);
+    $yr = intval($_GET['cal_y']);
+    if(!checkdate($mon, $day, $yr)) {
+        $day = intval($now['mday']);
+        $mon = intval($now['mon']);
+        $yr = intval($now['year']);
+    }
+
+    switch($_GET['view']) {
+        case 'day':
+            $nav .= ' -> '.$day.' '.calendar_month_name($mon).' '.$yr;
+            $pagetitle = get_string('dayview', 'calendar');
+        break;
+        case 'month':
+            $nav .= ' -> '.calendar_month_name($mon).' '.$yr;
+            $pagetitle = get_string('detailedmonthview', 'calendar');
+            $lastcolumn = false;
+        break;
+        case 'upcoming':
+            $pagetitle = get_string('upcomingevents', 'calendar');
+        break;
+        case 'event':
+            $pagetitle = get_string('eventview', 'calendar');
+            $nav .= ' -> '.$pagetitle; // Smart guy... :)
+        break;
+    }
+
+    // Let's see if we are supposed to provide a referring course link
+    // but NOT for the "main page" course
+    if($SESSION->cal_course_referer > 1 &&
+      ($shortname = get_field('course', 'shortname', 'id', $SESSION->cal_course_referer)) !== false) {
+        // If we know about the referring course, show a return link
+        $nav = '<a href="'.$CFG->wwwroot.'/course/view.php?id='.$SESSION->cal_course_referer.'">'.$shortname.'</a> -> '.$nav;
+    }
+
+    // Print title and header
+    if(!empty($pagetitle)) {
+        $pagetitle = ': '.$pagetitle;
+    }
+    print_header(get_string('calendar', 'calendar').$pagetitle, $site->fullname, $nav,
+                 '', '', true, '', '<p class="logininfo">'.user_login_string($site).'</p>');
+
+    echo calendar_overlib_html();
+
+    // Layout the whole page as three big columns.
+    echo '<table border="0" cellpadding="3" cellspacing="0" width="100%">';
+
+    // START: The left column ...
+    echo '<tr valign="top"><td valign="top" width="180">';
+
+    $sections = get_all_sections($site->id);
+
+    // Latest site news
+    if ($site->newsitems > 0 || $sections[0]->sequence || isediting($site->id) || isadmin()) {
+        echo "<td width=\"$side\" valign=top nowrap>";
+        $firstcolumn=true;
+
+        if ($sections[0]->sequence or isediting($site->id)) {
+            get_all_mods($site->id, $mods, $modnames, $modnamesplural, $modnamesused);
+            print_section_block(get_string("mainmenu"), $site, $sections[0],
+                                $mods, $modnames, $modnamesused, true, $side);
+        }
+        print_courses_sideblock(0, $side);
+        if ($site->newsitems) {
+            if ($news = forum_get_course_forum($site->id, "news")) {
+                print_side_block_start(get_string("latestnews"), $side, "sideblocklatestnews");
+                echo "<font size=\"-2\">";
+                forum_print_latest_discussions($news->id, $site->newsitems, "minimal", "", false);
+                echo "</font>";
+                print_side_block_end();
+            }
+        }
+        print_spacer(1,$side);
+    }
+
+    if (iscreator()) {
+        if (!$firstcolumn) {
+            echo "<td width=\"$side\" valign=top nowrap>";
+            $firstcolumn=true;
+        }
+        print_admin_links($site->id, $side);
+    }
+
+    if ($firstcolumn) {
+        echo '</td>';
+    }
+
+    // END: The left column
+
+    // START: Middle column
+    if ($lastcolumn) {
+        echo '<td width="70%" valign="top\">';
+    }
+    else {
+        echo '<td width="100%" valign="top">';
+    }
+
+    if($prefmenu) {
+        $text = '<div style="float: left;">'.get_string('calendarheading', 'calendar', strip_tags($site->shortname)).'</div><div style="float: right;">';
+        $text.= calendar_get_preferences_menu();
+        $text.= '</div>';
+    }
+    else {
+        $text = get_string('calendarheading', 'calendar', strip_tags($site->shortname));
+    }
+
+    print_heading_block($text);
+    print_spacer(8, 1);
+
+    $defaultcourses = calendar_get_default_courses();
+    $courses = array();
+
+    calendar_set_filters($courses, $groups, $users, $defaultcourses, $defaultcourses);
+
+    // Are we left with a bad filter in effect?
+    if($_GET['view'] != 'month') {
+        if(is_int($SESSION->cal_show_course)) {
+            // There is a filter in action that shows events from courses other than the current.
+            // Reset the filter... this effectively allows course filtering only in the month display.
+            // This filter resetting is also done in the course sideblock display, in case someone
+            // sets a filter for course X and then goes to view course Y.
+            $SESSION->cal_show_course = true;
+        }
+    }
+
+    switch($_GET['view']) {
+        case 'event':
+            optional_variable($_GET['id'], 0);
+            $event = get_record('event', 'id', intval($_GET['id']));
+            if($event === false) {
+                error('Invalid event id');
+            }
+            $date = calendar_show_event($event);
+            $day = $date['mday'];
+            $mon = $date['mon'];
+            $yr  = $date['year'];
+        break;
+        case 'day':
+            calendar_show_day($day, $mon, $yr, $courses, $groups, $users);
+        break;
+        case 'month':
+            calendar_show_month_detailed($mon, $yr, $courses, $groups, $users);
+        break;
+        case 'upcoming':
+            calendar_show_upcoming_events($courses, $groups, $users, get_user_preferences('calendar_lookahead', CALENDAR_UPCOMING_DAYS), get_user_preferences('calendar_maxevents', CALENDAR_UPCOMING_MAXEVENTS));
+        break;
+    }
+
+    echo '</td>';
+
+    // END: Middle column
+
+    // START: Last column (3-month display)
+    if ($lastcolumn) {
+        echo '<td valign="top">';
+        print_side_block_start(get_string('monthlyview', 'calendar'), '', 'sideblockmain');
+        list($prevmon, $prevyr) = calendar_sub_month($mon, $yr);
+        list($nextmon, $nextyr) = calendar_add_month($mon, $yr);
+        echo calendar_filter_controls($_GET['view']);
+        echo '<p>';
+        echo calendar_top_controls('display', array('m' => $prevmon, 'y' => $prevyr));
+        echo calendar_get_mini($courses, $groups, $users, $prevmon, $prevyr);
+        echo '</p><p>';
+        echo calendar_top_controls('display', array('m' => $mon, 'y' => $yr));
+        echo calendar_get_mini($courses, $groups, $users, $mon, $yr);
+        echo '</p><p>';
+        echo calendar_top_controls('display', array('m' => $nextmon, 'y' => $nextyr));
+        echo calendar_get_mini($courses, $groups, $users, $nextmon, $nextyr);
+        echo '</p>';
+        print_side_block_end();
+        print_spacer(1, $side);
+        echo '</td>';
+    }
+
+    echo '</tr></table>';
+    print_footer();
+
+function calendar_show_event($event) {
+    // In this case, we haven't been given month, day, year. So we 'll have to
+    // get them from the event date, and return them to the main function.
+
+    $startdate = usergetdate($event->timestart); // This is only to be returned
+    $coursecache = array();
+
+    print_side_block_start(get_string('eventview', 'calendar'), '', 'mycalendar');
+    calendar_print_event_table($event, $event->timestart, $event->timestart + $event->timeduration, $coursecache, true);
+    print_side_block_end();
+
+    return $startdate; // We need this to set "current" day, month, year
+}
+
+function calendar_show_day($d, $m, $y, $courses, $groups, $users) {
+    global $CFG, $THEME;
+
+    if(!checkdate($m, $d, $y)) {
+        $now = usergetdate(time());
+        list($d, $m, $y) = array(intval($now['mday']), intval($now['mon']), intval($now['year']));
+    }
+
+    $starttime = make_timestamp($y, $m, $d);
+    $endtime = $starttime + SECS_IN_DAY - 1;
+    $whereclause = calendar_sql_where($starttime, $endtime, $users, $groups, $courses);
+
+    if($whereclause === false) {
+        $events = array();
+    }
+    else {
+        $events = get_records_select('event', $whereclause);
+    }
+
+    // New event button
+    if(isguest()) {
+        $text = get_string('dayview', 'calendar');
+    }
+    else {
+        $text = '<div style="float: left;">'.get_string('dayview', 'calendar').'</div><div style="float: right;">';
+        $text.= '<form style="display: inline;" action="'.CALENDAR_URL.'event.php" method="get">';
+        $text.= '<input type="hidden" name="action" value="new" />';
+        $text.= '<input type="hidden" name="cal_m" value="'.$m.'" />';
+        $text.= '<input type="hidden" name="cal_y" value="'.$y.'" />';
+        $text.= '<input type="submit" value="'.get_string('newevent', 'calendar').'" />';
+        $text.= '</form></div>';
+    }
+
+    print_side_block_start($text, '', 'mycalendar');
+    echo '<p>'.calendar_top_controls('day', array('d' => $d, 'm' => $m, 'y' => $y)).'</p>';
+
+    if($events === false) {
+        // There is nothing to display today.
+        echo '<p style="text-align: center;">'.get_string('daywithnoevents', 'calendar').'</p>';
+    }
+    else {
+        $coursecache = array();
+        $summarize = array();
+
+        // First, print details about events that start today
+        foreach($events as $event) {
+            if($event->timestart >= $starttime && $event->timestart <= $endtime) {
+                // Print this
+                calendar_print_event_table($event, $starttime, $endtime, $coursecache);
+            }
+            else {
+                // Save this for later
+                $summarize[] = $event->id;
+            }
+        }
+
+        // Then, show a list of all events that just span this day
+        if(!empty($summarize)) {
+            $until = get_string('durationuntil', 'calendar');
+            echo '<p style="text-align: center;"><strong>'.get_string('spanningevents', 'calendar').':</strong></p>';
+            echo '<p style="text-align: center;"><ul>';
+            foreach($summarize as $index) {
+                $endstamp = $events[$index]->timestart + $events[$index]->timeduration;
+                $enddate = usergetdate($endstamp);
+                echo '<li><a href="view.php?view=event&amp;id='.$events[$index]->id.'">'.$events[$index]->name.'</a> ';
+                echo '('.$until.' <a href="'.calendar_get_link_href('view.php?view=day&amp;', $enddate['mday'], $enddate['mon'], $enddate['year']).'">';
+                echo calendar_day_representation($endstamp, false, false).'</a>)</li>';
+            }
+            echo '</ul></p>';
+        }
+    }
+
+    print_side_block_end();
+}
+
+function calendar_show_month_detailed($m, $y, $courses, $groups, $users) {
+    global $CFG, $SESSION, $USER;
+    global $day, $mon, $yr, $defaultcourses;
+
+    $getvars = 'from=month&amp;cal_d='.$day.'&amp;cal_m='.$mon.'&amp;cal_y='.$yr; // For filtering
+
+    $display = &New stdClass;
+    $display->minwday = get_user_preferences('calendar_startwday', CALENDAR_STARTING_WEEKDAY);
+    $display->maxwday = $display->minwday + 6;
+
+    if(!empty($m) && !empty($y)) {
+        $thisdate = usergetdate(time()); // Time and day at the user's location
+        if($m == $thisdate['mon'] && $y == $thisdate['year']) {
+            // Navigated to this month
+            $date = $thisdate;
+            $display->thismonth = true;
+        }
+        else {
+            // Navigated to other month, let's do a nice trick and save us a lot of work...
+            if(!checkdate($m, 1, $y)) {
+                $date = array('mday' => 1, 'mon' => $thisdate['mon'], 'year' => $thisdate['year']);
+                $display->thismonth = true;
+            }
+            else {
+                $date = array('mday' => 1, 'mon' => $m, 'year' => $y);
+                $display->thismonth = false;
+            }
+        }
+    }
+    else {
+        $date = usergetdate(time());
+        $display->thismonth = true;
+    }
+
+    // Fill in the variables we 're going to use, nice and tidy
+    list($d, $m, $y) = array($date['mday'], $date['mon'], $date['year']); // This is what we want to display
+    $display->maxdays = calendar_days_in_month($m, $y);
+
+    // We 'll keep these values as GMT here, and offset them when the time comes to query the db
+    $display->tstart = gmmktime(0, 0, 0, $m, 1, $y); // This is GMT
+    $display->tend = gmmktime(23, 59, 59, $m, $display->maxdays, $y); // GMT
+
+    $startwday = gmdate('w', $display->tstart); // $display->tstart is already GMT, so don't use date(): messes with server's TZ
+
+    // Align the starting weekday to fall in our display range
+    if($startwday < $display->minwday) {
+        $startwday += 7;
+    }
+
+    // Get events from database
+    $whereclause = calendar_sql_where(usertime($display->tstart), usertime($display->tend), $users, $groups, $courses);
+    if($whereclause === false) {
+        $events = array();
+    }
+    else {
+        $events = get_records_select('event', $whereclause);
+    }
+
+    // Extract information: events vs. time
+    calendar_events_by_day($events, $display->tstart, $eventsbyday, $durationbyday, $typesbyday);
+
+    // New event button
+    if(isguest()) {
+        $text = get_string('detailedmonthview', 'calendar');
+    }
+    else {
+        $text = '<div style="float: left;">'.get_string('detailedmonthview', 'calendar').'</div><div style="float: right;">';
+        $text.= '<form style="display: inline;" action="'.CALENDAR_URL.'event.php" method="get">';
+        $text.= '<input type="hidden" name="action" value="new" />';
+        $text.= '<input type="hidden" name="cal_m" value="'.$m.'" />';
+        $text.= '<input type="hidden" name="cal_y" value="'.$y.'" />';
+        $text.= '<input type="submit" value="'.get_string('newevent', 'calendar').'" />';
+        $text.= '</form></div>';
+    }
+
+    print_side_block_start($text, '', 'mycalendar');
+    echo calendar_top_controls('month', array('m' => $m, 'y' => $y));
+
+    // Start calendar display
+    echo '<table class="calendarmonth"><tr>'; // Begin table. First row: day names
+
+    // Print out the names of the weekdays
+    $days = array('sunday', 'monday', 'tuesday', 'wednesday', 'thursday', 'friday', 'saturday');
+    for($i = $display->minwday; $i <= $display->maxwday; ++$i) {
+        // This uses the % operator to get the correct weekday no matter what shift we have
+        // applied to the $display->minwday : $display->maxwday range from the default 0 : 6
+        echo '<td class="calendarheader">'.get_string($days[$i % 7], 'calendar')."</td>\n";
+    }
+
+    echo '</tr><tr>'; // End of day names; prepare for day numbers
+
+    // For the table display. $week is the row; $dayweek is the column.
+    $week = 1;
+    $dayweek = $startwday;
+
+    // Paddding (the first week may have blank days in the beginning)
+    for($i = $display->minwday; $i < $startwday; ++$i) {
+        echo '<td class="calendardaymonth">&nbsp;</td>'."\n";
+    }
+
+    // Now display all the calendar
+    for($day = 1; $day <= $display->maxdays; ++$day, ++$dayweek) {
+        if($dayweek > $display->maxwday) {
+            // We need to change week (table row)
+            echo "</tr>\n<tr>";
+            $dayweek = $display->minwday;
+            ++$week;
+        }
+
+        // Reset vars
+        $class = '';
+        $cell = '';
+        if($dayweek % 7 == 0 || $dayweek % 7 == 6) {
+            // Weekend. This is true no matter what the exact range is.
+            $class = 'calendardaymonth calendarweekend';
+        }
+        else {
+            // Normal working day.
+            $class = 'calendardaymonth';
+        }
+
+        // Special visual fx if an event is defined
+        if(isset($eventsbyday[$day])) {
+            if(isset($typesbyday[$day]['startglobal'])) {
+                $class .= ' cal_event_global';
+            }
+            else if(isset($typesbyday[$day]['startcourse'])) {
+                $class .= ' cal_event_course';
+            }
+            else if(isset($typesbyday[$day]['startgroup'])) {
+                $class .= ' cal_event_group';
+            }
+            else if(isset($typesbyday[$day]['startuser'])) {
+                $class .= ' cal_event_user';
+            }
+            if(count($eventsbyday[$day]) == 1) {
+                $title = get_string('oneevent', 'calendar');
+            }
+            else {
+                $title = get_string('manyevents', 'calendar', count($eventsbyday[$day]));
+            }
+            $cell = '<strong><a href="'.calendar_get_link_href(CALENDAR_URL.'view.php?view=day&amp;', $day, $m, $y).'" title="'.$title.'">'.$day.'</a></strong>';
+        }
+        else {
+            $cell = $day;
+        }
+
+        // Special visual fx if an event spans many days
+        if(isset($typesbyday[$day]['durationglobal'])) {
+            $class .= ' cal_duration_global';
+        }
+        else if(isset($typesbyday[$day]['durationcourse'])) {
+            $class .= ' cal_duration_course';
+        }
+        else if(isset($typesbyday[$day]['durationgroup'])) {
+            $class .= ' cal_duration_group';
+        }
+        else if(isset($typesbyday[$day]['durationuser'])) {
+            $class .= ' cal_duration_user';
+        }
+
+        // Special visual fx for today
+        if($display->thismonth && $day == $d) {
+            $class .= ' cal_today';
+        }
+
+        // Just display it
+        echo '<td class="'.$class.'">'.$cell;
+        if(isset($eventsbyday[$day])) {
+            echo '<table>';
+            foreach($eventsbyday[$day] as $eventindex) {
+                echo '<tr><td valign="top"><strong>&middot;</strong></td>';
+                echo '<td><a href="'.CALENDAR_URL.'view.php?view=event&amp;id='.$events[$eventindex]->id.'">'.$events[$eventindex]->name.'</a></td></tr>';
+            }
+            echo '</table>';
+        }
+        if(isset($durationbyday[$day])) {
+            foreach($durationbyday[$day] as $eventindex) {
+                echo '<div class="dimmed_text">('.$events[$eventindex]->name.')</div>';
+            }
+        }
+        echo "</td>\n";
+    }
+
+    // Paddding (the last week may have blank days at the end)
+    for($i = $dayweek; $i <= $display->maxwday; ++$i) {
+        echo '<td class="calendardaymonth">&nbsp;</td>';
+    }
+    echo "</tr>\n"; // Last row ends
+
+    echo "</table>\n<br />\n"; // Tabular display of days ends
+
+    // OK, now for the filtering display
+    echo '<table class="cal_filters">';
+    echo '<tbody>';
+    echo '<tr>';
+
+    // Global events
+    if($SESSION->cal_show_global) {
+        echo '<td class="cal_event_global" style="width: 8px;"></td><td><strong>'.get_string('globalevents', 'calendar').':</strong> ';
+        echo get_string('shown', 'calendar').' (<a href="'.CALENDAR_URL.'set.php?var=showglobal&amp;'.$getvars.'">'.get_string('clickhide', 'calendar').'</a>)</td>'."\n";
+    }
+    else {
+        echo '<td style="width: 8px;"></td><td><strong>'.get_string('globalevents', 'calendar').':</strong> ';
+        echo get_string('hidden', 'calendar').' (<a href="'.CALENDAR_URL.'set.php?var=showglobal&amp;'.$getvars.'">'.get_string('clickshow', 'calendar').'</a>)</td>'."\n";
+    }
+
+    // Course events (this is kinda... tricky... :)
+    echo '<td ';
+    if($SESSION->cal_show_course !== false) {
+        echo 'class="cal_event_course" ';
+    }
+    echo 'style="width: 8px;"></td><td><strong>'.get_string('courseevents', 'calendar').':</strong> ';
+
+    $defaultcourses = array_diff_assoc($defaultcourses, array(1 => 1)); // Filter the site out
+    $getcourses = array_keys($defaultcourses);
+
+    $select = 'id IN ('.implode(',', $getcourses).')';
+
+    $coursesdata = get_records_select('course', $select, 'fullname');
+    echo '<select name="course" onchange="document.location.href=\''.CALENDAR_URL.'set.php?var=setcourse&amp;'.$getvars.'&amp;id=\' + this.value;">';
+    echo '<option value="0"'.($SESSION->cal_show_course === false?' selected':'').'>'.get_string('hidden', 'calendar')."</option>\n";
+    echo '<option value="1"'.($SESSION->cal_show_course === true?' selected':'').'>'.get_string('shown', 'calendar')."</option>\n";
+    if($coursesdata !== false) {
+        foreach($coursesdata as $coursedata) {
+            echo "\n<option value='$coursedata->id'";
+            if(is_int($SESSION->cal_show_course) && $coursedata->id == $SESSION->cal_show_course) echo ' selected';
+                echo '>'.$coursedata->shortname."</option>\n";
+            }
+    }
+    echo '</select>';
+    echo '</td>';
+    echo "</tr>\n";
+    echo '<tr>';
+
+    // Group events
+    if($SESSION->cal_show_groups) {
+        echo '<td class="cal_event_group" style="width: 8px;"></td><td><strong>'.get_string('groupevents', 'calendar').':</strong> ';
+        echo get_string('shown', 'calendar').' (<a href="'.CALENDAR_URL.'set.php?var=showgroups&amp;'.$getvars.'">'.get_string('clickhide', 'calendar').'</a>)</td>'."\n";
+    }
+    else {
+        echo '<td style="width: 8px;"></td><td><strong>'.get_string('groupevents', 'calendar').':</strong> ';
+        echo get_string('hidden', 'calendar').' (<a href="'.CALENDAR_URL.'set.php?var=showgroups&amp;'.$getvars.'">'.get_string('clickshow', 'calendar').'</a>)</td>'."\n";
+    }
+    // User events
+    if($SESSION->cal_show_user) {
+        echo '<td class="cal_event_user" style="width: 8px;"></td><td><strong>'.get_string('userevents', 'calendar').':</strong> ';
+        echo get_string('shown', 'calendar').' (<a href="'.CALENDAR_URL.'set.php?var=showuser&amp;'.$getvars.'">'.get_string('clickhide', 'calendar').'</a>)</td>'."\n";
+    }
+    else {
+        echo '<td style="width: 8px;"></td><td><strong>'.get_string('userevents', 'calendar').':</strong> ';
+        echo get_string('hidden', 'calendar').' (<a href="'.CALENDAR_URL.'set.php?var=showuser&amp;'.$getvars.'">'.get_string('clickshow', 'calendar').'</a>)</td>'."\n";
+    }
+
+    echo "</tr>\n";
+    echo '<tbody></table><br />';
+    print_side_block_end();
+}
+
+function calendar_show_upcoming_events($courses, $groups, $users, $futuredays, $maxevents) {
+    $events = calendar_get_upcoming($courses, $groups, $users, $futuredays, $maxevents);
+    $numevents = count($events);
+
+    if(!$numevents) {
+        // There are no events in the specified time period
+        return;
+    }
+
+    print_side_block_start(get_string('upcomingevents', 'calendar'), '', 'mycalendar');
+    for($i = 0; $i < $numevents; ++$i) {
+        echo '<p>';
+        if(!empty($events[$i]->icon)) {
+            echo '<span class="cal_event">'.$events[$i]->icon.' </span>';
+        }
+        if(!empty($events[$i]->referer) && empty($events[$i]->icon)) {
+            echo '<span class="calendarreferer">'.$events[$i]->referer.': </span>';
+        }
+        echo '<span class="cal_event">'.$events[$i]->name.":</span>\n";
+        if(!empty($events[$i]->referer) && !empty($events[$i]->icon)) {
+            echo '<span class="calendarreferer">'.$events[$i]->referer.': </span>';
+        }
+        echo '<span class="cal_event_date">'.$events[$i]->time.'</span>';
+        echo '<br />'.$events[$i]->description.'<br />';
+        if($i < $lines - 1) {
+            echo '<hr />';
+        }
+        echo '</p>';
+    }
+    print_side_block_end();
+}
+
+
+function calendar_print_event_table($event, $starttime, $endtime, &$coursecache, $alldetails = false) {
+    global $CFG;
+
+    echo '<table class="cal_event_table"><thead>';
+
+    if(calendar_edit_event_allowed($event)) {
+        echo '<tr><td colspan="2">'.$event->name;
+        echo ' <a href="'.CALENDAR_URL.'event.php?action=edit&amp;id='.$event->id.'"><img style="vertical-align: middle;" src="'.$CFG->pixpath.'/t/edit.gif" alt="'.get_string('tt_editevent', 'calendar').'" title="'.get_string('tt_editevent', 'calendar').'" /></a>';
+        echo ' <a href="'.CALENDAR_URL.'event.php?action=delete&amp;id='.$event->id.'"><img style="vertical-align: middle;" src="'.$CFG->pixpath.'/t/delete.gif" alt="'.get_string('tt_deleteevent', 'calendar').'" title="'.get_string('tt_deleteevent', 'calendar').'" /></a>';
+        echo '</td></tr>';
+    }
+    else {
+        echo '<tr><td colspan="2">'.$event->name.'</td></tr>';
+    }
+
+    echo "</thead>\n<tbody>\n<tr><td style='vertical-align: top;'>";
+
+    if(!empty($event->modulename)) {
+        // The module name is set. This handling code should be synchronized with that in calendar_get_upcoming()
+        $module = calendar_get_module_cached($coursecache, $event->modulename, $event->instance, $event->courseid);
+        if($module === false) {
+            // This shouldn't have happened. What to do now? Just ignore it...
+            echo '</td></tr></table>';
+            return;
+        }
+        $modulename = get_string('modulename', $event->modulename);
+        $eventtype = get_string($event->eventtype, $event->modulename);
+        $icon = $CFG->modpixpath.'/'.$event->modulename.'/icon.gif';
+        $coursereferer = '<a href="'.$CFG->wwwroot.'/course/view.php?id='.$module->course.'">'.$coursecache[$module->course]->fullname.'</a>';
+        $instancereferer = '<a href="'.$CFG->wwwroot.'/mod/'.$event->modulename.'/view.php?id='.$module->id.'">'.$module->name.'</a>';
+
+        echo '<div><strong>'.get_string('course').':</strong></div><div>'.$coursereferer.'</div>';
+        echo '<div><strong><img src="'.$icon.'" title="'.$modulename.'" style="vertical-align: middle;" /> '.$modulename.':</strong></div><div>'.$instancereferer.'</div>';
+    }
+    else if($event->courseid > 1) {
+        $course = calendar_get_course_cached($coursecache, $event->courseid);
+        $coursereferer = '<a href="'.$CFG->wwwroot.'/course/view.php?id='.$course->id.'">'.$course->fullname.'</a>';
+        echo '<div><strong>'.get_string('course').':</strong></div><div>'.$coursereferer.'</div>';
+    }
+    else if($event->courseid == 1) {
+        echo '<div><strong>'.get_string('typesite', 'calendar').'</strong></div>';
+    }
+
+    if($event->timeduration) {
+        if($event->timestart + $event->timeduration > $endtime || $alldetails) {
+            // It doesn't end today, or full details requested, so we 'll go into a little more trouble
+            $enddate = usergetdate($event->timestart + $event->timeduration);
+            $enddisplay = calendar_get_link_tag(
+            calendar_day_representation($event->timestart + $event->timeduration, $starttime, false),
+            CALENDAR_URL.'view.php?view=day&amp;', $enddate['mday'], $enddate['mon'], $enddate['year']);
+            $enddisplay .= ', '.calendar_time_representation($event->timestart + $event->timeduration);
+        }
+        else {
+            $enddisplay = calendar_time_representation($event->timestart + $event->timeduration);
+        }
+        if($alldetails) {
+            // We want to give a full representation of the event's date
+            $startdate = usergetdate($event->timestart);
+            $startdisplay = calendar_get_link_tag(
+            calendar_day_representation($event->timestart, $starttime, false),
+            CALENDAR_URL.'view.php?view=day&amp;', $startdate['mday'], $startdate['mon'], $startdate['year']);
+            $startdisplay .= ', '.calendar_time_representation($event->timestart);
+        }
+        else {
+            $startdisplay = calendar_time_representation($event->timestart);
+        }
+        echo '<div><strong>'.get_string('eventstarttime', 'calendar').':</strong></div><div>'.$startdisplay.'</div>';
+        echo '<div><strong>'.get_string('eventendtime', 'calendar').':</strong></div><div>'.$enddisplay.'</div>';
+    }
+    else {
+        // Event without duration
+        if($alldetails) {
+            // We want to give a full representation of the event's date
+            $startdate = usergetdate($event->timestart);
+            $startdisplay = calendar_get_link_tag(
+            calendar_day_representation($event->timestart, $starttime, false),
+            CALENDAR_URL.'view.php?view=day&amp;', $startdate['mday'], $startdate['mon'], $startdate['year']);
+            $startdisplay .= ', '.calendar_time_representation($event->timestart);
+        }
+        else {
+            $startdisplay = calendar_time_representation($event->timestart);
+        }
+        echo '<div><strong>'.get_string('eventinstanttime', 'calendar').':</strong></div><div>'.$startdisplay.'</div>';
+    }
+
+    echo '</td><td class="cal_event_description">'.$event->description.'</td></tr>'."\n";
+    echo "</tbody>\n</table>\n";
+}
+
+?>