weekly release 3.4dev
[moodle.git] / calendar / externallib.php
1 <?php
2 // This file is part of Moodle - http://moodle.org/
3 //
4 // Moodle is free software: you can redistribute it and/or modify
5 // it under the terms of the GNU General Public License as published by
6 // the Free Software Foundation, either version 3 of the License, or
7 // (at your option) any later version.
8 //
9 // Moodle is distributed in the hope that it will be useful,
10 // but WITHOUT ANY WARRANTY; without even the implied warranty of
11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12 // GNU General Public License for more details.
13 //
14 // You should have received a copy of the GNU General Public License
15 // along with Moodle.  If not, see <http://www.gnu.org/licenses/>.
18 /**
19  * External calendar API
20  *
21  * @package    core_calendar
22  * @category   external
23  * @copyright  2012 Ankit Agarwal
24  * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
25  * @since Moodle 2.5
26  */
28 defined('MOODLE_INTERNAL') || die;
30 require_once("$CFG->libdir/externallib.php");
32 use \core_calendar\local\api as local_api;
33 use \core_calendar\external\events_exporter;
34 use \core_calendar\external\events_grouped_by_course_exporter;
35 use \core_calendar\external\events_related_objects_cache;
37 /**
38  * Calendar external functions
39  *
40  * @package    core_calendar
41  * @category   external
42  * @copyright  2012 Ankit Agarwal
43  * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
44  * @since Moodle 2.5
45  */
46 class core_calendar_external extends external_api {
49     /**
50      * Returns description of method parameters
51      *
52      * @return external_function_parameters
53      * @since Moodle 2.5
54      */
55     public static function delete_calendar_events_parameters() {
56         return new external_function_parameters(
57                 array('events' => new external_multiple_structure(
58                         new external_single_structure(
59                                 array(
60                                         'eventid' => new external_value(PARAM_INT, 'Event ID', VALUE_REQUIRED, '', NULL_NOT_ALLOWED),
61                                         'repeat'  => new external_value(PARAM_BOOL, 'Delete comeplete series if repeated event')
62                                 ), 'List of events to delete'
63                         )
64                     )
65                 )
66         );
67     }
69     /**
70      * Delete Calendar events
71      *
72      * @param array $eventids A list of event ids with repeat flag to delete
73      * @return null
74      * @since Moodle 2.5
75      */
76     public static function delete_calendar_events($events) {
77         global $CFG, $DB;
78         require_once($CFG->dirroot."/calendar/lib.php");
80         // Parameter validation.
81         $params = self::validate_parameters(self:: delete_calendar_events_parameters(), array('events' => $events));
83         $transaction = $DB->start_delegated_transaction();
85         foreach ($params['events'] as $event) {
86             $eventobj = calendar_event::load($event['eventid']);
88             // Let's check if the user is allowed to delete an event.
89             if (!calendar_edit_event_allowed($eventobj)) {
90                 throw new moodle_exception("nopermissions");
91             }
92             // Time to do the magic.
93             $eventobj->delete($event['repeat']);
94         }
96         // Everything done smoothly, let's commit.
97         $transaction->allow_commit();
99         return null;
100     }
102     /**
103      * Returns description of method result value
104      *
105      * @return external_description
106      * @since Moodle 2.5
107      */
108     public static function  delete_calendar_events_returns() {
109         return null;
110     }
112     /**
113      * Returns description of method parameters
114      *
115      * @return external_function_parameters
116      * @since Moodle 2.5
117      */
118     public static function get_calendar_events_parameters() {
119         return new external_function_parameters(
120                 array('events' => new external_single_structure(
121                             array(
122                                     'eventids' => new external_multiple_structure(
123                                             new external_value(PARAM_INT, 'event ids')
124                                             , 'List of event ids',
125                                             VALUE_DEFAULT, array(), NULL_ALLOWED
126                                                 ),
127                                     'courseids' => new external_multiple_structure(
128                                             new external_value(PARAM_INT, 'course ids')
129                                             , 'List of course ids for which events will be returned',
130                                             VALUE_DEFAULT, array(), NULL_ALLOWED
131                                                 ),
132                                     'groupids' => new external_multiple_structure(
133                                             new external_value(PARAM_INT, 'group ids')
134                                             , 'List of group ids for which events should be returned',
135                                             VALUE_DEFAULT, array(), NULL_ALLOWED
136                                                 )
137                             ), 'Event details', VALUE_DEFAULT, array()),
138                     'options' => new external_single_structure(
139                             array(
140                                     'userevents' => new external_value(PARAM_BOOL,
141                                              "Set to true to return current user's user events",
142                                              VALUE_DEFAULT, true, NULL_ALLOWED),
143                                     'siteevents' => new external_value(PARAM_BOOL,
144                                              "Set to true to return global events",
145                                              VALUE_DEFAULT, true, NULL_ALLOWED),
146                                     'timestart' => new external_value(PARAM_INT,
147                                              "Time from which events should be returned",
148                                              VALUE_DEFAULT, 0, NULL_ALLOWED),
149                                     'timeend' => new external_value(PARAM_INT,
150                                              "Time to which the events should be returned. We treat 0 and null as no end",
151                                              VALUE_DEFAULT, 0, NULL_ALLOWED),
152                                     'ignorehidden' => new external_value(PARAM_BOOL,
153                                              "Ignore hidden events or not",
154                                              VALUE_DEFAULT, true, NULL_ALLOWED),
156                             ), 'Options', VALUE_DEFAULT, array())
157                 )
158         );
159     }
161     /**
162      * Get Calendar events
163      *
164      * @param array $events A list of events
165      * @param array $options various options
166      * @return array Array of event details
167      * @since Moodle 2.5
168      */
169     public static function get_calendar_events($events = array(), $options = array()) {
170         global $SITE, $DB, $USER, $CFG;
171         require_once($CFG->dirroot."/calendar/lib.php");
173         // Parameter validation.
174         $params = self::validate_parameters(self::get_calendar_events_parameters(), array('events' => $events, 'options' => $options));
175         $funcparam = array('courses' => array(), 'groups' => array());
176         $hassystemcap = has_capability('moodle/calendar:manageentries', context_system::instance());
177         $warnings = array();
179         // Let us findout courses that we can return events from.
180         if (!$hassystemcap) {
181             $courses = enrol_get_my_courses('id');
182             $courses = array_keys($courses);
183             foreach ($params['events']['courseids'] as $id) {
184                try {
185                     $context = context_course::instance($id);
186                     self::validate_context($context);
187                     $funcparam['courses'][] = $id;
188                 } catch (Exception $e) {
189                     $warnings[] = array(
190                         'item' => 'course',
191                         'itemid' => $id,
192                         'warningcode' => 'nopermissions',
193                         'message' => 'No access rights in course context '.$e->getMessage().$e->getTraceAsString()
194                     );
195                 }
196             }
197         } else {
198             $courses = $params['events']['courseids'];
199             $funcparam['courses'] = $courses;
200         }
202         // Let us findout groups that we can return events from.
203         if (!$hassystemcap) {
204             $groups = groups_get_my_groups();
205             $groups = array_keys($groups);
206             foreach ($params['events']['groupids'] as $id) {
207                 if (in_array($id, $groups)) {
208                     $funcparam['groups'][] = $id;
209                 } else {
210                     $warnings[] = array('item' => $id, 'warningcode' => 'nopermissions', 'message' => 'you do not have permissions to access this group');
211                 }
212             }
213         } else {
214             $groups = $params['events']['groupids'];
215             $funcparam['groups'] = $groups;
216         }
218         // Do we need user events?
219         if (!empty($params['options']['userevents'])) {
220             $funcparam['users'] = array($USER->id);
221         } else {
222             $funcparam['users'] = false;
223         }
225         // Do we need site events?
226         if (!empty($params['options']['siteevents'])) {
227             $funcparam['courses'][] = $SITE->id;
228         }
230         // We treat 0 and null as no end.
231         if (empty($params['options']['timeend'])) {
232             $params['options']['timeend'] = PHP_INT_MAX;
233         }
235         // Event list does not check visibility and permissions, we'll check that later.
236         $eventlist = calendar_get_legacy_events($params['options']['timestart'], $params['options']['timeend'],
237             $funcparam['users'], $funcparam['groups'], $funcparam['courses'], true, $params['options']['ignorehidden']);
239         // WS expects arrays.
240         $events = array();
242         // We need to get events asked for eventids.
243         if ($eventsbyid = calendar_get_events_by_id($params['events']['eventids'])) {
244             $eventlist += $eventsbyid;
245         }
247         foreach ($eventlist as $eventid => $eventobj) {
248             $event = (array) $eventobj;
249             // Description formatting.
250             $calendareventobj = new calendar_event($event);
251             list($event['description'], $event['format']) = $calendareventobj->format_external_text();
253             if ($hassystemcap) {
254                 // User can see everything, no further check is needed.
255                 $events[$eventid] = $event;
256             } else if (!empty($eventobj->modulename)) {
257                 $courseid = $eventobj->courseid;
258                 if (!$courseid) {
259                     if (!$calendareventobj->context || !($context = $calendareventobj->context->get_course_context(false))) {
260                         continue;
261                     }
262                     $courseid = $context->instanceid;
263                 }
264                 $instances = get_fast_modinfo($courseid)->get_instances_of($eventobj->modulename);
265                 if (!empty($instances[$eventobj->instance]->uservisible)) {
266                     $events[$eventid] = $event;
267                 }
268             } else {
269                 // Can the user actually see this event?
270                 $eventobj = calendar_event::load($eventobj);
271                 if (($eventobj->courseid == $SITE->id) ||
272                             (!empty($eventobj->groupid) && in_array($eventobj->groupid, $groups)) ||
273                             (!empty($eventobj->courseid) && in_array($eventobj->courseid, $courses)) ||
274                             ($USER->id == $eventobj->userid) ||
275                             (calendar_edit_event_allowed($eventid))) {
276                     $events[$eventid] = $event;
277                 } else {
278                     $warnings[] = array('item' => $eventid, 'warningcode' => 'nopermissions', 'message' => 'you do not have permissions to view this event');
279                 }
280             }
281         }
282         return array('events' => $events, 'warnings' => $warnings);
283     }
285     /**
286      * Returns description of method result value
287      *
288      * @return external_description
289      * @since Moodle 2.5
290      */
291     public static function  get_calendar_events_returns() {
292         return new external_single_structure(array(
293                 'events' => new external_multiple_structure( new external_single_structure(
294                         array(
295                             'id' => new external_value(PARAM_INT, 'event id'),
296                             'name' => new external_value(PARAM_TEXT, 'event name'),
297                             'description' => new external_value(PARAM_RAW, 'Description', VALUE_OPTIONAL, null, NULL_ALLOWED),
298                             'format' => new external_format_value('description'),
299                             'courseid' => new external_value(PARAM_INT, 'course id'),
300                             'groupid' => new external_value(PARAM_INT, 'group id'),
301                             'userid' => new external_value(PARAM_INT, 'user id'),
302                             'repeatid' => new external_value(PARAM_INT, 'repeat id'),
303                             'modulename' => new external_value(PARAM_TEXT, 'module name', VALUE_OPTIONAL, null, NULL_ALLOWED),
304                             'instance' => new external_value(PARAM_INT, 'instance id'),
305                             'eventtype' => new external_value(PARAM_TEXT, 'Event type'),
306                             'timestart' => new external_value(PARAM_INT, 'timestart'),
307                             'timeduration' => new external_value(PARAM_INT, 'time duration'),
308                             'visible' => new external_value(PARAM_INT, 'visible'),
309                             'uuid' => new external_value(PARAM_TEXT, 'unique id of ical events', VALUE_OPTIONAL, null, NULL_NOT_ALLOWED),
310                             'sequence' => new external_value(PARAM_INT, 'sequence'),
311                             'timemodified' => new external_value(PARAM_INT, 'time modified'),
312                             'subscriptionid' => new external_value(PARAM_INT, 'Subscription id', VALUE_OPTIONAL, null, NULL_ALLOWED),
313                         ), 'event')
314                  ),
315                  'warnings' => new external_warnings()
316                 )
317         );
318     }
320     /**
321      * Returns description of method parameters.
322      *
323      * @since Moodle 3.3
324      * @return external_function_parameters
325      */
326     public static function get_calendar_action_events_by_timesort_parameters() {
327         return new external_function_parameters(
328             array(
329                 'timesortfrom' => new external_value(PARAM_INT, 'Time sort from', VALUE_DEFAULT, 0),
330                 'timesortto' => new external_value(PARAM_INT, 'Time sort to', VALUE_DEFAULT, null),
331                 'aftereventid' => new external_value(PARAM_INT, 'The last seen event id', VALUE_DEFAULT, 0),
332                 'limitnum' => new external_value(PARAM_INT, 'Limit number', VALUE_DEFAULT, 20)
333             )
334         );
335     }
337     /**
338      * Get calendar action events based on the timesort value.
339      *
340      * @since Moodle 3.3
341      * @param null|int $timesortfrom Events after this time (inclusive)
342      * @param null|int $timesortto Events before this time (inclusive)
343      * @param null|int $aftereventid Get events with ids greater than this one
344      * @param int $limitnum Limit the number of results to this value
345      * @return array
346      */
347     public static function get_calendar_action_events_by_timesort($timesortfrom = 0, $timesortto = null,
348                                                        $aftereventid = 0, $limitnum = 20) {
349         global $CFG, $PAGE, $USER;
351         require_once($CFG->dirroot . '/calendar/lib.php');
353         $user = null;
354         $params = self::validate_parameters(
355             self::get_calendar_action_events_by_timesort_parameters(),
356             [
357                 'timesortfrom' => $timesortfrom,
358                 'timesortto' => $timesortto,
359                 'aftereventid' => $aftereventid,
360                 'limitnum' => $limitnum,
361             ]
362         );
363         $context = \context_user::instance($USER->id);
364         self::validate_context($context);
366         if (empty($params['aftereventid'])) {
367             $params['aftereventid'] = null;
368         }
370         $renderer = $PAGE->get_renderer('core_calendar');
371         $events = local_api::get_action_events_by_timesort(
372             $params['timesortfrom'],
373             $params['timesortto'],
374             $params['aftereventid'],
375             $params['limitnum']
376         );
378         $exportercache = new events_related_objects_cache($events);
379         $exporter = new events_exporter($events, ['cache' => $exportercache]);
381         return $exporter->export($renderer);
382     }
384     /**
385      * Returns description of method result value.
386      *
387      * @since Moodle 3.3
388      * @return external_description
389      */
390     public static function get_calendar_action_events_by_timesort_returns() {
391         return events_exporter::get_read_structure();
392     }
394     /**
395      * Returns description of method parameters.
396      *
397      * @return external_function_parameters
398      */
399     public static function get_calendar_action_events_by_course_parameters() {
400         return new external_function_parameters(
401             array(
402                 'courseid' => new external_value(PARAM_INT, 'Course id'),
403                 'timesortfrom' => new external_value(PARAM_INT, 'Time sort from', VALUE_DEFAULT, null),
404                 'timesortto' => new external_value(PARAM_INT, 'Time sort to', VALUE_DEFAULT, null),
405                 'aftereventid' => new external_value(PARAM_INT, 'The last seen event id', VALUE_DEFAULT, 0),
406                 'limitnum' => new external_value(PARAM_INT, 'Limit number', VALUE_DEFAULT, 20)
407             )
408         );
409     }
411     /**
412      * Get calendar action events for the given course.
413      *
414      * @since Moodle 3.3
415      * @param int $courseid Only events in this course
416      * @param null|int $timesortfrom Events after this time (inclusive)
417      * @param null|int $timesortto Events before this time (inclusive)
418      * @param null|int $aftereventid Get events with ids greater than this one
419      * @param int $limitnum Limit the number of results to this value
420      * @return array
421      */
422     public static function get_calendar_action_events_by_course(
423         $courseid, $timesortfrom = null, $timesortto = null, $aftereventid = 0, $limitnum = 20) {
425         global $CFG, $PAGE, $USER;
427         require_once($CFG->dirroot . '/calendar/lib.php');
429         $user = null;
430         $params = self::validate_parameters(
431             self::get_calendar_action_events_by_course_parameters(),
432             [
433                 'courseid' => $courseid,
434                 'timesortfrom' => $timesortfrom,
435                 'timesortto' => $timesortto,
436                 'aftereventid' => $aftereventid,
437                 'limitnum' => $limitnum,
438             ]
439         );
440         $context = \context_user::instance($USER->id);
441         self::validate_context($context);
443         if (empty($params['aftereventid'])) {
444             $params['aftereventid'] = null;
445         }
447         $courses = enrol_get_my_courses('*', 'visible DESC,sortorder ASC', 0, [$courseid]);
448         $courses = array_values($courses);
450         if (empty($courses)) {
451             return [];
452         }
454         $course = $courses[0];
455         $renderer = $PAGE->get_renderer('core_calendar');
456         $events = local_api::get_action_events_by_course(
457             $course,
458             $params['timesortfrom'],
459             $params['timesortto'],
460             $params['aftereventid'],
461             $params['limitnum']
462         );
464         $exportercache = new events_related_objects_cache($events, $courses);
465         $exporter = new events_exporter($events, ['cache' => $exportercache]);
467         return $exporter->export($renderer);
468     }
470     /**
471      * Returns description of method result value.
472      *
473      * @return external_description
474      */
475     public static function get_calendar_action_events_by_course_returns() {
476         return events_exporter::get_read_structure();
477     }
479     /**
480      * Returns description of method parameters.
481      *
482      * @return external_function_parameters
483      */
484     public static function get_calendar_action_events_by_courses_parameters() {
485         return new external_function_parameters(
486             array(
487                 'courseids' => new external_multiple_structure(
488                     new external_value(PARAM_INT, 'Course id')
489                 ),
490                 'timesortfrom' => new external_value(PARAM_INT, 'Time sort from', VALUE_DEFAULT, null),
491                 'timesortto' => new external_value(PARAM_INT, 'Time sort to', VALUE_DEFAULT, null),
492                 'limitnum' => new external_value(PARAM_INT, 'Limit number', VALUE_DEFAULT, 10)
493             )
494         );
495     }
497     /**
498      * Get calendar action events for a given list of courses.
499      *
500      * @since Moodle 3.3
501      * @param array $courseids Only include events for these courses
502      * @param null|int $timesortfrom Events after this time (inclusive)
503      * @param null|int $timesortto Events before this time (inclusive)
504      * @param int $limitnum Limit the number of results per course to this value
505      * @return array
506      */
507     public static function get_calendar_action_events_by_courses(
508         array $courseids, $timesortfrom = null, $timesortto = null, $limitnum = 10) {
510         global $CFG, $PAGE, $USER;
512         require_once($CFG->dirroot . '/calendar/lib.php');
514         $user = null;
515         $params = self::validate_parameters(
516             self::get_calendar_action_events_by_courses_parameters(),
517             [
518                 'courseids' => $courseids,
519                 'timesortfrom' => $timesortfrom,
520                 'timesortto' => $timesortto,
521                 'limitnum' => $limitnum,
522             ]
523         );
524         $context = \context_user::instance($USER->id);
525         self::validate_context($context);
527         if (empty($params['courseids'])) {
528             return ['groupedbycourse' => []];
529         }
531         $renderer = $PAGE->get_renderer('core_calendar');
532         $courses = enrol_get_my_courses('*', 'visible DESC,sortorder ASC', 0, $params['courseids']);
533         $courses = array_values($courses);
535         if (empty($courses)) {
536             return ['groupedbycourse' => []];
537         }
539         $events = local_api::get_action_events_by_courses(
540             $courses,
541             $params['timesortfrom'],
542             $params['timesortto'],
543             $params['limitnum']
544         );
546         if (empty($events)) {
547             return ['groupedbycourse' => []];
548         }
550         $exportercache = new events_related_objects_cache($events, $courses);
551         $exporter = new events_grouped_by_course_exporter($events, ['cache' => $exportercache]);
553         return $exporter->export($renderer);
554     }
556     /**
557      * Returns description of method result value.
558      *
559      * @return external_description
560      */
561     public static function get_calendar_action_events_by_courses_returns() {
562         return events_grouped_by_course_exporter::get_read_structure();
563     }
565     /**
566      * Returns description of method parameters.
567      *
568      * @return external_function_parameters.
569      * @since Moodle 2.5
570      */
571     public static function create_calendar_events_parameters() {
572         // Userid is always current user, so no need to get it from client.
573         // Module based calendar events are not allowed here. Hence no need of instance and modulename.
574         // subscription id and uuid is not allowed as this is not an ical api.
575         return new external_function_parameters(
576                 array('events' => new external_multiple_structure(
577                         new external_single_structure(
578                             array(
579                                 'name' => new external_value(PARAM_TEXT, 'event name', VALUE_REQUIRED, '', NULL_NOT_ALLOWED),
580                                 'description' => new external_value(PARAM_RAW, 'Description', VALUE_DEFAULT, null, NULL_ALLOWED),
581                                 'format' => new external_format_value('description', VALUE_DEFAULT),
582                                 'courseid' => new external_value(PARAM_INT, 'course id', VALUE_DEFAULT, 0, NULL_NOT_ALLOWED),
583                                 'groupid' => new external_value(PARAM_INT, 'group id', VALUE_DEFAULT, 0, NULL_NOT_ALLOWED),
584                                 'repeats' => new external_value(PARAM_INT, 'number of repeats', VALUE_DEFAULT, 0, NULL_NOT_ALLOWED),
585                                 'eventtype' => new external_value(PARAM_TEXT, 'Event type', VALUE_DEFAULT, 'user', NULL_NOT_ALLOWED),
586                                 'timestart' => new external_value(PARAM_INT, 'timestart', VALUE_DEFAULT, time(), NULL_NOT_ALLOWED),
587                                 'timeduration' => new external_value(PARAM_INT, 'time duration', VALUE_DEFAULT, 0, NULL_NOT_ALLOWED),
588                                 'visible' => new external_value(PARAM_INT, 'visible', VALUE_DEFAULT, 1, NULL_NOT_ALLOWED),
589                                 'sequence' => new external_value(PARAM_INT, 'sequence', VALUE_DEFAULT, 1, NULL_NOT_ALLOWED),
590                             ), 'event')
591                 )
592             )
593         );
594     }
596     /**
597      * Delete Calendar events.
598      *
599      * @param array $events A list of events to create.
600      * @return array array of events created.
601      * @since Moodle 2.5
602      * @throws moodle_exception if user doesnt have the permission to create events.
603      */
604     public static function create_calendar_events($events) {
605         global $CFG, $DB, $USER;
606         require_once($CFG->dirroot."/calendar/lib.php");
608         // Parameter validation.
609         $params = self::validate_parameters(self::create_calendar_events_parameters(), array('events' => $events));
611         $transaction = $DB->start_delegated_transaction();
612         $return = array();
613         $warnings = array();
615         foreach ($params['events'] as $event) {
617             // Let us set some defaults.
618             $event['userid'] = $USER->id;
619             $event['modulename'] = '';
620             $event['instance'] = 0;
621             $event['subscriptionid'] = null;
622             $event['uuid']= '';
623             $event['format'] = external_validate_format($event['format']);
624             if ($event['repeats'] > 0) {
625                 $event['repeat'] = 1;
626             } else {
627                 $event['repeat'] = 0;
628             }
630             $eventobj = new calendar_event($event);
632             // Let's check if the user is allowed to delete an event.
633             if (!calendar_add_event_allowed($eventobj)) {
634                 $warnings [] = array('item' => $event['name'], 'warningcode' => 'nopermissions', 'message' => 'you do not have permissions to create this event');
635                 continue;
636             }
637             // Let's create the event.
638             $var = $eventobj->create($event);
639             $var = (array)$var->properties();
640             if ($event['repeat']) {
641                 $children = $DB->get_records('event', array('repeatid' => $var['id']));
642                 foreach ($children as $child) {
643                     $return[] = (array) $child;
644                 }
645             } else {
646                 $return[] = $var;
647             }
648         }
650         // Everything done smoothly, let's commit.
651         $transaction->allow_commit();
652         return array('events' => $return, 'warnings' => $warnings);
653     }
655     /**
656      * Returns description of method result value.
657      *
658      * @return external_description.
659      * @since Moodle 2.5
660      */
661     public static function  create_calendar_events_returns() {
662             return new external_single_structure(
663                     array(
664                         'events' => new external_multiple_structure( new external_single_structure(
665                                 array(
666                                     'id' => new external_value(PARAM_INT, 'event id'),
667                                     'name' => new external_value(PARAM_TEXT, 'event name'),
668                                     'description' => new external_value(PARAM_RAW, 'Description', VALUE_OPTIONAL),
669                                     'format' => new external_format_value('description'),
670                                     'courseid' => new external_value(PARAM_INT, 'course id'),
671                                     'groupid' => new external_value(PARAM_INT, 'group id'),
672                                     'userid' => new external_value(PARAM_INT, 'user id'),
673                                     'repeatid' => new external_value(PARAM_INT, 'repeat id', VALUE_OPTIONAL),
674                                     'modulename' => new external_value(PARAM_TEXT, 'module name', VALUE_OPTIONAL),
675                                     'instance' => new external_value(PARAM_INT, 'instance id'),
676                                     'eventtype' => new external_value(PARAM_TEXT, 'Event type'),
677                                     'timestart' => new external_value(PARAM_INT, 'timestart'),
678                                     'timeduration' => new external_value(PARAM_INT, 'time duration'),
679                                     'visible' => new external_value(PARAM_INT, 'visible'),
680                                     'uuid' => new external_value(PARAM_TEXT, 'unique id of ical events', VALUE_OPTIONAL, '', NULL_NOT_ALLOWED),
681                                     'sequence' => new external_value(PARAM_INT, 'sequence'),
682                                     'timemodified' => new external_value(PARAM_INT, 'time modified'),
683                                     'subscriptionid' => new external_value(PARAM_INT, 'Subscription id', VALUE_OPTIONAL),
684                                 ), 'event')
685                         ),
686                       'warnings' => new external_warnings()
687                     )
688             );
689     }
691     /**
692      * Returns description of method parameters.
693      *
694      * @return external_function_parameters
695      */
696     public static function get_calendar_event_by_id_parameters() {
697         return new external_function_parameters(
698             array(
699                 'eventid' => new external_value(PARAM_INT, 'The event id to be retrieved'),
700             )
701         );
702     }
703     /**
704      * Get calendar event by id.
705      *
706      * @param int $eventid The calendar event id to be retrieved.
707      * @return array Array of event details
708      */
709     public static function get_calendar_event_by_id($eventid) {
710         global $CFG;
711         require_once($CFG->dirroot."/calendar/lib.php");
713         // Parameter validation.
714         $params = ['eventid' => $eventid];
715         $params = self::validate_parameters(self::get_calendar_event_by_id_parameters(), $params);
717         $warnings = array();
719         // We need to get events asked for eventids.
720         $event = calendar_get_events_by_id([$eventid]);
721         $eventobj = calendar_event::load($eventid);
722         list($event[$eventid]->description, $event[$eventid]->format) = $eventobj->format_external_text();
723         $event[$eventid]->caneditevent = calendar_edit_event_allowed($eventobj);
725         return array('event' => $event[$eventid], 'warnings' => $warnings);
726     }
728     /**
729      * Returns description of method result value
730      *
731      * @return external_description
732      */
733     public static function  get_calendar_event_by_id_returns() {
735         return new external_single_structure(array(
736             'event' => new external_single_structure(
737                 array(
738                     'id' => new external_value(PARAM_INT, 'event id'),
739                     'name' => new external_value(PARAM_TEXT, 'event name'),
740                     'description' => new external_value(PARAM_RAW, 'Description', VALUE_OPTIONAL, null, NULL_ALLOWED),
741                     'format' => new external_format_value('description'),
742                     'courseid' => new external_value(PARAM_INT, 'course id'),
743                     'groupid' => new external_value(PARAM_INT, 'group id'),
744                     'userid' => new external_value(PARAM_INT, 'user id'),
745                     'repeatid' => new external_value(PARAM_INT, 'repeat id'),
746                     'modulename' => new external_value(PARAM_TEXT, 'module name', VALUE_OPTIONAL, null, NULL_ALLOWED),
747                     'instance' => new external_value(PARAM_INT, 'instance id'),
748                     'eventtype' => new external_value(PARAM_TEXT, 'Event type'),
749                     'timestart' => new external_value(PARAM_INT, 'timestart'),
750                     'timeduration' => new external_value(PARAM_INT, 'time duration'),
751                     'visible' => new external_value(PARAM_INT, 'visible'),
752                     'uuid' => new external_value(PARAM_TEXT, 'unique id of ical events', VALUE_OPTIONAL, null, NULL_NOT_ALLOWED),
753                     'sequence' => new external_value(PARAM_INT, 'sequence'),
754                     'timemodified' => new external_value(PARAM_INT, 'time modified'),
755                     'subscriptionid' => new external_value(PARAM_INT, 'Subscription id', VALUE_OPTIONAL, null, NULL_ALLOWED),
756                     'caneditevent' => new external_value(PARAM_BOOL, 'Whether the user can edit the event'),
757                 ),
758                 'event'
759             ),
760             'warnings' => new external_warnings()
761             )
762         );
763     }