diff --git a/lib/accesslib.php b/lib/accesslib.php index bd400e4e351..09191fadc50 100644 --- a/lib/accesslib.php +++ b/lib/accesslib.php @@ -2680,6 +2680,10 @@ function get_archetype_roles($archetype) { /** * Gets all the user roles assigned in this context, or higher contexts for a list of users. * + * If you try using the combination $userids = [], $checkparentcontexts = true then this is likely + * to cause an out-of-memory error on large Moodle sites, so this combination is deprecated and + * outputs a warning, even though it is the default. + * * @param context $context * @param array $userids. An empty list means fetch all role assignments for the context. * @param bool $checkparentcontexts defaults to true @@ -2687,7 +2691,13 @@ function get_archetype_roles($archetype) { * @return array */ function get_users_roles(context $context, $userids = [], $checkparentcontexts = true, $order = 'c.contextlevel DESC, r.sortorder ASC') { - global $USER, $DB; + global $DB; + + if (!$userids && $checkparentcontexts) { + debugging('Please do not call get_users_roles() with $checkparentcontexts = true ' . + 'and $userids array not set. This combination causes large Moodle sites ' . + 'with lots of site-wide role assignemnts to run out of memory.', DEBUG_DEVELOPER); + } if ($checkparentcontexts) { $contextids = $context->get_parent_context_ids(); diff --git a/lib/tests/accesslib_test.php b/lib/tests/accesslib_test.php index a4d16e5d60b..b98dc82fac0 100644 --- a/lib/tests/accesslib_test.php +++ b/lib/tests/accesslib_test.php @@ -1612,7 +1612,7 @@ class core_accesslib_testcase extends advanced_testcase { $u2roles = get_user_roles($coursecontext, $user2->id); - $allroles = get_users_roles($coursecontext); + $allroles = get_users_roles($coursecontext, [], false); $specificuserroles = get_users_roles($coursecontext, [$user1->id, $user2->id]); $this->assertEquals($u1roles, $allroles[$user1->id]); $this->assertEquals($u1roles, $specificuserroles[$user1->id]); diff --git a/user/classes/participants_table.php b/user/classes/participants_table.php index f634ab13e7b..14005b1e230 100644 --- a/user/classes/participants_table.php +++ b/user/classes/participants_table.php @@ -233,7 +233,6 @@ class participants_table extends \table_sql { $this->groups = groups_get_all_groups($courseid, 0, 0, 'g.*', true); } $this->allroles = role_fix_names(get_all_roles($this->context), $this->context); - $this->allroleassignments = get_users_roles($this->context, [], true, 'c.contextlevel DESC, r.sortorder ASC'); $this->assignableroles = get_assignable_roles($this->context, ROLENAME_ALIAS, false); $this->profileroles = get_profile_roles($this->context); } @@ -441,9 +440,21 @@ class participants_table extends \table_sql { $sort = 'ORDER BY ' . $sort; } - $this->rawdata = user_get_participants($this->course->id, $this->currentgroup, $this->accesssince, + $rawdata = user_get_participants($this->course->id, $this->currentgroup, $this->accesssince, $this->roleid, $this->enrolid, $this->status, $this->search, $twhere, $tparams, $sort, $this->get_page_start(), $this->get_page_size()); + $this->rawdata = []; + foreach ($rawdata as $user) { + $this->rawdata[$user->id] = $user; + } + $rawdata->close(); + + if ($this->rawdata) { + $this->allroleassignments = get_users_roles($this->context, array_keys($this->rawdata), + true, 'c.contextlevel DESC, r.sortorder ASC'); + } else { + $this->allroleassignments = []; + } // Set initial bars. if ($useinitialsbar) {