]> git.mjollnir.org Git - moodle.git/commitdiff
MDL-13943 improved perf when sending multiple grades into grade_update(); merged...
authorskodak <skodak>
Sun, 16 Mar 2008 23:22:47 +0000 (23:22 +0000)
committerskodak <skodak>
Sun, 16 Mar 2008 23:22:47 +0000 (23:22 +0000)
lib/grade/grade_item.php
lib/gradelib.php

index 3cf42bff71aaebb0186d05f794f988b2d34eb359..e70d535faac3eaf5e6161a432de7fb08e39b5269 100644 (file)
@@ -1460,9 +1460,10 @@ class grade_item extends grade_object {
      * @param int $usermodified - user which did the grading
      * @param int $dategraded
      * @param int $datesubmitted
+     * @param object $grade object - usefull for bulk upgrades
      * @return boolean success
      */
-    function update_raw_grade($userid, $rawgrade=false, $source=NULL, $feedback=false, $feedbackformat=FORMAT_MOODLE, $usermodified=null, $dategraded=null, $datesubmitted=null) {
+    function update_raw_grade($userid, $rawgrade=false, $source=NULL, $feedback=false, $feedbackformat=FORMAT_MOODLE, $usermodified=null, $dategraded=null, $datesubmitted=null, $grade=null) {
         global $USER;
 
         $result = true;
@@ -1472,7 +1473,10 @@ class grade_item extends grade_object {
             return false;
         }
 
-        $grade = new grade_grade(array('itemid'=>$this->id, 'userid'=>$userid));
+        if (is_null($grade)) {
+            //fetch from db
+            $grade = new grade_grade(array('itemid'=>$this->id, 'userid'=>$userid));
+        }
         $grade->grade_item =& $this; // prevent db fetching of this grade_item
 
         if (empty($usermodified)) {
index ea96b087055273e128ba395ad83276c9eb5ae056..5bc322f6e217012e85dd6b840b9f8731a15de723 100644 (file)
@@ -63,7 +63,7 @@ require_once($CFG->libdir . '/grade/grade_outcome.php');
  * @param mixed $itemdetails object or array describing the grading item, NULL if no change
  */
 function grade_update($source, $courseid, $itemtype, $itemmodule, $iteminstance, $itemnumber, $grades=NULL, $itemdetails=NULL) {
-    global $USER;
+    global $USER, $CFG;
 
     // only following grade_item properties can be changed in this function
     $allowed = array('itemname', 'idnumber', 'gradetype', 'grademax', 'grademin', 'scaleid', 'multfactor', 'plusfactor', 'deleted', 'hidden');
@@ -150,7 +150,7 @@ function grade_update($source, $courseid, $itemtype, $itemmodule, $iteminstance,
                         $grade_item->{$k} = $v;
                         $update = true;
                     }
-                    
+
                 } else {
                     if ($grade_item->{$k} != $v) {
                         $grade_item->{$k} = $v;
@@ -183,22 +183,79 @@ function grade_update($source, $courseid, $itemtype, $itemmodule, $iteminstance,
 
 /// Finally start processing of grades
     if (is_object($grades)) {
-        $grades = array($grades);
+        $grades = array($grades->userid=>$grades);
     } else {
         if (array_key_exists('userid', $grades)) {
-            $grades = array($grades);
+            $grades = array($grades['userid']=>$grades);
+        }
+    }
+
+/// normalize and verify grade array
+    foreach($grades as $k=>$g) {
+        if (!is_array($g)) {
+            $g = (array)$g;
+            $grades[$k] = $g;
         }
+
+        if (empty($g['userid']) or $k != $g['userid']) {
+            debugging('Incorrect grade array index, must be user id! Grade ignored.');
+            unset($grades[$k]);
+        }
+    }
+
+    if (empty($grades)) {
+        return GRADE_UPDATE_FAILED;
+    }
+
+    $count = count($grades);
+    if ($count == 1) {
+        reset($grades);
+        $uid = key($grades);
+        $sql = "SELECT * FROM {$CFG->prefix}grade_grades WHERE itemid = $grade_item->id AND userid = $uid";
+
+    } else if ($count < 200) {
+        $uids = implode(',', array_keys($grades));
+        $sql = "SELECT * FROM {$CFG->prefix}grade_grades WHERE itemid = $grade_item->id AND userid IN ($uids)";
+
+    } else {
+        $sql = "SELECT * FROM {$CFG->prefix}grade_grades WHERE itemid = $grade_item->id";
     }
 
+    $rs = get_recordset_sql($sql);
+
     $failed = false;
-    foreach ($grades as $grade) {
-        $grade = (array)$grade;
-        if (empty($grade['userid'])) {
-            $failed = true;
-            debugging('Invalid userid in grade submitted');
-            continue;
-        } else {
-            $userid = $grade['userid'];
+
+    while (count($grades) > 0) {
+        $grade_grade = null;
+        $grade       = null;
+
+        while ($rs and !rs_EOF($rs)) {
+            if (!$gd = rs_fetch_next_record($rs)) {
+                break;
+            }
+            $userid = $gd->userid;
+            if (!isset($grades[$userid])) {
+                // this grade not requested, continue
+                continue;
+            }
+            // existing grade requested
+            $grade       = $grades[$userid];
+            $grade_grade = new grade_grade($gd, false);
+            unset($grades[$userid]);
+            break;
+        }
+
+        if (is_null($grade_grade)) {
+            if (count($grades) == 0) {
+                // no more grades to process
+                break;
+            }
+
+            $grade       = reset($grades);
+            $userid      = $grade['userid'];
+            $grade_grade = new grade_grade(array('itemid'=>$grade_item->id, 'userid'=>$userid), false);
+            $grade_grade->load_optional_fields(); // add feedback and info too
+            unset($grades[$userid]);
         }
 
         $rawgrade       = false;
@@ -233,11 +290,15 @@ function grade_update($source, $courseid, $itemtype, $itemmodule, $iteminstance,
         }
 
         // update or insert the grade
-        if (!$grade_item->update_raw_grade($userid, $rawgrade, $source, $feedback, $feedbackformat, $usermodified, $dategraded, $datesubmitted)) {
+        if (!$grade_item->update_raw_grade($userid, $rawgrade, $source, $feedback, $feedbackformat, $usermodified, $dategraded, $datesubmitted, $grade_grade)) {
             $failed = true;
         }
     }
 
+    if ($rs) {
+        rs_close($rs);
+    }
+
     if (!$failed) {
         return GRADE_UPDATE_OK;
     } else {
@@ -360,7 +421,7 @@ function grade_get_grades($courseid, $itemtype, $itemmodule, $iteminstance, $use
                             $grade->grade          = null;
                             $grade->str_grade      = '-';
                             $grade->str_long_grade = $grade->str_grade;
-                             
+
                         } else if (in_array($grade_item->id, $needsupdate)) {
                             $grade->grade          = false;
                             $grade->str_grade      = get_string('error');