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

This commit is contained in:
gustav_delius
2006-03-26 07:59:43 +00:00
parent d4156b1bd1
commit d23e3e11dd
2 changed files with 56 additions and 53 deletions
+21 -53
View File
@@ -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('' => '');
// 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;
} 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 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) {
+35
View File
@@ -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 /////////////////////////////////////////////////