MDL-58768 Calendar: Update get_raw_events_legacy_implementation

Update get_raw_events_legacy_implementation to work with the passed $users parameter instead of the logged in user.
Also, fixed a bug where get_raw_events_legacy_implementation was failing when $users was set to true, and a list of
$groups was given.
This commit is contained in:
Shamim Rezaie 2018-03-29 01:58:06 +11:00
parent d8c6c21c95
commit 7385ee37f9
2 changed files with 204 additions and 68 deletions

View File

@ -96,11 +96,24 @@ class raw_event_retrieval_strategy implements raw_event_retrieval_strategy_inter
return array();
}
if (is_numeric($users)) {
$users = array($users);
}
if (is_numeric($groups)) {
$groups = array($groups);
}
if (is_numeric($courses)) {
$courses = array($courses);
}
if (is_numeric($categories)) {
$categories = array($categories);
}
// Array of filter conditions. To be concatenated by the OR operator.
$filters = [];
// User filter.
if ((is_array($users) && !empty($users)) or is_numeric($users)) {
if (is_array($users) && !empty($users)) {
// Events from a number of users.
list($insqlusers, $inparamsusers) = $DB->get_in_or_equal($users, SQL_PARAMS_NAMED);
$filters[] = "(e.userid $insqlusers AND e.courseid = 0 AND e.groupid = 0 AND e.categoryid = 0)";
@ -112,7 +125,7 @@ class raw_event_retrieval_strategy implements raw_event_retrieval_strategy_inter
// Boolean false (no users at all): We don't need to do anything.
// Group filter.
if ((is_array($groups) && !empty($groups)) or is_numeric($groups)) {
if (is_array($groups) && !empty($groups)) {
// Events from a number of groups.
list($insqlgroups, $inparamsgroups) = $DB->get_in_or_equal($groups, SQL_PARAMS_NAMED);
$filters[] = "e.groupid $insqlgroups";
@ -124,7 +137,7 @@ class raw_event_retrieval_strategy implements raw_event_retrieval_strategy_inter
// Boolean false (no groups at all): We don't need to do anything.
// Course filter.
if ((is_array($courses) && !empty($courses)) or is_numeric($courses)) {
if (is_array($courses) && !empty($courses)) {
list($insqlcourses, $inparamscourses) = $DB->get_in_or_equal($courses, SQL_PARAMS_NAMED);
$filters[] = "(e.groupid = 0 AND e.courseid $insqlcourses)";
$params = array_merge($params, $inparamscourses);
@ -134,7 +147,7 @@ class raw_event_retrieval_strategy implements raw_event_retrieval_strategy_inter
}
// Category filter.
if ((is_array($categories) && !empty($categories)) or is_numeric($categories)) {
if (is_array($categories) && !empty($categories)) {
list($insqlcategories, $inparamscategories) = $DB->get_in_or_equal($categories, SQL_PARAMS_NAMED);
$filters[] = "(e.groupid = 0 AND e.courseid = 0 AND e.categoryid $insqlcategories)";
$params = array_merge($params, $inparamscategories);
@ -168,54 +181,81 @@ class raw_event_retrieval_strategy implements raw_event_retrieval_strategy_inter
// Build SQL subquery and conditions for filtered events based on priorities.
$subquerywhere = '';
$subqueryconditions = [];
// Get the user's courses. Otherwise, get the default courses being shown by the calendar.
$usercourses = calendar_get_default_courses(null, 'id, category, groupmode, groupmodeforce');
// Set calendar filters.
list($usercourses, $usergroups, $user) = calendar_set_filters($usercourses, true);
$subqueryparams = [];
$allusercourses = [];
// Flag to indicate whether the query needs to exclude group overrides.
$viewgroupsonly = false;
if (is_array($users) && !empty($users)) {
$userrecords = $DB->get_records_sql("SELECT * FROM {user} WHERE id $insqlusers", $inparamsusers);
foreach ($userrecords as $userrecord) {
// Get the user's courses. Otherwise, get the default courses being shown by the calendar.
$usercourses = calendar_get_default_courses(null, 'id, category, groupmode, groupmodeforce',
false, $userrecord->id);
if ($user) {
// Set filter condition for the user's events.
$subqueryconditions[] = "(ev.userid = :user AND ev.courseid = 0 AND ev.groupid = 0 AND ev.categoryid = 0)";
$subqueryparams['user'] = $user;
// Set calendar filters.
list($usercourses, $usergroups, $user) = calendar_set_filters($usercourses, true, $userrecord);
foreach ($usercourses as $courseid) {
if (has_capability('moodle/site:accessallgroups', \context_course::instance($courseid))) {
$usergroupmembership = groups_get_all_groups($courseid, $user, 0, 'g.id');
if (count($usergroupmembership) == 0) {
$viewgroupsonly = true;
break;
$allusercourses = array_merge($allusercourses, $usercourses);
// Flag to indicate whether the query needs to exclude group overrides.
$viewgroupsonly = false;
if ($user) {
// Set filter condition for the user's events.
// Even though $user is a single scalar, we still use get_in_or_equal() because we are inside a loop.
list($inusers, $inuserparams) = $DB->get_in_or_equal($user, SQL_PARAMS_NAMED);
$subqueryconditions[] = "(ev.userid $inusers AND ev.courseid = 0 AND ev.groupid = 0 AND ev.categoryid = 0)";
$subqueryparams = array_merge($subqueryparams, $inuserparams);
foreach ($usercourses 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) {
$viewgroupsonly = true;
break;
}
}
}
}
}
}
// Set filter condition for the user's group events.
if ($usergroups === true || $viewgroupsonly) {
// Fetch group events, but not group overrides.
$subqueryconditions[] = "(ev.groupid != 0 AND ev.eventtype = 'group')";
} else if (!empty($usergroups)) {
// Fetch group events and group overrides.
list($inusergroups, $inusergroupparams) = $DB->get_in_or_equal($usergroups, SQL_PARAMS_NAMED);
$subqueryconditions[] = "(ev.groupid $inusergroups)";
$subqueryparams = array_merge($subqueryparams, $inusergroupparams);
// Set filter condition for the user's group events.
if ($usergroups === true || $viewgroupsonly) {
// Fetch group events, but not group overrides.
$subqueryconditions[] = "(ev.groupid != 0 AND ev.eventtype = 'group')";
} else if (!empty($usergroups)) {
// Fetch group events and group overrides.
list($inusergroups, $inusergroupparams) = $DB->get_in_or_equal($usergroups, SQL_PARAMS_NAMED);
$subqueryconditions[] = "(ev.groupid $inusergroups)";
$subqueryparams = array_merge($subqueryparams, $inusergroupparams);
}
}
} else if ($users === true) {
// Events from ALL users.
$subqueryconditions[] = "(ev.userid != 0 AND ev.courseid = 0 AND ev.groupid = 0 AND ev.categoryid = 0)";
if (is_array($groups)) {
// Events from a number of groups.
list($insqlgroups, $inparamsgroups) = $DB->get_in_or_equal($groups, SQL_PARAMS_NAMED);
$subqueryconditions[] = "ev.groupid $insqlgroups";
$subqueryparams = array_merge($subqueryparams, $inparamsgroups);
} else if ($groups === true) {
// Events from ALL groups.
$subqueryconditions[] = "ev.groupid != 0";
}
if ($courses === true) {
// ALL course events. It's not needed to worry about users' access as $users = true.
$subqueryconditions[] = "(ev.groupid = 0 AND ev.courseid != 0 AND ev.categoryid = 0)";
}
}
// Get courses to be used for the subquery.
$subquerycourses = [];
if (is_array($courses)) {
$subquerycourses = $courses;
} else if (is_numeric($courses)) {
$subquerycourses[] = $courses;
}
// Merge with user courses, if necessary.
if (!empty($usercourses)) {
$subquerycourses = array_merge($subquerycourses, $usercourses);
if (!empty($allusercourses)) {
$subquerycourses = array_merge($subquerycourses, $allusercourses);
// Make sure we remove duplicate values.
$subquerycourses = array_unique($subquerycourses);
}

View File

@ -90,15 +90,29 @@ class core_calendar_raw_event_retrieval_strategy_testcase extends advanced_testc
$this->assertCount(2, $events);
// Disable the lesson module.
$modulerecord = $DB->get_record('modules', ['name' => 'lesson']);
$modulerecord->visible = 0;
$DB->update_record('modules', $modulerecord);
$DB->set_field('modules', 'visible', 0, ['name' => 'lesson']);
// Check that we only return the assign event.
$events = $retrievalstrategy->get_raw_events(null, [0], null);
$this->assertCount(1, $events);
$event = reset($events);
$this->assertEquals('assign', $event->modulename);
// Now, log out and repeat the above test in the reverse order.
$this->setUser();
// Check that we only return the assign event (given that the lesson module is still disabled).
$events = $retrievalstrategy->get_raw_events([$student->id], [0], null);
$this->assertCount(1, $events);
$event = reset($events);
$this->assertEquals('assign', $event->modulename);
// Enable the lesson module.
$DB->set_field('modules', 'visible', 1, ['name' => 'lesson']);
// Get all events.
$events = $retrievalstrategy->get_raw_events(null, [0], null);
$this->assertCount(2, $events);
}
/**
@ -209,37 +223,37 @@ class core_calendar_raw_event_retrieval_strategy_testcase extends advanced_testc
calendar_event::create($event, false);
}
$timestart = $now - 100;
$timeend = $now + (3 * 86400);
$groups = [$group1->id, $group2->id];
// Get user override events.
$this->setUser($useroverridestudent);
$events = $retrievalstrategy->get_raw_events([$useroverridestudent->id], $groups, [$course->id]);
$this->assertCount(1, $events);
$event = reset($events);
$this->assertEquals('Assignment 1 due date - User override', $event->name);
// Do the following tests multiple times when logged in with different users. Also run the whole set when logged out.
// In any cases, the tests should not depend on the logged-in user.
foreach ([$useroverridestudent, $nogroupstudent, $group12student, $group1student, null] as $login) {
$this->setUser($login);
// Get events for user that does not belong to any group and has no user override events.
$this->setUser($nogroupstudent);
$events = $retrievalstrategy->get_raw_events([$nogroupstudent->id], $groups, [$course->id]);
$this->assertCount(1, $events);
$event = reset($events);
$this->assertEquals('Assignment 1 due date', $event->name);
// Get user override events.
$events = $retrievalstrategy->get_raw_events([$useroverridestudent->id], $groups, [$course->id]);
$this->assertCount(1, $events);
$event = reset($events);
$this->assertEquals('Assignment 1 due date - User override', $event->name);
// Get events for user that belongs to groups A and B and has no user override events.
$this->setUser($group12student);
$events = $retrievalstrategy->get_raw_events([$group12student->id], $groups, [$course->id]);
$this->assertCount(1, $events);
$event = reset($events);
$this->assertEquals('Assignment 1 due date - Group A override', $event->name);
// Get events for user that does not belong to any group and has no user override events.
$events = $retrievalstrategy->get_raw_events([$nogroupstudent->id], $groups, [$course->id]);
$this->assertCount(1, $events);
$event = reset($events);
$this->assertEquals('Assignment 1 due date', $event->name);
// Get events for user that belongs to group A and has no user override events.
$this->setUser($group1student);
$events = $retrievalstrategy->get_raw_events([$group1student->id], $groups, [$course->id]);
$this->assertCount(1, $events);
$event = reset($events);
$this->assertEquals('Assignment 1 due date - Group A override', $event->name);
// Get events for user that belongs to groups A and B and has no user override events.
$events = $retrievalstrategy->get_raw_events([$group12student->id], $groups, [$course->id]);
$this->assertCount(1, $events);
$event = reset($events);
$this->assertEquals('Assignment 1 due date - Group A override', $event->name);
// Get events for user that belongs to group A and has no user override events.
$events = $retrievalstrategy->get_raw_events([$group1student->id], $groups, [$course->id]);
$this->assertCount(1, $events);
$event = reset($events);
$this->assertEquals('Assignment 1 due date - Group A override', $event->name);
}
// Add repeating events.
$repeatingevents = [
@ -290,8 +304,6 @@ class core_calendar_raw_event_retrieval_strategy_testcase extends advanced_testc
* Test retrieval strategy with category specifications.
*/
public function test_get_raw_events_category() {
global $DB;
$this->resetAfterTest();
$retrievalstrategy = new raw_event_retrieval_strategy();
$generator = $this->getDataGenerator();
@ -351,4 +363,88 @@ class core_calendar_raw_event_retrieval_strategy_testcase extends advanced_testc
$events = $retrievalstrategy->get_raw_events(null, null, null, [$category1->id, $category2->id]);
$this->assertCount(2, $events);
}
public function test_get_raw_events_for_multiple_users() {
$this->resetAfterTest();
$generator = $this->getDataGenerator();
// Create users.
$user1 = $generator->create_user();
$user2 = $generator->create_user();
$user3 = $generator->create_user();
// Create user events.
$events = [
[
'name' => 'User1 Event',
'eventtype' => 'user',
'userid' => $user1->id,
'timestart' => time(),
], [
'name' => 'User2 Event',
'eventtype' => 'user',
'userid' => $user2->id,
'timestart' => time(),
], [
'name' => 'User3 Event',
'eventtype' => 'user',
'userid' => $user3->id,
'timestart' => time(),
]
];
foreach ($events as $event) {
calendar_event::create($event, false);
}
$retrievalstrategy = new raw_event_retrieval_strategy();
// Get all events.
$events = $retrievalstrategy->get_raw_events([$user1->id, $user2->id]);
$this->assertCount(2, $events);
$this->assertEquals(
['User1 Event', 'User2 Event'],
array_column($events, 'name'),
'', 0.0, 10, true);
}
public function test_get_raw_events_for_groups_with_no_members() {
$this->resetAfterTest();
$generator = $this->getDataGenerator();
$course = $generator->create_course();
// Create groups.
$group1 = $generator->create_group(['courseid' => $course->id, 'name' => 'Group 1']);
$group2 = $generator->create_group(['courseid' => $course->id, 'name' => 'Group 2']);
// Create group events.
$events = [
[
'name' => 'Group 1 Event',
'eventtype' => 'group',
'groupid' => $group1->id,
'timestart' => time(),
], [
'name' => 'Group 2 Event',
'eventtype' => 'group',
'groupid' => $group2->id,
'timestart' => time(),
]
];
foreach ($events as $event) {
calendar_event::create($event, false);
}
$retrievalstrategy = new raw_event_retrieval_strategy;
// Get group eventsl.
$events = $retrievalstrategy->get_raw_events(null, [$group1->id, $group2->id]);
$this->assertCount(2, $events);
$this->assertEquals(
['Group 1 Event', 'Group 2 Event'],
array_column($events, 'name'),
'', 0.0, 10, true);
}
}