MDL-86397 calendar: Filter user courses
In the calendar API, `raw_event_retrieval_strategy` accepts a list of courses to return events for. If one or more users are also specified, it will find the courses the are enrolled in, then call `calendar_set_filters()` to return a sorted list of those courses, and any groups within those courses that they can see events for. The list of courses in then filtered to those passed to `raw_event_retrieval_strategy`. If the user is enrolled on lots of courses, but is only viewing the caledar for one course, this results in a lot of redundant work to fetch group data for their courses which is then not used. This either involves a lot of extra complex queries, or results in an unncessary cache hit for each course. This change re-orders the code so that the list of enrolled courses is filtered to just those courses being viewed, before it is passed to `calendar_set_filters()`. This means we are only fetching group data for those courses we will be showing events for.
This commit is contained in:
@@ -187,6 +187,16 @@ class raw_event_retrieval_strategy implements raw_event_retrieval_strategy_inter
|
||||
$subqueryparams = [];
|
||||
$allusercourses = [];
|
||||
|
||||
$groupcourses = [];
|
||||
if (is_array($groups) && !empty($groups)) {
|
||||
$groupcourses = $DB->get_fieldset_sql(
|
||||
"SELECT DISTINCT courseid
|
||||
FROM {groups}
|
||||
WHERE id $insqlgroups",
|
||||
$inparamsgroups,
|
||||
);
|
||||
}
|
||||
|
||||
if (is_array($users) && !empty($users)) {
|
||||
$userrecords = $DB->get_records_sql("SELECT * FROM {user} WHERE id $insqlusers", $inparamsusers);
|
||||
foreach ($userrecords as $userrecord) {
|
||||
@@ -194,13 +204,14 @@ class raw_event_retrieval_strategy implements raw_event_retrieval_strategy_inter
|
||||
$usercourses = calendar_get_default_courses(null, 'id, category, groupmode, groupmodeforce',
|
||||
false, $userrecord->id);
|
||||
|
||||
// Set calendar filters.
|
||||
list($usercourses, $usergroups, $user) = calendar_set_filters($usercourses, true, $userrecord);
|
||||
$filteredcourses = array_merge(
|
||||
is_array($courses) ? $courses : [$courses],
|
||||
$groupcourses, // Include courses for any groups we've specified.
|
||||
);
|
||||
$filteredcourses = array_filter($usercourses, fn($course) => in_array($course->id, $filteredcourses));
|
||||
|
||||
$filteredcourses = is_array($courses) ? $courses : [$courses];
|
||||
$filteredcourses = array_filter($usercourses, function($course) use ($filteredcourses) {
|
||||
return in_array($course, $filteredcourses);
|
||||
});
|
||||
// Set calendar filters.
|
||||
[$filteredcourses, $usergroups, $user] = calendar_set_filters($filteredcourses, true, $userrecord);
|
||||
|
||||
$allusercourses = array_merge($allusercourses, $filteredcourses);
|
||||
|
||||
@@ -215,7 +226,7 @@ class raw_event_retrieval_strategy implements raw_event_retrieval_strategy_inter
|
||||
$subqueryconditions[] = $condition;
|
||||
$subqueryparams = array_merge($subqueryparams, $inuserparams);
|
||||
|
||||
foreach ($usercourses as $courseid) {
|
||||
foreach ($filteredcourses as $courseid) {
|
||||
if (has_capability('moodle/site:accessallgroups', \context_course::instance($courseid), $userrecord)) {
|
||||
$usergroupmembership = groups_get_all_groups($courseid, $user, 0, 'g.id');
|
||||
if (count($usergroupmembership) == 0) {
|
||||
|
||||
Reference in New Issue
Block a user