+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
Index: lang/en_utf8/quiz.php
===================================================================
RCS file: /cvsroot/moodle/moodle/lang/en_utf8/quiz.php,v
retrieving revision 1.143
diff -u -r1.143 quiz.php
--- lang/en_utf8/quiz.php 30 Sep 2009 10:57:57 -0000 1.143
+++ lang/en_utf8/quiz.php 10 Feb 2010 03:27:24 -0000
@@ -26,8 +26,10 @@
$string['addingshortanswer'] = 'Adding a Short-Answer question';
$string['addingtruefalse'] = 'Adding a True/False question';
$string['addmoreoverallfeedbacks'] = 'Add {no} more feedback fields';
+$string['addnewgroupoverride'] = 'Add group override';
$string['addnewpagesafterselected'] = 'Add new pages after selected questions';
$string['addnewquestionsqbank'] = 'Add questions to the category $a->catname: $a->link';
+$string['addnewuseroverride'] = 'Add user override';
$string['addpagehere'] = 'Add page here';
$string['addquestion'] = 'Add question';
$string['addquestions'] = 'Add questions';
@@ -248,6 +250,7 @@
$string['editquestions'] = 'Edit questions';
$string['editquiz'] = 'Edit Quiz';
$string['editquizquestions'] = 'Edit Quiz Questions';
+$string['editoverride'] = 'Edit overrides';
$string['emailconfirmbody'] = 'Dear $a->username,
Thank you for submitting your answers to
@@ -350,6 +353,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['guestsno'] = 'Sorry, guests cannot see or attempt quizzes';
$string['hidebreaks'] = 'Hide page breaks';
$string['hidereordertool'] = 'Hide the reordering tool';
@@ -454,6 +458,7 @@
$string['nominal'] = 'Nominal';
$string['nomoreattempts'] = 'No more attempts are allowed';
$string['none'] = 'None';
+$string['nooverridedata'] = 'You must override at least one of the quiz settings.';
$string['nopossibledatasets'] = 'No possible datasets';
$string['noquestionintext'] = 'The question text does not contain any embedded questions';
$string['noquestions'] = 'No questions have been added yet';
@@ -483,6 +488,7 @@
$string['onlyteachersexport'] = 'Only teachers can export questions';
$string['onlyteachersimport'] = 'Only teachers with editing rights can import questions';
$string['open'] = 'Started';
+$string['openafterclose'] = 'Could not update the quiz. You have specified a open date after the close date.';
$string['openclosedatesupdated'] = 'Quiz open and close dates updated';
$string['optional'] = 'optional';
$string['orderandpaging'] = 'Order and paging';
@@ -492,6 +498,10 @@
$string['outofshort'] = '$a->grade/$a->maxgrade';
$string['overallfeedback'] = 'Overall feedback';
$string['overdue'] = 'Overdue';
+$string['overrides'] = 'Overrides';
+$string['overridegroup'] = 'Override group';
+$string['overrideuser'] = 'Override user';
+$string['overrideuserstr'] = 'Override';
$string['pagesize'] = 'Attempts shown per page:';
$string['paragraphquestion'] = 'Paragraph Question not supported at line $a. The question will be ignored';
$string['parent'] = 'Parent';
@@ -659,6 +669,7 @@
$string['savegrades'] = 'Save grades';
$string['savemyanswers'] = 'Save my answers';
$string['savenosubmit'] = 'Save without submitting';
+$string['saveoverrideandstay'] = 'Save and enter another override';
$string['savequiz'] = 'Save this whole quiz';
$string['score'] = 'Raw score';
$string['scores'] = 'Scores';
@@ -752,6 +763,7 @@
$string['upgradesure'] = 'In particular the quiz module will perform an extensive change of the quiz tables and this upgrade has not yet been sufficiently tested. You are very strongly urged to backup your database tables before proceeding.
';
$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['validate'] = 'Validate';
$string['viewallanswers'] = 'View $a quiz attempts';
$string['viewallreports'] = 'View reports for $a attempts';
Index: mod/quiz/override_form.php
===================================================================
RCS file: mod/quiz/override_form.php
diff -N mod/quiz/override_form.php
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ mod/quiz/override_form.php 1 Jan 1970 00:00:00 -0000
@@ -0,0 +1,218 @@
+.
+
+
+/**
+ * Settings form for overrides in the quiz module.
+ *
+ * @package mod-quiz
+ * @author Matt Petro
+ * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+
+require_once $CFG->libdir.'/formslib.php';
+
+class quiz_override_form extends moodleform {
+
+ protected $cm; // course module object
+ protected $quiz; // quiz object
+ protected $context; // context object
+ protected $groupmode; // editing group override (true) or user override (false)
+
+ protected $currentgroupid; // what was the previous group id
+ protected $currentuserid; // what was the previous user id
+
+ const filterlists = false; // should the user and group lists be filtered to remove existing overrides?
+ // If this is false, then new overrides silently overwrite old ones
+
+ public function quiz_override_form($submiturl, $current, $cm, $quiz, $context, $groupmode){
+
+ $this->cm = $cm;
+ $this->quiz = $quiz;
+ $this->context = $context;
+ $this->groupmode = $groupmode;
+
+ $this->currentgroupid = isset($current->groupid)? $current->groupid : 0;
+ $this->currentuserid = isset($current->userid)? $current->userid : 0;
+
+ parent::moodleform($submiturl, null, 'post');
+
+ }
+
+ public function definition() {
+ global $CFG, $USER, $DB;
+
+ $cm = $this->cm;
+ $mform = $this->_form;
+
+ $cancelonly = false;
+
+ $mform->addElement('header', 'override', get_string('overrides', 'quiz'));
+
+ if ($this->groupmode) {
+ // Prepare the list of groups
+ $groups = groups_get_all_groups($cm->course, null, $cm->groupingid);
+ if (empty($groups)) {
+ $groups = array();
+ }
+
+ $groupchoices = array();
+ foreach ($groups as $group) {
+ $groupchoices[$group->id] = format_string($group->name);
+ }
+ unset($groups);
+
+ // Remove any groups that are already overridden
+
+ if (self::filterlists) {
+ $overrides = $DB->get_records('quiz_overrides', array('quiz' => $cm->instance));
+ if (!empty($overrides)) {
+ foreach ($overrides as $taken) {
+ if ($taken->groupid && array_key_exists($taken->groupid, $groupchoices)
+ && $taken->groupid != $this->currentgroupid) {
+ unset($groupchoices[$taken->groupid]);
+ }
+ }
+ }
+ }
+
+ if (count($groupchoices) == 0) {
+ $groupchoices[0] = get_string('none');
+ }
+
+ $mform->addElement('select', 'groupid', get_string('overridegroup', 'quiz'), $groupchoices);
+ $mform->addRule('groupid', get_string('required'), 'required', null, 'client');
+
+ } else {
+ // Prepare the list of users
+ if (!empty($cm->groupingid)) {
+ $groups = groups_get_all_groups($cm->course, 0, $cm->groupingid);
+ $groups = array_keys($groups);
+ } 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', '', '', $groups, '', false, true);
+ if (empty($users)) {
+ $users = array();
+ }
+
+ $userchoices = array();
+ foreach ($users as $id=>$user) {
+ if (empty($invalidusers[$id]) || (!empty($override) && $id == $override->userid)) {
+ $userchoices[$id] = fullname($user) . ', ' . $user->email;
+ }
+ }
+ unset($users);
+
+ // Remove any users that are already overridden
+ if (self::filterlists) {
+ $overrides = $DB->get_records('quiz_overrides', array('quiz' => $cm->instance));
+
+ if (!empty($overrides)) {
+ foreach ($overrides as $taken) {
+ if ($taken->userid && array_key_exists($taken->userid, $userchoices)
+ && $taken->userid != $this->currentuserid) {
+ unset($userchoices[$taken->userid]);
+ }
+ }
+ }
+ }
+
+ if (count($userchoices) == 0) {
+ $userchoices[0] = get_string('none');
+ }
+
+ $mform->addElement('searchableselector', 'userid', get_string('overrideuser', 'quiz'), $userchoices);
+ $mform->addRule('userid', get_string('required'), 'required', null, 'client');
+
+ }
+
+ // Open and close dates.
+ $mform->addElement('date_time_selector', 'timeopen', get_string('quizopen', 'quiz'), array('optional' => true));
+ $mform->setHelpButton('timeopen', array('timeopen', get_string('quizopen', 'quiz'), 'quiz'));
+
+ $mform->addElement('date_time_selector', 'timeclose', get_string('quizclose', 'quiz'), array('optional' => true));
+ $mform->setHelpButton('timeclose', array('timeopen', get_string('quizclose', 'quiz'), 'quiz'));
+
+ // Time limit.
+ $mform->addElement('duration', 'timelimit', get_string('quiztimer', 'quiz'), array('optional' => true));
+ $mform->setHelpButton('timelimit', array('timelimit', get_string('quiztimer','quiz'), 'quiz'));
+
+ $mform->addElement('hidden', 'id', 0);
+ $mform->setType('override', PARAM_INT);
+
+ $mform->addElement('hidden', 'cmid', 0);
+ $mform->setType('cmid', PARAM_INT);
+
+ // Submit buttons
+ $buttonarray = array();
+ $buttonarray[] = &$mform->createElement('submit', 'submitbutton', get_string('save', 'quiz'));
+ $buttonarray[] = &$mform->createElement('submit', 'againbutton', get_string('saveoverrideandstay', 'quiz'));
+ $buttonarray[] = &$mform->createElement('cancel');
+
+ $mform->addGroup($buttonarray, 'buttonbar', '', array(' '), false);
+ $mform->closeHeaderBefore('buttonbar');
+
+ }
+
+ // form verification
+ public function validation($data, $files) {
+ global $COURSE, $DB;
+ $errors = parent::validation($data, $files);
+
+ $mform =& $this->_form;
+ $quiz = $this->quiz;
+
+ if ($mform->elementExists('userid')) {
+ if (empty($data['userid'])) {
+ $errors['userid'] = get_string('required');
+ }
+ }
+
+ if ($mform->elementExists('groupid')) {
+ if (empty($data['groupid'])) {
+ $errors['groupid'] = get_string('required');
+ }
+ }
+
+ // Ensure that the dates make sense
+ $effectivetimeopen = (!empty($data['timeopen']))? $data['timeopen'] : $quiz->timeopen;
+ $effectivetimeclose = (!empty($data['timeclose']))? $data['timeclose'] : $quiz->timeclose;
+
+ if (!empty($data['timeopen'])) {
+ if ($effectivetimeclose && $data['timeopen'] > $effectivetimeclose ) {
+ $errors['timeopen'] = get_string('openafterclose', 'quiz');
+ }
+ }
+
+ if (!empty($data['timeclose']) && empty($errors['timeopen'])) {
+ if ($data['timeclose'] < $effectivetimeopen ) {
+ $errors['timeclose'] = get_string('closebeforeopen', 'quiz');
+ }
+ }
+
+ if (empty($data['timeopen']) && empty($data['timeclose']) && empty($data['timelimit'])) {
+ $errors['timeopen'] = get_string('nooverridedata', 'quiz');
+ $errors['timeclose'] = $errors['timeopen'];
+ $errors['timelimit'] = $errors['timeopen'];
+ }
+
+ return $errors;
+ }
+
+}
\ No newline at end of file
Index: mod/quiz/override.php
===================================================================
RCS file: mod/quiz/override.php
diff -N mod/quiz/override.php
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ mod/quiz/override.php 1 Jan 1970 00:00:00 -0000
@@ -0,0 +1,256 @@
+.
+
+
+/**
+ * This page handles listing and editing of quiz overrides
+ *
+ * @package mod-quiz
+ * @author Matt Petro
+ * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+
+require_once(dirname(__FILE__) . '/../../config.php');
+require_once($CFG->dirroot.'/mod/quiz/lib.php');
+require_once($CFG->dirroot.'/mod/quiz/locallib.php');
+require_once($CFG->dirroot.'/mod/quiz/override_form.php');
+
+
+$cmid = optional_param('cmid', 0, PARAM_INT); // course module ID, or
+$overrideid = optional_param('id', 0, PARAM_INT); // override ID
+
+$action = optional_param('action', '', PARAM_ALPHA); // one of 'delete','adduser','addgroup','edit'
+
+if ($overrideid) {
+
+ if (! $override = $DB->get_record('quiz_overrides', array('id' => $overrideid))) {
+ print_error('invalidoverrideid', 'quiz');
+ }
+ if (! $quiz = $DB->get_record('quiz', array('id' => $override->quiz))) {
+ print_error('invalidcoursemodule');
+ }
+ if (! $cm = get_coursemodule_from_instance("quiz", $quiz->id, $quiz->course)) {
+ print_error('invalidcoursemodule');
+ }
+} else if ($cmid) {
+
+ if (! $cm = get_coursemodule_from_id('quiz', $cmid)) {
+ print_error('invalidcoursemodule');
+ }
+ if (! $quiz = $DB->get_record('quiz', array('id' => $cm->instance))) {
+ print_error('invalidcoursemodule');
+ }
+} else {
+ print_error('invalidcoursemodule');
+}
+
+$url = new moodle_url('/mod/quiz/override.php', array('cmid'=>$cm->id, 'action'=>$action));
+
+$PAGE->set_url($url);
+
+require_login($cm->course, false, $cm);
+
+$context = get_context_instance(CONTEXT_MODULE, $cm->id);
+
+
+if ($action === 'delete' && confirm_sesskey()) {
+
+ // Remove it
+
+ require_capability('mod/quiz:manage', $context);
+
+ if (empty($override->id)) {
+ print_error('invalidoverrideid', 'quiz');
+ }
+
+ quiz_delete_override($quiz, $override->id);
+
+ $url->param('action', 'list');
+ redirect($url);
+}
+else if ($action === 'adduser' || $action === 'addgroup' || $action === 'edit') {
+
+ // Add or edit an override
+
+ require_capability('mod/quiz:manage', $context);
+
+ if ($action === 'edit') {
+ if (empty($override->id)) {
+ print_error('invalidoverrideid', 'quiz');
+ }
+ $data = $override;
+ }
+ else {
+ $data = new object();
+ $data->quiz = $quiz->id;
+ }
+
+ $data->cmid = $cm->id;
+
+ // Setup the form.
+ $group_mode = $action === 'addgroup' || !empty($data->groupid); // true if group-based override
+
+ $mform = new quiz_override_form($url, $data, $cm, $quiz, $context, $group_mode);
+ $mform->set_data($data);
+
+ if ($mform->is_cancelled()) {
+ $url->param('action', 'list');
+ redirect($url);
+ } else if ($fromform = $mform->get_data()) {
+
+ // Process the data
+
+ add_to_log($cm->course, 'quiz', 'edit overrides',
+ "override.php?cmid=$cm->id", $quiz->id, $cm->id);
+
+ $fromform->quiz = $quiz->id;
+
+ // See if we are replacing an existing override
+ if (empty($override->id)) {
+ $conditions = array(
+ 'quiz' => $quiz->id,
+ 'userid' => empty($fromform->userid)? 0 : $fromform->userid,
+ 'groupid' => empty($fromform->groupid)? 0 : $fromform->groupid);
+ if ($oldoverride = $DB->get_record('quiz_overrides', $conditions)) {
+ $fromform->id = $oldoverride->id;
+ }
+ }
+
+ if (!empty($fromform->id)) {
+ $DB->update_record('quiz_overrides', $fromform);
+ }
+ else {
+ $fromform->id = $DB->insert_record('quiz_overrides', $fromform);
+ }
+
+ quiz_events_update($quiz, $fromform);
+
+ if ($fromform->submitbutton) {
+ $url->param('action', 'list');
+ redirect($url);
+ }
+
+ // 'again' button pressed, so print the form
+ $mform->set_data(array('action' => ($group_mode)? 'addgroup' : 'adduser'));
+ }
+
+ // Print the form
+
+ $pagetitle = get_string('editoverride', 'quiz');
+ $PAGE->navbar->add($pagetitle);
+ $PAGE->set_title($pagetitle);
+
+ echo $OUTPUT->header();
+ echo $OUTPUT->heading($pagetitle);
+
+ $mform->display();
+
+ echo $OUTPUT->footer();
+}
+else {
+ // Display a list of overrides
+
+ require_capability('mod/quiz:manage', $context);
+
+ $overrides = $DB->get_records('quiz_overrides', array('quiz' => $quiz->id));
+ if (!$overrides) {
+ $overrides = array();
+ }
+
+ echo $OUTPUT->header();
+
+ // Print heading and tabs (if there is more than one).
+ $currenttab = 'overrides';
+ include('tabs.php');
+
+ // Initialise user table
+ $utable = new html_table();
+ $utable->tablealign = 'center';
+ $utable->align = array('left', 'left', 'left', 'left');
+ $utable->wrap = array('nowrap', '', 'nowrap','nowrap');
+ $utable->width = '90%';
+ $utable->head = array(
+ get_string('user'),
+ get_string('quizopen', 'quiz'),
+ get_string('quizclose', 'quiz'),
+ get_string('quiztimer', 'quiz'),
+ ''
+ );
+
+ // Initialise group table
+ $gtable = new html_table();
+ $gtable->tablealign = 'center';
+ $gtable->align = array('left', 'left', 'left', 'left');
+ $gtable->wrap = array('nowrap', '', 'nowrap','nowrap');
+ $gtable->width = '90%';
+ $gtable->head = array(
+ get_string('group'),
+ get_string('quizopen', 'quiz'),
+ get_string('quizclose', 'quiz'),
+ get_string('quiztimer', 'quiz'),
+ ''
+ );
+
+ $userurl = new moodle_url('/user/view.php', array());
+ $groupurl = new moodle_url('/group/overview.php', array('id' => $cm->course));
+
+ foreach ($overrides as $override) {
+
+ $timeopenstr = ($override->timeopen > 0)? userdate($override->timeopen) : '-';
+ $timeclosestr = ($override->timeclose > 0)? userdate($override->timeclose) : '-';
+ $timelimitstr = ($override->timelimit > 0)? format_time($override->timelimit) : '-';
+
+ // Icons:
+
+ // edit
+ $editurlstr = $url->out(true, array('action' => 'edit', 'id' => $override->id));
+ $iconstr = '' .
+ ' ';
+ // delete
+ $deleteurlstr = $url->out(true, array('action' => 'delete', 'id' => $override->id, 'sesskey' => sesskey()));
+ $iconstr .= '' .
+ ' ';
+
+ if ($override->groupid) {
+ $group = $DB->get_record('groups', array('id' => $override->groupid));
+ $usergroupstr = '' . $group->name . '';
+ $thistable =& $gtable;
+ }
+ else {
+ $user = $DB->get_record('user', array('id' => $override->userid), 'id,firstname,lastname' );
+ $usergroupstr = '' . fullname($user) . '';
+ $thistable =& $utable;
+ }
+
+ $thistable->data[] = array($usergroupstr, $timeopenstr, $timeclosestr, $timelimitstr, $iconstr);
+ }
+
+ // Output the tables and buttons
+
+ echo $OUTPUT->heading(get_string('groupoverrides', 'quiz'), 3);
+ echo $OUTPUT->table($gtable);
+
+ echo $OUTPUT->single_button($url->out(true, array('action' => 'addgroup')), get_string('addnewgroupoverride', 'quiz'), $method='post');
+
+ echo $OUTPUT->heading(get_string('useroverrides', 'quiz'), 3);
+ echo $OUTPUT->table($utable);
+
+ echo $OUTPUT->single_button($url->out(true, array('action' => 'adduser')), get_string('addnewuseroverride', 'quiz'), $method='post');
+
+ // Finish the page
+ echo $OUTPUT->footer();
+}
\ No newline at end of file