MDL-69908 user: include groups with exported course participants.

This commit is contained in:
Paul Holden 2021-05-21 08:00:39 +01:00
parent 9533e8ddf5
commit c260bad774
3 changed files with 95 additions and 4 deletions

View file

@ -1019,6 +1019,38 @@ function groups_get_members_ids_sql($groupids, context $context = null, $groupsj
return array($sql, $groupjoin->params);
}
/**
* Returns array with SQL and parameters returning userids and concatenated group names for given course
*
* This function uses 'gn[0-9]+_' prefix for table names and parameters
*
* @param int $courseid
* @param string $separator
* @return array [$sql, $params]
*/
function groups_get_names_concat_sql(int $courseid, string $separator = ', '): array {
global $DB;
// Use unique prefix just in case somebody makes some SQL magic with the result.
static $i = 0;
$i++;
$prefix = "gn{$i}_";
$groupalias = $prefix . 'g';
$groupmemberalias = $prefix . 'gm';
$groupcourseparam = $prefix . 'courseid';
$sqlgroupconcat = $DB->sql_group_concat("{$groupalias}.name", $separator, "{$groupalias}.name");
$sql = "SELECT {$groupmemberalias}.userid, {$sqlgroupconcat} AS groupnames
FROM {groups} {$groupalias}
JOIN {groups_members} {$groupmemberalias} ON {$groupmemberalias}.groupid = {$groupalias}.id
WHERE {$groupalias}.courseid = :{$groupcourseparam}
GROUP BY {$groupmemberalias}.userid";
return [$sql, [$groupcourseparam => $courseid]];
};
/**
* Get sql join to return users in a group
*

View file

@ -470,6 +470,44 @@ class core_grouplib_testcase extends advanced_testcase {
list($sql, $params) = groups_get_members_ids_sql(USERSWITHOUTGROUP, $syscontext);
}
/**
* Test retrieving users with concatenated group names from a course
*/
public function test_groups_get_names_concat_sql(): void {
global $DB;
$this->resetAfterTest();
// Create a course containing two groups.
$course = $this->getDataGenerator()->create_course();
$group1 = $this->getDataGenerator()->create_group(['courseid' => $course->id]);
$group2 = $this->getDataGenerator()->create_group(['courseid' => $course->id]);
// Create first user, add them to group 1 and group 2.
$user1 = $this->getDataGenerator()->create_and_enrol($course, 'student');
$this->getDataGenerator()->create_group_member(['userid' => $user1->id, 'groupid' => $group1->id]);
$this->getDataGenerator()->create_group_member(['userid' => $user1->id, 'groupid' => $group2->id]);
// Create second user, add them to group 1 only.
$user2 = $this->getDataGenerator()->create_and_enrol($course, 'student');
$this->getDataGenerator()->create_group_member(['userid' => $user2->id, 'groupid' => $group1->id]);
// Call our method, and assertion.
[$sql, $params] = groups_get_names_concat_sql($course->id);
$records = $DB->get_records_sql($sql, $params);
$this->assertEqualsCanonicalizing([
(object) [
'userid' => $user1->id,
'groupnames' => "{$group1->name}, {$group2->name}",
],
(object) [
'userid' => $user2->id,
'groupnames' => $group1->name,
],
], $records);
}
public function test_groups_get_group_by_name() {
$this->resetAfterTest(true);

View file

@ -93,6 +93,12 @@ if ($formaction == 'bulkchange.php') {
'lastname' => get_string('lastname'),
);
// Get the list of fields we have to hide.
$hiddenfields = [];
if (!has_capability('moodle/course:viewhiddenuserfields', $context)) {
$hiddenfields = array_flip(explode(',', $CFG->hiddenuserfields));
}
// TODO Does not support custom user profile fields (MDL-70456).
$identityfields = \core_user\fields::get_identity_fields($context, false);
$identityfieldsselect = '';
@ -102,15 +108,30 @@ if ($formaction == 'bulkchange.php') {
$identityfieldsselect .= ', u.' . $field . ' ';
}
if (!empty($userids)) {
list($insql, $inparams) = $DB->get_in_or_equal($userids);
[$useridsql, $useridparams] = $DB->get_in_or_equal($userids, SQL_PARAMS_NAMED, 'userid');
[$userordersql, $userorderparams] = users_order_by_sql('u', null, $context);
$params = array_merge($useridparams, $userorderparams);
// Add column for groups if the user can view them.
if (!isset($hiddenfields['groups'])) {
$columnnames['groupnames'] = get_string('groups');
$identityfieldsselect .= ', gcn.groupnames';
[$groupconcatnamesql, $groupconcatnameparams] = groups_get_names_concat_sql($course->id);
$groupconcatjoin = "LEFT JOIN ({$groupconcatnamesql}) gcn ON gcn.userid = u.id";
$params = array_merge($params, $groupconcatnameparams);
} else {
$groupconcatjoin = '';
}
$sql = "SELECT u.firstname, u.lastname" . $identityfieldsselect . "
FROM {user} u
WHERE u.id $insql";
{$groupconcatjoin}
WHERE u.id {$useridsql}
ORDER BY {$userordersql}";
$rs = $DB->get_recordset_sql($sql, $inparams);
$rs = $DB->get_recordset_sql($sql, $params);
\core\dataformat::download_data('courseid_' . $course->id . '_participants', $dataformat, $columnnames, $rs);
$rs->close();
}