From d115d8c736ff44bfc959c2c7b5908e83fb00bc9f Mon Sep 17 00:00:00 2001 From: gustav_delius Date: Sat, 2 Jul 2005 18:14:51 +0000 Subject: [PATCH] I have introduced the new field $attempt->uniqueid, see http://mantis.york.ac.uk/moodle/mod/forum/discuss.php?d=852#3380 --- mod/quiz/attempt.php | 6 +++--- mod/quiz/backuplib.php | 3 ++- mod/quiz/db/mysql.php | 10 ++++++++++ mod/quiz/editlib.php | 4 ++-- mod/quiz/grading.php | 6 +++--- mod/quiz/lib.php | 5 ++++- mod/quiz/locallib.php | 10 ++++++---- mod/quiz/question.php | 6 +++--- mod/quiz/questionlib.php | 14 +++++++------- mod/quiz/questiontypes/questiontype.php | 2 +- mod/quiz/report.php | 2 +- mod/quiz/report/overview/report.php | 9 +++++---- mod/quiz/report/regrade/report.php | 2 +- mod/quiz/restorelib.php | 24 ++++++++++++++---------- mod/quiz/restorelibpre15.php | 5 ++++- mod/quiz/review.php | 2 +- mod/quiz/reviewquestion.php | 4 ++-- mod/quiz/version.php | 2 +- 18 files changed, 70 insertions(+), 46 deletions(-) diff --git a/mod/quiz/attempt.php b/mod/quiz/attempt.php index f83230be61d..1de15d35f3c 100644 --- a/mod/quiz/attempt.php +++ b/mod/quiz/attempt.php @@ -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)); diff --git a/mod/quiz/backuplib.php b/mod/quiz/backuplib.php index ef943090d0e..fa4afbcf1c5 100644 --- a/mod/quiz/backuplib.php +++ b/mod/quiz/backuplib.php @@ -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)); } diff --git a/mod/quiz/db/mysql.php b/mod/quiz/db/mysql.php index cbfff5de336..91aa813e219 100644 --- a/mod/quiz/db/mysql.php +++ b/mod/quiz/db/mysql.php @@ -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; } diff --git a/mod/quiz/editlib.php b/mod/quiz/editlib.php index da46de69d6b..a84da852c4f 100644 --- a/mod/quiz/editlib.php +++ b/mod/quiz/editlib.php @@ -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 diff --git a/mod/quiz/grading.php b/mod/quiz/grading.php index 37978e39e87..e7c49639e23 100644 --- a/mod/quiz/grading.php +++ b/mod/quiz/grading.php @@ -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)) { diff --git a/mod/quiz/lib.php b/mod/quiz/lib.php index 7180e1c9a70..381e0ddb825 100644 --- a/mod/quiz/lib.php +++ b/mod/quiz/lib.php @@ -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; } } diff --git a/mod/quiz/locallib.php b/mod/quiz/locallib.php index d55b0867f9f..5d099ae0105 100644 --- a/mod/quiz/locallib.php +++ b/mod/quiz/locallib.php @@ -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; diff --git a/mod/quiz/question.php b/mod/quiz/question.php index a01836c9eda..686332921dd 100644 --- a/mod/quiz/question.php +++ b/mod/quiz/question.php @@ -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); } diff --git a/mod/quiz/questionlib.php b/mod/quiz/questionlib.php index ad98923ca9c..c6b5b232c3c 100644 --- a/mod/quiz/questionlib.php +++ b/mod/quiz/questionlib.php @@ -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; diff --git a/mod/quiz/questiontypes/questiontype.php b/mod/quiz/questiontypes/questiontype.php index 9fcb74e9b28..8e1ebb9ccf7 100644 --- a/mod/quiz/questiontypes/questiontype.php +++ b/mod/quiz/questiontypes/questiontype.php @@ -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; } } diff --git a/mod/quiz/report.php b/mod/quiz/report.php index 90b4c070860..f7cf623d290 100644 --- a/mod/quiz/report.php +++ b/mod/quiz/report.php @@ -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); } diff --git a/mod/quiz/report/overview/report.php b/mod/quiz/report/overview/report.php index 6e64bb7dc41..cc0cc60e85b 100644 --- a/mod/quiz/report/overview/report.php +++ b/mod/quiz/report/overview/report.php @@ -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 diff --git a/mod/quiz/report/regrade/report.php b/mod/quiz/report/regrade/report.php index ca9350de52d..17933ec185c 100644 --- a/mod/quiz/report/regrade/report.php +++ b/mod/quiz/report/regrade/report.php @@ -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) { diff --git a/mod/quiz/restorelib.php b/mod/quiz/restorelib.php index 9ea3c04aa17..4a5d25e570b 100644 --- a/mod/quiz/restorelib.php +++ b/mod/quiz/restorelib.php @@ -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); } ?> diff --git a/mod/quiz/restorelibpre15.php b/mod/quiz/restorelibpre15.php index c65c6bb7c69..dcdcc4c7c37 100644 --- a/mod/quiz/restorelibpre15.php +++ b/mod/quiz/restorelibpre15.php @@ -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); diff --git a/mod/quiz/review.php b/mod/quiz/review.php index 7674937b77a..986237a8e51 100644 --- a/mod/quiz/review.php +++ b/mod/quiz/review.php @@ -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); } diff --git a/mod/quiz/reviewquestion.php b/mod/quiz/reviewquestion.php index 584d34af904..546ee19b52e 100644 --- a/mod/quiz/reviewquestion.php +++ b/mod/quiz/reviewquestion.php @@ -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 { diff --git a/mod/quiz/version.php b/mod/quiz/version.php index 21edad644cc..72514c22f68 100644 --- a/mod/quiz/version.php +++ b/mod/quiz/version.php @@ -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)?