From: gustav_delius Date: Sun, 26 Mar 2006 07:59:43 +0000 (+0000) Subject: Moved the code for basing new attempts on previous attempts from questions to quiz... X-Git-Url: http://git.mjollnir.org/gw?a=commitdiff_plain;h=d23e3e11dd2d4855ea311cf5e9d42819bb29a0f5;p=moodle.git Moved the code for basing new attempts on previous attempts from questions to quiz and fixed the bug reported at http://moodle.org/mod/forum/discuss.php?d=42029#194212 in the process --- diff --git a/lib/questionlib.php b/lib/questionlib.php index be1a7d9b6c..0ec78fcc58 100644 --- a/lib/questionlib.php +++ b/lib/questionlib.php @@ -603,60 +603,28 @@ function get_question_states(&$questions, $cmoptions, $attempt) { $states[$i]->last_graded->responses = array('' => ''); } } else { - // Create a new state object - if ($cmoptions->attemptonlast and $attempt->attempt > 1 and !$attempt->preview) { - // build on states from last attempt - if (!$lastattemptid = get_field('quiz_attempts', 'uniqueid', 'quiz', $attempt->quiz, 'userid', $attempt->userid, 'attempt', $attempt->attempt-1)) { - error('Could not find previous attempt to build on'); - } - // Load the last graded state for the question - $sql = "SELECT $statefields". - " FROM {$CFG->prefix}question_states s,". - " {$CFG->prefix}question_sessions n". - " WHERE s.id = n.newgraded". - " AND n.attemptid = '$lastattemptid'". - " AND n.questionid = '$i'"; - if (!$states[$i] = get_record_sql($sql)) { - error('Could not find state for previous attempt to build on'); - } - restore_question_state($questions[$i], $states[$i]); - $states[$i]->attempt = $attempt->uniqueid; - $states[$i]->question = (int) $i; - $states[$i]->seq_number = 0; - $states[$i]->timestamp = $attempt->timestart; - $states[$i]->event = ($attempt->timefinish) ? QUESTION_EVENTCLOSE : QUESTION_EVENTOPEN; - $states[$i]->grade = 0; - $states[$i]->raw_grade = 0; - $states[$i]->penalty = 0; - $states[$i]->sumpenalty = 0; - $states[$i]->changed = true; - $states[$i]->last_graded = clone($states[$i]); - $states[$i]->last_graded->responses = array('' => ''); - - } else { - // create a new empty state - $states[$i] = new object; - $states[$i]->attempt = $attempt->uniqueid; - $states[$i]->question = (int) $i; - $states[$i]->seq_number = 0; - $states[$i]->timestamp = $attempt->timestart; - $states[$i]->event = ($attempt->timefinish) ? QUESTION_EVENTCLOSE : QUESTION_EVENTOPEN; - $states[$i]->grade = 0; - $states[$i]->raw_grade = 0; - $states[$i]->penalty = 0; - $states[$i]->sumpenalty = 0; - $states[$i]->responses = array('' => ''); - // Prevent further changes to the session from incrementing the - // sequence number - $states[$i]->changed = true; - - // Create the empty question type specific information - if (!$QTYPES[$questions[$i]->qtype] - ->create_session_and_responses($questions[$i], $states[$i], $cmoptions, $attempt)) { - return false; - } - $states[$i]->last_graded = clone($states[$i]); + // create a new empty state + $states[$i] = new object; + $states[$i]->attempt = $attempt->uniqueid; + $states[$i]->question = (int) $i; + $states[$i]->seq_number = 0; + $states[$i]->timestamp = $attempt->timestart; + $states[$i]->event = ($attempt->timefinish) ? QUESTION_EVENTCLOSE : QUESTION_EVENTOPEN; + $states[$i]->grade = 0; + $states[$i]->raw_grade = 0; + $states[$i]->penalty = 0; + $states[$i]->sumpenalty = 0; + $states[$i]->responses = array('' => ''); + // Prevent further changes to the session from incrementing the + // sequence number + $states[$i]->changed = true; + + // Create the empty question type specific information + if (!$QTYPES[$questions[$i]->qtype] + ->create_session_and_responses($questions[$i], $states[$i], $cmoptions, $attempt)) { + return false; } + $states[$i]->last_graded = clone($states[$i]); } } return $states; @@ -906,7 +874,7 @@ function regrade_question_in_attempt($question, $attempt, $cmoptions, $verbose=f } $replaystate->id = $states[$j]->id; - $replaystate->update = true; + $replaystate->update = true; // This will ensure that the existing database entry is updated rather than a new one created save_question_session($question, $replaystate); } if ($verbose) { diff --git a/mod/quiz/attempt.php b/mod/quiz/attempt.php index 28cc149372..9e87194887 100644 --- a/mod/quiz/attempt.php +++ b/mod/quiz/attempt.php @@ -293,6 +293,41 @@ } } + // If the new attempt is to be based on a previous attempt copy responses over + if ($newattempt and $attempt->attempt > 1 and $quiz->attemptonlast and !$attempt->preview) { + // Find the previous attempt + if (!$lastattemptid = get_field('quiz_attempts', 'uniqueid', 'quiz', $attempt->quiz, 'userid', $attempt->userid, 'attempt', $attempt->attempt-1)) { + error('Could not find previous attempt to build on'); + } + // For each question find the responses from the previous attempt and save them to the new session + foreach ($questions as $i => $question) { + // Load the last graded state for the question + $statefields = 'n.questionid as question, s.*, n.sumpenalty'; + $sql = "SELECT $statefields". + " FROM {$CFG->prefix}question_states s,". + " {$CFG->prefix}question_sessions n". + " WHERE s.id = n.newgraded". + " AND n.attemptid = '$lastattemptid'". + " AND n.questionid = '$i'"; + if (!$laststate = get_record_sql($sql)) { + // Only restore previous responses that have been graded + continue; + } + // Restore the state so that the responses will be restored + restore_question_state($questions[$i], $laststate); + // prepare the previous responses for new processing + $action = new stdClass; + $action->responses = $laststate->responses; + $action->timestamp = $laststate->timestamp; + $action->event = QUESTION_EVENTOPEN; + + // Process these responses ... + question_process_responses($questions[$i], $states[$i], $action, $quiz, $attempt); + // ... and save the new states + save_question_session($questions[$i], $states[$i]); + } + } + /// Process form data /////////////////////////////////////////////////