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:
+21
-53
@@ -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) {
|
||||
|
||||
@@ -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 /////////////////////////////////////////////////
|
||||
|
||||
|
||||
Reference in New Issue
Block a user