Skip to content

Commit

Permalink
MDL-47565 Quiz: display groups on result reports
Browse files Browse the repository at this point in the history
  • Loading branch information
jboulen committed Nov 3, 2024
1 parent d015c4c commit 6354b88
Show file tree
Hide file tree
Showing 9 changed files with 111 additions and 15 deletions.
52 changes: 52 additions & 0 deletions lib/grouplib.php
Original file line number Diff line number Diff line change
Expand Up @@ -1013,6 +1013,58 @@ function groups_print_activity_menu($cm, $urlroot, $return=false, $hideallpartic
}
}

/**
* Returns a data structure that can be used easily in a form with a 'select' element.
*
* @param stdClass|cm_info $cm course module object
* @param bool $hideallparticipants If true, this prevents the 'All participants' option from appearing.
*
* @return array Format ['label', [1 => 'Group A', 2 => 'Group B']]
*/
function groups_get_form_elements_for_activity(stdClass|cm_info $cm, bool $hideallparticipants = false): array {
global $USER, $OUTPUT;

if (!$groupmode = groups_get_activity_groupmode($cm)) {
return [false, []];
}

$context = context_module::instance($cm->id);
$aag = has_capability('moodle/site:accessallgroups', $context);

$usergroups = [];
if ($groupmode == VISIBLEGROUPS || $aag) {
$allowedgroups = groups_get_all_groups($cm->course, 0, $cm->groupingid, 'g.*', false, true); // Any group in grouping.
// Get user's own groups and put to the top.
$usergroups = groups_get_all_groups($cm->course, $USER->id, $cm->groupingid, 'g.*', false, true);
} else {
// Only assigned groups.
$allowedgroups = groups_get_all_groups($cm->course, $USER->id, $cm->groupingid, 'g.*', false, true);
}

$activegroup = groups_get_activity_group($cm, true, $allowedgroups);

$groupsmenu = [];
if ((!$allowedgroups || $groupmode == VISIBLEGROUPS || $aag) && !$hideallparticipants) {
$groupsmenu[0] = get_string('allparticipants');
}

$groupsmenu += groups_sort_menu_options($allowedgroups, $usergroups);

if ($groupmode == VISIBLEGROUPS) {
$grouplabel = get_string('groupsvisible');
} else {
$grouplabel = get_string('groupsseparate');
}

if ($aag && $cm->groupingid) {
if ($grouping = groups_get_grouping($cm->groupingid)) {
$grouplabel = $grouplabel . ' (' . format_string($grouping->name) . ')';
}
}

return [$grouplabel, $groupsmenu];
}

/**
* Returns group active in course, changes the group by default if 'group' page param present
*
Expand Down
20 changes: 13 additions & 7 deletions mod/quiz/classes/local/reports/attempts_report.php
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,9 @@ abstract class attempts_report extends report_base {
/** @var attempts_report_options_form The settings form to use. */
protected $form;

/** @var stdClass Data structure from {@see groups_get_form_elements_for_activity()}. */
protected $group;

/** @var string SQL fragment for selecting the attempt that gave the final grade,
* if applicable. */
protected $qmsubselect;
Expand Down Expand Up @@ -100,8 +103,11 @@ public function init($mode, $formclass, $quiz, $cm, $course): array {

$this->qmsubselect = quiz_report_qm_filter_select($quiz);

$this->group = (object) ['label' => false, 'options' => []];
list($this->group->label, $this->group->options) = groups_get_form_elements_for_activity($cm);

$this->form = new $formclass($this->get_base_url(),
['quiz' => $quiz, 'currentgroup' => $currentgroup, 'context' => $this->context]);
['quiz' => $quiz, 'currentgroup' => $currentgroup, 'context' => $this->context, 'group' => $this->group]);

return [$currentgroup, $studentsjoins, $groupstudentsjoins, $allowedjoins];
}
Expand Down Expand Up @@ -139,7 +145,7 @@ protected function get_students_joins($cm, $course = null) {
$studentsjoins = get_enrolled_with_capabilities_join($this->context, '',
['mod/quiz:attempt', 'mod/quiz:reviewmyattempts']);

if (empty($currentgroup)) {
if ($currentgroup === self::GROUPS_ALL_PARTICIPANTS || empty($currentgroup)) {
return [$currentgroup, $studentsjoins, $empty, $studentsjoins];
}

Expand Down Expand Up @@ -171,11 +177,6 @@ protected function print_standard_header_and_messages($cm, $course, $quiz,

$this->print_header_and_tabs($cm, $course, $quiz, $this->mode);

if (groups_get_activity_groupmode($cm)) {
// Groups are being used, so output the group selector if we are not downloading.
groups_print_activity_menu($cm, $options->get_url());
}

// Print information on the number of existing attempts.
if ($strattemptnum = quiz_num_attempt_summary($quiz, $cm, true, $currentgroup)) {
echo '<div class="quizattemptcounts">' . $strattemptnum . '</div>';
Expand Down Expand Up @@ -219,6 +220,11 @@ protected function add_user_columns($table, &$columns, &$headers) {
$columns[] = $field;
$headers[] = \core_user\fields::get_display_name($field);
}

if ($table->get_current_group() !== self::NO_GROUPS_ALLOWED) {
$columns[] = 'groupnames';
$headers[] = get_string('group');
}
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,11 @@ protected function other_attempt_fields(MoodleQuickForm $mform) {
protected function standard_preference_fields(MoodleQuickForm $mform) {
$mform->addElement('text', 'pagesize', get_string('pagesize', 'quiz'));
$mform->setType('pagesize', PARAM_INT);

if ($this->_customdata['group']->label !== false) {
$mform->addElement('select', 'group', $this->_customdata['group']->label, $this->_customdata['group']->options);
$mform->setType('group', PARAM_INT);
}
}

/**
Expand Down
31 changes: 30 additions & 1 deletion mod/quiz/classes/local/reports/attempts_report_table.php
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,9 @@ abstract class attempts_report_table extends \table_sql {
*/
protected $groupstudentsjoins;

/** @var int Group currently selected. Can be a value representing none group, all groups or a group ID. */
protected $currentgroup;

/** @var \core\dml\sql_join Contains joins, wheres, params to find the students in the course. */
protected $studentsjoins;

Expand Down Expand Up @@ -112,15 +115,23 @@ abstract class attempts_report_table extends \table_sql {
* @param \core\dml\sql_join $studentsjoins Contains joins, wheres, params
* @param array $questions
* @param moodle_url $reporturl
* @param int $currentgroup
*/
public function __construct($uniqueid, $quiz, $context, $qmsubselect,
attempts_report_options $options, \core\dml\sql_join $groupstudentsjoins, \core\dml\sql_join $studentsjoins,
$questions, $reporturl) {
$questions, $reporturl, $currentgroup = null) {
parent::__construct($uniqueid);

if ($currentgroup === null) {
$currentgroup = report_base::NO_GROUPS_ALLOWED;
debugging('Missing $currentgroup argument for '.get_called_class().'::'.__FUNCTION__.'()', DEBUG_DEVELOPER);
}

$this->quiz = $quiz;
$this->context = $context;
$this->qmsubselect = $qmsubselect;
$this->groupstudentsjoins = $groupstudentsjoins;
$this->currentgroup = $currentgroup;
$this->studentsjoins = $studentsjoins;
$this->questions = $questions;
$this->includecheckboxes = $options->checkboxcolumn;
Expand Down Expand Up @@ -566,6 +577,15 @@ public function base_sql(\core\dml\sql_join $allowedstudentsjoins) {
$params['finishedstate'] = quiz_attempt::FINISHED;
}

// This part handles group display.
if ($this->currentgroup !== report_base::NO_GROUPS_ALLOWED) {
$fields .= ', gcn.groupnames';

[$groupconcatnamesql, $groupconcatnameparams] = groups_get_names_concat_sql($this->quiz->course);
$from .= "\nLEFT JOIN ({$groupconcatnamesql}) gcn ON gcn.userid = u.id";
$params = array_merge($params, $groupconcatnameparams);
}

switch ($this->options->attempts) {
case attempts_report::ALL_WITH:
// Show all attempts, including students who are no longer in the course.
Expand Down Expand Up @@ -843,4 +863,13 @@ public function checkbox_col_header(string $columnname) {

return $OUTPUT->render($mastercheckbox);
}

/**
* Returns current group.
*
* @return int
*/
public function get_current_group() {
return $this->currentgroup;
}
}
3 changes: 3 additions & 0 deletions mod/quiz/classes/local/reports/report_base.php
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,9 @@ abstract class report_base {
/** @var int special value used in place of groupid, to mean the use cannot access any groups. */
const NO_GROUPS_ALLOWED = -2;

/** @var int special value used in place of groupid, to mean all groups. */
const GROUPS_ALL_PARTICIPANTS = 0;

/**
* Override this function to display the report.
*
Expand Down
5 changes: 3 additions & 2 deletions mod/quiz/report/overview/overview_table.php
Original file line number Diff line number Diff line change
Expand Up @@ -38,12 +38,13 @@ class quiz_overview_table extends attempts_report_table {
* @param \core\dml\sql_join $studentsjoins
* @param array $questions
* @param moodle_url $reporturl
* @param int $currentgroup
*/
public function __construct($quiz, $context, $qmsubselect,
quiz_overview_options $options, \core\dml\sql_join $groupstudentsjoins,
\core\dml\sql_join $studentsjoins, $questions, $reporturl) {
\core\dml\sql_join $studentsjoins, $questions, $reporturl, $currentgroup) {
parent::__construct('mod-quiz-report-overview-report', $quiz , $context,
$qmsubselect, $options, $groupstudentsjoins, $studentsjoins, $questions, $reporturl);
$qmsubselect, $options, $groupstudentsjoins, $studentsjoins, $questions, $reporturl, $currentgroup);
}

public function build_table() {
Expand Down
3 changes: 1 addition & 2 deletions mod/quiz/report/overview/report.php
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,6 @@ public function display($quiz, $cm, $course) {

if ($fromform = $this->form->get_data()) {
$options->process_settings_from_form($fromform);

} else {
$options->process_settings_from_params();
}
Expand All @@ -64,7 +63,7 @@ public function display($quiz, $cm, $course) {
$courseshortname = format_string($course->shortname, true,
['context' => context_course::instance($course->id)]);
$table = new quiz_overview_table($quiz, $this->context, $this->qmsubselect,
$options, $groupstudentsjoins, $studentsjoins, $questions, $options->get_url());
$options, $groupstudentsjoins, $studentsjoins, $questions, $options->get_url(), $currentgroup);
$filename = quiz_report_download_filename(get_string('overviewfilename', 'quiz_overview'),
$courseshortname, $quiz->name);
$table->is_downloading($options->download, $filename,
Expand Down
5 changes: 3 additions & 2 deletions mod/quiz/report/responses/last_responses_table.php
Original file line number Diff line number Diff line change
Expand Up @@ -35,11 +35,12 @@ class quiz_last_responses_table extends attempts_report_table {
* @param \core\dml\sql_join $studentsjoins
* @param array $questions
* @param moodle_url $reporturl
* @param int $currentgroup
*/
public function __construct($quiz, $context, $qmsubselect, quiz_responses_options $options,
\core\dml\sql_join $groupstudentsjoins, \core\dml\sql_join $studentsjoins, $questions, $reporturl) {
\core\dml\sql_join $groupstudentsjoins, \core\dml\sql_join $studentsjoins, $questions, $reporturl, $currentgroup) {
parent::__construct('mod-quiz-report-responses-report', $quiz, $context,
$qmsubselect, $options, $groupstudentsjoins, $studentsjoins, $questions, $reporturl);
$qmsubselect, $options, $groupstudentsjoins, $studentsjoins, $questions, $reporturl, $currentgroup);
}

public function build_table() {
Expand Down
2 changes: 1 addition & 1 deletion mod/quiz/report/responses/report.php
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ public function display($quiz, $cm, $course) {
$tableclassname = 'quiz_first_or_all_responses_table';
}
$table = new $tableclassname($quiz, $this->context, $this->qmsubselect,
$options, $groupstudentsjoins, $studentsjoins, $questions, $options->get_url());
$options, $groupstudentsjoins, $studentsjoins, $questions, $options->get_url(), $currentgroup);
$filename = quiz_report_download_filename(get_string('responsesfilename', 'quiz_responses'),
$courseshortname, $quiz->name);
$table->is_downloading($options->download, $filename,
Expand Down

0 comments on commit 6354b88

Please sign in to comment.