I have introduced the new field $attempt->uniqueid, see http://mantis.york.ac.uk/moodle/mod/forum/discuss.php?d=852#3380

This commit is contained in:
gustav_delius 2005-07-02 18:14:51 +00:00
parent 591212f69d
commit d115d8c736
18 changed files with 70 additions and 46 deletions

View file

@ -173,8 +173,8 @@
delete_records('quiz_grades', 'quiz', $quiz->id, 'userid', $USER->id);
foreach ($oldattempts as $oldattempt) {
// there should only be one but we loop just in case
delete_records('quiz_states', 'attempt', $oldattempt->id);
delete_records('quiz_newest_states', 'attemptid', $oldattempt->id);
delete_records('quiz_states', 'attempt', $oldattempt->uniqueid);
delete_records('quiz_newest_states', 'attemptid', $oldattempt->uniqueid);
}
}
}
@ -312,7 +312,7 @@
// Find all the questions for this attempt for which the newest
// state is not also the newest graded state
if ($closequestions = get_records_select('quiz_newest_states',
"attemptid = $attempt->id AND newest != newgraded", '', 'questionid, questionid')) {
"attemptid = $attempt->uniqueid AND newest != newgraded", '', 'questionid, questionid')) {
// load all the questions
$closequestionlist = implode(',', array_keys($closequestions));

View file

@ -865,6 +865,7 @@
$status =fwrite ($bf,start_tag("ATTEMPT",5,true));
//Print attempt contents
fwrite ($bf,full_tag("ID",6,false,$attempt->id));
fwrite ($bf,full_tag("UNIQUEID",6,false,$attempt->uniqueid));
fwrite ($bf,full_tag("USERID",6,false,$attempt->userid));
fwrite ($bf,full_tag("ATTEMPTNUM",6,false,$attempt->attempt));
fwrite ($bf,full_tag("SUMGRADES",6,false,$attempt->sumgrades));
@ -874,7 +875,7 @@
fwrite ($bf,full_tag("LAYOUT",6,false,$attempt->layout));
fwrite ($bf,full_tag("PREVIEW",6,false,$attempt->preview));
//Now write to xml the states (in this attempt)
$status = backup_quiz_states ($bf,$preferences,$attempt->id);
$status = backup_quiz_states ($bf,$preferences,$attempt->uniqueid);
//End attempt
$status =fwrite ($bf,end_tag("ATTEMPT",5,true));
}

View file

@ -860,6 +860,16 @@ function quiz_upgrade($oldversion) {
) TYPE=MyISAM COMMENT='essay question type specific state information'");
}
if ($oldversion < 2005070202) {
// add new unique id to prepare the way for lesson module to have its own attempts table
table_column('quiz_attempts', '', 'uniqueid', 'integer', '10', 'unsigned', '0', 'not null', 'id');
// initially we can use the id as the unique id because no other modules use attempts yet.
execute_sql("UPDATE {$CFG->prefix}quiz_attempts SET uniqueid = id", false);
// we set $CFG->attemptuniqueid to the next available id
$record = get_record_sql("SELECT max(id)+1 AS nextid FROM {$CFG->prefix}quiz_attempts");
set_config('attemptuniqueid', $record->nextid);
}
return true;
}

View file

@ -72,8 +72,8 @@ function quiz_delete_quiz_question($id, &$modform) {
// Delete all states associated with all attempts for this question in the quiz.
if ($attempts = get_records('quiz_attempts', 'quiz', $modform->instance)) {
foreach ($attempts as $attempt) {
delete_records('quiz_states', 'question', $question, 'attempt', $attempt->id);
delete_records('quiz_newest_states', 'questionid', $question, 'attemptid', $attempt->id);
delete_records('quiz_states', 'question', $question, 'attempt', $attempt->uniqueid);
delete_records('quiz_newest_states', 'questionid', $question, 'attemptid', $attempt->uniqueid);
}
}
// Delete all instances of the question in the quiz (there

View file

@ -124,7 +124,7 @@
" FROM {$CFG->prefix}quiz_states s,".
" {$CFG->prefix}quiz_newest_states n".
" WHERE s.id = n.newest".
" AND n.attemptid = '$attempt->id'".
" AND n.attemptid = '$attempt->uniqueid'".
" AND n.questionid = $question->id";
$state = get_record_sql($sql);
@ -150,7 +150,7 @@
$sumgrades = 0;
$questionids = explode(',', quiz_questions_in_quiz($attempt->layout));
foreach($questionids as $questionid) {
$lastgradedid = get_field('quiz_newest_states', 'newgraded', 'attemptid', $attempt->id, 'questionid', $questionid);
$lastgradedid = get_field('quiz_newest_states', 'newgraded', 'attemptid', $attempt->uniqueid, 'questionid', $questionid);
$sumgrades += get_field('quiz_states', 'grade', 'id', $lastgradedid);
}
@ -276,7 +276,7 @@
$ungraded = 0;
foreach ($attempts as $attempt) {
// grab the state then check if it is graded
if (!$neweststate = get_record('quiz_newest_states', 'attemptid', $attempt->id, 'questionid', $question->id)) {
if (!$neweststate = get_record('quiz_newest_states', 'attemptid', $attempt->uniqueid, 'questionid', $question->id)) {
error('Invalid attempt and question ids');
}
if (!$questionstate = get_record('quiz_essay_states', 'stateid', $neweststate->newest)) {

View file

@ -214,7 +214,10 @@ function quiz_delete_instance($id) {
if ($attempts = get_records("quiz_attempts", "quiz", "$quiz->id")) {
foreach ($attempts as $attempt) {
if (! delete_records("quiz_states", "attempt", "$attempt->id")) {
if (! delete_records("quiz_states", "attempt", "$attempt->uniqueid")) {
$result = false;
}
if (! delete_records("quiz_newest_states", "attemptid", "$attempt->uniqueid")) {
$result = false;
}
}

View file

@ -52,7 +52,7 @@ $QUIZ_GRADE_METHOD = array ( QUIZ_GRADEHIGHEST => get_string("gradehighest", "qu
* @param integer $attemptnumber The sequence number for the attempt.
*/
function quiz_create_attempt($quiz, $attemptnumber) {
global $USER;
global $USER, $CFG;
if (!$attemptnumber > 1 or !$quiz->attemptonlast or !$attempt = get_record('quiz_attempts', 'quiz', $quiz->id, 'userid', $USER->id, 'attempt', $attemptnumber-1)) {
// we are not building on last attempt so create a new attempt
@ -72,6 +72,8 @@ function quiz_create_attempt($quiz, $attemptnumber) {
$attempt->timestart = $timenow;
$attempt->timefinish = 0;
$attempt->timemodified = $timenow;
$attempt->uniqueid = $CFG->attemptuniqueid;
set_config('attemptuniqueid', $CFG->attemptuniqueid + 1);
return $attempt;
}
@ -502,16 +504,16 @@ function quiz_upgrade_states($attempt) {
// only one state record per question for this attempt.
// We set the timestamp of all states to the timemodified field of the attempt.
execute_sql("UPDATE {$CFG->prefix}quiz_states SET timestamp = '$attempt->timemodified' WHERE attempt = '$attempt->id'", false);
execute_sql("UPDATE {$CFG->prefix}quiz_states SET timestamp = '$attempt->timemodified' WHERE attempt = '$attempt->uniqueid'", false);
// For each state we create an entry in the quiz_newest_states table, with both newest and
// newgraded pointing to this state.
// Actually we only do this for states whose question is actually listed in $attempt->layout.
// We do not do it for states associated to wrapped questions like for example the questions
// used by a RANDOM question
$newest->attemptid = $attempt->id;
$newest->attemptid = $attempt->uniqueid;
$questionlist = quiz_questions_in_quiz($attempt->layout);
if ($states = get_records_select('quiz_states', "attempt = '$attempt->id' AND question IN ($questionlist)")) {
if ($states = get_records_select('quiz_states', "attempt = '$attempt->uniqueid' AND question IN ($questionlist)")) {
foreach ($states as $state) {
$newest->newgraded = $state->id;
$newest->newest = $state->id;

View file

@ -247,13 +247,13 @@
}
// set originalquestion in states
set_field('quiz_states', 'originalquestion', $oldquestionid, 'attempt', $attempt->id, 'question', $question->id, 'originalquestion', '0');
set_field('quiz_states', 'originalquestion', $oldquestionid, 'attempt', $attempt->uniqueid, 'question', $question->id, 'originalquestion', '0');
// replace question id in states
set_field('quiz_states', 'question', $question->id, 'attempt', $attempt->id, 'question', $oldquestionid);
set_field('quiz_states', 'question', $question->id, 'attempt', $attempt->uniqueid, 'question', $oldquestionid);
// replace question id in newest_states
set_field('quiz_newest_states', 'questionid', $question->id, 'attemptid', $attempt->id, 'questionid', $oldquestionid);
set_field('quiz_newest_states', 'questionid', $question->id, 'attemptid', $attempt->uniqueid, 'questionid', $oldquestionid);
}

View file

@ -154,7 +154,7 @@ function quiz_get_states(&$questions, $cmoptions, $attempt) {
" FROM {$CFG->prefix}quiz_states s,".
" {$CFG->prefix}quiz_newest_states n".
" WHERE s.id = n.newest".
" AND n.attemptid = '$attempt->id'".
" AND n.attemptid = '$attempt->uniqueid'".
" AND n.questionid IN ($questionlist)";
$states = get_records_sql($sql);
@ -163,7 +163,7 @@ function quiz_get_states(&$questions, $cmoptions, $attempt) {
" FROM {$CFG->prefix}quiz_states s,".
" {$CFG->prefix}quiz_newest_states n".
" WHERE s.id = n.newgraded".
" AND n.attemptid = '$attempt->id'".
" AND n.attemptid = '$attempt->uniqueid'".
" AND n.questionid IN ($questionlist)";
$gradedstates = get_records_sql($sql);
@ -182,7 +182,7 @@ function quiz_get_states(&$questions, $cmoptions, $attempt) {
if ($cmoptions->attemptonlast and $attempt->attempt > 1) {
// build on states from last attempt
if (empty($lastattemptid)) {
$lastattemptid = get_field('quiz_attempts', 'id', 'quiz', $attempt->quiz, 'userid', $attempt->userid, 'attempt', $attempt->attempt-1);
$lastattemptid = get_field('quiz_attempts', 'uniqueid', 'quiz', $attempt->quiz, 'userid', $attempt->userid, 'attempt', $attempt->attempt-1);
}
// Load the last graded state for the question
$sql = "SELECT $statefields".
@ -193,7 +193,7 @@ function quiz_get_states(&$questions, $cmoptions, $attempt) {
" AND n.questionid = '$i'";
$states[$i] = get_record_sql($sql);
quiz_restore_state($questions[$i], $states[$i]);
$states[$i]->attempt = $attempt->id;
$states[$i]->attempt = $attempt->uniqueid;
$states[$i]->question = (int) $i;
$states[$i]->seq_number = 0;
$states[$i]->timestamp = $attempt->timestart;
@ -203,7 +203,7 @@ function quiz_get_states(&$questions, $cmoptions, $attempt) {
$states[$i]->penalty = '';
$states[$i]->sumpenalty = '0.0';
$states[$i]->last_graded = new object;
$states[$i]->last_graded->attempt = $attempt->id;
$states[$i]->last_graded->attempt = $attempt->uniqueid;
$states[$i]->last_graded->question = (int) $i;
$states[$i]->last_graded->seq_number = 0;
$states[$i]->last_graded->timestamp = $attempt->timestart;
@ -217,7 +217,7 @@ function quiz_get_states(&$questions, $cmoptions, $attempt) {
} else {
// create a new empty state
$states[$i] = new object;
$states[$i]->attempt = $attempt->id;
$states[$i]->attempt = $attempt->uniqueid;
$states[$i]->question = (int) $i;
$states[$i]->seq_number = 0;
$states[$i]->timestamp = $attempt->timestart;
@ -436,7 +436,7 @@ function quiz_extract_responses($questions, $responses, $defaultevent) {
function quiz_regrade_question_in_attempt($question, $attempt, $cmoptions, $verbose=false) {
if ($states = get_records_select('quiz_states',
"attempt = '{$attempt->id}' AND question = '{$question->id}'", 'seq_number ASC')) {
"attempt = '{$attempt->uniqueid}' AND question = '{$question->id}'", 'seq_number ASC')) {
$states = array_values($states);
$attempt->sumgrades -= $states[count($states)-1]->grade;

View file

@ -893,7 +893,7 @@ class quiz_default_questiontype {
$students = array();
if($attempts = get_records_select('quiz_attempts', "quiz = '$quiz->id' AND preview = '0'")) {
foreach($attempts as $attempt) {
if (record_exists('quiz_states', 'attempt', $attempt->id, 'question', $question->id, 'originalquestion', 0)) {
if (record_exists('quiz_states', 'attempt', $attempt->uniqueid, 'question', $question->id, 'originalquestion', 0)) {
$students[$attempt->userid] = 1;
}
}

View file

@ -50,7 +50,7 @@
// Moodle 1.5 model (they will not yet have the timestamp set)
if ($attempts = get_records_sql("SELECT a.*".
" FROM {$CFG->prefix}quiz_attempts a, {$CFG->prefix}quiz_states s".
" WHERE a.quiz = '$quiz->id' AND s.attempt = a.id AND s.timestamp = 0")) {
" WHERE a.quiz = '$quiz->id' AND s.attempt = a.uniqueid AND s.timestamp = 0")) {
foreach ($attempts as $attempt) {
quiz_upgrade_states($attempt);
}

View file

@ -41,7 +41,8 @@ class quiz_report extends quiz_default_report {
if ($todelete = get_record('quiz_attempts', 'id', $attemptid)) {
delete_records('quiz_attempts', 'id', $attemptid);
delete_records('quiz_states', 'attempt', $attemptid);
delete_records('quiz_states', 'attempt', $todelete->uniqueid);
delete_records('quiz_newest_states', 'attemptid', $todelete->uniqueid);
// Search quiz_attempts for other instances by this user.
// If none, then delete record for this quiz, this user from quiz_grades
@ -189,7 +190,7 @@ class quiz_report extends quiz_default_report {
// Construct the SQL
$select = 'SELECT '.$db->Concat('u.id', '\'#\'', $db->IfNull('qa.attempt', '0')).' AS uniqueid, qa.id AS attempt, u.id AS userid, u.firstname, u.lastname, u.picture, '.
$select = 'SELECT '.$db->Concat('u.id', '\'#\'', $db->IfNull('qa.attempt', '0')).' AS uniqueid, qa.id AS attempt, qa.uniqueid as attemptuniqueid, u.id AS userid, u.firstname, u.lastname, u.picture, '.
'qa.sumgrades, qa.timefinish, qa.timestart, qa.timefinish - qa.timestart AS duration ';
$from = 'FROM '.$CFG->prefix.'user u LEFT JOIN '.$CFG->prefix.'quiz_attempts qa ON (u.id = qa.userid AND qa.quiz = '.$quiz->id.') ';
$where = 'WHERE u.id IN ('.implode(',', $users).') ';
@ -218,7 +219,7 @@ class quiz_report extends quiz_default_report {
if(!$questionsort) {
$qid = intval(substr($sortpart, 1));
$select .= ', grade ';
$from .= 'LEFT JOIN '.$CFG->prefix.'quiz_newest_states qns ON qns.attemptid = qa.id '.
$from .= 'LEFT JOIN '.$CFG->prefix.'quiz_newest_states qns ON qns.attemptid = qa.attemptuniqueid '.
'LEFT JOIN '.$CFG->prefix.'quiz_states qs ON qs.id = qns.newgraded ';
$where .= ' AND ('.sql_isnull('qns.questionid').' OR qns.questionid = '.$qid.')';
$newsort[] = 'grade '.(strpos($sortpart, 'ASC')? 'ASC' : 'DESC');
@ -284,7 +285,7 @@ class quiz_report extends quiz_default_report {
}
else {
foreach($questionids as $questionid) {
if ($gradedstateid = get_field('quiz_newest_states', 'newgraded', 'attemptid', $attempt->attempt, 'questionid', $questionid)) {
if ($gradedstateid = get_field('quiz_newest_states', 'newgraded', 'attemptid', $attempt->attemptuniqueid, 'questionid', $questionid)) {
$grade = round(get_field('quiz_states', 'grade', 'id', $gradedstateid), $quiz->decimalpoints);
} else {
// This is an old-style attempt

View file

@ -52,7 +52,7 @@ class quiz_report extends quiz_default_report {
$sumgrades = 0;
$questionids = explode(',', quiz_questions_in_quiz($attempt->layout));
foreach($questionids as $questionid) {
$lastgradedid = get_field('quiz_newest_states', 'newgraded', 'attemptid', $attempt->id, 'questionid', $questionid);
$lastgradedid = get_field('quiz_newest_states', 'newgraded', 'attemptid', $attempt->uniqueid, 'questionid', $questionid);
$sumgrades += get_field('quiz_states', 'grade', 'id', $lastgradedid);
}
if ($attempt->sumgrades != $sumgrades) {

View file

@ -1458,8 +1458,12 @@
$attempt->userid = $user->new_id;
}
//Set the uniqueid field
$attempt->uniqueid = $CFG->attemptuniqueid;
set_config('attemptuniqueid', $CFG->attemptuniqueid + 1);
//We have to recode the layout field (a list of questions id and pagebreaks)
$attempt->layout = quiz_recode_layout($attempt->layout, $restore);
$attempt->layout = quiz_recode_layout($attempt->layout, $restore);
//The structure is equal to the db, so insert the quiz_attempts
$newid = insert_record ("quiz_attempts",$attempt);
@ -2015,16 +2019,16 @@
function quiz_recode_layout($layout, $restore) {
//Recodes the quiz layout (a list of questions id and pagebreaks)
//Extracts question id from sequence
if ($questionids = explode(',', $layout)) {
foreach ($questionids as $id => $questionid) {
if ($questionid) { // If it iss zero then this is a pagebreak, don't translate
$newq = backup_getid($restore->backup_unique_code,"quiz_questions",$questionid);
$questionids[$id] = $newq->new_id;
//Extracts question id from sequence
if ($questionids = explode(',', $layout)) {
foreach ($questionids as $id => $questionid) {
if ($questionid) { // If it iss zero then this is a pagebreak, don't translate
$newq = backup_getid($restore->backup_unique_code,"quiz_questions",$questionid);
$questionids[$id] = $newq->new_id;
}
}
}
}
}
return implode(',', $questionids);
return implode(',', $questionids);
}
?>

View file

@ -1461,7 +1461,10 @@
if (isteacher($restore->course_id,$attempt->userid)) {
$attempt->preview = 1;
}
//Set the uniqueid field
$attempt->uniqueid = $CFG->attemptuniqueid;
set_config('attemptuniqueid', $CFG->attemptuniqueid + 1);
//The structure is equal to the db, so insert the quiz_attempts
$newid = insert_record ("quiz_attempts",$attempt);

View file

@ -31,7 +31,7 @@
error("The course module for the quiz with id $quiz->id is missing");
}
if (!count_records('quiz_newest_states', 'attemptid', $attempt->id)) {
if (!count_records('quiz_newest_states', 'attemptid', $attempt->uniqueid)) {
// this question has not yet been upgraded to the new model
quiz_upgrade_states($attempt);
}

View file

@ -31,9 +31,9 @@
if (! $attempt = get_record('quiz_attempts', 'id', $attemptid)) {
error('No such attempt ID exists');
}
if (! $neweststateid = get_field('quiz_newest_states', 'newest', 'attemptid', $attemptid, 'questionid', $questionid)) {
if (! $neweststateid = get_field('quiz_newest_states', 'newest', 'attemptid', $attempt->uniqueid, 'questionid', $questionid)) {
// newest_state not set, probably because this is an old attempt from the old quiz module code
if (! $state = get_record('quiz_states', 'question', $questionid, 'attempt', $attemptid)) {
if (! $state = get_record('quiz_states', 'question', $questionid, 'attempt', $attempt->uniqueid)) {
error('Invalid question id');
}
} else {

View file

@ -5,7 +5,7 @@
// This fragment is called by moodle_needs_upgrading() and /admin/index.php
////////////////////////////////////////////////////////////////////////////////
$module->version = 2005062600; // The (date) version of this module
$module->version = 2005070202; // The (date) version of this module
$module->requires = 2005021600; // Requires this Moodle version
$module->cron = 0; // How often should cron check this module (seconds)?