Index: lang/en_utf8/question.php =================================================================== RCS file: /home/cvs_repositories/globalcvs/ou-moodle/lang/en_utf8/question.php,v retrieving revision 1.6 diff -u -r1.6 question.php --- lang/en_utf8/question.php 25 Sep 2007 09:18:43 -0000 1.6 +++ lang/en_utf8/question.php 14 May 2008 15:59:16 -0000 @@ -33,6 +33,9 @@ $string['errorfilecannotbecopied'] = 'Error cannot copy file $a.'; $string['errorfilecannotbemoved'] = 'Error cannot move file $a.'; $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['errorsavingcomment'] = 'Error saving the comment for question $a->name in the database.'; +$string['errorupdatingattempt'] = 'Error updating attempt $a->id in the database.'; $string['exportcategory'] = 'Export category'; $string['filesareasite']= 'the site files area'; $string['filesareacourse']= 'the course files area'; Index: lang/en_utf8/quiz.php =================================================================== RCS file: /home/cvs_repositories/globalcvs/ou-moodle/lang/en_utf8/quiz.php,v retrieving revision 1.30.4.1 diff -u -r1.30.4.1 quiz.php --- lang/en_utf8/quiz.php 14 May 2008 11:07:40 -0000 1.30.4.1 +++ lang/en_utf8/quiz.php 14 May 2008 15:59:16 -0000 @@ -94,7 +94,8 @@ $string['categorynamecantbeblank'] = 'The category name cannot be blank.'; $string['categorynoedit'] = 'You do not have editing privileges in the category \'$a\'.'; $string['categoryupdated'] = 'The category was successfully updated'; -$string['changessaved'] = 'Grading Changes Saved'; +$string['changessaved'] = 'Grading changes saved'; +$string['changessavedwitherrors'] = 'Some errors occurred while saving the grading changes'; $string['checkanswer'] = 'Check'; $string['choice'] = 'Choice'; $string['choices'] = 'Available choices'; Index: mod/quiz/comment.php =================================================================== RCS file: /home/cvs_repositories/globalcvs/ou-moodle/mod/quiz/comment.php,v retrieving revision 1.6 diff -u -r1.6 comment.php --- mod/quiz/comment.php 17 Mar 2008 11:18:31 -0000 1.6 +++ mod/quiz/comment.php 14 May 2008 15:59:16 -0000 @@ -56,24 +56,28 @@ print_header(); print_heading(format_string($question->name)); - + //add_to_log($course->id, 'quiz', 'review', "review.php?id=$cm->id&attempt=$attempt->id", "$quiz->id", "$cm->id"); if ($data = data_submitted() and confirm_sesskey()) { // the following will update the state and attempt - question_process_comment($question, $state, $attempt, $data->response['comment'], $data->response['grade']); - // If the state has changed save it and update the quiz grade - if ($state->changed) { - save_question_session($question, $state); - quiz_save_best_grade($quiz, $attempt->userid); - } + $error = question_process_comment($question, $state, $attempt, $data->response['comment'], $data->response['grade']); + if (is_string($error)) { + notify($error); + } else { + // If the state has changed save it and update the quiz grade + if ($state->changed) { + save_question_session($question, $state); + quiz_save_best_grade($quiz, $attempt->userid); + } - notify(get_string('changessaved')); - echo '
"; - - print_footer(); - exit; + notify(get_string('changessaved')); + echo '"; + + print_footer(); + exit; + } } question_print_comment_box($question, $state, $attempt, $CFG->wwwroot.'/mod/quiz/comment.php'); Index: lib/questionlib.php =================================================================== RCS file: /home/cvs_repositories/globalcvs/ou-moodle/lib/questionlib.php,v retrieving revision 1.54 diff -u -r1.54 questionlib.php --- lib/questionlib.php 16 Apr 2008 16:12:29 -0000 1.54 +++ lib/questionlib.php 14 May 2008 15:59:16 -0000 @@ -1264,8 +1264,19 @@ } if ($action->event == QUESTION_EVENTMANUALGRADE) { - question_process_comment($question, $replaystate, $attempt, + // Ensure that the grade is in range - in the past this was not checked, + // but now it is (MDL-14835) - so we need to ensure the data is valid before + // proceeding. + if ($states[$j]->grade < 0) { + $states[$j]->grade = 0; + } else if ($states[$j]->grade > $question->maxgrade) { + $states[$j]->grade = $question->maxgrade; + } + $error = question_process_comment($question, $replaystate, $attempt, $replaystate->manualcomment, $states[$j]->grade); + if (is_string($error)) { + notify($error); + } } else { // Reprocess (regrade) responses @@ -1595,13 +1606,34 @@ } } +/** + * Process a manual grading action. That is, use $comment and $grade to update + * $state and $attempt. The attempt and the comment text are stored in the + * database. $state is only updated in memory, it is up to the call to store + * that, if appropriate. + * + * @param object $question the question + * @param object $state the state to be updated. + * @param object $attempt the attempt the state belongs to, to be updated. + * @param string $comment the comment the teacher added + * @param float $grade the grade the teacher assigned. + * @return mixed true on success, a string error message if a problem is detected + * (for example score out of range). + */ function question_process_comment($question, &$state, &$attempt, $comment, $grade) { + if ($grade < 0 || $grade > $question->maxgrade) { + $a = new stdClass; + $a->grade = $grade; + $a->maxgrade = $question->maxgrade; + $a->name = $question->name; + return get_string('errormanualgradeoutofrange', 'question', $a); + } // Update the comment and save it in the database $comment = trim($comment); $state->manualcomment = $comment; if (!set_field('question_sessions', 'manualcomment', $comment, 'attemptid', $attempt->uniqueid, 'questionid', $question->id)) { - error("Cannot save comment"); + return get_string('errorsavingcomment', 'question', $question); } // Update the attempt if the score has changed. @@ -1609,7 +1641,7 @@ $attempt->sumgrades = $attempt->sumgrades - $state->last_graded->grade + $grade; $attempt->timemodified = time(); if (!update_record('quiz_attempts', $attempt)) { - error('Failed to save the current quiz attempt!'); + get_string('errorupdatingattempt', 'question', $attempt); } } @@ -1640,6 +1672,7 @@ $state->changed = 1; } + return true; } /** Index: mod/quiz/report/grading/report.php =================================================================== RCS file: /home/cvs_repositories/globalcvs/ou-moodle/mod/quiz/report/grading/report.php,v retrieving revision 1.13 diff -u -r1.13 report.php --- mod/quiz/report/grading/report.php 18 Dec 2007 16:18:07 -0000 1.13 +++ mod/quiz/report/grading/report.php 14 May 2008 15:59:16 -0000 @@ -70,6 +70,7 @@ confirm_sesskey(); // now go through all of the responses and save them. + $allok = true; foreach($data->manualgrades as $uniqueid => $response) { // get our attempt if (! $attempt = get_record('quiz_attempts', 'uniqueid', $uniqueid)) { @@ -83,15 +84,22 @@ $state = &$states[$question->id]; // the following will update the state and attempt - question_process_comment($question, $state, $attempt, $response['comment'], $response['grade']); - - // If the state has changed save it and update the quiz grade - if ($state->changed) { + $error = question_process_comment($question, $state, $attempt, $response['comment'], $response['grade']); + if (is_string($error)) { + notify($error); + $allok = false; + } else if ($state->changed) { + // If the state has changed save it and update the quiz grade save_question_session($question, $state); quiz_save_best_grade($quiz, $attempt->userid); } } - notify(get_string('changessaved', 'quiz'), 'notifysuccess'); + + if ($allok) { + notify(get_string('changessaved', 'quiz'), 'notifysuccess'); + } else { + notify(get_string('changessavedwitherrors', 'quiz'), 'notifysuccess'); + } } // our 3 different views