From 10c17dcc10194de47d60715465b9af082923216f Mon Sep 17 00:00:00 2001 From: Simey Lameze Date: Tue, 7 Nov 2017 08:39:03 +0800 Subject: [PATCH] MDL-60628 calendar: support category events on get_calendar_events ws --- calendar/externallib.php | 71 ++++++++++++++++++++++++++++++++++++---- calendar/lib.php | 1 + 2 files changed, 66 insertions(+), 6 deletions(-) diff --git a/calendar/externallib.php b/calendar/externallib.php index 0ccbf31ae3b..213930f7ffc 100644 --- a/calendar/externallib.php +++ b/calendar/externallib.php @@ -138,7 +138,12 @@ class core_calendar_external extends external_api { new external_value(PARAM_INT, 'group ids') , 'List of group ids for which events should be returned', VALUE_DEFAULT, array(), NULL_ALLOWED - ) + ), + 'categoryids' => new external_multiple_structure( + new external_value(PARAM_INT, 'Category ids'), + 'List of category ids for which events will be returned', + VALUE_DEFAULT, array() + ), ), 'Event details', VALUE_DEFAULT, array()), 'options' => new external_single_structure( array( @@ -177,7 +182,7 @@ class core_calendar_external extends external_api { // Parameter validation. $params = self::validate_parameters(self::get_calendar_events_parameters(), array('events' => $events, 'options' => $options)); - $funcparam = array('courses' => array(), 'groups' => array()); + $funcparam = array('courses' => array(), 'groups' => array(), 'categories' => array()); $hassystemcap = has_capability('moodle/calendar:manageentries', context_system::instance()); $warnings = array(); @@ -203,8 +208,6 @@ class core_calendar_external extends external_api { $courses = $params['events']['courseids']; $funcparam['courses'] = $courses; } - // Now get categories we can get events from. - $categories = \coursecat::get_all(); // Let us findout groups that we can return events from. if (!$hassystemcap) { @@ -222,6 +225,62 @@ class core_calendar_external extends external_api { $funcparam['groups'] = $groups; } + $categories = array(); + if (empty($params['events']['categoryids']) && !empty($courses)) { + list($wheresql, $sqlparams) = $DB->get_in_or_equal($courses); + $wheresql = "id $wheresql"; + $courseswithcategory = $DB->get_records_select('course', $wheresql, $sqlparams); + + // Grab the list of course categories for the requested course list. + $coursecategories = array(); + foreach ($courseswithcategory as $course) { + if (empty($course->visible)) { + if (!has_capability('moodle/course:viewhidden', context_course::instance($course->id))) { + continue; + } + } + $category = \coursecat::get($course->category); + $coursecategories[] = $category; + } + + foreach (\coursecat::get_all() as $category) { + if (has_capability('moodle/category:manage', $category->get_context(), $USER, false)) { + // If a user can manage a category, then they can see all child categories. as well as all parent categories. + $categories[] = $category->id; + + foreach (\coursecat::get_all() as $cat) { + if (array_search($category->id, $cat->get_parents()) !== false) { + $categories[] = $cat->id; + } + } + $categories = array_merge($categories, $category->get_parents()); + } else if (isset($coursecategories[$category->id])) { + // The user has access to a course in this category. + // Fetch all of the parents too. + $categories = array_merge($categories, [$category->id], $category->get_parents()); + $categories[] = $category->id; + } + } + } else { + // Build the category list. + // This includes the current category. + foreach ($params['events']['categoryids'] as $categoryid) { + $category = \coursecat::get($categoryid); + $categories = [$category->id]; + // All of its descendants. + foreach (\coursecat::get_all() as $cat) { + if (array_search($categoryid, $cat->get_parents()) !== false) { + $categories[] = $cat->id; + } + } + + // And all of its parents. + $categories = array_merge($categories, $category->get_parents()); + } + } + + $funcparam['categories'] = array_unique($categories); + // Do we need user events? if (!empty($params['options']['userevents'])) { $funcparam['users'] = array($USER->id); @@ -241,7 +300,8 @@ class core_calendar_external extends external_api { // Event list does not check visibility and permissions, we'll check that later. $eventlist = calendar_get_legacy_events($params['options']['timestart'], $params['options']['timeend'], - $funcparam['users'], $funcparam['groups'], $funcparam['courses'], true, $params['options']['ignorehidden']); + $funcparam['users'], $funcparam['groups'], $funcparam['courses'], true, + $params['options']['ignorehidden'], $funcparam['categories']); // WS expects arrays. $events = array(); @@ -250,7 +310,6 @@ class core_calendar_external extends external_api { if ($eventsbyid = calendar_get_events_by_id($params['events']['eventids'])) { $eventlist += $eventsbyid; } - foreach ($eventlist as $eventid => $eventobj) { $event = (array) $eventobj; // Description formatting. diff --git a/calendar/lib.php b/calendar/lib.php index 8e76d8994cd..4790d705e8a 100644 --- a/calendar/lib.php +++ b/calendar/lib.php @@ -3289,6 +3289,7 @@ function core_calendar_user_preferences() { * @param boolean $withduration whether only events starting within time range selected * or events in progress/already started selected as well * @param boolean $ignorehidden whether to select only visible events or all events + * @param array $categories array of category ids and/or objects. * @return array $events of selected events or an empty array if there aren't any (or there was an error) */ function calendar_get_legacy_events($tstart, $tend, $users, $groups, $courses,