$string['errorfileschanged'] = 'Error files linked to from questions have changed since form was displayed.';
$string['errormanualgradeoutofrange'] = 'The grade $a->grade is not between 0 and $a->maxgrade for question $a->name. The score and comment have not been saved.';
$string['errormovingquestions'] = 'Error while moving questions with ids $a.';
+$string['errorprocessingresponses'] = 'An error occurred while processing your responses.';
$string['errorsavingcomment'] = 'Error saving the comment for question $a->name in the database.';
$string['errorupdatingattempt'] = 'Error updating attempt $a->id in the database.';
$string['emptyxml'] = 'Unkown error - empty imsmanifest.xml';
/**
* Processes an array of student responses, grading and saving them as appropriate
*
-* @return boolean Indicates success/failure
* @param object $question Full question object, passed by reference
* @param object $state Full state object, passed by reference
* @param object $action object with the fields ->responses which
* @param object $cmoptions
* @param object $attempt The attempt is passed by reference so that
* during grading its ->sumgrades field can be updated
+* @return boolean Indicates success/failure
*/
function question_process_responses(&$question, &$state, $action, $cmoptions, &$attempt) {
global $QTYPES;
if (!question_isgradingevent($action->event)) {
// Grade the response but don't update the overall grade
- $QTYPES[$question->qtype]->grade_responses($question, $state, $cmoptions);
+ if (!$QTYPES[$question->qtype]->grade_responses($question, $state, $cmoptions)) {
+ return false;
+ }
// Temporary hack because question types are not given enough control over what is going
// on. Used by Opaque questions.
// If we did not find a duplicate or if the attempt is closing, perform grading
if ((!$sameresponses and QUESTION_EVENTDUPLICATE != $state->event) or
QUESTION_EVENTCLOSE == $action->event) {
+ if (!$QTYPES[$question->qtype]->grade_responses($question, $state, $cmoptions)) {
+ return false;
+ }
- $QTYPES[$question->qtype]->grade_responses($question, $state, $cmoptions);
// Calculate overall grade using correct penalty method
question_apply_penalty_and_timelimit($question, $state, $attempt, $cmoptions);
}
/// Process each question in turn
$questionidarray = explode(',', $questionids);
+ $success = true;
foreach($questionidarray as $i) {
if (!isset($actions[$i])) {
$actions[$i]->responses = array('' => '');
$actions[$i]->event = QUESTION_EVENTOPEN;
}
$actions[$i]->timestamp = $timenow;
- question_process_responses($questions[$i], $states[$i], $actions[$i], $quiz, $attempt);
- save_question_session($questions[$i], $states[$i]);
+ if (question_process_responses($questions[$i], $states[$i], $actions[$i], $quiz, $attempt)) {
+ save_question_session($questions[$i], $states[$i]);
+ } else {
+ $success = false;
+ }
+ }
+
+ if (!$success) {
+ $pagebit = '';
+ if ($page) {
+ $pagebit = '&page=' . $page;
+ }
+ print_error('errorprocessingresponses', 'question',
+ $CFG->wwwroot . '/mod/quiz/attempt.php?q=' . $quiz->id . $pagebit);
}
$attempt->timemodified = $timenow;
$attempt->timefinish = $timenow;
/// Move each question to the closed state.
+ $success = true;
foreach ($questions as $key => $question) {
$action->event = QUESTION_EVENTCLOSE;
$action->responses = $states[$key]->responses;
$action->timestamp = $states[$key]->timestamp;
- question_process_responses($question, $states[$key], $action, $quiz, $attempt);
- save_question_session($question, $states[$key]);
+ if (question_process_responses($question, $closestates[$key], $action, $quiz, $attempt)) {
+ save_question_session($question, $closestates[$key]);
+ } else {
+ $success = false;
+ }
+ }
+
+ if (!$success) {
+ $pagebit = '';
+ if ($page) {
+ $pagebit = '&page=' . $page;
+ }
+ print_error('errorprocessingresponses', 'question',
+ $CFG->wwwroot . '/mod/quiz/attempt.php?q=' . $quiz->id . $pagebit);
}
/// Log the end of this attempt.
}
if ($actions = question_extract_responses($questions, $form, $event)) {
$actions[$id]->timestamp = 0; // We do not care about timelimits here
- question_process_responses($questions[$id], $curstate, $actions[$id], $quiz, $attempt);
+ if (!question_process_responses($questions[$id], $curstate, $actions[$id], $quiz, $attempt)) {
+ unset($SESSION->quizpreview);
+ print_error('errorprocessingresponses', 'question', $url->out());
+ }
if (!$curstate->changed) {
// Update the current state rather than creating a new one
$historylength--;
function grade_responses(&$question, &$state, $cmoptions) {
$state->raw_grade = 0;
$state->penalty = 0;
+ return true;
}
}