]> git.mjollnir.org Git - moodle.git/commitdiff
MDL-14835 - Grade not checked against valid range when manua grading
authortjhunt <tjhunt>
Thu, 15 May 2008 16:02:12 +0000 (16:02 +0000)
committertjhunt <tjhunt>
Thu, 15 May 2008 16:02:12 +0000 (16:02 +0000)
lang/en_utf8/question.php
lang/en_utf8/quiz.php
lib/questionlib.php
mod/quiz/comment.php
mod/quiz/report/grading/report.php

index b4a7fa02eb92035a79337f7876a306016c4a3536..aec638588808a4b31c82a69908ceef6f2ad6b04a 100644 (file)
@@ -37,8 +37,11 @@ $string['erroraccessingcontext'] = 'Cannot access context';
 $string['errordeletingquestionsfromcategory'] = 'Error deleting questions from category $a.';
 $string['errorfilecannotbecopied'] = 'Error cannot copy file $a.';
 $string['errorfilecannotbemoved'] = 'Error cannot move file $a.';
-$string['errormovingquestions'] = 'Error while moving questions with ids $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['errormovingquestions'] = 'Error while moving questions with ids $a.';
+$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 ed58394af91da94b29a34e78805075ff363eaadf..a6f05b6ad60ddfcb99883d31f4ef8555087bfbb7 100644 (file)
@@ -97,7 +97,8 @@ $string['categorymoveto'] = 'Move them to this category';
 $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 d9ecc9683fbddb3000de753d8c68a02793b8dec9..b14bd2aa826db49bdb09c72d5c1dbbf25cc05095 100644 (file)
@@ -1251,8 +1251,19 @@ function regrade_question_in_attempt($question, $attempt, $cmoptions, $verbose=f
             }
 
             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
@@ -1549,13 +1560,34 @@ function question_print_comment_box($question, $state, $attempt, $url) {
    }
 }
 
+/**
+ * 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)) {
-        print_error('cannotsavecomment');
+        return get_string('errorsavingcomment', 'question', $question);
     }
 
     // Update the attempt if the score has changed.
@@ -1563,7 +1595,7 @@ function question_process_comment($question, &$state, &$attempt, $comment, $grad
         $attempt->sumgrades = $attempt->sumgrades - $state->last_graded->grade + $grade;
         $attempt->timemodified = time();
         if (!update_record('quiz_attempts', $attempt)) {
-            print_error('cannotsavequiz');
+            return get_string('errorupdatingattempt', 'question', $attempt);
         }
     }
 
@@ -1594,6 +1626,7 @@ function question_process_comment($question, &$state, &$attempt, $comment, $grad
         $state->changed = 1;
     }
 
+    return true;
 }
 
 /**
index c361577dab19324be8d70941e0af6e30ee68bac8..29b8ae4eda2b9ba7b0b03299ea8f3555c0f35b89 100644 (file)
 
     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 '<div class="boxaligncenter"><input type="button" onclick="window.opener.location.reload(1); self.close();return false;" value="' .
+                    get_string('closewindow') . "\" /></div>";
+
+            print_footer();
+            exit;
         }
-
-        notify(get_string('changessaved'));
-        echo '<div class="boxaligncenter"><input type="button" onclick="window.opener.location.reload(1); self.close();return false;" value="' .
-                get_string('closewindow') . "\" /></div>";
-
-        print_footer();
-        exit;
     }
 
     question_print_comment_box($question, $state, $attempt, $CFG->wwwroot.'/mod/quiz/comment.php');
index 93f58faaeb5de00a8ee9aa63df49c624b6ce29c7..89a7c5de5a83ae9e0533437a87b005e8f8221373 100644 (file)
@@ -70,6 +70,7 @@ class quiz_report extends quiz_default_report {
             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 @@ class quiz_report extends quiz_default_report {
                 $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