$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;
}
$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) {
}
}
+ // 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 /////////////////////////////////////////////////