diff --git a/enrol/locallib.php b/enrol/locallib.php index beeb013e72d..91accbf8d1f 100644 --- a/enrol/locallib.php +++ b/enrol/locallib.php @@ -570,17 +570,28 @@ class course_enrolment_manager { */ public function search_users(string $search = '', bool $searchanywhere = false, int $page = 0, int $perpage = 25, bool $returnexactcount = false) { + global $USER; + [$ufields, $joins, $params, $wherecondition] = $this->get_basic_search_conditions($search, $searchanywhere); + $groupmode = groups_get_course_groupmode($this->course); + if ($groupmode == SEPARATEGROUPS && !has_capability('moodle/site:accessallgroups', $this->context)) { + $groups = groups_get_all_groups($this->course->id, $USER->id, 0, 'g.id'); + $groupids = array_column($groups, 'id'); + } else { + $groupids = []; + } + + [$enrolledsql, $enrolledparams] = get_enrolled_sql($this->context, '', $groupids); + $fields = 'SELECT ' . $ufields; $countfields = 'SELECT COUNT(u.id)'; $sql = " FROM {user} u $joins - JOIN {user_enrolments} ue ON ue.userid = u.id - JOIN {enrol} e ON ue.enrolid = e.id - WHERE $wherecondition - AND e.courseid = :courseid"; - $params['courseid'] = $this->course->id; + JOIN ($enrolledsql) je ON je.id = u.id + WHERE $wherecondition"; + + $params = array_merge($params, $enrolledparams); return $this->execute_search_queries($search, $fields, $countfields, $sql, $params, $page, $perpage, 0, $returnexactcount); } diff --git a/enrol/tests/course_enrolment_manager_test.php b/enrol/tests/course_enrolment_manager_test.php index c8cd3bdf38d..91b90edae1a 100644 --- a/enrol/tests/course_enrolment_manager_test.php +++ b/enrol/tests/course_enrolment_manager_test.php @@ -16,6 +16,7 @@ namespace core_enrol; +use context_course; use course_enrolment_manager; /** @@ -25,10 +26,11 @@ use course_enrolment_manager; * @category test * @copyright 2016 Ruslan Kabalin, Lancaster University * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + * @covers \course_enrolment_manager */ class course_enrolment_manager_test extends \advanced_testcase { /** - * The course context used in tests. + * The course used in tests. * @var \stdClass */ private $course = null; @@ -546,4 +548,57 @@ class course_enrolment_manager_test extends \advanced_testcase { $this->assertArrayNotHasKey('totalusers', $users); } } + + /** + * Test that search_users observes course group mode restrictions correctly + */ + public function test_search_users_course_groupmode(): void { + global $DB, $PAGE; + + $this->resetAfterTest(); + + $teacher = $this->getDataGenerator()->create_and_enrol($this->course, 'teacher'); + $this->getDataGenerator()->create_group_member(['groupid' => $this->groups['group1']->id, 'userid' => $teacher->id]); + $this->setUser($teacher); + + $users = (new course_enrolment_manager($PAGE, $this->course))->search_users('', false, 0, 25, true); + $this->assertEqualsCanonicalizing([ + $teacher->username, + $this->users['user0']->username, + $this->users['user1']->username, + $this->users['user21']->username, + $this->users['user22']->username, + $this->users['userall']->username, + $this->users['usertch']->username, + ], array_column($users['users'], 'username')); + $this->assertEquals(7, $users['totalusers']); + + // Switch course to separate groups. + $this->course->groupmode = SEPARATEGROUPS; + update_course($this->course); + + $users = (new course_enrolment_manager($PAGE, $this->course))->search_users('', false, 0, 25, true); + $this->assertEqualsCanonicalizing([ + $teacher->username, + $this->users['user1']->username, + $this->users['userall']->username, + ], array_column($users['users'], 'username')); + $this->assertEquals(3, $users['totalusers']); + + // Allow teacher to access all groups. + $roleid = $DB->get_field('role', 'id', ['shortname' => 'teacher']); + assign_capability('moodle/site:accessallgroups', CAP_ALLOW, $roleid, context_course::instance($this->course->id)->id); + + $users = (new course_enrolment_manager($PAGE, $this->course))->search_users('', false, 0, 25, true); + $this->assertEqualsCanonicalizing([ + $teacher->username, + $this->users['user0']->username, + $this->users['user1']->username, + $this->users['user21']->username, + $this->users['user22']->username, + $this->users['userall']->username, + $this->users['usertch']->username, + ], array_column($users['users'], 'username')); + $this->assertEquals(7, $users['totalusers']); + } }