From 7bc488dc3d62f74a8ce4080665ba363e79c71aee Mon Sep 17 00:00:00 2001 From: Tim Hunt Date: Mon, 10 May 2010 22:15:17 +0000 Subject: [PATCH] quiz settings MDL-21780 more work on group and user setting overrides The group setting tab is now disabled if there are no groups in the course. The code also now respects groupings. Thanks to Matt Petro for this patch. --- mod/quiz/editlib.php | 3 +- mod/quiz/lang/en/quiz.php | 3 + mod/quiz/lib.php | 6 +- mod/quiz/override_form.php | 26 +++++--- mod/quiz/overrides.php | 127 ++++++++++++++++++++++++++++--------- mod/quiz/tabs.php | 6 +- 6 files changed, 127 insertions(+), 44 deletions(-) diff --git a/mod/quiz/editlib.php b/mod/quiz/editlib.php index acd51d0208b..51784a34351 100644 --- a/mod/quiz/editlib.php +++ b/mod/quiz/editlib.php @@ -394,7 +394,8 @@ function quiz_print_question_list($quiz, $pageurl, $allowdelete = true, $pageopen = false; - $returnurl = $pageurl->out(); + $returnurl = $pageurl->out($returnurl); + echo '
'; var_dump($returnurl); echo '
'; // DONOTCOMMIT $questiontotalcount = count($order); foreach ($order as $i => $qnum) { diff --git a/mod/quiz/lang/en/quiz.php b/mod/quiz/lang/en/quiz.php index eb7f0c0a4b1..a4bcb90a063 100644 --- a/mod/quiz/lang/en/quiz.php +++ b/mod/quiz/lang/en/quiz.php @@ -390,6 +390,7 @@ $string['gradingdetailspenalty'] = 'This submission attracted a penalty of {$a}. $string['gradingdetailszeropenalty'] = 'You were not penalized for this submission.'; $string['gradingmethod'] = 'Grading method: {$a}'; $string['groupoverrides'] = 'Group overrides'; +$string['groupsnone'] = 'There are no groups in this course'; $string['guestsno'] = 'Sorry, guests cannot see or attempt quizzes'; $string['hidebreaks'] = 'Hide page breaks'; $string['hidereordertool'] = 'Hide the reordering tool'; @@ -418,6 +419,7 @@ $string['importmax10error'] = 'There is an error in the question. You may not ha $string['importminerror'] = 'There is an error in the question. There are not enough answers for this question type'; $string['importparseerror'] = 'Error(s) found parsing the import file. No questions have been imported. To import any good questions try again setting \'Stop on error\' to \'No\''; $string['importquestions'] = 'Import questions from file'; +$string['inactiveoverridehelp'] = '* Student does not have the correct group or role to attempt the quiz'; $string['incorrect'] = 'Incorrect'; $string['indivresp'] = 'Responses of Individuals to Each Item'; $string['info'] = 'Info'; @@ -827,6 +829,7 @@ $string['upgradesure'] = '
In particular the quiz module will perform an ext $string['url'] = 'URL'; $string['usedcategorymoved'] = 'This category has been preserved and moved to the site level because it is a published category still in use by other courses.'; $string['useroverrides'] = 'User overrides'; +$string['usersnone'] = 'No students have access to this quiz'; $string['validate'] = 'Validate'; $string['viewallanswers'] = 'View {$a} quiz attempts'; $string['viewallreports'] = 'View reports for {$a} attempts'; diff --git a/mod/quiz/lib.php b/mod/quiz/lib.php index 82e47139aa2..3269211c39c 100644 --- a/mod/quiz/lib.php +++ b/mod/quiz/lib.php @@ -269,12 +269,10 @@ function quiz_update_effective_access($quiz, $userid) { // check for group overrides $groupings = groups_get_user_groups($quiz->course, $userid); - $groupingid = empty($cm->groupingid)? 0 : $cm->groupingid; - - if (!empty($groupings[$groupingid])) { + if (!empty($groupings[0])) { // Select all overrides that apply to the User's groups - list($extra, $params) = $DB->get_in_or_equal(array_values($groupings[$groupingid])); + list($extra, $params) = $DB->get_in_or_equal(array_values($groupings[0])); $sql = "SELECT * FROM {quiz_overrides} WHERE groupid $extra AND quiz = ?"; $params[] = $quiz->id; diff --git a/mod/quiz/override_form.php b/mod/quiz/override_form.php index 788cae71256..2eb65d369b8 100644 --- a/mod/quiz/override_form.php +++ b/mod/quiz/override_form.php @@ -66,9 +66,11 @@ class quiz_override_form extends moodleform { $mform->freeze('groupid'); } else { // Prepare the list of groups - $groups = groups_get_all_groups($cm->course, null, $cm->groupingid); + $groups = groups_get_all_groups($cm->course); if (empty($groups)) { - $groups = array(); + // generate an error + $link = new moodle_url('/mod/quiz/overrides.php', array('cmid'=>$cm->id)); + print_error('groupsnone', 'quiz', $link); } $groupchoices = array(); @@ -95,16 +97,24 @@ class quiz_override_form extends moodleform { $mform->freeze('userid'); } else { // Prepare the list of users - if (!empty($cm->groupingid)) { + $users = array(); + if (!empty($CFG->enablegroupmembersonly) && $cm->groupmembersonly) { + // only users from the grouping $groups = groups_get_all_groups($cm->course, 0, $cm->groupingid); - $groups = array_keys($groups); + if (empty($groups)) { + // empty grouping + } else { + $users = get_users_by_capability($this->context, 'mod/quiz:attempt', 'u.id,u.firstname,u.lastname,u.email' , + 'firstname ASC, lastname ASC', '', '', array_keys($groups), '', false, true); + } } else { - $groups = null; + $users = get_users_by_capability($this->context, 'mod/quiz:attempt', 'u.id,u.firstname,u.lastname,u.email' , + 'firstname ASC, lastname ASC', '', '', '', '', false, true); } - $users = get_users_by_capability($this->context, 'mod/quiz:attempt', 'u.id,u.firstname,u.lastname,u.email' , - 'firstname ASC, lastname ASC', '', '', $groups, '', false, true); if (empty($users)) { - $users = array(); + // generate an error + $link = new moodle_url('/mod/quiz/overrides.php', array('cmid'=>$cm->id)); + print_error('usersnone', 'quiz', $link); } $userchoices = array(); diff --git a/mod/quiz/overrides.php b/mod/quiz/overrides.php index c2c081fa9a3..8c15de1d9c5 100644 --- a/mod/quiz/overrides.php +++ b/mod/quiz/overrides.php @@ -31,9 +31,7 @@ require_once($CFG->dirroot.'/mod/quiz/override_form.php'); $cmid = required_param('cmid', PARAM_INT); // course module ID, or -$mode = optional_param('mode', 'group', PARAM_ALPHA); // one of 'user' or 'group' - -$groupmode = ($mode == "group"); +$mode = optional_param('mode', '', PARAM_ALPHA); // one of 'user' or 'group', default is 'group' if (! $cm = get_coursemodule_from_id('quiz', $cmid)) { print_error('invalidcoursemodule'); @@ -42,6 +40,22 @@ if (! $quiz = $DB->get_record('quiz', array('id' => $cm->instance))) { print_error('invalidcoursemodule'); } +// Get the course groups +$groups = groups_get_all_groups($cm->course); +if ($groups === false) { + $groups = array(); +} + +// Default mode is "group", unless there are no groups +if ($mode != "user" and $mode != "group") { + if (!empty($groups)) { + $mode = "group"; + } else { + $mode = "user"; + } +} +$groupmode = ($mode == "group"); + $url = new moodle_url('/mod/quiz/overrides.php', array('cmid'=>$cm->id, 'mode'=>$mode)); $PAGE->set_url($url); @@ -58,34 +72,44 @@ require_capability('mod/quiz:manageoverrides', $context); $PAGE->set_title(get_string('overrides', 'quiz')); echo $OUTPUT->header(); -// Print heading and tabs (if there is more than one). -$currenttab = 'overrides'; -include('tabs.php'); +// Delete orphaned group overrides +$sql = 'SELECT o.id + FROM {quiz_overrides} o LEFT JOIN {groups} g + ON o.groupid = g.id + WHERE o.groupid IS NOT NULL + AND g.id IS NULL + AND o.quiz = ?'; +$params = array($quiz->id); +$orphaned = $DB->get_records_sql($sql, $params); +if (!empty($orphaned)) { + $DB->delete_records_list('quiz_overrides', 'id', array_keys($orphaned)); +} // Fetch all overrides -$conds = array('quiz' => $quiz->id); if ($groupmode) { $colname = get_string('group'); $sql = 'SELECT o.*, g.name - FROM {quiz_overrides} o LEFT JOIN {groups} g + FROM {quiz_overrides} o JOIN {groups} g ON o.groupid = g.id - WHERE o.groupid IS NOT NULL - AND o.quiz = ? + WHERE o.quiz = ? ORDER BY g.name'; } else { $colname = get_string('user'); $sql = 'SELECT o.*, u.firstname, u.lastname, u.id as uid - FROM {quiz_overrides} o LEFT JOIN {user} u + FROM {quiz_overrides} o JOIN {user} u ON o.userid = u.id - WHERE o.userid IS NOT NULL - AND o.quiz = ? + WHERE o.quiz = ? ORDER BY u.lastname, u.firstname'; } $params = array($quiz->id); $overrides = $DB->get_records_sql($sql, $params); +// Print heading and tabs (if there is more than one). +$currenttab = 'overrides'; +include('tabs.php'); + // Initialise table $table = new html_table(); $table->headspan = array(1,2,1); @@ -102,16 +126,23 @@ $groupurl = new moodle_url('/group/overview.php', array('id' => $cm->course)); $overridedeleteurl = new moodle_url('/mod/quiz/overridedelete.php'); $overrideediturl = new moodle_url('/mod/quiz/overrideedit.php'); +$hasinactive = false; // are there any inactive overrides + foreach ($overrides as $override) { $fields = array(); $values = array(); + $active = true; - // check for orphaned overrides - if (!isset($override->name) && !isset($override->uid)) { - // no corresponding user/group record, so remove the override - quiz_delete_override($quiz, $override->id); - continue; + // check for inactive overrides + if (!$groupmode) { + if (!has_capability('mod/quiz:attempt', $context, $override->userid)) { + // user not allowed to take the quiz + $active = false; + } else if (!empty($CFG->enablegroupmembersonly) && $cm->groupmembersonly && !groups_has_membership($cm, $override->userid)) { + // user does not belong to the current grouping + $active = false; + } } // Format timeopen @@ -146,14 +177,18 @@ foreach ($overrides as $override) { // Icons: - // edit - $editurlstr = $overrideediturl->out(true, array('id' => $override->id)); - $iconstr = '' . - '' . get_string('edit') . ' '; - // duplicate - $copyurlstr = $overrideediturl->out(true, array('id' => $override->id, 'action' => 'duplicate')); - $iconstr .= '' . - '' . get_string('copy') . ' '; + $iconstr = ''; + + if ($active) { + // edit + $editurlstr = $overrideediturl->out(true, array('id' => $override->id)); + $iconstr = '' . + '' . get_string('edit') . ' '; + // duplicate + $copyurlstr = $overrideediturl->out(true, array('id' => $override->id, 'action' => 'duplicate')); + $iconstr .= '' . + '' . get_string('copy') . ' '; + } // delete $deleteurlstr = $overridedeleteurl->out(true, array('id' => $override->id, 'sesskey' => sesskey())); $iconstr .= '' . @@ -166,8 +201,11 @@ foreach ($overrides as $override) { $usergroupstr = '' . fullname($override) . ''; } - if (!empty($table->data)) { - $table->data[] = 'hr'; + $class = ''; + if (!$active) { + $class = "dimmed_text"; + $usergroupstr .= '*'; + $hasinactive = true; } $usergroupcell = new html_table_cell(); @@ -179,6 +217,7 @@ foreach ($overrides as $override) { for ($i = 0; $i < count($fields); ++$i) { $row = new html_table_row(); + $row->attributes['class'] = $class; if ($i == 0) { $row->cells[] = $usergroupcell; } @@ -201,14 +240,42 @@ echo html_writer::start_tag('div', array('id' => 'quizoverrides')); if (count($table->data)) { echo html_writer::table($table); } +if ($hasinactive) { + echo $OUTPUT->notification(get_string('inactiveoverridehelp', 'quiz'), 'dimmed_text'); +} echo html_writer::start_tag('div', array('class' => 'buttons')); +$options = array(); if ($groupmode) { + if (empty($groups)) { + // there are no groups + echo $OUTPUT->notification(get_string('groupsnone', 'quiz'), 'error'); + $options['disabled'] = true; + } echo $OUTPUT->single_button($overrideediturl->out(true, array('action' => 'addgroup', 'cmid' => $cm->id)), - get_string('addnewgroupoverride', 'quiz')); + get_string('addnewgroupoverride', 'quiz'), 'post', $options); } else { + $users = array(); + // See if there are any students in the quiz + if (!empty($CFG->enablegroupmembersonly) && $cm->groupmembersonly) { + // restrict to grouping + $limitgroups = groups_get_all_groups($cm->course, 0, $cm->groupingid); + if (!empty($limitgroups)) { + $users = get_users_by_capability($context, 'mod/quiz:attempt', 'u.id', '', '', 1, array_keys($limitgroups)); // Limit to one user for speed + } else { + // empty grouping + } + } else { + $users = get_users_by_capability($context, 'mod/quiz:attempt', 'u.id'); // Limit to one user for speed + } + + if (empty($users)) { + // there are no students + echo $OUTPUT->notification(get_string('usersnone', 'quiz'), 'error'); + $options['disabled'] = true; + } echo $OUTPUT->single_button($overrideediturl->out(true, array('action' => 'adduser', 'cmid' => $cm->id)), - get_string('addnewuseroverride', 'quiz')); + get_string('addnewuseroverride', 'quiz'), 'post', $options); } echo html_writer::end_tag('div'); echo html_writer::end_tag('div'); diff --git a/mod/quiz/tabs.php b/mod/quiz/tabs.php index fe613833a14..f051a029f97 100644 --- a/mod/quiz/tabs.php +++ b/mod/quiz/tabs.php @@ -101,11 +101,15 @@ if ($currenttab == 'overrides' and isset($mode)) { $currenttab = $mode; $strgroup = get_string('groupoverrides', 'quiz'); + if (empty($groups)) { + $inactive[] = 'group'; + } $struser = get_string('useroverrides', 'quiz'); - $row[] = new tabobject('group', "$CFG->wwwroot/mod/quiz/overrides.php?cmid=$cm->id", $strgroup); + $row[] = new tabobject('group', "$CFG->wwwroot/mod/quiz/overrides.php?cmid=$cm->id&mode=group", $strgroup); $row[] = new tabobject('user', "$CFG->wwwroot/mod/quiz/overrides.php?cmid=$cm->id&mode=user", $struser); $tabs[] = $row; + } if (!$quiz->questions) {