This commit is contained in:
Eloy Lafuente (stronk7) 2019-01-30 23:48:48 +01:00
commit 8eb26c2c4a
2 changed files with 117 additions and 44 deletions

View File

@ -193,16 +193,20 @@ function groups_get_grouping($groupingid, $fields='*', $strictness=IGNORE_MISSIN
}
/**
* Gets array of all groups in a specified course.
* Gets array of all groups in a specified course (subject to the conditions imposed by the other arguments).
*
* @category group
* @param int $courseid The id of the course.
* @param mixed $userid optional user id or array of ids, returns only groups of the user.
* @param int|int[] $userid optional user id or array of ids, returns only groups continaing one or more of those users.
* @param int $groupingid optional returns only groups in the specified grouping.
* @param string $fields
* @param bool $withmembers If true - this will return an extra field which is the list of userids that
* are members of this group.
* @return array Returns an array of the group objects (userid field returned if array in $userid)
* @param string $fields defaults to g.*. This allows you to vary which fields are returned.
* If $groupingid is specified, the groupings_groups table will be available with alias gg.
* If $userid is specified, the groups_members table will be available as gm.
* @param bool $withmembers if true return an extra field members (int[]) which is the list of userids that
* are members of each group. For this to work, g.id (or g.*) must be included in $fields.
* In this case, the final results will always be an array indexed by group id.
* @return array returns an array of the group objects (unless you have done something very weird
* with the $fields option).
*/
function groups_get_all_groups($courseid, $userid=0, $groupingid=0, $fields='g.*', $withmembers=false) {
global $DB;
@ -247,57 +251,54 @@ function groups_get_all_groups($courseid, $userid=0, $groupingid=0, $fields='g.*
// Yay! We could use the cache. One more query saved.
return $groups;
}
$memberselect = '';
$memberjoin = '';
if (empty($userid)) {
$userfrom = "";
$userwhere = "";
$params = array();
} else {
$params = [];
$userfrom = '';
$userwhere = '';
if (!empty($userid)) {
list($usql, $params) = $DB->get_in_or_equal($userid);
$userfrom = ", {groups_members} gm";
$userwhere = "AND g.id = gm.groupid AND gm.userid $usql";
$userfrom = "JOIN {groups_members} gm ON gm.groupid = g.id";
$userwhere = "AND gm.userid $usql";
}
$groupingfrom = '';
$groupingwhere = '';
if (!empty($groupingid)) {
$groupingfrom = ", {groupings_groups} gg";
$groupingwhere = "AND g.id = gg.groupid AND gg.groupingid = ?";
$groupingfrom = "JOIN {groupings_groups} gg ON gg.groupid = g.id";
$groupingwhere = "AND gg.groupingid = ?";
$params[] = $groupingid;
} else {
$groupingfrom = "";
$groupingwhere = "";
}
if ($withmembers) {
$memberselect = $DB->sql_concat("COALESCE(ugm.userid, 0)", "':'", 'g.id') . ' AS ugmid, ugm.userid, ';
$memberjoin = ' LEFT JOIN {groups_members} ugm ON ugm.groupid = g.id ';
}
array_unshift($params, $courseid);
$results = $DB->get_records_sql("SELECT $memberselect $fields
FROM {groups} g $userfrom $groupingfrom $memberjoin
WHERE g.courseid = ? $userwhere $groupingwhere
ORDER BY name ASC", $params);
$results = $DB->get_records_sql("
SELECT $fields
FROM {groups} g
$userfrom
$groupingfrom
WHERE g.courseid = ?
$userwhere
$groupingwhere
ORDER BY g.name ASC", $params);
if ($withmembers) {
// We need to post-process the results back into standard format.
$groups = [];
foreach ($results as $row) {
if (!isset($groups[$row->id])) {
$row->members = [$row->userid => $row->userid];
unset($row->userid);
unset($row->ugmid);
$groups[$row->id] = $row;
} else {
$groups[$row->id]->members[$row->userid] = $row->userid;
}
}
$results = $groups;
if (!$withmembers) {
return $results;
}
return $results;
// We also want group members. We do this in a separate query, becuse the above
// query will return a lot of data (e.g. g.description) for each group, and
// some groups may contain hundreds of members. We don't want the results
// to contain hundreds of copies of long descriptions.
$groups = [];
foreach ($results as $row) {
$groups[$row->id] = $row;
$groups[$row->id]->members = [];
}
$groupmembers = $DB->get_records_list('groups_members', 'groupid', array_keys($groups));
foreach ($groupmembers as $gm) {
$groups[$gm->groupid]->members[$gm->userid] = $gm->userid;
}
return $groups;
}
/**

View File

@ -907,6 +907,78 @@ class core_grouplib_testcase extends advanced_testcase {
$this->assertEquals('Group 2', $groups[1]->name);
}
/**
* Tests for groups_get_all_groups when grouping is set and we want members as well.
*/
public function test_groups_get_all_groups_in_grouping_with_members() {
$generator = $this->getDataGenerator();
$this->resetAfterTest();
// Create courses.
$course1 = $generator->create_course();
$course2 = $generator->create_course();
// Create users.
$c1user1 = $generator->create_user();
$c12user1 = $generator->create_user();
$c12user2 = $generator->create_user();
// Enrol users.
$generator->enrol_user($c1user1->id, $course1->id);
$generator->enrol_user($c12user1->id, $course1->id);
$generator->enrol_user($c12user1->id, $course2->id);
$generator->enrol_user($c12user2->id, $course1->id);
$generator->enrol_user($c12user2->id, $course2->id);
// Create groupings and groups for course1.
$c1grouping1 = $generator->create_grouping(array('courseid' => $course1->id));
$c1grouping2 = $generator->create_grouping(array('courseid' => $course1->id));
$c1group1 = $generator->create_group(array('courseid' => $course1->id));
$c1group2 = $generator->create_group(array('courseid' => $course1->id));
$c1group3 = $generator->create_group(array('courseid' => $course1->id));
groups_assign_grouping($c1grouping1->id, $c1group1->id);
groups_assign_grouping($c1grouping1->id, $c1group2->id);
groups_assign_grouping($c1grouping2->id, $c1group3->id);
// Create groupings and groups for course2.
$c2grouping1 = $generator->create_grouping(array('courseid' => $course2->id));
$c2group1 = $generator->create_group(array('courseid' => $course1->id));
groups_assign_grouping($c2grouping1->id, $c2group1->id);
// Assign users to groups.
$generator->create_group_member(array('groupid' => $c1group1->id, 'userid' => $c1user1->id));
$generator->create_group_member(array('groupid' => $c1group1->id, 'userid' => $c12user1->id));
$generator->create_group_member(array('groupid' => $c1group2->id, 'userid' => $c12user2->id));
$generator->create_group_member(array('groupid' => $c2group1->id, 'userid' => $c12user2->id));
// Test without userid.
$groups = groups_get_all_groups($course1->id, null, $c1grouping1->id, 'g.*', true);
$this->assertEquals(
[$c1group1->id, $c1group2->id],
array_keys($groups),
'', 0.0, 10, true
);
$this->assertEquals(
[$c1user1->id => $c1user1->id, $c12user1->id => $c12user1->id],
$groups[$c1group1->id]->members
);
$this->assertEquals(
[$c12user2->id => $c12user2->id],
$groups[$c1group2->id]->members
);
// Test with userid.
$groups = groups_get_all_groups($course1->id, $c1user1->id, $c1grouping1->id, 'g.*', true);
$this->assertEquals([$c1group1->id], array_keys($groups));
$this->assertEquals(
[$c1user1->id, $c12user1->id],
$groups[$c1group1->id]->members,
'', 0.0, 10, true
);
}
/**
* Tests for groups_get_user_groups() method.
*/