MDL-18375 calendar: added multiple calendar support
[moodle.git] / calendar / export_execute.php
1 <?php
3 require_once('../config.php');
4 //require_once($CFG->dirroot.'/course/lib.php');
5 require_once($CFG->dirroot.'/calendar/lib.php');
6 require_once($CFG->libdir.'/bennu/bennu.inc.php');
8 $userid = optional_param('userid', 0, PARAM_INT);
9 $username = optional_param('username', '', PARAM_TEXT);
10 $authtoken = required_param('authtoken', PARAM_ALPHANUM);
11 $generateurl = optional_param('generateurl', '', PARAM_TEXT);
13 if (empty($CFG->enablecalendarexport)) {
14     die('no export');
15 }
17 //Fetch user information
18 $checkuserid = !empty($userid) && $user = $DB->get_record('user', array('id' => $userid), 'id,password');
19 //allowing for fallback check of old url - MDL-27542
20 $checkusername = !empty($username) && $user = $DB->get_record('user', array('username' => $username), 'id,password');
21 if (!$checkuserid && !$checkusername) {
22     //No such user
23     die('Invalid authentication');
24 }
26 //Check authentication token
27 $authuserid = !empty($userid) && $authtoken == sha1($userid . $user->password . $CFG->calendar_exportsalt);
28 //allowing for fallback check of old url - MDL-27542
29 $authusername = !empty($username) && $authtoken == sha1($username . $user->password . $CFG->calendar_exportsalt);
30 if (!$authuserid && !$authusername) {
31     die('Invalid authentication');
32 }
34 $what = optional_param('preset_what', 'all', PARAM_ALPHA);
35 $time = optional_param('preset_time', 'weeknow', PARAM_ALPHA);
37 // MDL-18375, Multi-Calendar Support
38 $calendarsystem_gregorian = calendarsystem_plugin_factory::factory('gregorian');
39 $now = $calendarsystem_gregorian->usergetdate(time());
40 // Let's see if we have sufficient and correct data
41 $allowed_what = array('all', 'courses');
42 $allowed_time = array('weeknow', 'weeknext', 'monthnow', 'monthnext', 'recentupcoming', 'custom');
44 if (!empty($generateurl)) {
45     $authtoken = sha1($user->id . $user->password . $CFG->calendar_exportsalt);
46     $params = array();
47     $params['preset_what'] = $what;
48     $params['preset_time'] = $time;
49     $params['userid'] = $userid;
50     $params['authtoken'] = $authtoken;
51     $params['generateurl'] = true;
53     $link = new moodle_url('/calendar/export.php', $params);
54     redirect($link->out());
55     die;
56 }
58 if(!empty($what) && !empty($time)) {
59     if(in_array($what, $allowed_what) && in_array($time, $allowed_time)) {
60         $courses = enrol_get_users_courses($user->id, true, 'id, visible, shortname');
62         if ($what == 'all') {
63             $users = $user->id;
64             $groups = array();
65             foreach ($courses as $course) {
66                 $course_groups = groups_get_all_groups($course->id, $user->id);
67                 $groups = array_merge($groups, array_keys($course_groups));
68             }
69             if (empty($groups)) {
70                 $groups = false;
71             }
72             $courses[SITEID] = new stdClass;
73             $courses[SITEID]->shortname = get_string('globalevents', 'calendar');
74         } else {
75             $users = false;
76             $groups = false;
77         }
79         switch($time) {
80             case 'weeknow':
81                 $startweekday  = get_user_preferences('calendar_startwday', calendar_get_starting_weekday());
82                 $startmonthday = find_day_in_month($now['mday'] - 6, $startweekday, $now['mon'], $now['year']);
83                 $startmonth    = $now['mon'];
84                 $startyear     = $now['year'];
85                 if($startmonthday > $calendarsystem_gregorian->calendar_days_in_month($startmonth, $startyear)) {
86                     list($startmonth, $startyear) = calendar_add_month($startmonth, $startyear);
87                     $startmonthday = find_day_in_month(1, $startweekday, $startmonth, $startyear);
88                 }
89                 $timestart = $calendarsystem_gregorian->make_timestamp($startyear, $startmonth, $startmonthday);
90                 $endmonthday = $startmonthday + 7;
91                 $endmonth    = $startmonth;
92                 $endyear     = $startyear;
93                 if($endmonthday > $calendarsystem_gregorian->calendar_days_in_month($endmonth, $endyear)) {
94                     list($endmonth, $endyear) = calendar_add_month($endmonth, $endyear);
95                     $endmonthday = find_day_in_month(1, $startweekday, $endmonth, $endyear);
96                 }
97                 $timeend = $calendarsystem_gregorian->make_timestamp($endyear, $endmonth, $endmonthday) - 1;
98             break;
99             case 'weeknext':
100                 $startweekday  = get_user_preferences('calendar_startwday', calendar_get_starting_weekday());
101                 $startmonthday = find_day_in_month($now['mday'] + 1, $startweekday, $now['mon'], $now['year']);
102                 $startmonth    = $now['mon'];
103                 $startyear     = $now['year'];
104                 if($startmonthday > $calendarsystem_gregorian->calendar_days_in_month($startmonth, $startyear)) {
105                     list($startmonth, $startyear) = calendar_add_month($startmonth, $startyear);
106                     $startmonthday = find_day_in_month(1, $startweekday, $startmonth, $startyear);
107                 }
108                 $timestart = $calendarsystem_gregorian->make_timestamp($startyear, $startmonth, $startmonthday);
109                 $endmonthday = $startmonthday + 7;
110                 $endmonth    = $startmonth;
111                 $endyear     = $startyear;
112                 if($endmonthday > $calendarsystem_gregorian->calendar_days_in_month($endmonth, $endyear)) {
113                     list($endmonth, $endyear) = calendar_add_month($endmonth, $endyear);
114                     $endmonthday = find_day_in_month(1, $startweekday, $endmonth, $endyear);
115                 }
116                 $timeend = $calendarsystem_gregorian->make_timestamp($endyear, $endmonth, $endmonthday) - 1;
117             break;
118             case 'monthnow':
119                 $timestart = $calendarsystem_gregorian->make_timestamp($now['year'], $now['mon'], 1);
120                 $timeend   = $calendarsystem_gregorian->make_timestamp($now['year'], $now['mon'], calendar_days_in_month($now['mon'], $now['year']), 23, 59, 59);
121             break;
122             case 'monthnext':
123                 list($nextmonth, $nextyear) = calendar_add_month($now['mon'], $now['year']);
124                 $timestart = $calendarsystem_gregorian->make_timestamp($nextyear, $nextmonth, 1);
125                 $timeend   = $calendarsystem_gregorian->make_timestamp($nextyear, $nextmonth, calendar_days_in_month($nextmonth, $nextyear), 23, 59, 59);
126             break;
127             case 'recentupcoming':
128                 //Events in the last 5 or next 60 days
129                 $timestart = time() - 432000;
130                 $timeend = time() + 5184000;
131             break;
132             case 'custom':
133                 // Events based on custom date range.
134                 $timestart = time() - $CFG->calendar_exportlookback * DAYSECS;
135                 $timeend = time() + $CFG->calendar_exportlookahead * DAYSECS;
136             break;
137         }
138     }
139     else {
140         // Parameters given but incorrect, redirect back to export page
141         redirect($CFG->wwwroot.'/calendar/export.php');
142         die();
143     }
145 $events = calendar_get_events($timestart, $timeend, $users, $groups, array_keys($courses), false);
147 $ical = new iCalendar;
148 $ical->add_property('method', 'PUBLISH');
149 foreach($events as $event) {
150    if (!empty($event->modulename)) {
151         $cm = get_coursemodule_from_instance($event->modulename, $event->instance);
152         if (!groups_course_module_visible($cm)) {
153             continue;
154         }
155     }
156     $hostaddress = str_replace('http://', '', $CFG->wwwroot);
157     $hostaddress = str_replace('https://', '', $hostaddress);
159     $ev = new iCalendar_event;
160     $ev->add_property('uid', $event->id.'@'.$hostaddress);
161     $ev->add_property('summary', $event->name);
162     $ev->add_property('description', clean_param($event->description, PARAM_NOTAGS));
163     $ev->add_property('class', 'PUBLIC'); // PUBLIC / PRIVATE / CONFIDENTIAL
164     $ev->add_property('last-modified', Bennu::timestamp_to_datetime($event->timemodified));
165     $ev->add_property('dtstamp', Bennu::timestamp_to_datetime()); // now
166     $ev->add_property('dtstart', Bennu::timestamp_to_datetime($event->timestart)); // when event starts
167     if ($event->timeduration > 0) {
168         //dtend is better than duration, because it works in Microsoft Outlook and works better in Korganizer
169         $ev->add_property('dtend', Bennu::timestamp_to_datetime($event->timestart + $event->timeduration));
170     }
171     if ($event->courseid != 0) {
172         $coursecontext = context_course::instance($event->courseid);
173         $ev->add_property('categories', format_string($courses[$event->courseid]->shortname, true, array('context' => $coursecontext)));
174     }
175     $ical->add_component($ev);
178 $serialized = $ical->serialize();
179 if(empty($serialized)) {
180     // TODO
181     die('bad serialization');
184 $filename = 'icalexport.ics';
186 header('Last-Modified: '. gmdate('D, d M Y H:i:s', time()) .' GMT');
187 header('Cache-Control: private, must-revalidate, pre-check=0, post-check=0, max-age=0');
188 header('Expires: '. gmdate('D, d M Y H:i:s', 0) .'GMT');
189 header('Pragma: no-cache');
190 header('Accept-Ranges: none'); // Comment out if PDFs do not work...
191 header('Content-disposition: attachment; filename='.$filename);
192 header('Content-length: '.strlen($serialized));
193 header('Content-type: text/calendar; charset=utf-8');
195 echo $serialized;