]> git.mjollnir.org Git - moodle.git/commitdiff
MDL-11357, MDL-11358 cleanup and improvements in public grade API - new function...
authorskodak <skodak>
Sat, 22 Sep 2007 20:21:44 +0000 (20:21 +0000)
committerskodak <skodak>
Sat, 22 Sep 2007 20:21:44 +0000 (20:21 +0000)
lib/grade/grade_grade.php
lib/gradelib.php
lib/simpletest/testgradelib.php
mod/assignment/lib.php

index e38fd78e848db64efa87c4f104b82e77dd32267a..36d44377327bdbc4e3a0cb07de75527e972b4b49 100644 (file)
@@ -137,6 +137,48 @@ class grade_grade extends grade_object {
      */
     var $excluded = 0;
 
+
+    /**
+     * Returns array of grades for given grade_item+users.
+     * @param object $grade_item
+     * @param array $userids
+     * @param bool $include_missing include grades taht do not exist yet
+     * @return array userid=>grade_grade array
+     */
+    function fetch_users_grades($grade_item, $userids, $include_missing=true) {
+
+        // hmm, there might be a problem with length of sql query
+        // if there are too many users requested - we might run out of memory anyway
+        $limit = 2000;
+        $count = count($userids);
+        if ($count > $limit) {
+            $half = (int)($count/2);
+            $first  = array_slice($userids, 0, $half);
+            $second = array_slice($userids, $half);
+            return grade_grade::fetch_users_grades($grade_item, $first, $include_missing) + grade_grade::fetch_users_grades($grade_item, $second, $include_missing);
+        }
+
+        $user_ids_cvs = implode(',', $userids);
+        $result = array();
+        if ($grade_records = get_records_select('grade_grades', "itemid={$grade_item->id} AND userid IN ($user_ids_cvs)")) {
+            foreach ($grade_records as $record) {
+                $result[$record->userid] = new grade_grade($record, false);
+            }
+        }
+        if ($include_missing) {
+            foreach ($userids as $userid) {
+                if (!array_key_exists($userid, $result)) {
+                    $grade_grade = new grade_grade();
+                    $grade_grade->userid = $userid;
+                    $grade_grade->itemid = $grade_item->id;
+                    $result[$userid] = $grade_grade;
+                }
+            }
+        }
+
+        return $result;
+    }
+
     /**
      * Loads the grade_item object referenced by $this->itemid and saves it as $this->grade_item for easy access.
      * @return object grade_item.
index 7b551e32875d79484c4f9e3a47485069ab397802..0db1e595c7436ce4210e729b225fda2818ba0be8 100644 (file)
@@ -49,6 +49,8 @@ require_once($CFG->libdir . '/grade/grade_outcome.php');
  * Only following grade item properties can be changed 'itemname', 'idnumber', 'gradetype', 'grademax',
  * 'grademin', 'scaleid', 'multfactor', 'plusfactor', 'deleted'.
  *
+ * Manual, course or category items can not be updated by this function.
+
  * @param string $source source of the grade such as 'mod/assignment'
  * @param int $courseid id of course
  * @param string $itemtype type of grade item - mod, block
@@ -217,104 +219,16 @@ function grade_update($source, $courseid, $itemtype, $itemmodule, $iteminstance,
     }
 }
 
-
-/**
- * Tells a module whether a grade (or grade_item if $userid is not given) is currently locked or not.
- * If it's locked to the current user then the module can print a nice message or prevent editing in the module.
- * If no $userid is given, the method will always return the grade_item's locked state.
- * If a $userid is given, the method will first check the grade_item's locked state (the column). If it is locked,
- * the method will return true no matter the locked state of the specific grade being checked. If unlocked, it will
- * return the locked state of the specific grade.
- *
- * @param int $courseid id of course
- * @param string $itemtype 'mod', 'block'
- * @param string $itemmodule 'forum, 'quiz', etc.
- * @param int $iteminstance id of the item module
- * @param int $itemnumber most probably 0, modules can use other numbers when having more than one grades for each user
- * @param int $userid ID of the graded user
- * @return boolean Whether the grade is locked or not
- */
-function grade_is_locked($courseid, $itemtype, $itemmodule, $iteminstance, $itemnumber, $userid=NULL) {
-
-    if (!$grade_items = grade_item::fetch_all(compact('courseid', 'itemtype', 'itemmodule', 'iteminstance', 'itemnumber'))) {
-        return false;
-
-    } else if (count($grade_items) == 1){
-        $grade_item = reset($grade_items);
-        return $grade_item->is_locked($userid);
-
-    } else {
-        debugging('Found more than one grade item');
-        foreach ($grade_items as $grade_item) {
-            if ($grade_item->is_locked($userid)) {
-                return true;
-            }
-        }
-        return false;
-    }
-}
-
-/**
- * Returns list of outcomes used in activity together with current outcomes for user
- * @param int $courseid id of course
- * @param string $itemtype 'mod', 'block'
- * @param string $itemmodule 'forum, 'quiz', etc.
- * @param int $iteminstance id of the item module
- * @param int $userid optional id of the graded user
- * @return array of outcome information objects (scaleid, name, grade and locked status) indexed with itemnumbers
- */
-function grade_get_outcomes($courseid, $itemtype, $itemmodule, $iteminstance, $userid=0) {
-    $result = array();
-    $course_item = grade_item::fetch_course_item($courseid);
-    $needsupdate = $course_item->needsupdate;
-
-    if ($items = grade_item::fetch_all(array('itemtype'=>$itemtype, 'itemmodule'=>$itemmodule, 'iteminstance'=>$iteminstance, 'courseid'=>$courseid))) {
-        foreach ($items as $item) {
-            if (empty($item->outcomeid)) {
-                continue;
-            }
-            if (!$outcome = grade_outcome::fetch(array('id'=>$item->outcomeid))) {
-                debugging('Incorect outcomeid found');
-                continue;
-            }
-            // prepare outcome info with user grade
-            $o = new object();
-            $o->scaleid = $outcome->scaleid;
-            $o->name    = $outcome->get_name();
-
-            if (empty($userid)) {
-                //no user info
-            } if ($grade = $item->get_grade($userid,false)) {
-                $o->grade  = $grade->finalgrade;
-                $o->locked = $grade->is_locked();
-                $o->hidden = $grade->is_hidden();
-
-            } else {
-                $o->grade = null;
-                $o->locked = $item->is_locked();
-                $o->hidden = $grade->is_hidden();
-            }
-
-            if ($needsupdate) {
-                $o->grade = false;
-            } else {
-                $o->grade = intval($o->grade); // 0 means no grade, int for scales
-            }
-
-            $result[$item->itemnumber] = $o;
-        }
-    }
-
-    return $result;
-}
-
 /**
  * Updates outcomes of user
+ * Manual outcomes can not be updated.
+ * @param string $source source of the grade such as 'mod/assignment'
  * @param int $courseid id of course
  * @param string $itemtype 'mod', 'block'
  * @param string $itemmodule 'forum, 'quiz', etc.
  * @param int $iteminstance id of the item module
  * @param int $userid ID of the graded user
+ * @param array $data array itemnumber=>outcomegrade
  */
 function grade_update_outcomes($source, $courseid, $itemtype, $itemmodule, $iteminstance, $userid, $data) {
     if ($items = grade_item::fetch_all(array('itemtype'=>$itemtype, 'itemmodule'=>$itemmodule, 'iteminstance'=>$iteminstance, 'courseid'=>$courseid))) {
@@ -329,7 +243,8 @@ function grade_update_outcomes($source, $courseid, $itemtype, $itemmodule, $item
 }
 
 /**
- * Returns list of grades used in activity optionally with current grades of one user
+ * Returns grading information for given activity - optionally with users grades
+ * Manual, course or category items can not be queried.
  * @param int $courseid id of course
  * @param string $itemtype 'mod', 'block'
  * @param string $itemmodule 'forum, 'quiz', etc.
@@ -337,82 +252,181 @@ function grade_update_outcomes($source, $courseid, $itemtype, $itemmodule, $item
  * @param int $userid optional id of the graded user; if userid not used, returns only information about grade_item
  * @return array of grade information objects (scaleid, name, grade and locked status, etc.) indexed with itemnumbers
  */
-function grade_get_final_grades($courseid, $itemtype, $itemmodule, $iteminstance, $userid=0) {
-    $result = array();
-    $course_item = grade_item::fetch_course_item($courseid);
-    $needsupdate = $course_item->needsupdate;
+function grade_get_grades($courseid, $itemtype, $itemmodule, $iteminstance, $userid_or_ids=0) {
+    $return = new object();
+    $return->items    = array();
+    $return->outcomes = array();
 
-    if ($items = grade_item::fetch_all(array('itemtype'=>$itemtype, 'itemmodule'=>$itemmodule, 'iteminstance'=>$iteminstance, 'courseid'=>$courseid))) {
-        foreach ($items as $item) {
-            if (!empty($item->outcomeid)) {
-                continue;
-            }
-            // prepare grade info with user grade
-            $o = new object();
-            $o->scaleid   = $item->scaleid;
-            $o->name      = $item->get_name();
-            $o->grademin  = $item->grademin;
-            $o->grademax  = $item->grademax;
-            $o->gradepass = $item->gadepass;
-
-            if (empty($userid)) {
-                //no user info
-
-            } if ($grade = $item->get_grade($userid, false)) {
-                $o->grade          = $grade->finalgrade;
-                $o->locked         = $grade->is_locked();
-                $o->hidden         = $grade->is_hidden();
-                $o->overridden     = $grade->overridden;
-                $o->feedback       = $text->feedback;
-                $o->feedbackformat = $text->feedbackformat;
-
-            } else {
-                $o->grade          = null;
-                $o->locked         = $item->is_locked();
-                $o->hidden         = $grade->is_hidden();
-                $o->overridden     = 0;
-                $o->feedback       = null;
-                $o->feedbackformat = FORMAT_MOODLE;
-            }
-
-            // create text representation of grade
-            if ($needsupdate) {
-                $o->grade     = false;
-                $o->str_grade = get_string('error');
+    $course_item = grade_item::fetch_course_item($courseid);
+    $needsupdate = array();
+    if ($course_item->needsupdate) {
+        $result = grade_regrade_final_grades($courseid);
+        if ($result !== true) {
+            $needsupdate = array_keys($result);
+        }
+    }
 
-            } else if (is_null($o->grade)) {
-                $o->str_grade = get_string('nograde');
+    if ($grade_items = grade_item::fetch_all(array('itemtype'=>$itemtype, 'itemmodule'=>$itemmodule, 'iteminstance'=>$iteminstance, 'courseid'=>$courseid))) {
+        foreach ($grade_items as $grade_item) {
+            if (empty($grade_item->outcomeid)) {
+                // prepare information about grade item
+                $item = new object();
+                $item->itemnumber = $grade_item->itemnumber;
+                $item->scaleid    = $grade_item->scaleid;
+                $item->name       = $grade_item->get_name();
+                $item->grademin   = $grade_item->grademin;
+                $item->grademax   = $grade_item->grademax;
+                $item->gradepass  = $grade_item->gradepass;
+                $item->locked     = $grade_item->is_locked();
+                $item->hidden     = $grade_item->is_hidden();
+                $item->grades     = array();
+
+                switch ($grade_item->gradetype) {
+                    case GRADE_TYPE_NONE:
+                        continue;
 
-            } else {
-                switch ($item->gradetype) {
                     case GRADE_TYPE_VALUE:
-                        $o->str_grade = $o->grade;
+                        $item->scaleid = 0;
                         break;
 
-                    case GRADE_TYPE_SCALE:
-                        $scale = $item->load_scale();
-                        $o->str_grade = format_string($scale[$o->grade-1]);
+                    case GRADE_TYPE_TEXT:
+                        $item->scaleid   = 0;
+                        $item->grademin   = 0;
+                        $item->grademax   = 0;
+                        $item->gradepass  = 0;
                         break;
+                }
 
-                    case GRADE_TYPE_NONE:
-                    case GRADE_TYPE_TEXT:
-                    default:
-                        $o->str_grade = '';
+                if (empty($userid_or_ids)) {
+                    $userids = array();
+
+                } else if (is_array($userid_or_ids)) {
+                    $userids = $userid_or_ids;
+
+                } else {
+                    $userids = array($userid_or_ids);
                 }
-            }
 
-            // create html representation of feedback
-            if (is_null($o->feedback)) {
-                $o->str_feedback = '';
+                if ($userids) {
+                    $grade_grades = grade_grade::fetch_users_grades($grade_item, $userids, true);
+                    foreach ($userids as $userid) {
+                        $grade_grades[$userid]->grade_item =& $grade_item;
+
+                        $grade = new object();
+                        $grade->grade          = $grade_grades[$userid]->finalgrade;
+                        $grade->locked         = $grade_grades[$userid]->is_locked();
+                        $grade->hidden         = $grade_grades[$userid]->is_hidden();
+                        $grade->overridden     = $grade_grades[$userid]->overridden;
+                        $grade->feedback       = $grade_grades[$userid]->feedback;
+                        $grade->feedbackformat = $grade_grades[$userid]->feedbackformat;
+
+                        // create text representation of grade
+                        if (in_array($grade_item->id, $needsupdate)) {
+                            $grade->grade     = false;
+                            $grade->str_grade = get_string('error');
+
+                        } else if (is_null($grade->grade)) {
+                            $grade->str_grade = get_string('nograde');
+
+                        } else {
+                            switch ($grade_item->gradetype) {
+                                case GRADE_TYPE_VALUE:
+                                    $grade->str_grade = $grade->grade; //TODO: fix localisation and decimal places
+                                    break;
+
+                                case GRADE_TYPE_SCALE:
+                                    $scale = $grade_item->load_scale();
+                                    $grade->str_grade = format_string($scale->scale_items[$grade->grade-1]);
+                                    break;
+
+                                case GRADE_TYPE_TEXT:
+                                default:
+                                    $grade->str_grade = '';
+                            }
+                        }
+
+                        // create html representation of feedback
+                        if (is_null($grade->feedback)) {
+                            $grade->str_feedback = '';
+                        } else {
+                            $grade->str_feedback = format_text($grade->feedback, $grade->feedbackformat);
+                        }
+
+                        $item->grades[$userid] = $grade;
+                    }
+                }
+                $return->items[$grade_item->itemnumber] = $item;
+
             } else {
-                $o->str_feedback = format_text($o->feedback, $o->feedbackformat);
-            }
+                if (!$grade_outcome = grade_outcome::fetch(array('id'=>$grade_item->outcomeid))) {
+                    debugging('Incorect outcomeid found');
+                    continue;
+                }
+
+                // outcome info
+                $outcome = new object();
+                $outcome->itemnumber = $grade_item->itemnumber;
+                $outcome->scaleid    = $grade_outcome->scaleid;
+                $outcome->name       = $grade_outcome->get_name();
+                $outcome->locked     = $grade_item->is_locked();
+                $outcome->hidden     = $grade_item->is_hidden();
+
+                if (empty($userid_or_ids)) {
+                    $userids = array();
+                } else if (is_array($userid_or_ids)) {
+                    $userids = $userid_or_ids;
+                } else {
+                    $userids = array($userid_or_ids);
+                }
 
-            $result[$item->itemnumber] = $o;
+                if ($userids) {
+                    $grade_grades = grade_grade::fetch_users_grades($grade_item, $userids, true);
+                    foreach ($userids as $userid) {
+                        $grade_grades[$userid]->grade_item =& $grade_item;
+
+                        $grade = new object();
+                        $grade->grade          = $grade_grades[$userid]->finalgrade;
+                        $grade->locked         = $grade_grades[$userid]->is_locked();
+                        $grade->hidden         = $grade_grades[$userid]->is_hidden();
+                        $grade->feedback       = $grade_grades[$userid]->feedback;
+                        $grade->feedbackformat = $grade_grades[$userid]->feedbackformat;
+
+                        // create text representation of grade
+                        if (in_array($grade_item->id, $needsupdate)) {
+                            $grade->grade     = false;
+                            $grade->str_grade = get_string('error');
+
+                        } else if (is_null($grade->grade)) {
+                            $grade->grade = 0;
+                            $grade->str_grade = get_string('nooutcome', 'grades');
+
+                        } else {
+                            $grade->grade = (int)$grade->grade;
+                            $scale = $grade_item->load_scale();
+                            $grade->str_grade = format_string($scale->scale_items[(int)$grade->grade-1]);
+                        }
+
+                        // create html representation of feedback
+                        if (is_null($grade->feedback)) {
+                            $grade->str_feedback = '';
+                        } else {
+                            $grade->str_feedback = format_text($grade->feedback, $grade->feedbackformat);
+                        }
+
+                        $outcome->grades[$userid] = $grade;
+                    }
+                }
+                $return->outcomes[$grade_item->itemnumber] = $outcome;
+
+            }
         }
     }
 
-    return $result;
+    // sort results using itemnumbers
+    ksort($return->items, SORT_NUMERIC);
+    ksort($return->outcomes, SORT_NUMERIC);
+
+    return $return;
 }
 
 /***** END OF PUBLIC API *****/
@@ -891,7 +905,10 @@ function grade_cron() {
         rs_close($rs);
     }
 
-    $sql = "SELECT g.*
+    $grade_inst = new grade_grade();
+    $fields = 'g.'.implode(',g.', $grade_inst->required_fields);
+
+    $sql = "SELECT $fields
               FROM {$CFG->prefix}grade_grades g, {$CFG->prefix}grade_items i
              WHERE g.locked = 0 AND g.locktime > 0 AND g.locktime < $now AND g.itemid=i.id AND EXISTS (
                 SELECT 'x' FROM {$CFG->prefix}grade_items c WHERE c.itemtype='course' AND c.needsupdate=0 AND c.courseid=i.courseid)";
index eae24b277dd264ad717d82c8417151c549e7ecf3..7a782ac5519819cb83efe4e2ec25f2f469c21012 100644 (file)
@@ -38,11 +38,8 @@ if (!defined('MOODLE_INTERNAL')) {
 require_once($CFG->libdir.'/simpletest/fixtures/gradetest.php');
 
 class gradelib_test extends grade_test {
-    function test_grade_is_locked() {
-        $grade_item = $this->grade_items[0];
-        $this->assertFalse(grade_is_locked($grade_item->courseid, $grade_item->itemtype, $grade_item->itemmodule, $grade_item->iteminstance, $grade_item->itemnumber));
-        $grade_item = $this->grade_items[6];
-        $this->assertTrue(grade_is_locked($grade_item->courseid, $grade_item->itemtype, $grade_item->itemmodule, $grade_item->iteminstance, $grade_item->itemnumber));
+    function test_grade_get_grades() {
+        //TODO
     }
 }
 
index 22eb3e43598333530e995953e1779e1cde5ddeee..07b81962c5229fc2b59715b8c0143932bcd8672a 100644 (file)
@@ -33,7 +33,6 @@ class assignment_base {
     var $usehtmleditor;
     var $defaultformat;
     var $context;
-    var $lockedgrades;
 
     /**
      * Constructor for the base assignment class
@@ -79,9 +78,6 @@ class assignment_base {
         $this->assignment->cmidnumber = $this->cm->id;     // compatibility with modedit assignment obj
         $this->assignment->courseid   = $this->course->id; // compatibility with modedit assignment obj
 
-        require_once($CFG->libdir.'/gradelib.php');
-        $this->lockedgrades = grade_is_locked($this->course->id, 'mod', 'assignment', $this->assignment->id, 0);
-
         $this->strassignment = get_string('modulename', 'assignment');
         $this->strassignments = get_string('modulenameplural', 'assignment');
         $this->strsubmissions = get_string('submissions', 'assignment');
@@ -497,11 +493,6 @@ class assignment_base {
         //make user global so we can use the id
         global $USER;
 
-        // no grading when grades are locked
-        if ($this->lockedgrades) {
-            $mode = 'all';
-        }
-
         switch ($mode) {
             case 'grade':                         // We are in a popup window grading
                 if ($submission = $this->process_feedback()) {
@@ -694,20 +685,22 @@ class assignment_base {
         }
 
         if (!empty($CFG->enableoutcomes) and empty($SESSION->flextable['mod-assignment-submissions']->collapse['outcomes'])) {
-            if ($outcomes_data = grade_get_outcomes($this->course->id, 'mod', 'assignment', $this->assignment->id, $submission->userid)) {
-                foreach($outcomes_data as $n=>$data) {
+            $grading_info = grade_get_grades($this->course->id, 'mod', 'assignment', $this->assignment->id, $submission->userid);
+
+            if (!empty($grading_info->outcomes)) {
+                foreach($grading_info->outcomes as $n=>$outcome) {
                     if ($data->locked) {
                         continue;
                     }
 
                     if ($quickgrade){
                         $output.= 'opener.document.getElementById("outcome_'.$n.'_'.$submission->userid.
-                        '").selectedIndex="'.$data->grade.'";'."\n";
+                        '").selectedIndex="'.$outcome->grades[$submission->userid]->grade.'";'."\n";
+
                     } else {
-                        $options = make_grades_menu(-$data->scaleid);
+                        $options = make_grades_menu(-$outcome->scaleid);
                         $options[0] = get_string('nooutcome', 'grades');
-                        $output.= 'opener.document.getElementById("outcome_'.$n.'_'.$submission->userid.'").innerHTML="'.$options[$data->grade]."\";\n";
-
+                        $output.= 'opener.document.getElementById("outcome_'.$n.'_'.$submission->userid.'").innerHTML="'.$options[$outcome->grades[$submission->userid]->grade]."\";\n";
                     }
 
                 }
@@ -876,15 +869,16 @@ class assignment_base {
 
         echo '<div class="clearer"></div>';
 
-        if (!empty($CFG->enableoutcomes) and $outcomes_data = grade_get_outcomes($this->course->id, 'mod', 'assignment', $this->assignment->id, $userid)) {
-            foreach($outcomes_data as $n=>$data) {
-                echo '<div class="outcome"><label for="menuoutcome_'.$n.'">'.$data->name.'</label> ';
-                $options = make_grades_menu(-$data->scaleid);
-                if ($data->locked) {
+        if (!empty($CFG->enableoutcomes)) {
+            $grading_info = grade_get_grades($this->course->id, 'mod', 'assignment', $this->assignment->id, $submission->userid);
+            foreach($grading_info->outcomes as $n=>$outcome) {
+                echo '<div class="outcome"><label for="menuoutcome_'.$n.'">'.$outcome->name.'</label> ';
+                $options = make_grades_menu(-$outcome->scaleid);
+                if ($outcome->grades[$submission->userid]->locked) {
                     $options[0] = get_string('nooutcome', 'grades');
-                    echo $options[$data->grade];
+                    echo $options[$outcome->grades[$submission->userid]->grade];
                 } else {
-                    choose_from_menu($options, 'outcome_'.$n.'['.$userid.']', $data->grade, get_string('nooutcome', 'grades'), '', 0, false, false, 0, 'menuoutcome_'.$n);
+                    choose_from_menu($options, 'outcome_'.$n.'['.$userid.']', $outcome->grades[$submission->userid]->grade, get_string('nooutcome', 'grades'), '', 0, false, false, 0, 'menuoutcome_'.$n);
                 }
                 echo '</div>';
                 echo '<div class="clearer"></div>';
@@ -985,13 +979,11 @@ class assignment_base {
          */
         $perpage    = get_user_preferences('assignment_perpage', 10);
 
-        if ($this->lockedgrades) {
-            $quickgrade = 0;
-        } else {
-            $quickgrade = get_user_preferences('assignment_quickgrade', 0);
-        }
+        $quickgrade = get_user_preferences('assignment_quickgrade', 0);
+
+        $grading_info = grade_get_grades($this->course->id, 'mod', 'assignment', $this->assignment->id);
 
-        if (!empty($CFG->enableoutcomes) and grade_get_outcomes($this->course->id, 'mod', 'assignment', $this->assignment->id)) {
+        if (!empty($CFG->enableoutcomes) and !empty($grading_info->outcomes)) {
             $uses_outcomes = true;
         } else {
             $uses_outcomes = false;
@@ -1139,7 +1131,7 @@ class assignment_base {
         $grademenu = make_grades_menu($this->assignment->grade);
 
         if (($ausers = get_records_sql($select.$sql.$sort, $table->get_page_start(), $table->get_page_size())) !== false) {
-
+            $grading_info = grade_get_grades($this->course->id, 'mod', 'assignment', $this->assignment->id, array_keys($ausers));
             foreach ($ausers as $auser) {
             /// Calculate user status
                 $auser->status = ($auser->timemarked > 0) && ($auser->timemarked >= $auser->timemodified);
@@ -1222,33 +1214,29 @@ class assignment_base {
 
                 $buttontext = ($auser->status == 1) ? $strupdate : $strgrade;
 
-                if ($this->lockedgrades) {
-                    $status = get_string('gradeitemlocked', 'grades');
-                } else {
-                    ///No more buttons, we use popups ;-).
-                    $popup_url = '/mod/assignment/submissions.php?id='.$this->cm->id
-                               . '&amp;userid='.$auser->id.'&amp;mode=single'.'&amp;offset='.$offset++;
-                    $button = link_to_popup_window ($popup_url, 'grade'.$auser->id, $buttontext, 600, 780,
-                                                    $buttontext, 'none', true, 'button'.$auser->id);
+                ///No more buttons, we use popups ;-).
+                $popup_url = '/mod/assignment/submissions.php?id='.$this->cm->id
+                           . '&amp;userid='.$auser->id.'&amp;mode=single'.'&amp;offset='.$offset++;
+                $button = link_to_popup_window ($popup_url, 'grade'.$auser->id, $buttontext, 600, 780,
+                                                $buttontext, 'none', true, 'button'.$auser->id);
 
-                    $status  = '<div id="up'.$auser->id.'" class="s'.$auser->status.'">'.$button.'</div>';
-                }
+                $status  = '<div id="up'.$auser->id.'" class="s'.$auser->status.'">'.$button.'</div>';
 
                 $outcomes = '';
 
-                if ($uses_outcomes and $outcomes_data = grade_get_outcomes($this->course->id, 'mod', 'assignment', $this->assignment->id, $auser->id)) {
+                if ($uses_outcomes) {
 
-                    foreach($outcomes_data as $n=>$data) {
-                        $outcomes .= '<div class="outcome"><label>'.$data->name.'</label>';
-                        $options = make_grades_menu(-$data->scaleid);
+                    foreach($grading_info->outcomes as $n=>$outcome) {
+                        $outcomes .= '<div class="outcome"><label>'.$outcome->name.'</label>';
+                        $options = make_grades_menu(-$outcome->scaleid);
 
-                        if ($data->locked or !$quickgrade) {
+                        if ($outcome->grades[$auser->id]->locked or !$quickgrade) {
                             $options[0] = get_string('nooutcome', 'grades');
-                            $outcomes .= ': <span id="outcome_'.$n.'_'.$auser->id.'">'.$options[$data->grade].'</span>';
+                            $outcomes .= ': <span id="outcome_'.$n.'_'.$auser->id.'">'.$options[$outcome->grades[$auser->id]->grade].'</span>';
                         } else {
                             $outcomes .= ' ';
                             $outcomes .= choose_from_menu($options, 'outcome_'.$n.'['.$auser->id.']',
-                                        $data->grade, get_string('nooutcome', 'grades'), '', 0, true, false, 0, 'outcome_'.$n.'_'.$auser->id);
+                                        $outcome->grades[$auser->id]->grade, get_string('nooutcome', 'grades'), '', 0, true, false, 0, 'outcome_'.$n.'_'.$auser->id);
                         }
                         $outcomes .= '</div>';
                     }
@@ -1296,20 +1284,18 @@ class assignment_base {
         echo '<input type="text" id="perpage" name="perpage" size="1" value="'.$perpage.'" />';
         helpbutton('pagesize', get_string('pagesize','assignment'), 'assignment');
         echo '</td></tr>';
-        if (!$this->lockedgrades) {
-            echo '<tr align="right">';
-            echo '<td>';
-            print_string('quickgrade','assignment');
-            echo ':</td>';
-            echo '<td align="left">';
-            if ($quickgrade){
-                echo '<input type="checkbox" name="quickgrade" value="1" checked="checked" />';
-            } else {
-                echo '<input type="checkbox" name="quickgrade" value="1" />';
-            }
-            helpbutton('quickgrade', get_string('quickgrade', 'assignment'), 'assignment').'</p></div>';
-            echo '</td></tr>';
+        echo '<tr align="right">';
+        echo '<td>';
+        print_string('quickgrade','assignment');
+        echo ':</td>';
+        echo '<td align="left">';
+        if ($quickgrade){
+            echo '<input type="checkbox" name="quickgrade" value="1" checked="checked" />';
+        } else {
+            echo '<input type="checkbox" name="quickgrade" value="1" />';
         }
+        helpbutton('quickgrade', get_string('quickgrade', 'assignment'), 'assignment').'</p></div>';
+        echo '</td></tr>';
         echo '<tr>';
         echo '<td colspan="2" align="right">';
         echo '<input type="submit" value="'.get_string('savepreferences').'" />';
@@ -1393,10 +1379,12 @@ class assignment_base {
         }
 
         $data = array();
-        if ($outcomes = grade_get_outcomes($this->course->id, 'mod', 'assignment', $this->assignment->id, $userid)) {
-            foreach($outcomes as $n=>$old) {
+        $grading_info = grade_get_grades($this->course->id, 'mod', 'assignment', $this->assignment->id, $userid);
+
+        if (!empty($grading_info->outcomes)) {
+            foreach($grading_info->outcomes as $n=>$old) {
                 $name = 'outcome_'.$n;
-                if (isset($formdata->{$name}[$userid]) and $old->grade != $formdata->{$name}[$userid]) {
+                if (isset($formdata->{$name}[$userid]) and $old->grades[$userid]->grade != $formdata->{$name}[$userid]) {
                     $data[$n] = $formdata->{$name}[$userid];
                 }
             }