quiz: MDL-16478 Allow different open/close dates, etc. for individual students or groups.

This was implemented by Matt Petro of the University of Wisconsin - Madison Engineering
School and Math Department. Many thanks. Reviewed by and committed by Tim Hunt.

This adds a new Overrides tab to the UI, with sub-tabs Group overrides and User overrides.
Each of those lists all the overrides that currently exist, and lets you manage them and
create more.

When a quiz is being attempted, the override that applies to the current user is combined
with the current quiz settings loaded from the quiz table (normally called $quiz).
If there are both user and group overrides, then just the specific user override is used (more specific).
If the user is in several groups, then the overrides are combined to give the most permissive set of options.

There is one new database table quiz_overrides, to store the overrides.
This commit is contained in:
Tim Hunt 2010-03-08 16:01:38 +00:00
parent cdede6fbfe
commit 990650f94c
25 changed files with 1309 additions and 127 deletions

View file

@ -52,6 +52,16 @@ $capabilities = array(
)
),
// Edit the quiz overrides
'mod/quiz:manageoverrides' => array(
'captype' => 'write',
'contextlevel' => CONTEXT_MODULE,
'legacy' => array(
'editingteacher' => CAP_ALLOW,
'admin' => CAP_ALLOW
)
),
// Preview the quiz.
'mod/quiz:preview' => array(
'captype' => 'write', // Only just a write.

View file

@ -21,6 +21,8 @@ function xmldb_quiz_install() {
update_log_display_entry('quiz', 'start attempt', 'quiz', 'name');
update_log_display_entry('quiz', 'close attempt', 'quiz', 'name');
update_log_display_entry('quiz', 'continue attempt', 'quiz', 'name');
update_log_display_entry('quiz', 'edit override', 'quiz', 'name');
update_log_display_entry('quiz', 'delete override', 'quiz', 'name');
$record = new object();
$record->name = 'overview';

View file

@ -1,5 +1,5 @@
<?xml version="1.0" encoding="UTF-8" ?>
<XMLDB PATH="mod/quiz/db" VERSION="20090420" COMMENT="XMLDB file for Moodle mod/quiz"
<XMLDB PATH="mod/quiz/db" VERSION="20100220" COMMENT="XMLDB file for Moodle mod/quiz"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="../../../lib/xmldb/xmldb.xsd"
>
@ -109,7 +109,7 @@
<KEY NAME="quizid" TYPE="foreign" FIELDS="quizid" REFTABLE="quiz" REFFIELDS="id" PREVIOUS="primary"/>
</KEYS>
</TABLE>
<TABLE NAME="quiz_report" COMMENT="Lists all the installed quiz reports and their display order and so on. No need to worry about deleting old records. Only records with an equivalent directory are displayed." PREVIOUS="quiz_feedback">
<TABLE NAME="quiz_report" COMMENT="Lists all the installed quiz reports and their display order and so on. No need to worry about deleting old records. Only records with an equivalent directory are displayed." PREVIOUS="quiz_feedback" NEXT="quiz_overrides">
<FIELDS>
<FIELD NAME="id" TYPE="int" LENGTH="10" NOTNULL="true" UNSIGNED="true" SEQUENCE="true" NEXT="name"/>
<FIELD NAME="name" TYPE="char" LENGTH="255" NOTNULL="false" SEQUENCE="false" COMMENT="name of the report, same as the directory name" PREVIOUS="id" NEXT="displayorder"/>
@ -122,5 +122,24 @@
<KEY NAME="primary" TYPE="primary" FIELDS="id"/>
</KEYS>
</TABLE>
<TABLE NAME="quiz_overrides" COMMENT="The overrides to quiz settings on a per-user and per-group basis." PREVIOUS="quiz_report">
<FIELDS>
<FIELD NAME="id" TYPE="int" LENGTH="10" NOTNULL="true" UNSIGNED="true" SEQUENCE="true" NEXT="quiz"/>
<FIELD NAME="quiz" TYPE="int" LENGTH="10" NOTNULL="true" UNSIGNED="true" DEFAULT="0" SEQUENCE="false" COMMENT="Foreign key references quiz.id" PREVIOUS="id" NEXT="groupid"/>
<FIELD NAME="groupid" TYPE="int" LENGTH="10" NOTNULL="false" UNSIGNED="true" SEQUENCE="false" COMMENT="Foreign key references groups.id. Can be null if this is a per-user override." PREVIOUS="quiz" NEXT="userid"/>
<FIELD NAME="userid" TYPE="int" LENGTH="10" NOTNULL="false" UNSIGNED="true" SEQUENCE="false" COMMENT="Foreign key references user.id. Can be null if this is a per-group override." PREVIOUS="groupid" NEXT="timeopen"/>
<FIELD NAME="timeopen" TYPE="int" LENGTH="10" NOTNULL="false" UNSIGNED="true" SEQUENCE="false" COMMENT="Time at which students may start attempting this quiz. Can be null, in which case the quiz default is used." PREVIOUS="userid" NEXT="timeclose"/>
<FIELD NAME="timeclose" TYPE="int" LENGTH="10" NOTNULL="false" UNSIGNED="true" SEQUENCE="false" COMMENT="Time by which students must have completed their attempt. Can be null, in which case the quiz default is used." PREVIOUS="timeopen" NEXT="timelimit"/>
<FIELD NAME="timelimit" TYPE="int" LENGTH="10" NOTNULL="false" UNSIGNED="true" SEQUENCE="false" COMMENT="Time limit in seconds. Can be null, in which case the quiz default is used." PREVIOUS="timeclose" NEXT="attempts"/>
<FIELD NAME="attempts" TYPE="int" LENGTH="6" NOTNULL="false" UNSIGNED="true" SEQUENCE="false" PREVIOUS="timelimit" NEXT="password"/>
<FIELD NAME="password" TYPE="char" LENGTH="255" NOTNULL="false" SEQUENCE="false" COMMENT="Quiz password. Can be null, in which case the quiz default is used." PREVIOUS="attempts"/>
</FIELDS>
<KEYS>
<KEY NAME="primary" TYPE="primary" FIELDS="id" NEXT="quiz"/>
<KEY NAME="quiz" TYPE="foreign" FIELDS="quiz" REFTABLE="quiz" REFFIELDS="id" PREVIOUS="primary" NEXT="groupid"/>
<KEY NAME="groupid" TYPE="foreign" FIELDS="groupid" REFTABLE="groups" REFFIELDS="id" PREVIOUS="quiz" NEXT="userid"/>
<KEY NAME="userid" TYPE="foreign" FIELDS="userid" REFTABLE="user" REFFIELDS="id" PREVIOUS="groupid"/>
</KEYS>
</TABLE>
</TABLES>
</XMLDB>

View file

@ -292,6 +292,40 @@ function xmldb_quiz_upgrade($oldversion) {
upgrade_mod_savepoint($result, 2009042000, 'quiz');
}
if ($result && $oldversion < 2010030501) {
/// fix log actions
update_log_display_entry('quiz', 'edit override', 'quiz', 'name');
update_log_display_entry('quiz', 'delete override', 'quiz', 'name');
/// Define table quiz_overrides to be created
$table = new xmldb_table('quiz_overrides');
/// Adding fields to table quiz_overrides
$table->add_field('id', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, XMLDB_SEQUENCE, null);
$table->add_field('quiz', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, '0');
$table->add_field('groupid', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, null, null, null);
$table->add_field('userid', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, null, null, null);
$table->add_field('timeopen', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, null, null, null);
$table->add_field('timeclose', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, null, null, null);
$table->add_field('timelimit', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, null, null, null);
$table->add_field('attempts', XMLDB_TYPE_INTEGER, '6', XMLDB_UNSIGNED, null, null, null);
$table->add_field('password', XMLDB_TYPE_CHAR, '255', null, null, null, null);
/// Adding keys to table quiz_overrides
$table->add_key('primary', XMLDB_KEY_PRIMARY, array('id'));
$table->add_key('quiz', XMLDB_KEY_FOREIGN, array('quiz'), 'quiz', array('id'));
$table->add_key('groupid', XMLDB_KEY_FOREIGN, array('groupid'), 'groups', array('id'));
$table->add_key('userid', XMLDB_KEY_FOREIGN, array('userid'), 'user', array('id'));
/// Conditionally launch create table for quiz_overrides
if (!$dbman->table_exists($table)) {
$dbman->create_table($table);
}
/// quiz savepoint reached
upgrade_mod_savepoint($result, 2010030501, 'quiz');
}
return $result;
}