Cleaning up, completing, bugfixing, adding features to iCalendar export of

Moodle calendar.

* Adding strings
* Adding more information to iCalendar output
* Making iCalendar output compatible with a wider range of calender software
* Removing (non-functional) advanced options for now, and other superfluous
code
* Paying attention to all / course events option
* Adding authentication token system to allow subscription
* Adding JavaScript to generate URL for subscription
* Adding links from calendar page

Author: Andrew Walbran <andrew.walbran@catalyst.net.nz>
This commit is contained in:
martinlanghoff 2006-11-23 20:21:29 +00:00
parent dc3306290d
commit ea18531301
5 changed files with 108 additions and 43 deletions

View File

@ -11,6 +11,8 @@ $day = optional_param('cal_d', 0, PARAM_INT);
$mon = optional_param('cal_m', 0, PARAM_INT);
$yr = optional_param('cal_y', 0, PARAM_INT);
require_login();
if(!$site = get_site()) {
redirect($CFG->wwwroot.'/'.$CFG->admin.'/index.php');
}
@ -54,6 +56,9 @@ echo '<tr>';
echo '<td class="maincalendar">';
$username = $USER->username;
$usernameencoded = urlencode($USER->username);
$authtoken = sha1($USER->username . $USER->password);
switch($action) {
case 'advanced':
@ -67,7 +72,7 @@ switch($action) {
$allownextmonth = calendar_days_in_month($now['mon'], $now['year']) - $now['mday'] < 7;
// If today it's weekend but tomorrow it isn't, do NOT give the "this week" option
$allowthisweek = !((CALENDAR_WEEKEND & (1 << $now['wday'])) && !(CALENDAR_WEEKEND & (1 << (($now['wday'] + 1) % 7))));
print_heading(get_string('export', 'calendar'));
echo '<div class="header">' . get_string('export', 'calendar') . '</div>';
include('export_basic.html');
}

View File

@ -18,27 +18,49 @@
<?php if($allownextmonth) { ?>
<input type="radio" name="preset_time" id="pt_monnext" value="monthnext" /><label for="pt_monnext"><?php print_string('monthnext', 'calendar'); ?></label><br />
<?php } ?>
<input type="radio" name="preset_time" id="pt_recupc" value="recentupcoming" /><label for="pt_recupc"><?php print_string('recentupcoming', 'calendar'); ?></label><br />
</div>
<div style="text-align: right;">
<input type="hidden" name="cal_d" value="" />
<input type="hidden" name="cal_m" value="" />
<input type="hidden" name="cal_y" value="" />
<input type="hidden" name="action" value="export" />
<input type="hidden" name="username" value="<?php echo $username; ?>" />
<input type="hidden" name="authtoken" value="<?php echo $authtoken; ?>" />
<script type="text/javascript" language="JavaScript">
//<![CDATA[
function generate_url() {
if (document.getElementById("pw_course").checked) {
preset_what = "courses";
} else {
preset_what = "all";
}
if (<?php echo (int) $allowthisweek; ?> && document.getElementById("pt_wknow").checked) {
preset_time = "weeknow";
} else if (<?php echo (int) $allownextweek; ?> && document.getElementById("pt_wknext").checked) {
preset_time = "weeknext";
} else if (<?php echo (int) $allownextmonth; ?> && document.getElementById("pt_monnext").checked) {
preset_time = "monthnext";
} else if (document.getElementById("pt_monnow").checked) {
preset_time = "monthnow";
} else {
preset_time = "recentupcoming";
}
url = "<?php echo $CFG->wwwroot; ?>/calendar/export_execute.php?preset_what=" + preset_what + "&preset_time=" + preset_time + "&username=<?php echo $usernameencoded; ?>&authtoken=<?php echo $authtoken; ?>";
document.getElementById("url").innerText = url;
document.getElementById("url").innerHTML = url; //Need this as well, for Firefox
document.getElementById("urlbox").style.display = "block";
}
//]]>
</script>
<input type="button" value="<?php print_string('generateurlbutton', 'calendar'); ?>" onclick="javascript:generate_url()" />
<input type="submit" value="<?php print_string('exportbutton', 'calendar'); ?>" />
</div>
</form>
</fieldset>
<br />
<fieldset>
<legend><?php print_string('advancedoptions', 'calendar'); ?></legend>
<form method="get" action="export.php">
<?php print_string('advancedoptionsexplain', 'calendar'); ?>
<div style="text-align: right;">
<input type="hidden" name="cal_d" value="" />
<input type="hidden" name="cal_m" value="" />
<input type="hidden" name="cal_y" value="" />
<input type="hidden" name="action" value="advanced" />
<input type="submit" value="<?php print_string('advancedoptions', 'calendar'); ?>" />
<div id="urlbox" style="display: none; ">
<p><?php print_string('urlforical', 'calendar'); ?>:</p>
<div id="url" style="overflow: scroll; width: 650px; "></div>
</div>
</form>
</fieldset>

View File

@ -5,16 +5,19 @@ require_once('../config.php');
require_once($CFG->dirroot.'/calendar/lib.php');
require_once($CFG->libdir.'/bennu/bennu.inc.php');
require_login();
if(isguest()) {
redirect($CFG->wwwroot.'/calendar/view.php');
$username = required_param('username', PARAM_TEXT);
$authtoken = required_param('authtoken', PARAM_ALPHANUM);
//Fetch user information
if (!$user = get_complete_user_data('username', $username)) {
//No such user
die("No such user '$username'");
}
$action = optional_param('action', '', PARAM_ALPHA);
$course = optional_param('course', 0);
$day = optional_param('cal_d', 0, PARAM_INT);
$mon = optional_param('cal_m', 0, PARAM_INT);
$yr = optional_param('cal_y', 0, PARAM_INT);
//Check authentication token
if ($authtoken != sha1($username . $user->password)) {
die('Invalid authentication token');
}
$what = optional_param('preset_what', '', PARAM_ALPHA);
$time = optional_param('preset_time', '', PARAM_ALPHA);
@ -22,12 +25,19 @@ $time = optional_param('preset_time', '', PARAM_ALPHA);
$now = usergetdate(time());
// Let's see if we have sufficient and correct data
$allowed_what = array('all', 'courses');
$allowed_time = array('weeknow', 'weeknext', 'monthnow', 'monthnext');
$allowed_time = array('weeknow', 'weeknext', 'monthnow', 'monthnext', 'recentupcoming');
if(!empty($what) && !empty($time)) {
if(in_array($what, $allowed_what) && in_array($time, $allowed_time)) {
$courses = array() + $USER->student + $USER->teacher;
$courses = array_keys($courses);
$courses = get_my_courses($user->id);
$include_user = ($what == 'all');
if ($include_user) {
//Also include site (global) events
$courses[SITEID] = new stdClass;
$courses[SITEID]->shortname = get_string('globalevents', 'calendar');
}
switch($time) {
case 'weeknow':
$startweekday = get_user_preferences('calendar_startwday', CALENDAR_STARTING_WEEKDAY);
@ -76,23 +86,21 @@ if(!empty($what) && !empty($time)) {
$timestart = make_timestamp($nextyear, $nextmonth, 1);
$timeend = make_timestamp($nextyear, $nextmonth, calendar_days_in_month($nextmonth, $nextyear), 23, 59, 59);
break;
case 'recentupcoming':
//Events in the last 5 or next 60 days
$timestart = time() - 432000;
$timeend = time() + 5184000;
break;
}
/*
print_object($now);
print_object('start: '. $timestart);
print_object('end: '. $timeend);
*/
}
else {
// Parameters given but incorrect, redirect back to export page
redirect($CFG->wwwroot.'/calendar/export.php');
echo "aa";
die();
}
}
$whereclause = calendar_sql_where($timestart, $timeend, false, false, $courses, false);
$whereclause = calendar_sql_where($timestart, $timeend, $include_user ? array($user->id) : false, false, array_keys($courses), false);
if($whereclause === false) {
$events = array();
}
@ -100,9 +108,8 @@ else {
$events = get_records_select('event', $whereclause, 'timestart');
}
if(empty($events)) {
// TODO
die('no events');
if ($events === false) {
$events = array();
}
$ical = new iCalendar;
@ -111,11 +118,17 @@ foreach($events as $event) {
$ev = new iCalendar_event;
$ev->add_property('summary', $event->name);
$ev->add_property('description', $event->description);
$ev->add_property('class', 'public'); // PUBLIC / PRIVATE / CONFIDENTIAL
$ev->add_property('last-modified', 0); // lastmodified
$ev->add_property('class', 'PUBLIC'); // PUBLIC / PRIVATE / CONFIDENTIAL
$ev->add_property('last-modified', Bennu::timestamp_to_datetime($event->timemodified));
$ev->add_property('dtstamp', Bennu::timestamp_to_datetime()); // now
$ev->add_property('dtstart', Bennu::timestamp_to_datetime($event->timestart)); // when event starts
$ev->add_property('duration', 0); // when event starts
if ($event->timeduration > 0) {
//dtend is better than duration, because it works in Microsoft Outlook and works better in Korganizer
$ev->add_property('dtend', Bennu::timestamp_to_datetime($event->timestart + $event->timeduration));
}
if ($event->courseid != 0) {
$ev->add_property('categories', $courses[$event->courseid]->shortname);
}
$ical->add_component($ev);
}
@ -125,7 +138,7 @@ if(empty($serialized)) {
die('bad serialization');
}
//IE compatibiltiy HACK!
//IE compatibility HACK!
if(ini_get('zlib.output_compression')) {
ini_set('zlib.output_compression', 'Off');
}
@ -139,7 +152,7 @@ header('Pragma: no-cache');
header('Accept-Ranges: none'); // Comment out if PDFs do not work...
header('Content-disposition: attachment; filename='.$filename);
header('Content-length: '.strlen($serialized));
header('Content-type: text/plain');
header('Content-type: text/calendar');
echo $serialized;

View File

@ -150,6 +150,15 @@
calendar_show_upcoming_events($courses, $groups, $users, get_user_preferences('calendar_lookahead', CALENDAR_UPCOMING_DAYS), get_user_preferences('calendar_maxevents', CALENDAR_UPCOMING_MAXEVENTS));
break;
}
//Link to calendar export page
echo '<p><a href="export.php">' . get_string('exportcalendar', 'calendar') . '</a></p>';
if (!empty($USER->id)) {
$authtoken = sha1($USER->username . $USER->password);
$usernameencoded = urlencode($USER->username);
echo "<p><a href=\"export_execute.php?preset_what=all&preset_time=recentupcoming&username=$usernameencoded&authtoken=$authtoken\">" . get_string('quickdownloadcalendar', 'calendar') . '</a></p>';
}
echo '</td>';

View File

@ -1,11 +1,12 @@
<?PHP // $Id$
// calendar.php - created with Moodle 1.7 beta + (2006101003)
$string['advancedoptions'] = 'Advanced options';
$string['calendar'] = 'Calendar';
$string['calendarheading'] = '$a Calendar';
$string['clickhide'] = 'click to hide';
$string['clickshow'] = 'click to show';
$string['commontasks'] = 'Options';
$string['confirmeventdelete'] = 'Are you sure you want to delete this event?';
$string['courseevents'] = 'Course events';
$string['dayview'] = 'Day View';
@ -32,7 +33,9 @@ $string['eventkind'] = 'Type of event';
$string['eventname'] = 'Name';
$string['eventnone'] = 'No events';
$string['eventrepeat'] = 'Repeats';
$string['eventsall'] = 'All events';
$string['eventsfor'] = '$a events';
$string['eventsrelatedtocourses'] = 'Events related to courses';
$string['eventstarttime'] = 'Start time';
$string['eventtime'] = 'Time';
$string['eventview'] = 'Event Details';
@ -42,16 +45,24 @@ $string['explain_maxevents'] = 'This sets the maximum number of upcoming events
$string['explain_persistflt'] = 'If this is enabled, then Moodle will remember your last event filter settings and automatically restore them each time you login.';
$string['explain_startwday'] = 'Calendar weeks will be shown as starting on the day that you select here.';
$string['explain_timeformat'] = 'You can choose to see times in either 12 or 24 hour format. If you choose \"default\", then the format will be automatically chosen according to the language you use in the site.';
$string['export'] = 'Export';
$string['exportcalendar'] = 'Export calendar';
$string['exportbutton'] = 'Export';
$string['for'] = 'for';
$string['fri'] = 'Fri';
$string['friday'] = 'Friday';
$string['generateurlbutton'] = 'Get calendar URL';
$string['globalevents'] = 'Global events';
$string['gotocalendar'] = 'Go to calendar';
$string['groupevents'] = 'Group events';
$string['hidden'] = 'hidden';
$string['iwanttoexport'] = 'Export';
$string['manyevents'] = '$a events';
$string['mon'] = 'Mon';
$string['monday'] = 'Monday';
$string['monthlyview'] = 'Monthly View';
$string['monthnext'] = 'Next month';
$string['monththis'] = 'This month';
$string['newevent'] = 'New Event';
$string['noupcomingevents'] = 'There are no upcoming events';
$string['oneevent'] = '1 event';
@ -62,6 +73,8 @@ $string['pref_startwday'] = 'First day of week';
$string['pref_timeformat'] = 'Time display format';
$string['preferences'] = 'Preferences';
$string['preferences_available'] = 'Your personal preferences';
$string['quickdownloadcalendar'] = 'Quick download / subscribe to calendar';
$string['recentupcoming'] = 'Recent and next 60 days';
$string['repeateditall'] = 'Apply changes to all $a events in this repeat series';
$string['repeateditthis'] = 'Apply changes to this event only';
$string['repeatnone'] = 'No repeats';
@ -96,9 +109,12 @@ $string['typegroup'] = 'Group event';
$string['typesite'] = 'Site event';
$string['typeuser'] = 'User event';
$string['upcomingevents'] = 'Upcoming Events';
$string['urlforical'] = 'URL for iCalendar export, for subscribing to calendar';
$string['userevents'] = 'User events';
$string['wed'] = 'Wed';
$string['wednesday'] = 'Wednesday';
$string['weeknext'] = 'Next week';
$string['weekthis'] = 'This week';
$string['yesterday'] = 'Yesterday';
$string['youcandeleteallrepeats'] = 'This event is part of a repeating event series. You can delete this event only, or all $a events in the series at once.';