*** D:/VertrigoServ/www/moode_up/lib/grade/grade_category.php	Thu Nov 22 06:56:23 2007
--- D:/VertrigoServ/www/moode_up/lib/grade/grade_category_new.php	Thu Nov 22 06:56:27 2007
***************
*** 157,163 ****
          if (empty($grade_category->parent)) {
              return '/'.$grade_category->id.'/';
          } else {
!             $parent = get_record('grade_categories', 'id', $grade_category->parent);
              return grade_category::build_path($parent).$grade_category->id.'/';
          }
      }
--- 157,165 ----
          if (empty($grade_category->parent)) {
              return '/'.$grade_category->id.'/';
          } else {
!             $obj = grade_object::get_instance('grade_category');
!             $parent = $obj->lib_wrapper->get_record('grade_categories', 'id', $grade_category->parent);
! 
              return grade_category::build_path($parent).$grade_category->id.'/';
          }
      }
***************
*** 170,176 ****
       * @return object grade_category instance or false if none found.
       */
      function fetch($params) {
!         return grade_object::fetch_helper('grade_categories', 'grade_category', $params);
      }
  
      /**
--- 172,179 ----
       * @return object grade_category instance or false if none found.
       */
      function fetch($params) {
!         $obj = grade_object::get_instance('grade_category');
!         return $obj->fetch_helper('grade_categories', 'grade_category', $params);
      }
  
      /**
***************
*** 181,187 ****
       * @return array array of grade_category insatnces or false if none found.
       */
      function fetch_all($params) {
!         return grade_object::fetch_all_helper('grade_categories', 'grade_category', $params);
      }
  
      /**
--- 184,191 ----
       * @return array array of grade_category insatnces or false if none found.
       */
      function fetch_all($params) {
!         $obj = grade_object::get_instance('grade_category');
!         return $obj->fetch_all_helper('grade_categories', 'grade_category', $params);
      }
  
      /**
***************
*** 225,233 ****
       */
      function delete($source=null) {
          $grade_item = $this->load_grade_item();
  
          if ($this->is_course_category()) {
!             if ($categories = grade_category::fetch_all(array('courseid'=>$this->courseid))) {
                  foreach ($categories as $category) {
                      if ($category->id == $this->id) {
                          continue; // do not delete course category yet
--- 229,238 ----
       */
      function delete($source=null) {
          $grade_item = $this->load_grade_item();
+         $obj = grade_object::get_instance('grade_category');
  
          if ($this->is_course_category()) {
!             if ($categories = $obj->fetch_all(array('courseid'=>$this->courseid))) {
                  foreach ($categories as $category) {
                      if ($category->id == $this->id) {
                          continue; // do not delete course category yet
***************
*** 236,242 ****
                  }
              }
  
!             if ($items = grade_item::fetch_all(array('courseid'=>$this->courseid))) {
                  foreach ($items as $item) {
                      if ($item->id == $grade_item->id) {
                          continue; // do not delete course item yet
--- 241,247 ----
                  }
              }
  
!             if ($items = $grade_item->fetch_all(array('courseid'=>$this->courseid))) {
                  foreach ($items as $item) {
                      if ($item->id == $grade_item->id) {
                          continue; // do not delete course item yet
***************
*** 251,262 ****
              $parent = $this->load_parent_category();
  
              // Update children's categoryid/parent field first
!             if ($children = grade_item::fetch_all(array('categoryid'=>$this->id))) {
                  foreach ($children as $child) {
                      $child->set_parent($parent->id);
                  }
              }
!             if ($children = grade_category::fetch_all(array('parent'=>$this->id))) {
                  foreach ($children as $child) {
                      $child->set_parent($parent->id);
                  }
--- 256,267 ----
              $parent = $this->load_parent_category();
  
              // Update children's categoryid/parent field first
!             if ($children = $grade_item->fetch_all(array('categoryid'=>$this->id))) {
                  foreach ($children as $child) {
                      $child->set_parent($parent->id);
                  }
              }
!             if ($children = $obj->fetch_all(array('parent'=>$this->id))) {
                  foreach ($children as $child) {
                      $child->set_parent($parent->id);
                  }
***************
*** 283,292 ****
  
          if (empty($this->courseid)) {
              error('Can not insert grade category without course id!');
          }
  
          if (empty($this->parent)) {
!             $course_category = grade_category::fetch_course_category($this->courseid);
              $this->parent = $course_category->id;
          }
  
--- 288,298 ----
  
          if (empty($this->courseid)) {
              error('Can not insert grade category without course id!');
+             return false;
          }
  
          if (empty($this->parent)) {
!             $course_category = $obj->fetch_course_category($this->courseid);
              $this->parent = $course_category->id;
          }
  
***************
*** 347,354 ****
              debugging("Can not regrade non existing category");
              return false;
          }
! 
!         $db_item = grade_category::fetch(array('id'=>$this->id));
  
          $aggregationdiff = $db_item->aggregation         != $this->aggregation;
          $keephighdiff    = $db_item->keephigh            != $this->keephigh;
--- 353,360 ----
              debugging("Can not regrade non existing category");
              return false;
          }
!         $obj = grade_object::get_instance('grade_category');
!         $db_item = $obj->fetch(array('id'=>$this->id));
  
          $aggregationdiff = $db_item->aggregation         != $this->aggregation;
          $keephighdiff    = $db_item->keephigh            != $this->keephigh;
***************
*** 403,409 ****
              $sql = "SELECT *
                        FROM {$CFG->prefix}grade_items
                       WHERE id IN ($gis)";
!             $items = get_records_sql($sql);
          }
  
          if ($userid) {
--- 409,415 ----
              $sql = "SELECT *
                        FROM {$CFG->prefix}grade_items
                       WHERE id IN ($gis)";
!             $items = $this->lib_wrapper->get_records_sql($sql);
          }
  
          if ($userid) {
***************
*** 412,418 ****
              $usersql = "";
          }
  
!         $grade_inst = new grade_grade();
          $fields = 'g.'.implode(',g.', $grade_inst->required_fields);
  
          // where to look for final grades - include grade of this item too, we will store the results there
--- 418,424 ----
              $usersql = "";
          }
  
!         $grade_inst = grade_object::get_instance('grade_grade');
          $fields = 'g.'.implode(',g.', $grade_inst->required_fields);
  
          // where to look for final grades - include grade of this item too, we will store the results there
***************
*** 423,434 ****
                ORDER BY g.userid";
  
          // group the results by userid and aggregate the grades for this user
!         if ($rs = get_recordset_sql($sql)) {
              $prevuser = 0;
              $grade_values = array();
              $excluded     = array();
              $oldgrade     = null;
!             while ($used = rs_fetch_next_record($rs)) {
                  if ($used->userid != $prevuser) {
                      $this->aggregate_grades($prevuser, $items, $grade_values, $oldgrade, $excluded);
                      $prevuser = $used->userid;
--- 429,440 ----
                ORDER BY g.userid";
  
          // group the results by userid and aggregate the grades for this user
!         if ($rs = $this->lib_wrapper->get_recordset_sql($sql)) {
              $prevuser = 0;
              $grade_values = array();
              $excluded     = array();
              $oldgrade     = null;
!             while ($used = $this->lib_wrapper->rs_fetch_next_record($rs)) {
                  if ($used->userid != $prevuser) {
                      $this->aggregate_grades($prevuser, $items, $grade_values, $oldgrade, $excluded);
                      $prevuser = $used->userid;
***************
*** 445,451 ****
                  }
              }
              $this->aggregate_grades($prevuser, $items, $grade_values, $oldgrade, $excluded);//the last one
!             rs_close($rs);
          }
  
          return true;
--- 451,457 ----
                  }
              }
              $this->aggregate_grades($prevuser, $items, $grade_values, $oldgrade, $excluded);//the last one
!             $this->lib_wrapper->rs_close($rs);
          }
  
          return true;
***************
*** 475,486 ****
                  // we need proper floats here for !== comparison later
                  $oldfinalgrade = (float)$oldgrade->finalgrade;
              }
!             $grade = new grade_grade($oldgrade, false);
              $grade->grade_item =& $this->grade_item;
  
          } else {
              // insert final grade - it will be needed later anyway
!             $grade = new grade_grade(array('itemid'=>$this->grade_item->id, 'userid'=>$userid), false);
              $grade->grade_item =& $this->grade_item;
              $grade->insert('system');
              $oldfinalgrade = null;
--- 481,492 ----
                  // we need proper floats here for !== comparison later
                  $oldfinalgrade = (float)$oldgrade->finalgrade;
              }
!             $grade = $this->get_instance('grade_grade', $oldgrade, false);
              $grade->grade_item =& $this->grade_item;
  
          } else {
              // insert final grade - it will be needed later anyway
!             $grade = $this->get_instance('grade_grade', array('itemid'=>$this->grade_item->id, 'userid'=>$userid), false);
              $grade->grade_item =& $this->grade_item;
              $grade->insert('system');
              $oldfinalgrade = null;
***************
*** 752,764 ****
       * @return array
       */
      function fetch_course_tree($courseid, $include_category_items=false) {
!         $course_category = grade_category::fetch_course_category($courseid);
          $category_array = array('object'=>$course_category, 'type'=>'category', 'depth'=>1,
                                  'children'=>$course_category->get_children($include_category_items));
          $sortorder = 1;
          $course_category->set_sortorder($sortorder);
          $course_category->sortorder = $sortorder;
!         return grade_category::_fetch_course_tree_recursion($category_array, $sortorder);
      }
  
      function _fetch_course_tree_recursion($category_array, &$sortorder) {
--- 758,771 ----
       * @return array
       */
      function fetch_course_tree($courseid, $include_category_items=false) {
!         $obj = grade_object::get_instance('grade_category');
!         $course_category = $obj->fetch_course_category($courseid);
          $category_array = array('object'=>$course_category, 'type'=>'category', 'depth'=>1,
                                  'children'=>$course_category->get_children($include_category_items));
          $sortorder = 1;
          $course_category->set_sortorder($sortorder);
          $course_category->sortorder = $sortorder;
!         return $obj->_fetch_course_tree_recursion($category_array, $sortorder);
      }
  
      function _fetch_course_tree_recursion($category_array, &$sortorder) {
***************
*** 782,793 ****
              $cat_item_id = null;
              foreach($category_array['children'] as $oldorder=>$child_array) {
                  if ($child_array['type'] == 'courseitem' or $child_array['type'] == 'categoryitem') {
!                     $result['children'][$sortorder] = grade_category::_fetch_course_tree_recursion($child_array, $sortorder);
                  }
              }
              foreach($category_array['children'] as $oldorder=>$child_array) {
                  if ($child_array['type'] != 'courseitem' and $child_array['type'] != 'categoryitem') {
!                     $result['children'][++$sortorder] = grade_category::_fetch_course_tree_recursion($child_array, $sortorder);
                  }
              }
          }
--- 789,800 ----
              $cat_item_id = null;
              foreach($category_array['children'] as $oldorder=>$child_array) {
                  if ($child_array['type'] == 'courseitem' or $child_array['type'] == 'categoryitem') {
!                     $result['children'][$sortorder] = $this->_fetch_course_tree_recursion($child_array, $sortorder);
                  }
              }
              foreach($category_array['children'] as $oldorder=>$child_array) {
                  if ($child_array['type'] != 'courseitem' and $child_array['type'] != 'categoryitem') {
!                     $result['children'][++$sortorder] = $this->_fetch_course_tree_recursion($child_array, $sortorder);
                  }
              }
          }
***************
*** 807,814 ****
          // fetch all course grade items and categories into memory - we do not expect hundreds of these in course
          // we have to limit the number of queries though, because it will be used often in grade reports
  
!         $cats  = get_records('grade_categories', 'courseid', $this->courseid);
!         $items = get_records('grade_items', 'courseid', $this->courseid);
  
          // init children array first
          foreach ($cats as $catid=>$cat) {
--- 814,821 ----
          // fetch all course grade items and categories into memory - we do not expect hundreds of these in course
          // we have to limit the number of queries though, because it will be used often in grade reports
  
!         $cats  = $this->lib_wrapper->get_records('grade_categories', 'courseid', $this->courseid);
!         $items = $this->lib_wrapper->get_records('grade_items', 'courseid', $this->courseid);
  
          // init children array first
          foreach ($cats as $catid=>$cat) {
***************
*** 852,858 ****
  
                  $cats[$cat->parent]->children[$sortorder] = $cat;
              }
- 
              if ($catid == $this->id) {
                  $category = &$cats[$catid];
              }
--- 859,864 ----
***************
*** 861,867 ****
          unset($items); // not needed
          unset($cats); // not needed
  
!         $children_array = grade_category::_get_children_recursion($category);
  
          ksort($children_array);
  
--- 867,873 ----
          unset($items); // not needed
          unset($cats); // not needed
  
!         $children_array = $this->_get_children_recursion($category);
  
          ksort($children_array);
  
***************
*** 874,880 ****
          $children_array = array();
          foreach($category->children as $sortorder=>$child) {
              if (array_key_exists('itemtype', $child)) {
!                 $grade_item = new grade_item($child, false);
                  if (in_array($grade_item->itemtype, array('course', 'category'))) {
                      $type  = $grade_item->itemtype.'item';
                      $depth = $category->depth;
--- 880,886 ----
          $children_array = array();
          foreach($category->children as $sortorder=>$child) {
              if (array_key_exists('itemtype', $child)) {
!                 $grade_item = $this->get_instance('grade_item', $child, false);
                  if (in_array($grade_item->itemtype, array('course', 'category'))) {
                      $type  = $grade_item->itemtype.'item';
                      $depth = $category->depth;
***************
*** 885,892 ****
                  $children_array[$sortorder] = array('object'=>$grade_item, 'type'=>$type, 'depth'=>$depth);
  
              } else {
!                 $children = grade_category::_get_children_recursion($child);
!                 $grade_category = new grade_category($child, false);
                  if (empty($children)) {
                      $children = array();
                  }
--- 891,898 ----
                  $children_array[$sortorder] = array('object'=>$grade_item, 'type'=>$type, 'depth'=>$depth);
  
              } else {
!                 $children = $this->_get_children_recursion($child);
!                 $grade_category = $this->get_instance('grade_category', $child, false);
                  if (empty($children)) {
                      $children = array();
                  }
***************
*** 929,937 ****
              $params = array('courseid'=>$this->courseid, 'itemtype'=>'category', 'iteminstance'=>$this->id);
          }
  
!         if (!$grade_items = grade_item::fetch_all($params)) {
              // create a new one
!             $grade_item = new grade_item($params, false);
              $grade_item->gradetype = GRADE_TYPE_VALUE;
              $grade_item->insert('system');
  
--- 935,945 ----
              $params = array('courseid'=>$this->courseid, 'itemtype'=>'category', 'iteminstance'=>$this->id);
          }
  
!         $grade_item = grade_object::get_instance('grade_item');
! 
!         if (!$grade_items = $grade_item->fetch_all($params)) {
              // create a new one
!             $grade_item = $this->get_instance('grade_item', $params, false);
              $grade_item->gradetype = GRADE_TYPE_VALUE;
              $grade_item->insert('system');
  
***************
*** 966,972 ****
       */
      function get_parent_category() {
          if (!empty($this->parent)) {
!             $parent_category = new grade_category(array('id' => $this->parent));
              return $parent_category;
          } else {
              return null;
--- 974,980 ----
       */
      function get_parent_category() {
          if (!empty($this->parent)) {
!             $parent_category = $this->get_instance('grade_category', array('id' => $this->parent));
              return $parent_category;
          } else {
              return null;
***************
*** 980,986 ****
       */
      function get_name() {
          if (empty($this->parent)) {
!             $course = get_record('course', 'id', $this->courseid);
              return format_string($course->fullname);
          } else {
              return $this->fullname;
--- 988,994 ----
       */
      function get_name() {
          if (empty($this->parent)) {
!             $course = $this->lib_wrapper->get_record('course', 'id', $this->courseid);
              return format_string($course->fullname);
          } else {
              return $this->fullname;
***************
*** 1006,1012 ****
          }
  
          // find parent and check course id
!         if (!$parent_category = grade_category::fetch(array('id'=>$parentid, 'courseid'=>$this->courseid))) {
              return false;
          }
  
--- 1014,1021 ----
          }
  
          // find parent and check course id
!         $obj = grade_object::get_instance('grade_category');
!         if (!$parent_category = $obj->fetch(array('id'=>$parentid, 'courseid'=>$this->courseid))) {
              return false;
          }
  
***************
*** 1089,1100 ****
      function fetch_course_category($courseid) {
  
          // course category has no parent
!         if ($course_category = grade_category::fetch(array('courseid'=>$courseid, 'parent'=>null))) {
              return $course_category;
          }
  
          // create a new one
!         $course_category = new grade_category();
          $course_category->insert_course_category($courseid);
  
          return $course_category;
--- 1098,1110 ----
      function fetch_course_category($courseid) {
  
          // course category has no parent
!         $obj = grade_object::get_instance('grade_category');
!         if ($course_category = $obj->fetch(array('courseid'=>$courseid, 'parent'=>null))) {
              return $course_category;
          }
  
          // create a new one
!         $course_category = grade_object::get_instance('grade_category');
          $course_category->insert_course_category($courseid);
  
          return $course_category;
***************
*** 1133,1139 ****
  
          if ($cascade) {
              //process all children - items and categories
!             if ($children = grade_item::fetch_all(array('categoryid'=>$this->id))) {
                  foreach($children as $child) {
                      $child->set_locked($lockedstate, true, false);
                      if (empty($lockedstate) and $refresh) {
--- 1143,1150 ----
  
          if ($cascade) {
              //process all children - items and categories
!             $grade_item = grade_object::get_instance('grade_item');
!             if ($children = $grade_item->fetch_all(array('categoryid'=>$this->id))) {
                  foreach($children as $child) {
                      $child->set_locked($lockedstate, true, false);
                      if (empty($lockedstate) and $refresh) {
***************
*** 1142,1148 ****
                      }
                  }
              }
!             if ($children = grade_category::fetch_all(array('parent'=>$this->id))) {
                  foreach($children as $child) {
                      $child->set_locked($lockedstate, true, true);
                  }
--- 1153,1160 ----
                      }
                  }
              }
!             $obj = grade_object::get_instance('grade_category');
!             if ($children = $obj->fetch_all(array('parent'=>$this->id))) {
                  foreach($children as $child) {
                      $child->set_locked($lockedstate, true, true);
                  }
***************
*** 1182,1193 ****
          $this->load_grade_item();
          $this->grade_item->set_hidden($hidden);
          if ($cascade) {
!             if ($children = grade_item::fetch_all(array('categoryid'=>$this->id))) {
                  foreach($children as $child) {
                      $child->set_hidden($hidden, $cascade);
                  }
              }
!             if ($children = grade_category::fetch_all(array('parent'=>$this->id))) {
                  foreach($children as $child) {
                      $child->set_hidden($hidden, $cascade);
                  }
--- 1194,1207 ----
          $this->load_grade_item();
          $this->grade_item->set_hidden($hidden);
          if ($cascade) {
!             $grade_item = grade_object::get_instance('grade_item');
!             if ($children = $grade_item->fetch_all(array('categoryid'=>$this->id))) {
                  foreach($children as $child) {
                      $child->set_hidden($hidden, $cascade);
                  }
              }
!             $obj = grade_object::get_instance('grade_category');
!             if ($children = $obj->fetch_all(array('parent'=>$this->id))) {
                  foreach($children as $child) {
                      $child->set_hidden($hidden, $cascade);
                  }
***************
*** 1240,1246 ****
      function updated_forced_settings() {
          global $CFG;
          $sql = "UPDATE {$CFG->prefix}grade_items SET needsupdate=1 WHERE itemtype='course' or itemtype='category'";
!         execute_sql($sql, false);
      }
  }
  ?>
--- 1254,1260 ----
      function updated_forced_settings() {
          global $CFG;
          $sql = "UPDATE {$CFG->prefix}grade_items SET needsupdate=1 WHERE itemtype='course' or itemtype='category'";
!         $this->lib_wrapper->execute_sql($sql, false);
      }
  }
  ?>
*** D:/VertrigoServ/www/moode_up/lib/grade/grade_grade.php	Thu Nov 22 07:01:55 2007
--- D:/VertrigoServ/www/moode_up/lib/grade/grade_grade_new.php	Thu Nov 22 07:02:24 2007
***************
*** 158,164 ****
       * @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;
--- 158,165 ----
       * @return array userid=>grade_grade array
       */
      function fetch_users_grades($grade_item, $userids, $include_missing=true) {
!         
!         $obj = grade_object::get_instance('grade_grade');
          // 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;
***************
*** 167,186 ****
              $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;
--- 168,187 ----
              $half = (int)($count/2);
              $first  = array_slice($userids, 0, $half);
              $second = array_slice($userids, $half);
!             return $obj->fetch_users_grades($grade_item, $first, $include_missing) + $obj->fetch_users_grades($grade_item, $second, $include_missing);
          }
  
          $user_ids_cvs = implode(',', $userids);
          $result = array();
!         if ($grade_records = $obj->lib_wrapper->get_records_select('grade_grades', "itemid={$grade_item->id} AND userid IN ($user_ids_cvs)")) {
              foreach ($grade_records as $record) {
!                 $result[$record->userid] = $obj->get_instance('grade_grade', $record, false);
              }
          }
          if ($include_missing) {
              foreach ($userids as $userid) {
                  if (!array_key_exists($userid, $result)) {
!                     $grade_grade = grade_object::get_instance('grade_grade');
                      $grade_grade->userid = $userid;
                      $grade_grade->itemid = $grade_item->id;
                      $result[$userid] = $grade_grade;
***************
*** 203,213 ****
          }
  
          if (empty($this->grade_item)) {
!             $this->grade_item = grade_item::fetch(array('id'=>$this->itemid));
  
          } else if ($this->grade_item->id != $this->itemid) {
              debugging('Itemid mismatch');
!             $this->grade_item = grade_item::fetch(array('id'=>$this->itemid));
          }
  
          return $this->grade_item;
--- 204,215 ----
          }
  
          if (empty($this->grade_item)) {
!             $grade_item = grade_object::get_instance('grade_item');
!             $this->grade_item = $grade_item->fetch(array('id'=>$this->itemid));
  
          } else if ($this->grade_item->id != $this->itemid) {
              debugging('Itemid mismatch');
!             $this->grade_item = $grade_item->fetch(array('id'=>$this->itemid));
          }
  
          return $this->grade_item;
***************
*** 386,399 ****
          $items_sql = implode(',', $items);
  
          $now = time(); // no rounding needed, this is not supposed to be called every 10 seconds
! 
!         if ($rs = get_recordset_select('grade_grades', "itemid IN ($items_sql) AND locked = 0 AND locktime > 0 AND locktime < $now")) {
!             while ($grade = rs_fetch_next_record($rs)) {
!                 $grade_grade = new grade_grade($grade, false);
                  $grade_grade->locked = time();
                  $grade_grade->update('locktime');
              }
!             rs_close($rs);
          }
      }
  
--- 388,401 ----
          $items_sql = implode(',', $items);
  
          $now = time(); // no rounding needed, this is not supposed to be called every 10 seconds
!         $obj = grade_object::get_instance('grade_grade');
!         if ($rs = $obj->lib_wrapper->get_recordset_select('grade_grades', "itemid IN ($items_sql) AND locked = 0 AND locktime > 0 AND locktime < $now")) {
!             while ($grade = $obj->lib_wrapper->rs_fetch_next_record($rs)) {
!                 $grade_grade = $obj->get_instance('grade_grade', $grade, false);
                  $grade_grade->locked = time();
                  $grade_grade->update('locktime');
              }
!             $obj->lib_wrapper->rs_close($rs);
          }
      }
  
***************
*** 503,509 ****
       * @return object grade_grade instance or false if none found.
       */
      function fetch($params) {
!         return grade_object::fetch_helper('grade_grades', 'grade_grade', $params);
      }
  
      /**
--- 505,512 ----
       * @return object grade_grade instance or false if none found.
       */
      function fetch($params) {
!         $obj = grade_object::get_instance('grade_grade');
!         return $obj->fetch_helper('grade_grades', 'grade_grade', $params);
      }
  
      /**
***************
*** 514,520 ****
       * @return array array of grade_grade insatnces or false if none found.
       */
      function fetch_all($params) {
!         return grade_object::fetch_all_helper('grade_grades', 'grade_grade', $params);
      }
  
      /**
--- 517,524 ----
       * @return array array of grade_grade insatnces or false if none found.
       */
      function fetch_all($params) {
!         $obj = grade_object::get_instance('grade_grade');
!         return $obj->fetch_all_helper('grade_grades', 'grade_grade', $params);
      }
  
      /**
***************
*** 555,561 ****
          global $CFG;
  
          if (count($grade_grades) !== count($grade_items)) {
!             error('Incorrect size of arrays in params of grade_grade::get_hiding_affected()!');
          }
  
          $dependson = array();
--- 559,565 ----
          global $CFG;
  
          if (count($grade_grades) !== count($grade_items)) {
!             error('Incorrent size of arrays in params of grade_grade::get_hiding_affected()!');
          }
  
          $dependson = array();
*** D:/VertrigoServ/www/moode_up/lib/grade/grade_item.php	Thu Nov 22 07:03:21 2007
--- D:/VertrigoServ/www/moode_up/lib/grade/grade_item_new.php	Thu Nov 22 07:03:25 2007
***************
*** 281,298 ****
              return false;
          }
  
!         $db_item = new grade_item(array('id' => $this->id));
  
!         $calculationdiff = $db_item->calculation != $this->calculation;
!         $categorydiff    = $db_item->categoryid  != $this->categoryid;
!         $gradetypediff   = $db_item->gradetype   != $this->gradetype;
!         $grademaxdiff    = $db_item->grademax    != $this->grademax;
!         $grademindiff    = $db_item->grademin    != $this->grademin;
!         $scaleiddiff     = $db_item->scaleid     != $this->scaleid;
!         $outcomeiddiff   = $db_item->outcomeid   != $this->outcomeid;
!         $multfactordiff  = $db_item->multfactor  != $this->multfactor;
!         $plusfactordiff  = $db_item->plusfactor  != $this->plusfactor;
!         $locktimediff    = $db_item->locktime    != $this->locktime;
          $acoefdiff       = $db_item->aggregationcoef != $this->aggregationcoef;
  
          $needsupdatediff = !$db_item->needsupdate &&  $this->needsupdate;    // force regrading only if setting the flag first time
--- 281,298 ----
              return false;
          }
  
!         $db_item = $this->get_instance('grade_item', array('id' => $this->id));
  
!         $calculationdiff = $db_item->calculation     != $this->calculation;
!         $categorydiff    = $db_item->categoryid      != $this->categoryid;
!         $gradetypediff   = $db_item->gradetype       != $this->gradetype;
!         $grademaxdiff    = $db_item->grademax        != $this->grademax;
!         $grademindiff    = $db_item->grademin        != $this->grademin;
!         $scaleiddiff     = $db_item->scaleid         != $this->scaleid;
!         $outcomeiddiff   = $db_item->outcomeid       != $this->outcomeid;
!         $multfactordiff  = $db_item->multfactor      != $this->multfactor;
!         $plusfactordiff  = $db_item->plusfactor      != $this->plusfactor;
!         $locktimediff    = $db_item->locktime        != $this->locktime;
          $acoefdiff       = $db_item->aggregationcoef != $this->aggregationcoef;
  
          $needsupdatediff = !$db_item->needsupdate &&  $this->needsupdate;    // force regrading only if setting the flag first time
***************
*** 311,317 ****
       * @return object grade_item instance or false if none found.
       */
      function fetch($params) {
!         return grade_object::fetch_helper('grade_items', 'grade_item', $params);
      }
  
      /**
--- 311,318 ----
       * @return object grade_item instance or false if none found.
       */
      function fetch($params) {
!         $obj = grade_object::get_instance('grade_item');
!         return $obj->fetch_helper('grade_items', 'grade_item', $params);
      }
  
      /**
***************
*** 322,328 ****
       * @return array array of grade_item insatnces or false if none found.
       */
      function fetch_all($params) {
!         return grade_object::fetch_all_helper('grade_items', 'grade_item', $params);
      }
  
      /**
--- 323,330 ----
       * @return array array of grade_item insatnces or false if none found.
       */
      function fetch_all($params) {
!         $obj = grade_object::get_instance('grade_item');
!         return $obj->fetch_all_helper('grade_items', 'grade_item', $params);
      }
  
      /**
***************
*** 335,341 ****
              $this->force_regrading();
          }
  
!         if ($grades = grade_grade::fetch_all(array('itemid'=>$this->id))) {
              foreach ($grades as $grade) {
                  $grade->delete($source);
              }
--- 337,344 ----
              $this->force_regrading();
          }
  
!         $grade_grade = grade_object::get_instance('grade_grade');
!         if ($grades = $grade_grade->fetch_all(array('itemid'=>$this->id))) {
              foreach ($grades as $grade) {
                  $grade->delete($source);
              }
***************
*** 360,373 ****
          $this->load_scale();
  
          // add parent category if needed
          if (empty($this->categoryid) and !$this->is_course_item() and !$this->is_category_item()) {
!             $course_category = grade_category::fetch_course_category($this->courseid);
              $this->categoryid = $course_category->id;
  
          }
  
          // always place the new items at the end, move them after insert if needed
!         $last_sortorder = get_field_select('grade_items', 'MAX(sortorder)', "courseid = {$this->courseid}");
          if (!empty($last_sortorder)) {
              $this->sortorder = $last_sortorder + 1;
          } else {
--- 363,377 ----
          $this->load_scale();
  
          // add parent category if needed
+         $grade_category = grade_object::get_instance('grade_category');
          if (empty($this->categoryid) and !$this->is_course_item() and !$this->is_category_item()) {
!             $course_category = $grade_category->fetch_course_category($this->courseid);
              $this->categoryid = $course_category->id;
  
          }
  
          // always place the new items at the end, move them after insert if needed
!         $last_sortorder = $this->lib_wrapper->get_field_select('grade_items', 'MAX(sortorder)', "courseid = {$this->courseid}");
          if (!empty($last_sortorder)) {
              $this->sortorder = $last_sortorder + 1;
          } else {
***************
*** 410,422 ****
          }
  
          if ($this->itemtype == 'mod' and !$this->is_outcome_item()) {
!             if (!$cm = get_coursemodule_from_instance($this->itemmodule, $this->iteminstance, $this->courseid)) {
                  return false;
              }
              if (!empty($cm->idnumber)) {
                  return false;
              }
!             if (set_field('course_modules', 'idnumber', addslashes($idnumber), 'id', $cm->id)) {
                  $this->idnumber = $idnumber;
                  return $this->update();
              }
--- 414,426 ----
          }
  
          if ($this->itemtype == 'mod' and !$this->is_outcome_item()) {
!             if (!$cm = $this->lib_wrapper->get_coursemodule_from_instance($this->itemmodule, $this->iteminstance, $this->courseid)) {
                  return false;
              }
              if (!empty($cm->idnumber)) {
                  return false;
              }
!             if ($this->lib_wrapper->set_field('course_modules', 'idnumber', addslashes($idnumber), 'id', $cm->id)) {
                  $this->idnumber = $idnumber;
                  return $this->update();
              }
***************
*** 442,448 ****
          }
  
          if (!empty($userid)) {
!             if ($grade = grade_grade::fetch(array('itemid'=>$this->id, 'userid'=>$userid))) {
                  $grade->grade_item =& $this; // prevent db fetching of cached grade_item
                  return $grade->is_locked();
              }
--- 446,453 ----
          }
  
          if (!empty($userid)) {
!             $grade_grade = grade_object::get_instance('grade_grade');
!             if ($grade = $grade_grade->fetch(array('itemid'=>$this->id, 'userid'=>$userid))) {
                  $grade->grade_item =& $this; // prevent db fetching of cached grade_item
                  return $grade->is_locked();
              }
***************
*** 471,477 ****
              if ($cascade) {
                  $grades = $this->get_final();
                  foreach($grades as $g) {
!                     $grade = new grade_grade($g, false);
                      $grade->grade_item =& $this;
                      $grade->set_locked(1, null, false);
                  }
--- 476,482 ----
              if ($cascade) {
                  $grades = $this->get_final();
                  foreach($grades as $g) {
!                     $grade = $this->get_instance('grade_grade', $g, false);
                      $grade->grade_item =& $this;
                      $grade->set_locked(1, null, false);
                  }
***************
*** 490,496 ****
              $this->update();
  
              if ($cascade) {
!                 if ($grades = grade_grade::fetch_all(array('itemid'=>$this->id))) {
                      foreach($grades as $grade) {
                          $grade->grade_item =& $this;
                          $grade->set_locked(0, null, false);
--- 495,502 ----
              $this->update();
  
              if ($cascade) {
!                 $grade_grade = grade_object::get_instance('grade_grade');
!                 if ($grades = $grade_grade->fetch_all(array('itemid'=>$this->id))) {
                      foreach($grades as $grade) {
                          $grade->grade_item =& $this;
                          $grade->set_locked(0, null, false);
***************
*** 576,582 ****
          $this->update();
  
          if ($cascade) {
!             if ($grades = grade_grade::fetch_all(array('itemid'=>$this->id))) {
                  foreach($grades as $grade) {
                      $grade->grade_item =& $this;
                      $grade->set_hidden($hidden, $cascade);
--- 582,589 ----
          $this->update();
  
          if ($cascade) {
!             $grade_grade = grade_object::get_instance('grade_grade');
!             if ($grades = $grade_grade->fetch_all(array('itemid'=>$this->id))) {
                  foreach($grades as $grade) {
                      $grade->grade_item =& $this;
                      $grade->set_hidden($hidden, $cascade);
***************
*** 591,597 ****
       */
      function has_hidden_grades($groupsql="", $groupwheresql="") {
          global $CFG;
!         return get_field_sql("SELECT COUNT(*) FROM {$CFG->prefix}grade_grades g LEFT JOIN "
                              ."{$CFG->prefix}user u ON g.userid = u.id $groupsql WHERE itemid = $this->id AND hidden = 1 $groupwheresql");
      }
  
--- 598,604 ----
       */
      function has_hidden_grades($groupsql="", $groupwheresql="") {
          global $CFG;
!         return $this->lib_wrapper->get_field_sql("SELECT COUNT(*) FROM {$CFG->prefix}grade_grades g LEFT JOIN "
                              ."{$CFG->prefix}user u ON g.userid = u.id $groupsql WHERE itemid = $this->id AND hidden = 1 $groupwheresql");
      }
  
***************
*** 601,607 ****
      function regrading_finished() {
          $this->needsupdate = 0;
          //do not use $this->update() because we do not want this logged in grade_item_history
!         set_field('grade_items', 'needsupdate', 0, 'id', $this->id);
      }
  
      /**
--- 608,614 ----
      function regrading_finished() {
          $this->needsupdate = 0;
          //do not use $this->update() because we do not want this logged in grade_item_history
!         $this->lib_wrapper->set_field('grade_items', 'needsupdate', 0, 'id', $this->id);
      }
  
      /**
***************
*** 655,670 ****
  
          // normal grade item - just new final grades
          $result = true;
!         $grade_inst = new grade_grade();
          $fields = implode(',', $grade_inst->required_fields);
          if ($userid) {
!             $rs = get_recordset_select('grade_grades', "itemid={$this->id} AND userid=$userid", '', $fields);
          } else {
!             $rs = get_recordset('grade_grades', 'itemid', $this->id, '', $fields);
          }
          if ($rs) {
!             while ($grade_record = rs_fetch_next_record($rs)) {
!                 $grade = new grade_grade($grade_record, false);
  
                  if (!empty($grade_record->locked) or !empty($grade_record->overridden)) {
                      // this grade is locked - final grade must be ok
--- 662,677 ----
  
          // normal grade item - just new final grades
          $result = true;
!         $grade_inst = grade_object::get_instance('grade_grade');
          $fields = implode(',', $grade_inst->required_fields);
          if ($userid) {
!             $rs = $this->lib_wrapper->get_recordset_select('grade_grades', "itemid={$this->id} AND userid=$userid", '', $fields);
          } else {
!             $rs = $this->lib_wrapper->get_recordset('grade_grades', 'itemid', $this->id, '', $fields);
          }
          if ($rs) {
!             while ($grade_record = $this->lib_wrapper->rs_fetch_next_record($rs)) {
!                 $grade = $this->get_instance('grade_grade', $grade_record, false);
  
                  if (!empty($grade_record->locked) or !empty($grade_record->overridden)) {
                      // this grade is locked - final grade must be ok
***************
*** 679,685 ****
                      }
                  }
              }
!             rs_close($rs);
          }
  
          return $result;
--- 686,692 ----
                      }
                  }
              }
!             $this->lib_wrapper->rs_close($rs);
          }
  
          return $result;
***************
*** 745,752 ****
              return null;
  
          } else {
!             debugging("Unkown grade type");
!             return null;
          }
      }
  
--- 752,759 ----
              return null;
  
          } else {
!             dubugging("Unkown grade type");
!             return null;;
          }
      }
  
***************
*** 758,764 ****
          $this->needsupdate = 1;
          //mark this item and course item only - categories and calculated items are always regraded
          $wheresql = "(itemtype='course' OR id={$this->id}) AND courseid={$this->courseid}";
!         set_field_select('grade_items', 'needsupdate', 1, $wheresql);
      }
  
      /**
--- 765,771 ----
          $this->needsupdate = 1;
          //mark this item and course item only - categories and calculated items are always regraded
          $wheresql = "(itemtype='course' OR id={$this->id}) AND courseid={$this->courseid}";
!         $this->lib_wrapper->set_field_select('grade_items', 'needsupdate', 1, $wheresql);
      }
  
      /**
***************
*** 774,780 ****
          if (!empty($this->scaleid)) {
              //do not load scale if already present
              if (empty($this->scale->id) or $this->scale->id != $this->scaleid) {
!                 $this->scale = grade_scale::fetch(array('id'=>$this->scaleid));
                  $this->scale->load_items();
              }
  
--- 781,788 ----
          if (!empty($this->scaleid)) {
              //do not load scale if already present
              if (empty($this->scale->id) or $this->scale->id != $this->scaleid) {
!                 $grade_scale = grade_object::get_instance('grade_scale');
!                 $this->scale = $grade_scale->fetch(array('id'=>$this->scaleid));
                  $this->scale->load_items();
              }
  
***************
*** 797,803 ****
       */
      function load_outcome() {
          if (!empty($this->outcomeid)) {
!             $this->outcome = grade_outcome::fetch(array('id'=>$this->outcomeid));
          }
          return $this->outcome;
      }
--- 805,812 ----
       */
      function load_outcome() {
          if (!empty($this->outcomeid)) {
!             $grade_outcome = grade_object::get_instance('grade_outcome');
!             $this->outcome = $grade_outcome->fetch(array('id'=>$this->outcomeid));
          }
          return $this->outcome;
      }
***************
*** 813,819 ****
              return $this->get_item_category();
  
          } else {
!             return grade_category::fetch(array('id'=>$this->categoryid));
          }
      }
  
--- 822,829 ----
              return $this->get_item_category();
  
          } else {
!             $grade_category = grade_object::get_instance('grade_category');
!             return $grade_category->fetch(array('id'=>$this->categoryid));
          }
      }
  
***************
*** 838,844 ****
          if (!$this->is_course_item() and !$this->is_category_item()) {
              return false;
          }
!         return grade_category::fetch(array('id'=>$this->iteminstance));
      }
  
      /**
--- 848,855 ----
          if (!$this->is_course_item() and !$this->is_category_item()) {
              return false;
          }
!         $grade_category = grade_object::get_instance('grade_category');
!         return $grade_category->fetch(array('id'=>$this->iteminstance));
      }
  
      /**
***************
*** 915,928 ****
       * @return course item object
       */
      function fetch_course_item($courseid) {
!         if ($course_item = grade_item::fetch(array('courseid'=>$courseid, 'itemtype'=>'course'))) {
              return $course_item;
          }
  
          // first get category - it creates the associated grade item
!         $course_category = grade_category::fetch_course_category($courseid);
  
!         return grade_item::fetch(array('courseid'=>$courseid, 'itemtype'=>'course'));
      }
  
      /**
--- 926,941 ----
       * @return course item object
       */
      function fetch_course_item($courseid) {
!         $obj = grade_object::get_instance('grade_item');;
!         if ($course_item = $obj->fetch(array('courseid'=>$courseid, 'itemtype'=>'course'))) {
              return $course_item;
          }
  
          // first get category - it creates the associated grade item
!         $grade_category = grade_object::get_instance('grade_category');
!         $course_category = $grade_category->fetch_course_category($courseid);
  
!         return $obj->fetch(array('courseid'=>$courseid, 'itemtype'=>'course'));
      }
  
      /**
***************
*** 962,968 ****
       */
      function get_calculation() {
          if ($this->is_calculated()) {
!             return grade_item::denormalize_formula($this->calculation, $this->courseid);
  
          } else {
              return NULL;
--- 975,981 ----
       */
      function get_calculation() {
          if ($this->is_calculated()) {
!             return $this->denormalize_formula($this->calculation, $this->courseid);
  
          } else {
              return NULL;
***************
*** 977,983 ****
       * @return boolean success
       */
      function set_calculation($formula) {
!         $this->calculation = grade_item::normalize_formula($formula, $this->courseid);
          $this->calculation_normalized = true;
          return $this->update();
      }
--- 990,996 ----
       * @return boolean success
       */
      function set_calculation($formula) {
!         $this->calculation = $this->normalize_formula($formula, $this->courseid);
          $this->calculation_normalized = true;
          return $this->update();
      }
***************
*** 996,1002 ****
          // denormalize formula - convert ##giXX## to [[idnumber]]
          if (preg_match_all('/##gi(\d+)##/', $formula, $matches)) {
              foreach ($matches[1] as $id) {
!                 if ($grade_item = grade_item::fetch(array('id'=>$id, 'courseid'=>$courseid))) {
                      if (!empty($grade_item->idnumber)) {
                          $formula = str_replace('##gi'.$grade_item->id.'##', '[['.$grade_item->idnumber.']]', $formula);
                      }
--- 1009,1016 ----
          // denormalize formula - convert ##giXX## to [[idnumber]]
          if (preg_match_all('/##gi(\d+)##/', $formula, $matches)) {
              foreach ($matches[1] as $id) {
!                 $obj = grade_object::get_instance('grade_item');;
!                 if ($grade_item = $obj->fetch(array('id'=>$id, 'courseid'=>$courseid))) {
                      if (!empty($grade_item->idnumber)) {
                          $formula = str_replace('##gi'.$grade_item->id.'##', '[['.$grade_item->idnumber.']]', $formula);
                      }
***************
*** 1023,1029 ****
          }
  
          // normalize formula - we want grade item ids ##giXXX## instead of [[idnumber]]
!         if ($grade_items = grade_item::fetch_all(array('courseid'=>$courseid))) {
              foreach ($grade_items as $grade_item) {
                  $formula = str_replace('[['.$grade_item->idnumber.']]', '##gi'.$grade_item->id.'##', $formula);
              }
--- 1037,1044 ----
          }
  
          // normalize formula - we want grade item ids ##giXXX## instead of [[idnumber]]
!         $obj = grade_object::get_instance('grade_item');;
!         if ($grade_items = $obj->fetch_all(array('courseid'=>$courseid))) {
              foreach ($grade_items as $grade_item) {
                  $formula = str_replace('[['.$grade_item->idnumber.']]', '##gi'.$grade_item->id.'##', $formula);
              }
***************
*** 1039,1050 ****
       */
      function get_final($userid=NULL) {
          if ($userid) {
!             if ($user = get_record('grade_grades', 'itemid', $this->id, 'userid', $userid)) {
                  return $user;
              }
  
          } else {
!             if ($grades = get_records('grade_grades', 'itemid', $this->id)) {
                  //TODO: speed up with better SQL
                  $result = array();
                  foreach ($grades as $grade) {
--- 1054,1065 ----
       */
      function get_final($userid=NULL) {
          if ($userid) {
!             if ($user = $this->lib_wrapper->get_record('grade_grades', 'itemid', $this->id, 'userid', $userid)) {
                  return $user;
              }
  
          } else {
!             if ($grades = $this->lib_wrapper->get_records('grade_grades', 'itemid', $this->id)) {
                  //TODO: speed up with better SQL
                  $result = array();
                  foreach ($grades as $grade) {
***************
*** 1068,1074 ****
              return false;
          }
  
!         $grade = new grade_grade(array('userid'=>$userid, 'itemid'=>$this->id));
          if (empty($grade->id) and $create) {
              $grade->insert();
          }
--- 1083,1089 ----
              return false;
          }
  
!         $grade = $this->get_instance('grade_grade', array('userid'=>$userid, 'itemid'=>$this->id));
          if (empty($grade->id) and $create) {
              $grade->insert();
          }
***************
*** 1121,1127 ****
          $sql = "UPDATE {$CFG->prefix}grade_items
                     SET sortorder = sortorder + 1
                   WHERE sortorder > $sortorder AND courseid = {$this->courseid}";
!         execute_sql($sql, false);
  
          $this->set_sortorder($sortorder + 1);
      }
--- 1136,1142 ----
          $sql = "UPDATE {$CFG->prefix}grade_items
                     SET sortorder = sortorder + 1
                   WHERE sortorder > $sortorder AND courseid = {$this->courseid}";
!         $this->lib_wrapper->execute_sql($sql, false);
  
          $this->set_sortorder($sortorder + 1);
      }
***************
*** 1162,1168 ****
          }
  
          // find parent and check course id
!         if (!$parent_category = grade_category::fetch(array('id'=>$parentid, 'courseid'=>$this->courseid))) {
              return false;
          }
  
--- 1177,1184 ----
          }
  
          // find parent and check course id
!         $grade_category = grade_object::get_instance('grade_category');
!         if (!$parent_category = $grade_category->fetch(array('id'=>$parentid, 'courseid'=>$this->courseid))) {
              return false;
          }
  
***************
*** 1247,1253 ****
                                 $outcomes_sql";
              }
  
!             if ($children = get_records_sql($sql)) {
                  $this->dependson_cache = array_keys($children);
                  return $this->dependson_cache;
              } else {
--- 1263,1269 ----
                                 $outcomes_sql";
              }
  
!             if ($children = $this->lib_wrapper->get_records_sql($sql)) {
                  $this->dependson_cache = array_keys($children);
                  return $this->dependson_cache;
              } else {
***************
*** 1272,1283 ****
                  return;
              }
  
!             if (!$activity = get_record($this->itemmodule, 'id', $this->iteminstance)) {
                  debugging("Can not find $this->itemmodule activity with id $this->iteminstance");
                  return;
              }
  
!             if (!$cm = get_coursemodule_from_instance($this->itemmodule, $activity->id, $this->courseid)) {
                  debugging('Can not find course module');
                  return;
              }
--- 1288,1299 ----
                  return;
              }
  
!             if (!$activity = $this->lib_wrapper->get_record($this->itemmodule, 'id', $this->iteminstance)) {
                  debugging("Can not find $this->itemmodule activity with id $this->iteminstance");
                  return;
              }
  
!             if (!$cm = $this->lib_wrapper->get_coursemodule_from_instance($this->itemmodule, $activity->id, $this->courseid)) {
                  debugging('Can not find course module');
                  return;
              }
***************
*** 1313,1319 ****
              return false;
          }
  
!         $grade = new grade_grade(array('itemid'=>$this->id, 'userid'=>$userid));
          $grade->grade_item =& $this; // prevent db fetching of this grade_item
  
          if (empty($usermodified)) {
--- 1329,1335 ----
              return false;
          }
  
!         $grade = $this->get_instance('grade_grade', array('itemid'=>$this->id, 'userid'=>$userid));
          $grade->grade_item =& $this; // prevent db fetching of this grade_item
  
          if (empty($usermodified)) {
***************
*** 1396,1402 ****
              }
  
          } else if (!$this->needsupdate) {
!             $course_item = grade_item::fetch_course_item($this->courseid);
              if (!$course_item->needsupdate) {
                  if (!grade_regrade_final_grades($this->courseid, $userid, $this)) {
                      $this->force_regrading();
--- 1412,1419 ----
              }
  
          } else if (!$this->needsupdate) {
!             $obj = grade_object::get_instance('grade_item');;
!             $course_item = $obj->fetch_course_item($this->courseid);
              if (!$course_item->needsupdate) {
                  if (!grade_regrade_final_grades($this->courseid, $userid, $this)) {
                      $this->force_regrading();
***************
*** 1436,1442 ****
              return false;
          }
  
!         $grade = new grade_grade(array('itemid'=>$this->id, 'userid'=>$userid));
          $grade->grade_item =& $this; // prevent db fetching of this grade_item
  
          if (empty($usermodified)) {
--- 1453,1459 ----
              return false;
          }
  
!         $grade = $this->get_instance('grade_grade', array('itemid'=>$this->id, 'userid'=>$userid));
          $grade->grade_item =& $this; // prevent db fetching of this grade_item
  
          if (empty($usermodified)) {
***************
*** 1519,1525 ****
              $this->force_regrading();
  
          } else if (!$this->needsupdate) {
!             $course_item = grade_item::fetch_course_item($this->courseid);
              if (!$course_item->needsupdate) {
                  if (!grade_regrade_final_grades($this->courseid, $userid, $this)) {
                      $this->force_regrading();
--- 1536,1543 ----
              $this->force_regrading();
  
          } else if (!$this->needsupdate) {
!             $obj = grade_object::get_instance('grade_item');;
!             $course_item = $obj->fetch_course_item($this->courseid);
              if (!$course_item->needsupdate) {
                  if (!grade_regrade_final_grades($this->courseid, $userid, $this)) {
                      $this->force_regrading();
***************
*** 1567,1573 ****
              $usersql = "";
          }
  
!         $grade_inst = new grade_grade();
          $fields = 'g.'.implode(',g.', $grade_inst->required_fields);
  
          $sql = "SELECT $fields
--- 1585,1591 ----
              $usersql = "";
          }
  
!         $grade_inst = grade_object::get_instance('grade_grade');
          $fields = 'g.'.implode(',g.', $grade_inst->required_fields);
  
          $sql = "SELECT $fields
***************
*** 1578,1588 ****
          $return = true;
  
          // group the grades by userid and use formula on the group
!         if ($rs = get_recordset_sql($sql)) {
              $prevuser = 0;
              $grade_records   = array();
              $oldgrade    = null;
!             while ($used = rs_fetch_next_record($rs)) {
                  if ($used->userid != $prevuser) {
                      if (!$this->use_formula($prevuser, $grade_records, $useditems, $oldgrade)) {
                          $return = false;
--- 1596,1606 ----
          $return = true;
  
          // group the grades by userid and use formula on the group
!         if ($rs = $this->lib_wrapper->get_recordset_sql($sql)) {
              $prevuser = 0;
              $grade_records   = array();
              $oldgrade    = null;
!             while ($used = $this->lib_wrapper->rs_fetch_next_record($rs)) {
                  if ($used->userid != $prevuser) {
                      if (!$this->use_formula($prevuser, $grade_records, $useditems, $oldgrade)) {
                          $return = false;
***************
*** 1600,1606 ****
                  $return = false;
              }
          }
!         rs_close($rs);
  
          return $return;
      }
--- 1618,1624 ----
                  $return = false;
              }
          }
!         $this->lib_wrapper->rs_close($rs);
  
          return $return;
      }
***************
*** 1634,1644 ****
                  // we need proper floats here for !== comparison later
                  $oldfinalgrade = (float)$oldgrade->finalgrade;
              }
!             $grade = new grade_grade($oldgrade, false); // fetching from db is not needed
              $grade->grade_item =& $this;
  
          } else {
!             $grade = new grade_grade(array('itemid'=>$this->id, 'userid'=>$userid), false);
              $grade->grade_item =& $this;
              $grade->insert('system');
              $oldfinalgrade = null;
--- 1652,1662 ----
                  // we need proper floats here for !== comparison later
                  $oldfinalgrade = (float)$oldgrade->finalgrade;
              }
!             $grade = $this->get_instance('grade_grade', $oldgrade, false); // fetching from db is not needed
              $grade->grade_item =& $this;
  
          } else {
!             $grade = $this->get_instance('grade_grade', array('itemid'=>$this->id, 'userid'=>$userid), false);
              $grade->grade_item =& $this;
              $grade->insert('system');
              $oldfinalgrade = null;
***************
*** 1691,1697 ****
          global $CFG;
          require_once($CFG->libdir.'/mathslib.php');
  
!         $formulastr = grade_item::normalize_formula($formulastr, $this->courseid);
  
          if (empty($formulastr)) {
              return true;
--- 1709,1715 ----
          global $CFG;
          require_once($CFG->libdir.'/mathslib.php');
  
!         $formulastr = $this->normalize_formula($formulastr, $this->courseid);
  
          if (empty($formulastr)) {
              return true;
***************
*** 1731,1737 ****
                        FROM {$CFG->prefix}grade_items gi
                       WHERE gi.id IN ($gis) and gi.courseid={$this->courseid}"; // from the same course only!
  
!             if (!$grade_items = get_records_sql($sql)) {
                  $grade_items = array();
              }
          }
--- 1749,1755 ----
                        FROM {$CFG->prefix}grade_items gi
                       WHERE gi.id IN ($gis) and gi.courseid={$this->courseid}"; // from the same course only!
  
!             if (!$grade_items = $this->lib_wrapper->get_records_sql($sql)) {
                  $grade_items = array();
              }
          }
*** D:/VertrigoServ/www/moode_up/lib/grade/grade_object.php	Thu Nov 22 07:04:58 2007
--- D:/VertrigoServ/www/moode_up/lib/grade/grade_object_new.php	Thu Nov 22 07:05:01 2007
***************
*** 60,86 ****
      var $timemodified;
  
      /**
       * Constructor. Optionally (and by default) attempts to fetch corresponding row from DB.
       * @param array $params an array with required parameters for this grade object.
       * @param boolean $fetch Whether to fetch corresponding row from DB or not,
       *        optional fields might not be defined if false used
       */
      function grade_object($params=NULL, $fetch=true) {
          if (!empty($params) and (is_array($params) or is_object($params))) {
              if ($fetch) {
                  if ($data = $this->fetch($params)) {
!                     grade_object::set_properties($this, $data);
                  } else {
!                     grade_object::set_properties($this, $this->optional_fields);//apply defaults for optional fields
!                     grade_object::set_properties($this, $params);
                  }
  
              } else {
!                 grade_object::set_properties($this, $params);
              }
  
          } else {
!             grade_object::set_properties($this, $this->optional_fields);//apply defaults for optional fields
          }
      }
  
--- 60,94 ----
      var $timemodified;
  
      /**
+      * A wrapper object around moodle procedural functions (especially dmllib).
+      * @var object $lib_wrapper
+      */
+     var $lib_wrapper;
+ 
+     /**
       * Constructor. Optionally (and by default) attempts to fetch corresponding row from DB.
       * @param array $params an array with required parameters for this grade object.
       * @param boolean $fetch Whether to fetch corresponding row from DB or not,
       *        optional fields might not be defined if false used
       */
      function grade_object($params=NULL, $fetch=true) {
+         $this->lib_wrapper = new grade_lib_wrapper();
+ 
          if (!empty($params) and (is_array($params) or is_object($params))) {
              if ($fetch) {
                  if ($data = $this->fetch($params)) {
!                     $this->set_properties($this, $data);
                  } else {
!                     $this->set_properties($this, $this->optional_fields);//apply defaults for optional fields
!                     $this->set_properties($this, $params);
                  }
  
              } else {
!                 $this->set_properties($this, $params);
              }
  
          } else {
!             $this->set_properties($this, $this->optional_fields);//apply defaults for optional fields
          }
      }
  
***************
*** 97,103 ****
              if (empty($this->id)) {
                  $this->$field = $default;
              } else {
!                 $this->$field = get_field($this->table, $field, 'id', $this->id);
              }
          }
      }
--- 105,111 ----
              if (empty($this->id)) {
                  $this->$field = $default;
              } else {
!                 $this->$field = $this->lib_wrapper->get_field($this->table, $field, 'id', $this->id);
              }
          }
      }
***************
*** 130,136 ****
       * @return mixed object instance or false if not found
       */
      function fetch_helper($table, $classname, $params) {
!         if ($instances = grade_object::fetch_all_helper($table, $classname, $params)) {
              if (count($instances) > 1) {
                  // we should not tolerate any errors here - problems might appear later
                  error('Found more than one record in fetch() !');
--- 138,145 ----
       * @return mixed object instance or false if not found
       */
      function fetch_helper($table, $classname, $params) {
!         $obj = new grade_object();
!         if ($instances = $obj->fetch_all_helper($table, $classname, $params)) {
              if (count($instances) > 1) {
                  // we should not tolerate any errors here - problems might appear later
                  error('Found more than one record in fetch() !');
***************
*** 147,152 ****
--- 156,162 ----
       * @return mixed array of object instances or false if not found
       */
      function fetch_all_helper($table, $classname, $params) {
+         $obj = new grade_object();
          $instance = new $classname();
  
          $classvars = (array)$instance;
***************
*** 173,183 ****
              $wheresql = implode("AND", $wheresql);
          }
  
!         if ($datas = get_records_select($table, $wheresql, 'id')) {
              $result = array();
              foreach($datas as $data) {
                  $instance = new $classname();
!                 grade_object::set_properties($instance, $data);
                  $result[$instance->id] = $instance;
              }
              return $result;
--- 183,193 ----
              $wheresql = implode("AND", $wheresql);
          }
  
!         if ($datas = $obj->lib_wrapper->get_records_select($table, $wheresql, 'id')) {
              $result = array();
              foreach($datas as $data) {
                  $instance = new $classname();
!                 $obj->set_properties($instance, $data);
                  $result[$instance->id] = $instance;
              }
              return $result;
***************
*** 202,208 ****
  
          $data = $this->get_record_data();
  
!         if (!update_record($this->table, addslashes_recursive($data))) {
              return false;
          }
  
--- 212,218 ----
  
          $data = $this->get_record_data();
  
!         if (!$this->lib_wrapper->update_record($this->table, addslashes_recursive($data))) {
              return false;
          }
  
***************
*** 213,219 ****
              $data->source       = $source;
              $data->timemodified = time();
              $data->userlogged   = $USER->id;
!             insert_record($this->table.'_history', addslashes_recursive($data));
          }
  
          return true;
--- 223,229 ----
              $data->source       = $source;
              $data->timemodified = time();
              $data->userlogged   = $USER->id;
!             $this->lib_wrapper->insert_record($this->table.'_history', addslashes_recursive($data));
          }
  
          return true;
***************
*** 234,240 ****
  
          $data = $this->get_record_data();
  
!         if (delete_records($this->table, 'id', $this->id)) {
              if (empty($CFG->disablegradehistory)) {
                  unset($data->id);
                  unset($data->timecreated);
--- 244,250 ----
  
          $data = $this->get_record_data();
  
!         if ($this->lib_wrapper->delete_records($this->table, 'id', $this->id)) {
              if (empty($CFG->disablegradehistory)) {
                  unset($data->id);
                  unset($data->timecreated);
***************
*** 243,249 ****
                  $data->source       = $source;
                  $data->timemodified = time();
                  $data->userlogged   = $USER->id;
!                 insert_record($this->table.'_history', addslashes_recursive($data));
              }
              return true;
  
--- 253,259 ----
                  $data->source       = $source;
                  $data->timemodified = time();
                  $data->userlogged   = $USER->id;
!                 $this->lib_wrapper->insert_record($this->table.'_history', addslashes_recursive($data));
              }
              return true;
  
***************
*** 287,293 ****
  
          $data = $this->get_record_data();
  
!         if (!$this->id = insert_record($this->table, addslashes_recursive($data))) {
              debugging("Could not insert object into db");
              return false;
          }
--- 297,303 ----
  
          $data = $this->get_record_data();
  
!         if (!$this->id = $this->lib_wrapper->insert_record($this->table, addslashes_recursive($data))) {
              debugging("Could not insert object into db");
              return false;
          }
***************
*** 304,310 ****
              $data->source       = $source;
              $data->timemodified = time();
              $data->userlogged   = $USER->id;
!             insert_record($this->table.'_history', addslashes_recursive($data));
          }
  
          return $this->id;
--- 314,320 ----
              $data->source       = $source;
              $data->timemodified = time();
              $data->userlogged   = $USER->id;
!             $this->lib_wrapper->insert_record($this->table.'_history', addslashes_recursive($data));
          }
  
          return $this->id;
***************
*** 322,333 ****
              return false;
          }
  
!         if (!$params = get_record($this->table, 'id', $this->id)) {
              debugging("Object with this id:{$this->id} does not exist in table:{$this->table}, can not update from db!");
              return false;
          }
  
!         grade_object::set_properties($this, $params);
  
          return true;
      }
--- 332,343 ----
              return false;
          }
  
!         if (!$params = $this->lib_wrapper->get_record($this->table, 'id', $this->id)) {
              debugging("Object with this id:{$this->id} does not exist in table:{$this->table}, can not update from db!");
              return false;
          }
  
!         $this->set_properties($this, $params);
  
          return true;
      }
***************
*** 343,348 ****
--- 353,400 ----
              if (in_array($var, $instance->required_fields) or array_key_exists($var, $instance->optional_fields)) {
                  $instance->$var = $value;
              }
+         }
+     }
+     
+     /**
+      * The following function is a helper for making the code more testable. It allows
+      * unit tests to mock the objects instantiated and used within method bodies. If no params are given,
+      * a static instance is returned.
+      * @param string $class
+      * @param array $params
+      * @param bool $fetch
+      * @param bool $set Whether or not to set the instance instead of getting it
+      */
+     function get_instance($class, $params=NULL, $fetch=true, $set=false, $object=null) {
+         static $grade_instances = array();  
+         $classes = array('grade_item', 'grade_category', 'grade_grade', 'grade_outcome', 'grade_scale');
+         
+         if ($set) {
+             if (!is_object($object)) {
+                 debugging('grade_object::set_instance was given a non-object as parameter!');
+                 return false;
+             }
+             
+             if (in_array($class, $classes)) {
+                 $grade_instances[$class] =& $object;
+                 return true;
+             } else {
+                 debugging("grade_object::set_instance was given an object that is not supported ($class)!");
+                 return false;
+             }
+ 
+         } else {
+             if (!in_array($class, $classes)) {
+                 return false;
+             } elseif (is_null($params)) {
+                 if (!array_key_exists($class, $grade_instances)) {
+                     $grade_instances[$class] =& new $class;
+                 }
+                 $instance =& $grade_instances[$class];
+                 return $instance;
+             } else { 
+                 return new $class($params, $fetch);
+             } 
          }
      }
  }
*** D:/VertrigoServ/www/moode_up/lib/grade/grade_outcome.php	Thu Nov 22 07:05:54 2007
--- D:/VertrigoServ/www/moode_up/lib/grade/grade_outcome_new.php	Thu Nov 22 07:05:58 2007
***************
*** 92,98 ****
       */
      function delete($source=null) {
          if (!empty($this->courseid)) {
!             delete_records('grade_outcomes_courses', 'outcomeid', $this->id, 'courseid', $this->courseid);
          }
          return parent::delete($source);
      }
--- 92,98 ----
       */
      function delete($source=null) {
          if (!empty($this->courseid)) {
!             $this->lib_wrapper->delete_records('grade_outcomes_courses', 'outcomeid', $this->id, 'courseid', $this->courseid);
          }
          return parent::delete($source);
      }
***************
*** 113,119 ****
                  $goc = new object();
                  $goc->courseid = $this->courseid;
                  $goc->outcomeid = $this->id;
!                 insert_record('grade_outcomes_courses', $goc);
              }
          }
          return $result;
--- 113,119 ----
                  $goc = new object();
                  $goc->courseid = $this->courseid;
                  $goc->outcomeid = $this->id;
!                 $this->lib_wrapper->insert_record('grade_outcomes_courses', $goc);
              }
          }
          return $result;
***************
*** 129,139 ****
  
          if ($result = parent::update($source)) {
              if (!empty($this->courseid)) {
!                 if (!get_records('grade_outcomes_courses', 'courseid', $this->courseid, 'outcomeid', $this->id)) {
                      $goc = new object();
                      $goc->courseid = $this->courseid;
                      $goc->outcomeid = $this->id;
!                     insert_record('grade_outcomes_courses', $goc);
                  }
              }
          }
--- 129,139 ----
  
          if ($result = parent::update($source)) {
              if (!empty($this->courseid)) {
!                 if (!$this->lib_wrapper->get_records('grade_outcomes_courses', 'courseid', $this->courseid, 'outcomeid', $this->id)) {
                      $goc = new object();
                      $goc->courseid = $this->courseid;
                      $goc->outcomeid = $this->id;
!                     $this->lib_wrapper->insert_record('grade_outcomes_courses', $goc);
                  }
              }
          }
***************
*** 148,154 ****
       * @return object grade_outcome instance or false if none found.
       */
      function fetch($params) {
!         return grade_object::fetch_helper('grade_outcomes', 'grade_outcome', $params);
      }
  
      /**
--- 148,155 ----
       * @return object grade_outcome instance or false if none found.
       */
      function fetch($params) {
!         $obj = grade_object::get_instance('grade_outcome');
!         return $obj->fetch_helper('grade_outcomes', 'grade_outcome', $params);
      }
  
      /**
***************
*** 159,165 ****
       * @return array array of grade_outcome insatnces or false if none found.
       */
      function fetch_all($params) {
!         return grade_object::fetch_all_helper('grade_outcomes', 'grade_outcome', $params);
      }
  
      /**
--- 160,167 ----
       * @return array array of grade_outcome insatnces or false if none found.
       */
      function fetch_all($params) {
!         $obj = grade_object::get_instance('grade_outcome');
!         return $obj->fetch_all_helper('grade_outcomes', 'grade_outcome', $params);
      }
  
      /**
***************
*** 168,174 ****
       */
      function load_scale() {
          if (empty($this->scale->id) or $this->scale->id != $this->scaleid) {
!             $this->scale = grade_scale::fetch(array('id'=>$this->scaleid));
              $this->scale->load_items();
          }
          return $this->scale;
--- 170,177 ----
       */
      function load_scale() {
          if (empty($this->scale->id) or $this->scale->id != $this->scaleid) {
!             $grade_scale = grade_object::get_instance('grade_scale');
!             $this->scale = $grade_scale->fetch(array('id'=>$this->scaleid));
              $this->scale->load_items();
          }
          return $this->scale;
***************
*** 180,186 ****
       * @return object
       */
      function fetch_all_global() {
!         if (!$outcomes = grade_outcome::fetch_all(array('courseid'=>null))) {
              $outcomes = array();
          }
          return $outcomes;
--- 183,190 ----
       * @return object
       */
      function fetch_all_global() {
!         $obj = grade_object::get_instance('grade_outcome');
!         if (!$outcomes = $obj->fetch_all(array('courseid'=>null))) {
              $outcomes = array();
          }
          return $outcomes;
***************
*** 193,199 ****
       * @return object
       */
      function fetch_all_local($courseid) {
!         if (!$outcomes =grade_outcome::fetch_all(array('courseid'=>$courseid))) {
              $outcomes = array();
          }
          return $outcomes;
--- 197,204 ----
       * @return object
       */
      function fetch_all_local($courseid) {
!         $obj = grade_object::get_instance('grade_outcome');
!         if (!$outcomes =$obj->fetch_all(array('courseid'=>$courseid))) {
              $outcomes = array();
          }
          return $outcomes;
***************
*** 208,213 ****
--- 213,220 ----
      function fetch_all_available($courseid) {
          global $CFG;
  
+         $obj = grade_object::get_instance('grade_outcome');
+ 
          $result = array();
          $sql = "SELECT go.*
                    FROM {$CFG->prefix}grade_outcomes go, {$CFG->prefix}grade_outcomes_courses goc
***************
*** 216,223 ****
  
          if ($datas = get_records_sql($sql)) {
              foreach($datas as $data) {
!                 $instance = new grade_outcome();
!                 grade_object::set_properties($instance, $data);
                  $result[$instance->id] = $instance;
              }
          }
--- 223,230 ----
  
          if ($datas = get_records_sql($sql)) {
              foreach($datas as $data) {
!                 $instance = grade_object::get_instance('grade_outcome');
!                 $obj->set_properties($instance, $data);
                  $result[$instance->id] = $instance;
              }
          }
***************
*** 269,275 ****
              return 1;
          }
  
!         return count_records('grade_outcomes_courses', 'outcomeid', $this->id);
      }
  
      /**
--- 276,282 ----
              return 1;
          }
  
!         return $this->lib_wrapper->count_records('grade_outcomes_courses', 'outcomeid', $this->id);
      }
  
      /**
***************
*** 277,283 ****
       * @return int
       */
      function get_item_uses_count() {
!         return count_records('grade_items', 'outcomeid', $this->id);
      }
  
      /**
--- 284,290 ----
       * @return int
       */
      function get_item_uses_count() {
!         return $this->lib_wrapper->count_records('grade_items', 'outcomeid', $this->id);
      }
  
      /**
***************
*** 301,307 ****
          }
  
          if ($average === false && $items === false) {
!             debugging('Either the 1st or 2nd param of grade_outcome::get_grade_info() must be true, or both, but not both false!');
              return false;
          }
  
--- 308,314 ----
          }
  
          if ($average === false && $items === false) {
!             debugging('Either the 1st or 2nd param of $this->get_grade_info() must be true, or both, but not both false!');
              return false;
          }
  
***************
*** 322,328 ****
                     AND {$CFG->prefix}grade_outcomes.id = $this->id
                     $wheresql";
  
!         $grades = get_records_sql($sql);
          $retval = array();
  
          if ($average !== false && count($grades) > 0) {
--- 329,335 ----
                     AND {$CFG->prefix}grade_outcomes.id = $this->id
                     $wheresql";
  
!         $grades = $this->lib_wrapper->get_records_sql($sql);
          $retval = array();
  
          if ($average !== false && count($grades) > 0) {
***************
*** 343,349 ****
  
          if ($items !== false) {
              foreach ($grades as $grade) {
!                 $retval['items'][$grade->id] = new grade_item($grade);
              }
          }
  
--- 350,356 ----
  
          if ($items !== false) {
              foreach ($grades as $grade) {
!                 $retval['items'][$grade->id] = $this->get_instance('grade_item', $grade);
              }
          }
  
*** D:/VertrigoServ/www/moode_up/lib/grade/grade_scale.php	Thu Nov 22 07:06:43 2007
--- D:/VertrigoServ/www/moode_up/lib/grade/grade_scale_new.php	Thu Nov 22 07:06:47 2007
***************
*** 82,88 ****
       * @return object grade_scale instance or false if none found.
       */
      function fetch($params) {
!         return grade_object::fetch_helper('scale', 'grade_scale', $params);
      }
  
      /**
--- 82,89 ----
       * @return object grade_scale instance or false if none found.
       */
      function fetch($params) {
!         $obj = grade_object::get_instance('grade_scale');
!         return $obj->fetch_helper('scale', 'grade_scale', $params);
      }
  
      /**
***************
*** 93,99 ****
       * @return array array of grade_scale insatnces or false if none found.
       */
      function fetch_all($params) {
!         return grade_object::fetch_all_helper('scale', 'grade_scale', $params);
      }
  
      /**
--- 94,101 ----
       * @return array array of grade_scale insatnces or false if none found.
       */
      function fetch_all($params) {
!         $obj = grade_object::get_instance('grade_scale');
!         return $obj->fetch_all_helper('scale', 'grade_scale', $params);
      }
  
      /**
***************
*** 190,196 ****
       */
      function get_nearest_item($grade) {
          // Obtain nearest scale item from average
!         $scales_array = get_records_list('scale', 'id', $this->id);
          $scale = $scales_array[$this->id];
          $scales = explode(",", $scale->scale);
  
--- 192,198 ----
       */
      function get_nearest_item($grade) {
          // Obtain nearest scale item from average
!         $scales_array = $this->lib_wrapper->get_records_list('scale', 'id', $this->id);
          $scale = $scales_array[$this->id];
          $scales = explode(",", $scale->scale);
  
***************
*** 207,213 ****
       * @return object
       */
      function fetch_all_global() {
!         return grade_scale::fetch_all(array('courseid'=>0));
      }
  
      /**
--- 209,216 ----
       * @return object
       */
      function fetch_all_global() {
!         $obj = grade_object::get_instance('grade_scale');
!         return $obj->fetch_all(array('courseid'=>0));
      }
  
      /**
***************
*** 215,221 ****
       * @return object
       */
      function fetch_all_local($courseid) {
!         return grade_scale::fetch_all(array('courseid'=>$courseid));
      }
  
      /**
--- 218,225 ----
       * @return object
       */
      function fetch_all_local($courseid) {
!         $obj = grade_object::get_instance('grade_scale');
!         return $obj->fetch_all(array('courseid'=>$courseid));
      }
  
      /**
***************
*** 235,252 ****
  
          // count grade items excluding the
          $sql = "SELECT COUNT(id) FROM {$CFG->prefix}grade_items WHERE scaleid = {$this->id} AND outcomeid IS NULL";
!         if (count_records_sql($sql)) {
              return true;
          }
  
          // count outcomes
          $sql = "SELECT COUNT(id) FROM {$CFG->prefix}grade_outcomes WHERE scaleid = {$this->id}";
!         if (count_records_sql($sql)) {
              return true;
          }
  
          $legacy_mods = false;
!         if ($mods = get_records('modules', 'visible', 1)) {
              foreach ($mods as $mod) {
                  //Check cm->name/lib.php exists
                  if (file_exists($CFG->dirroot.'/mod/'.$mod->name.'/lib.php')) {
--- 239,256 ----
  
          // count grade items excluding the
          $sql = "SELECT COUNT(id) FROM {$CFG->prefix}grade_items WHERE scaleid = {$this->id} AND outcomeid IS NULL";
!         if ($this->lib_wrapper->count_records_sql($sql)) {
              return true;
          }
  
          // count outcomes
          $sql = "SELECT COUNT(id) FROM {$CFG->prefix}grade_outcomes WHERE scaleid = {$this->id}";
!         if ($this->lib_wrapper->count_records_sql($sql)) {
              return true;
          }
  
          $legacy_mods = false;
!         if ($mods = $this->lib_wrapper->get_records('modules', 'visible', 1)) {
              foreach ($mods as $mod) {
                  //Check cm->name/lib.php exists
                  if (file_exists($CFG->dirroot.'/mod/'.$mod->name.'/lib.php')) {
***************
*** 270,281 ****
          // some mods are missing the new xxx_scale_used_anywhere() - use the really slow old way
          if ($legacy_mods) {
              if (!empty($this->courseid)) {
!                 if (course_scale_used($this->courseid,$this->id)) {
                      return true;
                  }
              } else {
                  $courses = array();
!                 if (site_scale_used($this->id,$courses)) {
                      return true;
                  }
              }
--- 274,285 ----
          // some mods are missing the new xxx_scale_used_anywhere() - use the really slow old way
          if ($legacy_mods) {
              if (!empty($this->courseid)) {
!                 if ($this->lib_wrapper->course_scale_used($this->courseid,$this->id)) {
                      return true;
                  }
              } else {
                  $courses = array();
!                 if ($this->lib_wrapper->site_scale_used($this->id,$courses)) {
                      return true;
                  }
              }
*** D:/VertrigoServ/www/moode_up/lib/grade/lib_wrapper.php	Thu Nov 22 07:09:12 2007
--- D:/VertrigoServ/www/moode_up/lib/grade/lib_wrapper_new.php	Thu Nov 22 07:09:23 2007
***************
*** 1 ****
--- 1,124 ----
+ <?php // $Id: grade_item.php,v 1.142 2007/11/01 08:25:10 skodak Exp $
  
+ ///////////////////////////////////////////////////////////////////////////
+ //                                                                       //
+ // NOTICE OF COPYRIGHT                                                   //
+ //                                                                       //
+ // Moodle - Modular Object-Oriented Dynamic Learning Environment         //
+ //          http://moodle.com                                            //
+ //                                                                       //
+ // Copyright (C) 1999 onwards Martin Dougiamas  http://dougiamas.com     //
+ //                                                                       //
+ // This program is free software; you can redistribute it and/or modify  //
+ // it under the terms of the GNU General Public License as published by  //
+ // the Free Software Foundation; either version 2 of the License, or     //
+ // (at your option) any later version.                                   //
+ //                                                                       //
+ // This program is distributed in the hope that it will be useful,       //
+ // but WITHOUT ANY WARRANTY; without even the implied warranty of        //
+ // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         //
+ // GNU General Public License for more details:                          //
+ //                                                                       //
+ //          http://www.gnu.org/copyleft/gpl.html                         //
+ //                                                                       //
+ ///////////////////////////////////////////////////////////////////////////
+ 
+ class grade_lib_wrapper {
+     function get_records_sql($sql, $limitfrom='', $limitnum='') {
+         return get_records_sql($sql, $limitfrom, $limitnum);
+     }
+     
+     function get_records_select($table, $select='', $sort='', $fields='*', $limitfrom='', $limitnum='') {
+         return get_records_select($table, $select, $sort, $fields, $limitfrom, $limitnum);
+     }
+ 
+     function get_recordset($table, $field='', $value='', $sort='', $fields='*', $limitfrom='', $limitnum='') {
+         return get_recordset($table, $field, $value, $sort, $fields, $limitfrom, $limitnum); 
+     }
+ 
+     function get_recordset_select($table, $select='', $sort='', $fields='*', $limitfrom='', $limitnum='') {
+         return get_recordset_select($table, $select, $sort, $fields, $limitfrom, $limitnum);
+     }
+ 
+     function get_recordset_sql($sql, $limitfrom=null, $limitnum=null) {
+         return get_recordset_sql($sql, $limitfrom, $limitnum);
+     }
+     
+     function get_record($table, $field1, $value1, $field2='', $value2='', $field3='', $value3='', $fields='*') {
+         return get_record($table, $field1, $value1, $field2, $value2, $field3, $value3, $fields);
+     }
+ 
+     function get_records($table, $field='', $value='', $sort='', $fields='*', $limitfrom='', $limitnum='') {
+         return get_records($table, $field, $value, $sort, $fields, $limitfrom, $limitnum);
+     }
+ 
+     function get_records_list($table, $field='', $values='', $sort='', $fields='*', $limitfrom='', $limitnum='') {
+         return get_records_list($table, $field, $values, $sort, $fields, $limitfrom, $limitnum);
+     }
+ 
+     function get_field($table, $return, $field1, $value1, $field2='', $value2='', $field3='', $value3='') {
+         return get_field($table, $return, $field1, $value1, $field2, $value2, $field3, $value3);
+     }
+ 
+     function get_field_sql($sql) {
+         return get_field_sql($sql);
+     }
+ 
+     function get_field_select($table, $return, $select) {
+         return get_field_select($table, $return, $select);
+     }
+ 
+     function set_field($table, $newfield, $newvalue, $field1, $value1, $field2='', $value2='', $field3='', $value3='') {
+         return set_field($table, $newfield, $newvalue, $field1, $value1, $field2, $value2, $field3, $value3);
+     }
+ 
+     function set_field_select($table, $newfield, $newvalue, $select, $localcall = false) {
+         return set_field_select($table, $newfield, $newvalue, $select, $localcall);
+     }
+ 
+     function rs_fetch_next_record(&$rs) {
+         return rs_fetch_next_record($rs);
+     }
+ 
+     function execute_sql($command, $feedback=true) {
+         return execute_sql($command, $feedback);
+     }
+     
+     function update_record($table, $dataobject) {
+         return update_record($table, $dataobject);
+     }
+     
+     function insert_record($table, $dataobject, $returnid=true, $primarykey='id') {
+         return insert_record($table, $dataobject, $returnid, $primarykey);
+     }
+     
+     function delete_records($table, $field1='', $value1='', $field2='', $value2='', $field3='', $value3='') {
+         return delete_records($table, $field1, $value1, $field2, $value2, $field3, $value3);
+     }
+     
+     function count_records($table, $field1='', $value1='', $field2='', $value2='', $field3='', $value3='') {
+         return count_records($table, $field1, $value1, $field2, $value2, $field3, $value3);
+     }
+     
+     function count_records_sql($sql) {
+         return count_records_sql($sql);
+     }
+ 
+     function rs_close(&$rs) {
+         return;
+     }
+     
+     function get_coursemodule_from_instance($modulename, $instance, $courseid=0) {
+         return get_coursemodule_from_instance($modulename, $instance, $courseid);
+     }
+ 
+     function course_scale_used($courseid, $scaleid) {
+         return course_scale_used($courseid, $scaleid);
+     }
+     
+     function site_scale_used($scaleid,&$courses) {
+         return site_scale_used($scaleid, $courses);
+     }
+ }
+ 
+ ?>
*** D:/VertrigoServ/www/moode_up/lib/grade/simpletest/testgradecategory.php	Thu Nov 22 07:10:31 2007
--- D:/VertrigoServ/www/moode_up/lib/grade/simpletest/testgradecategory_new.php	Thu Nov 22 07:10:34 2007
***************
*** 1,4 ****
! <?php // $Id: testgradecategory.php,v 1.16 2007/11/22 05:42:47 nicolasconnault Exp $
  
  ///////////////////////////////////////////////////////////////////////////
  //                                                                       //
--- 1,4 ----
! <?php // $Id: testgradecategory.php,v 1.15 2007/11/15 06:44:27 nicolasconnault Exp $
  
  ///////////////////////////////////////////////////////////////////////////
  //                                                                       //
***************
*** 26,32 ****
  /**
   * Unit tests for grade_category object.
   *
!  * @author nicolas@moodle.com
   * @license http://www.gnu.org/copyleft/gpl.html GNU Public License
   * @package moodlecore
   */
--- 26,32 ----
  /**
   * Unit tests for grade_category object.
   *
!  * @author nicolasconnault@gmail.com
   * @license http://www.gnu.org/copyleft/gpl.html GNU Public License
   * @package moodlecore
   */
***************
*** 39,143 ****
  
  class grade_category_test extends grade_test {
  
!     function test_grade_category_construct() {
!         $course_category = grade_category::fetch_course_category($this->courseid);
! 
!         $params = new stdClass();
! 
!         $params->courseid = $this->courseid;
!         $params->fullname = 'unittestcategory4';
! 
!         $grade_category = new grade_category($params, false);
!         $grade_category->insert();
! 
!         $this->assertEqual($params->courseid, $grade_category->courseid);
!         $this->assertEqual($params->fullname, $grade_category->fullname);
!         $this->assertEqual(2, $grade_category->depth);
!         $this->assertEqual("/$course_category->id/$grade_category->id/", $grade_category->path);
!         $parentpath = $grade_category->path;
! 
!         // Test a child category
!         $params->parent = $grade_category->id;
!         $params->fullname = 'unittestcategory5';
!         $grade_category = new grade_category($params, false);
!         $grade_category->insert();
! 
!         $this->assertEqual(3, $grade_category->depth);
!         $this->assertEqual($parentpath.$grade_category->id."/", $grade_category->path);
!         $parentpath = $grade_category->path;
! 
!         // Test a third depth category
!         $params->parent = $grade_category->id;
!         $params->fullname = 'unittestcategory6';
!         $grade_category = new grade_category($params, false);
!         $grade_category->insert();
!         $this->assertEqual(4, $grade_category->depth);
!         $this->assertEqual($parentpath.$grade_category->id."/", $grade_category->path);
      }
  
      function test_grade_category_build_path() {
!         $grade_category = new grade_category($this->grade_categories[1]);
          $this->assertTrue(method_exists($grade_category, 'build_path'));
!         $path = grade_category::build_path($grade_category);
          $this->assertEqual($grade_category->path, $path);
      }
  
!     function test_grade_category_fetch() {
!         $grade_category = new grade_category();
!         $this->assertTrue(method_exists($grade_category, 'fetch'));
! 
!         $grade_category = grade_category::fetch(array('id'=>$this->grade_categories[0]->id));
!         $this->assertEqual($this->grade_categories[0]->id, $grade_category->id);
!         $this->assertEqual($this->grade_categories[0]->fullname, $grade_category->fullname);
!     }
! 
!     function test_grade_category_fetch_all() {
!         $grade_category = new grade_category();
!         $this->assertTrue(method_exists($grade_category, 'fetch_all'));
  
!         $grade_categories = grade_category::fetch_all(array('courseid'=>$this->courseid));
!         $this->assertEqual(count($this->grade_categories), count($grade_categories)-1);
!     }
  
-     function test_grade_category_update() {
-         $grade_category = new grade_category($this->grade_categories[0]);
          $this->assertTrue(method_exists($grade_category, 'update'));
  
          $grade_category->fullname = 'Updated info for this unittest grade_category';
          $grade_category->path = null; // path must be recalculated if missing
          $grade_category->depth = null;
          $grade_category->aggregation = GRADE_AGGREGATE_MAX; // should force regrading
! 
!         $grade_item = $grade_category->get_grade_item();
          $this->assertEqual(0, $grade_item->needsupdate);
! 
          $this->assertTrue($grade_category->update());
! 
!         $fullname = get_field('grade_categories', 'fullname', 'id', $this->grade_categories[0]->id);
!         $this->assertEqual($grade_category->fullname, $fullname);
! 
!         $path = get_field('grade_categories', 'path', 'id', $this->grade_categories[0]->id);
!         $this->assertEqual($grade_category->path, $path);
! 
!         $depth = get_field('grade_categories', 'depth', 'id', $this->grade_categories[0]->id);
!         $this->assertEqual($grade_category->depth, $depth);
! 
!         $grade_item = $grade_category->get_grade_item();
!         $this->assertEqual(1, $grade_item->needsupdate);
      }
  
      function test_grade_category_delete() {
-         $grade_category = new grade_category($this->grade_categories[0]);
-         $this->assertTrue(method_exists($grade_category, 'delete'));
  
          $this->assertTrue($grade_category->delete());
-         $this->assertFalse(get_record('grade_categories', 'id', $grade_category->id));
      }
  
      function test_grade_category_insert() {
-         $course_category = grade_category::fetch_course_category($this->courseid);
  
!         $grade_category = new grade_category();
          $this->assertTrue(method_exists($grade_category, 'insert'));
  
          $grade_category->fullname    = 'unittestcategory4';
--- 39,162 ----
  
  class grade_category_test extends grade_test {
  
!     function setUp() {
!         parent::setUp();
!         $this->load_grade_items();        
      }
  
      function test_grade_category_build_path() {
!         $grade_category = new grade_category(array('parent' => 2, 'id' => 3, 'path' => '/1/2/3/'), false);
!         $grade_category->lib_wrapper = new mock_lib_wrapper();
          $this->assertTrue(method_exists($grade_category, 'build_path'));
!         
!         // Mock get_record of parent category (2) then (1)
!         $obj = grade_object::get_instance('grade_category');
!         $obj->lib_wrapper->expectCallCount('get_record', 2);
!         $parent2 = new stdClass();
!         $parent2->parent = 1;
!         $parent2->id = 2;
!         $obj->lib_wrapper->setReturnValueAt(0, 'get_record', $parent2);
!         $parent1 = new stdClass();
!         $parent1->parent = null;
!         $parent1->id = 1;
!         $obj->lib_wrapper->setReturnValueAt(1, 'get_record', $parent1);
!         $path = $grade_category->build_path($grade_category);
          $this->assertEqual($grade_category->path, $path);
      }
  
!     function test_grade_category_update() {
  
!         Mock::generatePartial('grade_category', 'partial_mock', array('load_grade_item',
!                                                                       'build_path', 
!                                                                       'apply_forced_settings', 
!                                                                       'qualifies_for_regrading',
!                                                                       'force_regrading'));
! 
!         $grade_category = &new partial_mock($this);
!         $grade_category->grade_category($this->grade_categories[1], false);
!         
!         // There is a static call to grade_category::build_path(): prepare the static instance 
!         $obj = grade_object::get_instance('grade_category');
!         $parent = new stdClass();
!         $parent->parent = null;
!         $parent->id = 1;
!         $obj->lib_wrapper->setReturnValue('get_record', $parent);
  
          $this->assertTrue(method_exists($grade_category, 'update'));
  
          $grade_category->fullname = 'Updated info for this unittest grade_category';
          $grade_category->path = null; // path must be recalculated if missing
          $grade_category->depth = null;
          $grade_category->aggregation = GRADE_AGGREGATE_MAX; // should force regrading
!         $grade_category->droplow = 1;
!         $grade_category->keephigh = 1;
!         $grade_category->lib_wrapper = new mock_lib_wrapper();
!         
!         $grade_category->lib_wrapper->expectOnce('update_record');
!         $grade_category->lib_wrapper->setReturnValue('update_record', true);
!         
!         $grade_item = new grade_item(array('id' => 99, 'itemtype' => 'course', 'courseid' => $this->courseid, 'needsupdate' => 0), false);
!         $grade_category->grade_item = $grade_item;
          $this->assertEqual(0, $grade_item->needsupdate);
!         
!         // Set method expectations
!         $grade_category->expectOnce('load_grade_item');
!         $grade_category->expectOnce('apply_forced_settings');
!         $grade_category->setReturnValue('qualifies_for_regrading', true);
!         $grade_category->expectOnce('force_regrading'); 
!         
          $this->assertTrue($grade_category->update());
!         
!         $this->assertEqual(0, $grade_category->keephigh);
!         $this->assertEqual(1, $grade_category->droplow);
!         $this->assertTrue($grade_category->timemodified > 0);
!         $this->assertTrue($grade_category->timemodified <= time());
      }
  
      function test_grade_category_delete() {
  
+         Mock::generatePartial('grade_category', 'mock_grade_category_for_delete', array('load_grade_item',
+                                                                                         'is_course_category', 
+                                                                                         'load_parent_category', 
+                                                                                         'force_regrading'));
+ 
+         $grade_category = &new mock_grade_category_for_delete($this);
+         $grade_category->lib_wrapper = new mock_lib_wrapper();
+         $grade_category->id = 1;
+         $grade_category->expectOnce('load_grade_item');
+         $grade_category->setReturnValue('is_course_category', false);
+         $grade_category->expectOnce('force_regrading');
+         $grade_category->expectOnce('load_parent_category');
+ 
+         $parent_category = new mock_grade_category();
+         $grade_category->lib_wrapper = new mock_lib_wrapper();
+         $parent_category->id = 1;
+         $grade_category->setReturnReference('load_parent_category', $parent_category);
+ 
+         $grade_item = new mock_grade_item();
+         $grade_item->id = 2;
+         $grade_category->setReturnReference('load_grade_item', $grade_item);
+         
+         $grade_category->lib_wrapper->expectOnce('delete_records', array('grade_categories', 'id', $grade_category->id));
+         $grade_category->lib_wrapper->setReturnValue('delete_records', true);
+         
+         $grade_category->lib_wrapper->expectOnce('insert_record'); // grade_history entry
+         
+         $this->assertTrue(method_exists($grade_category, 'delete'));
          $this->assertTrue($grade_category->delete());
      }
  
      function test_grade_category_insert() {
  
!         Mock::generatePartial('grade_category', 'mock_grade_category_for_insert', array('update',
!                                                                                         'apply_forced_settings',
!                                                                                         'force_regrading'));
! 
!         $course_category = $this->grade_categories[0];
! 
!         $grade_category = new mock_grade_category_for_insert($this);
!         $grade_category->lib_wrapper = new mock_lib_wrapper();
!         
          $this->assertTrue(method_exists($grade_category, 'insert'));
  
          $grade_category->fullname    = 'unittestcategory4';
***************
*** 147,427 ****
          $grade_category->keephigh    = 100;
          $grade_category->droplow     = 10;
          $grade_category->hidden      = 0;
!         $grade_category->parent      = $this->grade_categories[0]->id;
! 
!         $grade_category->insert();
  
!         $this->assertEqual('/'.$course_category->id.'/'.$this->grade_categories[0]->id.'/'.$grade_category->id.'/', $grade_category->path);
!         $this->assertEqual(3, $grade_category->depth);
  
!         $last_grade_category = end($this->grade_categories);
! 
!         $this->assertFalse(empty($grade_category->grade_item));
!         $this->assertEqual($grade_category->id, $grade_category->grade_item->iteminstance);
!         $this->assertEqual('category', $grade_category->grade_item->itemtype);
  
-         $this->assertEqual($grade_category->id, $last_grade_category->id + 1);
          $this->assertFalse(empty($grade_category->timecreated));
          $this->assertFalse(empty($grade_category->timemodified));
      }
  
      function test_grade_category_insert_course_category() {
!         $grade_category = new grade_category();
          $this->assertTrue(method_exists($grade_category, 'insert_course_category'));
  
          $id = $grade_category->insert_course_category($this->courseid);
          $this->assertNotNull($id);
!         $this->assertEqual('Course grade category', $grade_category->fullname);
!         $this->assertEqual(GRADE_AGGREGATE_MEAN, $grade_category->aggregate);
!         $this->assertEqual("/$id/", $grade_category->path);
!         $this->assertEqual(1, $grade_category->depth);
          $this->assertNull($grade_category->parent);
      }
  
      function test_grade_category_qualifies_for_regrading() {
!         $grade_category = new grade_category($this->grade_categories[0]);
          $this->assertTrue(method_exists($grade_category, 'qualifies_for_regrading'));
! 
          $this->assertFalse($grade_category->qualifies_for_regrading());
  
          $grade_category->aggregation = GRADE_AGGREGATE_MAX;
          $this->assertTrue($grade_category->qualifies_for_regrading());
  
-         $grade_category = new grade_category($this->grade_categories[0]);
          $grade_category->droplow = 99;
          $this->assertTrue($grade_category->qualifies_for_regrading());
  
-         $grade_category = new grade_category($this->grade_categories[0]);
          $grade_category->keephigh = 99;
          $this->assertTrue($grade_category->qualifies_for_regrading());
      }
  
!     function test_grade_category_force_regrading() {
!         $grade_category = new grade_category($this->grade_categories[1]);
!         $this->assertTrue(method_exists($grade_category, 'force_regrading'));
! 
!         $grade_category->load_grade_item();
!         $this->assertEqual(0, $grade_category->grade_item->needsupdate);
! 
!         $grade_category->force_regrading();
! 
!         $grade_category->grade_item = null;
!         $grade_category->load_grade_item();
  
!         $this->assertEqual(1, $grade_category->grade_item->needsupdate);
!     }
  
!     function test_grade_category_generate_grades() {
!         $category = new grade_category($this->grade_categories[3]);
!         $this->assertTrue(method_exists($category, 'generate_grades'));
!         $category->load_grade_item();
! 
!         $grades = get_records('grade_grades', 'itemid', $category->grade_item->id);
!         $this->assertFalse($grades);
! 
!         $category->generate_grades();
!         $grades = get_records('grade_grades', 'itemid', $category->grade_item->id);
!         $this->assertEqual(3, count($grades));
! 
!         $rawvalues = array();
!         foreach ($grades as $grade) {
!             $this->assertWithinMargin($grade->rawgrade, $grade->rawgrademin, $grade->rawgrademax);
!             $rawvalues[] = (int)$grade->rawgrade;
!         }
!         sort($rawvalues);
!         // calculated mean results
!         $this->assertEqual($rawvalues, array(20,50,100));
      }
  
      function test_grade_category_aggregate_grades() {
!         $category = new grade_category($this->grade_categories[0]);
!         $this->assertTrue(method_exists($category, 'aggregate_grades'));
!         // tested above in test_grade_category_generate_grades()
      }
  
      function test_grade_category_apply_limit_rules() {
!         $category = new grade_category();
          $grades = array(5.374, 9.4743, 2.5474, 7.3754);
  
!         $category->droplow = 2;
!         $category->apply_limit_rules($grades);
          sort($grades, SORT_NUMERIC);
          $this->assertEqual(array(7.3754, 9.4743), $grades);
  
!         $category = new grade_category();
          $grades = array(5.374, 9.4743, 2.5474, 7.3754);
  
!         $category->keephigh = 1;
!         $category->droplow = 0;
!         $category->apply_limit_rules($grades);
          $this->assertEqual(count($grades), 1);
          $grade = reset($grades);
          $this->assertEqual(9.4743, $grade);
      }
  
-     /**
-      * TODO implement
-      */
      function test_grade_category_is_aggregationcoef_used() {
  
      }
  
      function test_grade_category_fetch_course_tree() {
!         $category = new grade_category();
!         $this->assertTrue(method_exists($category, 'fetch_course_tree'));
          //TODO: add some tests
      }
  
      function test_grade_category_get_children() {
!         $course_category = grade_category::fetch_course_category($this->courseid);
! 
!         $category = new grade_category($this->grade_categories[0]);
!         $this->assertTrue(method_exists($category, 'get_children'));
  
!         $children_array = $category->get_children(0);
  
          $this->assertTrue(is_array($children_array));
!         $this->assertFalse(empty($children_array[2]));
!         $this->assertFalse(empty($children_array[2]['object']));
!         $this->assertFalse(empty($children_array[2]['children']));
!         $this->assertEqual($this->grade_categories[1]->id, $children_array[2]['object']->id);
!         $this->assertEqual($this->grade_categories[2]->id, $children_array[5]['object']->id);
!         $this->assertEqual($this->grade_items[0]->id, $children_array[2]['children'][3]['object']->id);
!         $this->assertEqual($this->grade_items[1]->id, $children_array[2]['children'][4]['object']->id);
!         $this->assertEqual($this->grade_items[2]->id, $children_array[5]['children'][6]['object']->id);
!     }
! 
!     function test_grade_category_load_grade_item() {
!         $category = new grade_category($this->grade_categories[0]);
!         $this->assertTrue(method_exists($category, 'load_grade_item'));
!         $this->assertEqual(null, $category->grade_item);
!         $category->load_grade_item();
!         $this->assertEqual($this->grade_items[3]->id, $category->grade_item->id);
!     }
! 
!     function test_grade_category_get_grade_item() {
!         $category = new grade_category($this->grade_categories[0]);
!         $this->assertTrue(method_exists($category, 'get_grade_item'));
!         $grade_item = $category->get_grade_item();
!         $this->assertEqual($this->grade_items[3]->id, $grade_item->id);
      }
  
      function test_grade_category_load_parent_category() {
!         $category = new grade_category($this->grade_categories[1]);
!         $this->assertTrue(method_exists($category, 'load_parent_category'));
!         $this->assertEqual(null, $category->parent_category);
!         $category->load_parent_category();
!         $this->assertEqual($this->grade_categories[0]->id, $category->parent_category->id);
!     }
  
!     function test_grade_category_get_parent_category() {
!         $category = new grade_category($this->grade_categories[1]);
!         $this->assertTrue(method_exists($category, 'get_parent_category'));
!         $parent_category = $category->get_parent_category();
!         $this->assertEqual($this->grade_categories[0]->id, $parent_category->id);
      }
  
      function test_grade_category_get_name() {
!         $category = new grade_category($this->grade_categories[0]);
!         $this->assertTrue(method_exists($category, 'get_name'));
!         $this->assertEqual($this->grade_categories[0]->fullname, $category->get_name());
!     }
! 
!     function test_grade_category_set_parent() {
!         $category = new grade_category($this->grade_categories[1]);
!         $this->assertTrue(method_exists($category, 'set_parent'));
!         // TODO: implement detailed tests
! 
!         $course_category = grade_category::fetch_course_category($this->courseid);
!         $this->assertTrue($category->set_parent($course_category->id));
!         $this->assertEqual($course_category->id, $category->parent);
!     }
! 
!     function test_grade_category_get_final() {
!         $category = new grade_category($this->grade_categories[0]);
!         $this->assertTrue(method_exists($category, 'get_final'));
!         $category->load_grade_item();
!         $this->assertEqual($category->get_final(), $category->grade_item->get_final());
!     }
! 
!     function test_grade_category_get_sortorder() {
!         $category = new grade_category($this->grade_categories[0]);
!         $this->assertTrue(method_exists($category, 'get_sortorder'));
!         $category->load_grade_item();
!         $this->assertEqual($category->get_sortorder(), $category->grade_item->get_sortorder());
!     }
! 
!     function test_grade_category_set_sortorder() {
!         $category = new grade_category($this->grade_categories[0]);
!         $this->assertTrue(method_exists($category, 'set_sortorder'));
!         $category->load_grade_item();
!         $this->assertEqual($category->set_sortorder(10), $category->grade_item->set_sortorder(10));
!     }
  
-     function test_grade_category_move_after_sortorder() {
-         $category = new grade_category($this->grade_categories[0]);
-         $this->assertTrue(method_exists($category, 'move_after_sortorder'));
-         $category->load_grade_item();
-         $this->assertEqual($category->move_after_sortorder(10), $category->grade_item->move_after_sortorder(10));
      }
  
!     function test_grade_category_is_course_category() {
!         $category = grade_category::fetch_course_category($this->courseid);
!         $this->assertTrue(method_exists($category, 'is_course_category'));
!         $this->assertTrue($category->is_course_category());
      }
  
      function test_grade_category_fetch_course_category() {
!         $category = new grade_category();
!         $this->assertTrue(method_exists($category, 'fetch_course_category'));
!         $category = grade_category::fetch_course_category($this->courseid);
!         $this->assertTrue(empty($category->parent));
!     }
!     /**
!      * TODO implement
!      */
!     function test_grade_category_is_editable() {
! 
!     }
! 
!     function test_grade_category_is_locked() {
!         $category = new grade_category($this->grade_categories[0]);
!         $this->assertTrue(method_exists($category, 'is_locked'));
!         $category->load_grade_item();
!         $this->assertEqual($category->is_locked(), $category->grade_item->is_locked());
      }
  
      function test_grade_category_set_locked() {
!         $category = new grade_category($this->grade_categories[0]);
!         $this->assertTrue(method_exists($category, 'set_locked'));
!         $this->assertTrue($category->set_locked(1));
!     }
  
!     function test_grade_category_is_hidden() {
!         $category = new grade_category($this->grade_categories[0]);
!         $this->assertTrue(method_exists($category, 'is_hidden'));
!         $category->load_grade_item();
!         $this->assertEqual($category->is_hidden(), $category->grade_item->is_hidden());
      }
  
      function test_grade_category_set_hidden() {
!         $category = new grade_category($this->grade_categories[0]);
!         $this->assertTrue(method_exists($category, 'set_hidden'));
!         $category->set_hidden(1);
!         $category->load_grade_item();
!         $this->assertEqual(true, $category->grade_item->is_hidden());
!     }
! 
!     function generate_random_raw_grade($item, $userid) {
!         $grade = new grade_grade();
!         $grade->itemid = $item->id;
!         $grade->userid = $userid;
!         $grade->grademin = 0;
!         $grade->grademax = 1;
!         $valuetype = "grade$item->gradetype";
!         $grade->rawgrade = rand(0, 1000) / 1000;
!         $grade->insert();
!         return $grade->rawgrade;
!     }
  }
  ?>
--- 166,603 ----
          $grade_category->keephigh    = 100;
          $grade_category->droplow     = 10;
          $grade_category->hidden      = 0;
!         $grade_category->parent      = $this->grade_categories[1]->id;
  
!         $grade_category->lib_wrapper->expectCallCount('insert_record', 2); // main insert and history table insert 
!         $grade_category->lib_wrapper->setReturnValue('insert_record', 4);
!         $grade_category->lib_wrapper->expectOnce('get_record'); // for update_from_db() method
!         $grade_category->lib_wrapper->setReturnValue('get_record', array(1));
  
!         $grade_category->insert();
!         
!         // Don't test path and depth, they're the job of the update method 
!         $this->assertEqual($grade_category->id, 4);
  
          $this->assertFalse(empty($grade_category->timecreated));
          $this->assertFalse(empty($grade_category->timemodified));
      }
  
      function test_grade_category_insert_course_category() {
!         $grade_category = new mock_grade_category_for_insert($this);
!         $grade_category->lib_wrapper = new mock_lib_wrapper();
          $this->assertTrue(method_exists($grade_category, 'insert_course_category'));
+         $grade_category->expectOnce('apply_forced_settings');
+         $grade_category->expectOnce('update', array('system'));
  
+         $grade_category->lib_wrapper->expectCallCount('insert_record', 2); // main insert and history table insert 
+         $grade_category->lib_wrapper->setReturnValue('insert_record', 1);
+         $grade_category->lib_wrapper->expectOnce('get_record'); // for update_from_db() method
+         $grade_category->lib_wrapper->setReturnValue('get_record', array(1));
+         
          $id = $grade_category->insert_course_category($this->courseid);
+         
          $this->assertNotNull($id);
!         $this->assertEqual(get_string('coursegradecategory', 'grades'), $grade_category->fullname);
!         $this->assertEqual(GRADE_AGGREGATE_MEAN, $grade_category->aggregation);
          $this->assertNull($grade_category->parent);
+         $this->assertFalse(empty($grade_category->timecreated));
+         $this->assertFalse(empty($grade_category->timemodified));
      }
  
      function test_grade_category_qualifies_for_regrading() {
!         $grade_category = new grade_category($this->grade_categories[0], false);
          $this->assertTrue(method_exists($grade_category, 'qualifies_for_regrading'));
!         
!         $obj = grade_object::get_instance('grade_category');
!         $obj->expectCallCount('fetch', 4, array(array('id' => $grade_category->id)));
!         $obj->setReturnValue('fetch', fullclone($grade_category));
!         $grade_item = new stdClass();
!         $grade_item->lib_wrapper = new mock_lib_wrapper();
!         $grade_item->aggregation = GRADE_AGGREGATE_MEAN;
!         
          $this->assertFalse($grade_category->qualifies_for_regrading());
  
          $grade_category->aggregation = GRADE_AGGREGATE_MAX;
          $this->assertTrue($grade_category->qualifies_for_regrading());
  
          $grade_category->droplow = 99;
          $this->assertTrue($grade_category->qualifies_for_regrading());
  
          $grade_category->keephigh = 99;
          $this->assertTrue($grade_category->qualifies_for_regrading());
      }
  
!     function test_grade_category_generate_grades() {
  
!         Mock::generatePartial('grade_category', 'mock_grade_category_for_generate_grades', array('load_grade_item',
!                                                                                                  'aggregate_grades'));
  
!         // No generating should occur if the item is locked, but the method still returns true
!         $grade_category = new mock_grade_category_for_generate_grades($this);
!         $grade_category->lib_wrapper = new mock_lib_wrapper();
!         $grade_item = new mock_grade_item();
!         $grade_item->setReturnValue('is_locked', true); 
!         $grade_category->grade_item = $grade_item;
!         $this->assertTrue(method_exists($grade_category, 'generate_grades'));
!         $grade_category->expectNever('aggregate_grades');
!         $this->assertTrue($grade_category->generate_grades());
!         
!         // We can't verify DB records, so let's check method calls
!         $grade_category = new mock_grade_category_for_generate_grades($this);
!         $grade_category->lib_wrapper = new mock_lib_wrapper();
!         $grade_item = new mock_grade_item();
!         $grade_item->id = 1;
!         $grade_category->grade_item = $grade_item;
!         $grade_item->setReturnValue('is_locked', false);
!         $grade_item->setReturnValue('depends_on', array(1, 2, 3)); 
!         $grade_category->lib_wrapper->expectOnce('get_records_sql');
!         $grade_category->lib_wrapper->setReturnValue('get_records_sql', array($this->grade_items[2], $this->grade_items[3], $this->grade_items[4]));
!         $grade_category->lib_wrapper->expectOnce('get_recordset_sql');
!         $grade_category->lib_wrapper->setReturnValue('get_recordset_sql', 1);
!         $grade_category->lib_wrapper->expectCallCount('rs_fetch_next_record', 4);
! 
!         $record = new stdClass();
!         $record->userid = 1;
!         $record->itemid = 1;
!         $record->finalgrade = 20; 
!         $record->excluded = false;
!         $grade_category->lib_wrapper->setReturnValueAt(0, 'rs_fetch_next_record', $record);
!         $record2 = new stdClass();
!         $record2->userid = 2;
!         $record2->itemid = 2;
!         $record2->finalgrade = 20; 
!         $record2->excluded = false;
!         $grade_category->lib_wrapper->setReturnValueAt(1, 'rs_fetch_next_record', $record2);
!         $record3 = new stdClass();
!         $record3->userid = 3;
!         $record3->itemid = 3;
!         $record3->finalgrade = 20; 
!         $record3->excluded = false;
!         $grade_category->lib_wrapper->setReturnValueAt(2, 'rs_fetch_next_record', $record3);
!         $this->assertTrue($grade_category->generate_grades()); 
      }
  
      function test_grade_category_aggregate_grades() {
!         Mock::generatePartial('grade_category', 'mock_grade_category_for_aggregate_grades', array('aggregate_values', 'apply_limit_rules'));
!         // Setup method arguments (no optionals!)
!         $arg_userid = null;
!         $arg_items = array();
!         $arg_grade_values = array(1 => 20); // should get unset early on in the method
!         $arg_oldgrade = new stdClass();
!         $arg_oldgrade->finalgrade = null; // These two are set to null to avoid a grade_grade->update() in the aggregate_grades() method
!         $arg_oldgrade->rawgrade = null;
!         $arg_oldgrade->itemid = 1;
!         $arg_oldgrade->rawgrademin = 0;
!         $arg_oldgrade->rawgrademax = 100;
!         $arg_oldgrade->rawscaleid = null;
!         $arg_excluded = false;
!     
!         // Set up rest of objects
!         $grade_category = new mock_grade_category_for_aggregate_grades($this);
!         $grade_category->lib_wrapper = new mock_lib_wrapper();
!         $grade_item = new mock_grade_item();
!         $grade_item->id = 1;
!         $grade_item->gradetype = GRADE_TYPE_VALUE;
!         $this->assertTrue(method_exists($grade_category, 'aggregate_grades'));
! 
!         // If no userid given, should return null;
!         $grade_category->expectNever('aggregate_values');
!         $grade_category->expectNever('apply_limit_rules');
!         $this->assertNull($grade_category->aggregate_grades($arg_userid, $arg_items, $arg_grade_values, $arg_oldgrade, $arg_excluded));
!         // Return without doing anything if the grade or grade_item is locked (we have control over the grade_item here because
!         // the grade_grade->grade_item is the same as the grade_category->grade_item
!         $arg_userid = 1;
!         $grade_item->setReturnValueAt(0, 'is_locked', true);
!         $grade_category->grade_item = $grade_item;
!         $this->assertNull($grade_category->aggregate_grades($arg_userid, $arg_items, $arg_grade_values, $arg_oldgrade, $arg_excluded));
! 
!         // Proceed further by setting grade_item->is_locked to false. Still return null because no other grade_values than main item's 
!         $grade_item->setReturnValueAt(1, 'is_locked', false);
!         $this->assertNull($grade_category->aggregate_grades($arg_userid, $arg_items, $arg_grade_values, $arg_oldgrade, $arg_excluded));
!         
!         // Going further now with a proper array of gradevalues and items. Also provide an excluded itemid
!         $gi = new mock_grade_item();
!         $gi->grademin = 0;
!         $gi->grademax = 100;
!         $arg_items = array(1 => $grade_item, 2 => fullclone($gi), 3 => fullclone($gi), 4 => fullclone($gi), 5 => fullclone($gi));
!         $arg_grade_values = array(1 => 20, 2 => null, 3 => 8, 4 => 67, 5 => 53);
!         $arg_excluded = array(3);
!         $grade_category = new mock_grade_category_for_aggregate_grades($this);
!         $grade_item->grademin = 0;
!         $grade_item->grademax = 100;
!         $grade_item->scaleid = null;
!         $grade_category->grade_item = $grade_item;
!         $grade_category->expectOnce('apply_limit_rules');
!         $grade_category->expectOnce('aggregate_values');
!         $grade_category->aggregateonlygraded = true;
!         $this->assertNull($grade_category->aggregate_grades($arg_userid, $arg_items, $arg_grade_values, $arg_oldgrade, $arg_excluded));
      }
  
      function test_grade_category_apply_limit_rules() {
!         $grade_category = new grade_category();
          $grades = array(5.374, 9.4743, 2.5474, 7.3754);
  
!         $grade_category->droplow = 2;
!         $grade_category->apply_limit_rules($grades);
          sort($grades, SORT_NUMERIC);
          $this->assertEqual(array(7.3754, 9.4743), $grades);
  
!         $grade_category = new grade_category();
          $grades = array(5.374, 9.4743, 2.5474, 7.3754);
  
!         $grade_category->keephigh = 1;
!         $grade_category->droplow = 0;
!         $grade_category->apply_limit_rules($grades);
          $this->assertEqual(count($grades), 1);
          $grade = reset($grades);
          $this->assertEqual(9.4743, $grade);
      }
  
      function test_grade_category_is_aggregationcoef_used() {
  
      }
  
      function test_grade_category_fetch_course_tree() {
!         $grade_category = new grade_category();
!         $this->assertTrue(method_exists($grade_category, 'fetch_course_tree'));
          //TODO: add some tests
      }
  
      function test_grade_category_get_children() {
!         $grade_category = new grade_category();
!         $grade_category->id = 1;
!         $grade_category->lib_wrapper = new mock_lib_wrapper();
  
!         // Setup course cats and items: 
!         // 1 course
!         // |_ 2 category
!         // | |_ 3 item
!         // | |_ 4 item
!         // |_ 5 category
!         // | |_ 6 item
!         // | |_ 7 item
! 
!         $cats = array();
!         $cat = new stdClass();
!         $cat->id = 1;
!         $cat->parent = null;
!         $cat->sortorder = 1;
!         $cat->depth = 0;
!         $cats[1] = fullclone($cat);
!         $cat->id = 3;
!         $cat->parent = 1;
!         $cat->sortorder = 2;
!         $cat->depth = 1;
!         $cats[3] = fullclone($cat);
!         $cat->id = 4;
!         $cat->sortorder = 5;
!         $cat->depth = 1;
!         $cats[4] = fullclone($cat);
! 
!         $item = new stdClass();
!         $item->itemtype = 'course';
!         $item->iteminstance = 1;
!         $item->sortorder = 1;
!         $items = array();
!         $items[5] = fullclone($item);
!         $item->itemtype = 'category';
!         $item->iteminstance = 3;
!         $item->sortorder = 2;
!         $items[6] = fullclone($item);
!         $item->iteminstance = 4;
!         $item->sortorder = 5;
!         $items[7] = fullclone($item);
!         $item->itemtype = 'item';
!         $item->categoryid = 3;
!         $item->sortorder = 3;
!         $items[8] = fullclone($item);
!         $item->categoryid = 3;
!         $item->sortorder = 4;
!         $items[9] = fullclone($item);
!         $item->categoryid = 4;
!         $item->sortorder = 6;
!         $items[10] = fullclone($item);
!         $item->categoryid = 4;
!         $item->sortorder = 7;
!         $items[11] = fullclone($item);
! 
!         $grade_category->lib_wrapper->setReturnValueAt(0, 'get_records', $cats);
!         $grade_category->lib_wrapper->setReturnValueAt(1, 'get_records', $items);
!         $this->assertTrue(method_exists($grade_category, 'get_children'));
!     
!         // Do not test recursion
!         $children_array = $grade_category->get_children(true);
  
          $this->assertTrue(is_array($children_array));
!         $this->assertEqual(3, count($children_array));
!         $this->assertEqual('grade_item', get_class($children_array[1]['object']));
!         $this->assertEqual('courseitem', $children_array[1]['type']);
!         $this->assertequal(0, $children_array[1]['depth']);
!         $this->assertEqual('course', $children_array[1]['object']->itemtype);
! 
!         $this->assertEqual('grade_category', get_class($children_array[2]['object']));
!         $this->assertEqual('category', $children_array[2]['type']);
!         $this->assertequal(1, $children_array[2]['depth']);
!         $this->assertEqual(3, count($children_array[2]['children']));
      }
  
      function test_grade_category_load_parent_category() {
!         Mock::generatePartial('grade_category', 'mock_grade_category_for_load_parent_category', array('get_parent_category'));
  
!         $grade_category = new mock_grade_category_for_load_parent_category($this);;
!         $grade_category->parent = 1;
!         $parent = new grade_category($this->grade_categories[0], false);
!         $grade_category->setReturnReference('get_parent_category', $parent);
!         $grade_category->expectOnce('get_parent_category', array());
!         $this->assertTrue(method_exists($grade_category, 'load_parent_category'));
!         $this->assertEqual(null, $grade_category->parent_category);
!         $grade_category->load_parent_category();
!         $this->assertEqual($this->grade_categories[0]->id, $grade_category->parent_category->id);
      }
  
      function test_grade_category_get_name() {
!         $grade_category = new grade_category($this->grade_categories[0], false);
!         $grade_category->lib_wrapper = new mock_lib_wrapper();
!         $this->assertTrue(method_exists($grade_category, 'get_name'));
!         $grade_category->lib_wrapper->expectOnce('get_record', array('course', 'id', $this->courseid));
!         $course = new stdClass();
!         $course->fullname = $grade_category->fullname;
!         $grade_category->lib_wrapper->setReturnValue('get_record', $course);
!         $grade_category->parent = null;
!         $this->assertEqual(format_string($this->grade_categories[0]->fullname), $grade_category->get_name());
! 
!         // Test with a parent id
!         $grade_category = new grade_category($this->grade_categories[0], false);
!         $grade_category->lib_wrapper = new mock_lib_wrapper();
!         $grade_category->parent = 1;
!         $grade_category->lib_wrapper->expectNever('get_record');
!         $this->assertEqual(format_string($this->grade_categories[0]->fullname), $grade_category->get_name()); 
  
      }
  
!     function test_grade_category_set_parent() {
!         $methods_to_mock = array('is_course_category', 'update', 'fetch', 'force_regrading');
!         
!         Mock::generatePartial('grade_category', 'mock_grade_category_for_set_parent', $methods_to_mock);
!         $grade_category_template = new mock_grade_category_for_set_parent($this);
!         $grade_category_template->parent = 1;
!         $grade_category_template->courseid = $this->courseid;
!         
!         $this->assertTrue(method_exists($grade_category_template, 'set_parent'));
!         
!         // Test when requested parentid is already the category's parent id (1 in this case)
!         $grade_category = fullclone($grade_category_template);
!         $grade_category->expectNever('is_course_category');
!         $grade_category->expectNever('update');
!         $grade_category->expectNever('fetch');
!         $this->assertTrue($grade_category->set_parent(1));
! 
!         $grade_category_template->parent = 2;
!         
!         // Test when parent category is not found in DB
!         $this->reset_mocks();
!         $grade_category = fullclone($grade_category_template);
!         $grade_category->expectOnce('is_course_category');
!         $grade_category->setReturnValue('is_course_category', false);
!         $obj = grade_object::get_instance('grade_category');
!         $obj->expectOnce('fetch', array(array('id' => 1, 'courseid' => $this->courseid)));
!         $obj->setReturnValue('fetch', false);
!         $grade_category->expectNever('update');
!         $grade_category->expectNever('force_regrading');
!         $this->assertFalse($grade_category->set_parent(1));
!     
!         // Test when parent category is found in DB
!         $this->reset_mocks();
!         $grade_category = fullclone($grade_category_template);
!         $grade_category->expectOnce('is_course_category');
!         $grade_category->setReturnValue('is_course_category', false);
!         $obj = grade_object::get_instance('grade_category');
!         $obj->expectOnce('fetch', array(array('id' => 1, 'courseid' => $this->courseid)));
!         $obj->setReturnValue('fetch', $this->grade_categories[0]); 
!         $grade_category->expectOnce('force_regrading', array());
!         $grade_category->expectOnce('update');
!         $grade_category->setReturnValue('update', true);
!         $this->assertTrue($grade_category->set_parent(1));
      }
  
      function test_grade_category_fetch_course_category() {
!         $methods_to_mock = array('instantiate_new_grade_category', 'fetch', 'insert_course_category'); 
!         Mock::generatePartial('grade_category', 'mock_grade_category_for_fetch_course_category', $methods_to_mock);
!         $grade_category = new mock_grade_category_for_fetch_course_category($this);
!         $grade_category->lib_wrapper = new mock_lib_wrapper();
!         $this->assertTrue(method_exists($grade_category, 'fetch_course_category'));
!         
!         // Test method when course category already exists
!         $grade_category->expectNever('instantiate_new_grade_category');
!         $obj = grade_object::get_instance('grade_category');
!         $obj->setReturnValue('fetch', $this->grade_categories[0]);
!         $this->assertEqual($this->grade_categories[0], $grade_category->fetch_course_category($this->courseid));
!         
!         // Test method when course category does not exists 
      }
+     
  
      function test_grade_category_set_locked() {
!         $methods_to_mock = array('load_grade_item', 'instantiate_new_grade_item', 'fetch_all');
!         
!         $lockedstate = true;
!         $cascade = false;
!         $refresh = false;
!         
!         // Test non-cascading set_locked
!         Mock::generatePartial('grade_category', 'mock_grade_category_for_set_locked', $methods_to_mock);
!         $grade_item = new mock_grade_item();
!         $grade_item->expectCallCount('set_locked', 2, array($lockedstate, $cascade, true));
!         $grade_item->setReturnValue('set_locked', true); 
!         $grade_item->expectNever('fetch_all');
!         $grade_category = new mock_grade_category_for_set_locked($this);
!         $grade_category->expectOnce('load_grade_item');
!         $grade_category->expectNever('instantiate_new_grade_item');
!         $this->assertTrue(method_exists($grade_category, 'set_locked'));
!         $grade_category->grade_item = $grade_item;
! 
!         $this->assertTrue($grade_category->set_locked($lockedstate, $cascade, $refresh));
!         
!         // Test cascading set_locked
!         $cascading = true;
!         $grade_category = new mock_grade_category_for_set_locked($this);
!         $obj = grade_object::get_instance('grade_item');
!         $obj->setReturnValue('fetch_all', array(fullclone($grade_item), fullclone($grade_item)));
!         $grade_category->expectOnce('load_grade_item');
!         $grade_category->grade_item = $grade_item;
  
!         $this->assertTrue($grade_category->set_locked($lockedstate, $cascade, $refresh));
      }
  
      function test_grade_category_set_hidden() {
!         $methods_to_mock = array('load_grade_item', 'instantiate_new_grade_item', 'fetch_all');
!         
!         $hiddenstate = true;
!         $cascade = false;
!         
!         // Test non-cascading set_hidden
!         Mock::generatePartial('grade_category', 'mock_grade_category_for_set_hidden', $methods_to_mock);
!         $grade_item = new mock_grade_item();
!         $grade_item->expectCallCount('set_hidden', 2, array($hiddenstate, $cascade));
!         $grade_item->setReturnValue('set_hidden', true); 
!         $grade_item->expectNever('fetch_all');
!         $grade_category = new mock_grade_category_for_set_hidden($this);
!         $grade_category->expectOnce('load_grade_item');
!         $grade_category->expectNever('instantiate_new_grade_item');
!         $this->assertTrue(method_exists($grade_category, 'set_hidden'));
!         $grade_category->grade_item = $grade_item;
! 
!         $grade_category->set_hidden($hiddenstate, $cascade);
!         
!         // Test cascading set_hidden
!         $cascading = true;
!         $grade_category = new mock_grade_category_for_set_hidden($this);
!         $obj = grade_object::get_instance('grade_item');
!         $obj->setReturnValue('fetch_all', array(fullclone($grade_item), fullclone($grade_item)));
!         $grade_category->expectOnce('load_grade_item');
!         $grade_category->grade_item = $grade_item;
! 
!         $grade_category->set_hidden($hiddenstate, $cascade);
!     } 
  }
  ?>
*** D:/VertrigoServ/www/moode_up/lib/grade/simpletest/testgradegrades.php	Thu Nov 22 06:58:53 2007
--- D:/VertrigoServ/www/moode_up/lib/grade/simpletest/testgradegrades_new.php	Thu Nov 22 06:59:00 2007
***************
*** 1,4 ****
! <?php // $Id: testgradegrades.php,v 1.9 2007/11/22 05:42:48 nicolasconnault Exp $
  
  ///////////////////////////////////////////////////////////////////////////
  //                                                                       //
--- 1,4 ----
! <?php // $Id: testgradegrades.php,v 1.8 2007/11/13 10:31:08 nicolasconnault Exp $
  
  ///////////////////////////////////////////////////////////////////////////
  //                                                                       //
***************
*** 38,43 ****
--- 38,52 ----
  require_once($CFG->libdir.'/simpletest/fixtures/gradetest.php');
  
  class grade_grade_test extends grade_test {
+     
+     function setUp() {
+         parent::setUp();
+         $this->load_grade_grades();
+     }
+ 
+     function tearDown() {
+         parent::tearDown();
+     }
  
      function test_grade_grade_construct() {
          $params = new stdClass();
***************
*** 55,60 ****
--- 64,70 ----
  
      function test_grade_grade_insert() {
          $grade_grade = new grade_grade();
+         $grade_grade->lib_wrapper = new mock_lib_wrapper();
          $this->assertTrue(method_exists($grade_grade, 'insert'));
  
          $grade_grade->itemid = $this->grade_items[0]->id;
***************
*** 62,147 ****
          $grade_grade->rawgrade = 88;
          $grade_grade->rawgrademax = 110;
          $grade_grade->rawgrademin = 18;
  
          // Check the grade_item's needsupdate variable first
-         $grade_grade->load_grade_item();
          $this->assertFalse($grade_grade->grade_item->needsupdate);
  
          $grade_grade->insert();
  
!         $last_grade_grade = end($this->grade_grades);
  
!         $this->assertEqual($grade_grade->id, $last_grade_grade->id + 1);
!         $this->assertFalse(empty($grade_grade->timecreated));
!         $this->assertFalse(empty($grade_grade->timemodified));
      }
  
      function test_grade_grade_update() {
!         $grade_grade = new grade_grade($this->grade_grades[0]);
          $this->assertTrue(method_exists($grade_grade, 'update'));
!     }
! 
!     function test_grade_grade_fetch() {
!         $grade_grade = new grade_grade();
!         $this->assertTrue(method_exists($grade_grade, 'fetch'));
! 
!         $grades = grade_grade::fetch(array('id'=>$this->grade_grades[0]->id));
!         $this->assertEqual($this->grade_grades[0]->id, $grades->id);
!         $this->assertEqual($this->grade_grades[0]->rawgrade, $grades->rawgrade);
!     }
! 
!     function test_grade_grade_fetch_all() {
!         $grade_grade = new grade_grade();
!         $this->assertTrue(method_exists($grade_grade, 'fetch_all'));
! 
!         $grades = grade_grade::fetch_all(array());
!         $this->assertEqual(count($this->grade_grades), count($grades));
      }
  
      function test_grade_grade_load_grade_item() {
!         $grade_grade = new grade_grade($this->grade_grades[0]);
          $this->assertTrue(method_exists($grade_grade, 'load_grade_item'));
          $this->assertNull($grade_grade->grade_item);
          $this->assertTrue($grade_grade->itemid);
          $this->assertNotNull($grade_grade->load_grade_item());
          $this->assertNotNull($grade_grade->grade_item);
          $this->assertEqual($this->grade_items[0]->id, $grade_grade->grade_item->id);
      }
  
- 
      function test_grade_grade_standardise_score() {
          $this->assertEqual(4, round(grade_grade::standardise_score(6, 0, 7, 0, 5)));
          $this->assertEqual(40, grade_grade::standardise_score(50, 30, 80, 0, 100));
      }
  
! 
      function test_grade_grade_set_locked() {
!         $grade_item = new grade_item($this->grade_items[0]);
!         $grade = new grade_grade($grade_item->get_final(1));
          $this->assertTrue(method_exists($grade, 'set_locked'));
  
          $this->assertTrue(empty($grade_item->locked));
          $this->assertTrue(empty($grade->locked));
! 
!         $this->assertTrue($grade->set_locked(true));
          $this->assertFalse(empty($grade->locked));
!         $this->assertTrue($grade->set_locked(false));
          $this->assertTrue(empty($grade->locked));
  
!         $this->assertTrue($grade_item->set_locked(true));
!         $grade = new grade_grade($grade_item->get_final(1));
! 
!         $this->assertFalse(empty($grade->locked));
!         $this->assertFalse($grade->set_locked(false));
! 
!         $this->assertTrue($grade_item->set_locked(false));
!         $grade = new grade_grade($grade_item->get_final(1));
  
!         $this->assertTrue($grade->set_locked(false));
      }
  
      function test_grade_grade_is_locked() {
!         $grade = new grade_grade($this->grade_grades[0]);
          $this->assertTrue(method_exists($grade, 'is_locked'));
  
          $this->assertFalse($grade->is_locked());
--- 72,172 ----
          $grade_grade->rawgrade = 88;
          $grade_grade->rawgrademax = 110;
          $grade_grade->rawgrademin = 18;
+         
+         $grade_item = new grade_item($this->grade_items[0], false);
+         $grade_grade->grade_item = $grade_item;
  
          // Check the grade_item's needsupdate variable first
          $this->assertFalse($grade_grade->grade_item->needsupdate);
+         
+         $grade_grade->lib_wrapper->expectCallCount('insert_record', 2); // main insert and history table insert 
+         $grade_grade->lib_wrapper->setReturnValue('insert_record', 1);
+         $grade_grade->lib_wrapper->expectOnce('get_record'); // for update_from_db() method
+         $grade_grade->lib_wrapper->setReturnValue('get_record', array(1));
  
          $grade_grade->insert();
  
!         $this->assertEqual($grade_grade->id, 1);
  
!         // timecreated doesn't refer to creation in the DB, but to time of submission. Timemodified refers to date of grading
!         $this->assertTrue(empty($grade_grade->timecreated));
!         $this->assertTrue(empty($grade_grade->timemodified));
      }
  
      function test_grade_grade_update() {
!         $grade_grade = new grade_grade($this->grade_grades[0], false);
!         $grade_grade->lib_wrapper = new mock_lib_wrapper();
!         $grade_grade->lib_wrapper->expectOnce('update_record');
!         $grade_grade->lib_wrapper->setReturnValue('update_record', true);
          $this->assertTrue(method_exists($grade_grade, 'update'));
!         $grade_grade->update();
      }
  
      function test_grade_grade_load_grade_item() {
!         $grade_grade = new grade_grade($this->grade_grades[0], false);
!         $grade_grade->lib_wrapper = new mock_lib_wrapper();
!         $grade_grade->itemid = $this->grade_items[0]->id;
          $this->assertTrue(method_exists($grade_grade, 'load_grade_item'));
          $this->assertNull($grade_grade->grade_item);
          $this->assertTrue($grade_grade->itemid);
+         
+         $grade_item = grade_object::get_instance('grade_item');
+         $grade_item->expectOnce('fetch', array(array('id' => $grade_grade->itemid)));
+         $gi = $this->grade_items[0];
+         $grade_item->setReturnReference('fetch', $gi);
          $this->assertNotNull($grade_grade->load_grade_item());
          $this->assertNotNull($grade_grade->grade_item);
          $this->assertEqual($this->grade_items[0]->id, $grade_grade->grade_item->id);
      }
  
      function test_grade_grade_standardise_score() {
          $this->assertEqual(4, round(grade_grade::standardise_score(6, 0, 7, 0, 5)));
          $this->assertEqual(40, grade_grade::standardise_score(50, 30, 80, 0, 100));
      }
  
!     /**
!      * In this test we always set the 2nd param of set_locked() to false, because it 
!      * would otherwise trigger the refresh_grades method, which is not being tested here.
!      */ 
      function test_grade_grade_set_locked() {
!         $grade_item = new grade_item($this->grade_items[0], false);
!         $grade = new grade_grade($this->grade_grades[0], false);
!         $grade->lib_wrapper = new mock_lib_wrapper();
!         $grade->lib_wrapper->expectCallCount('update_record', 2);
!         $grade->lib_wrapper->setReturnValue('update_record', true);
!         $grade->grade_item = $grade_item;
!         $grade->itemid = $grade_item->id;
! 
          $this->assertTrue(method_exists($grade, 'set_locked'));
  
          $this->assertTrue(empty($grade_item->locked));
          $this->assertTrue(empty($grade->locked));
!         
!         // Test locking the grade when needsupdate is true
!         $grade->grade_item->needsupdate = true;
!         $this->assertFalse($grade->set_locked(true, false, false)); 
! 
!         // Test locking the grade when needsupdate is false
!         $grade->grade_item->needsupdate = false;
!         $this->assertTrue($grade->set_locked(true, false, false));
          $this->assertFalse(empty($grade->locked));
!         $this->assertTrue($grade->set_locked(false, false, false));
          $this->assertTrue(empty($grade->locked));
  
!         $grade = new grade_grade($this->grade_grades[0], false);
!         $grade->lib_wrapper = new mock_lib_wrapper();
!         $grade->lib_wrapper->expectOnce('update_record');
!         $grade->lib_wrapper->setreturnvalue('update_record', true);
!         $grade->grade_item = $grade_item;
!         $grade->itemid = $grade_item->id;
  
!         $this->assertTrue($grade->set_locked(false, false, false));
      }
  
+ 
      function test_grade_grade_is_locked() {
!         $grade = new grade_grade($this->grade_grades[0], false);
!         $grade->grade_item = new grade_item($this->grade_items[0], false);
          $this->assertTrue(method_exists($grade, 'is_locked'));
  
          $this->assertFalse($grade->is_locked());
***************
*** 150,171 ****
      }
  
      function test_grade_grade_set_hidden() {
!         $grade_item = new grade_item($this->grade_items[0]);
!         $grade = new grade_grade($grade_item->get_final(1));
          $this->assertTrue(method_exists($grade, 'set_hidden'));
  
          $this->assertEqual(0, $grade_item->hidden);
          $this->assertEqual(0, $grade->hidden);
! 
          $grade->set_hidden(0);
          $this->assertEqual(0, $grade->hidden);
  
          $grade->set_hidden(1);
          $this->assertEqual(1, $grade->hidden);
      }
  
      function test_grade_grade_is_hidden() {
!         $grade = new grade_grade($this->grade_grades[0]);
          $this->assertTrue(method_exists($grade, 'is_hidden'));
  
          $this->assertFalse($grade->is_hidden());
--- 175,204 ----
      }
  
      function test_grade_grade_set_hidden() {
!         $grade_item = new grade_item($this->grade_items[0], false);
!         $grade = new grade_grade($this->grade_grades[0], false);
!         $grade->lib_wrapper = new mock_lib_wrapper();
!         $grade->lib_wrapper->expectCallCount('update_record', 2);
!         $grade->lib_wrapper->setreturnvalue('update_record', true);
!         $grade->grade_item = $grade_item;
!         $grade->itemid = $grade_item->id;
          $this->assertTrue(method_exists($grade, 'set_hidden'));
  
          $this->assertEqual(0, $grade_item->hidden);
          $this->assertEqual(0, $grade->hidden);
!         
          $grade->set_hidden(0);
          $this->assertEqual(0, $grade->hidden);
  
          $grade->set_hidden(1);
          $this->assertEqual(1, $grade->hidden);
+ 
+         // @TODO test with cascading on (2nd param set to true)
      }
  
      function test_grade_grade_is_hidden() {
!         $grade = new grade_grade($this->grade_grades[0], false);
!         $grade->grade_item = new grade_item($this->grade_items[0], false);
          $this->assertTrue(method_exists($grade, 'is_hidden'));
  
          $this->assertFalse($grade->is_hidden());
***************
*** 178,184 ****
          $grade->hidden = time()+666;
          $this->assertTrue($grade->is_hidden());
      }
- 
- 
  }
  ?>
--- 211,215 ----
*** D:/VertrigoServ/www/moode_up/lib/grade/simpletest/testgradeitem.php	Thu Nov 22 07:12:29 2007
--- D:/VertrigoServ/www/moode_up/lib/grade/simpletest/testgradeitem_new.php	Thu Nov 22 07:12:32 2007
***************
*** 1,4 ****
! <?php // $Id: testgradeitem.php,v 1.14 2007/11/22 05:42:48 nicolasconnault Exp $
  
  ///////////////////////////////////////////////////////////////////////////
  //                                                                       //
--- 1,4 ----
! <?php // $Id: testgradeitem.php,v 1.13 2007/11/22 05:37:49 nicolasconnault Exp $
  
  ///////////////////////////////////////////////////////////////////////////
  //                                                                       //
***************
*** 40,46 ****
  @set_time_limit(0);
  
  class grade_item_test extends grade_test {
! 
      function test_grade_item_construct() {
          $params = new stdClass();
  
--- 40,51 ----
  @set_time_limit(0);
  
  class grade_item_test extends grade_test {
!     
!     function setUp() {
!         parent::setUp();
!         $this->load_grade_items();        
!     }
!     
      function test_grade_item_construct() {
          $params = new stdClass();
  
***************
*** 59,65 ****
      }
  
      function test_grade_item_insert() {
!         $grade_item = new grade_item();
          $this->assertTrue(method_exists($grade_item, 'insert'));
  
          $grade_item->courseid = $this->courseid;
--- 64,74 ----
      }
  
      function test_grade_item_insert() {
!         
!         Mock::generatePartial('grade_item', 'mock_grade_item_for_insert', array('load_scale', 'is_course_item', 'is_category_item', 'force_regrading'));
!         $grade_item = new mock_grade_item_for_insert($this);
!         $grade_item->lib_wrapper = new mock_lib_wrapper();
!         
          $this->assertTrue(method_exists($grade_item, 'insert'));
  
          $grade_item->courseid = $this->courseid;
***************
*** 69,298 ****
          $grade_item->itemmodule = 'quiz';
          $grade_item->iteminfo = 'Grade item used for unit testing';
  
          $grade_item->insert();
  
!         $last_grade_item = end($this->grade_items);
  
!         $this->assertEqual($grade_item->id, $last_grade_item->id + 1);
!         $this->assertEqual(11, $grade_item->sortorder);
      }
  
      function test_grade_item_delete() {
!         $grade_item = new grade_item($this->grade_items[0]);
          $this->assertTrue(method_exists($grade_item, 'delete'));
  
!         $this->assertTrue($grade_item->delete());
! 
!         $this->assertFalse(get_record('grade_items', 'id', $grade_item->id));
      }
  
      function test_grade_item_update() {
!         $grade_item = new grade_item($this->grade_items[0]);
!         $this->assertTrue(method_exists($grade_item, 'update'));
! 
          $grade_item->iteminfo = 'Updated info for this unittest grade_item';
  
!         $this->assertTrue($grade_item->update());
! 
!         $grade_item->grademin = 14;
!         $this->assertTrue($grade_item->qualifies_for_regrading());
!         $this->assertTrue($grade_item->update());
! 
!         $iteminfo = get_field('grade_items', 'iteminfo', 'id', $this->grade_items[0]->id);
!         $this->assertEqual($grade_item->iteminfo, $iteminfo);
      }
  
      function test_grade_item_load_scale() {
!         $grade_item = new grade_item($this->grade_items[2]);
          $this->assertTrue(method_exists($grade_item, 'load_scale'));
!         $scale = $grade_item->load_scale();
!         $this->assertFalse(empty($grade_item->scale));
!         $this->assertEqual($scale->id, $this->grade_items[2]->scaleid);
      }
  
      function test_grade_item_load_outcome() {
!         $grade_item = new grade_item($this->grade_items[0]);
          $this->assertTrue(method_exists($grade_item, 'load_outcome'));
!         //TODO: add tests
      }
  
      function test_grade_item_qualifies_for_regrading() {
!         $grade_item = new grade_item($this->grade_items[0]);
          $this->assertTrue(method_exists($grade_item, 'qualifies_for_regrading'));
  
          $this->assertFalse($grade_item->qualifies_for_regrading());
  
!         $grade_item->iteminfo = 'Updated info for this unittest grade_item';
! 
!         $this->assertFalse($grade_item->qualifies_for_regrading());
! 
!         $grade_item->grademin = 14;
! 
          $this->assertTrue($grade_item->qualifies_for_regrading());
      }
  
      function test_grade_item_force_regrading() {
!         $grade_item = new grade_item($this->grade_items[0]);
          $this->assertTrue(method_exists($grade_item, 'force_regrading'));
  
          $this->assertEqual(0, $grade_item->needsupdate);
  
          $grade_item->force_regrading();
          $this->assertEqual(1, $grade_item->needsupdate);
-         $grade_item->update_from_db();
-         $this->assertEqual(1, $grade_item->needsupdate);
-     }
- 
-     function test_grade_item_fetch() {
-         $grade_item = new grade_item();
-         $this->assertTrue(method_exists($grade_item, 'fetch'));
- 
-         $grade_item = grade_item::fetch(array('id'=>$this->grade_items[0]->id));
-         $this->assertEqual($this->grade_items[0]->id, $grade_item->id);
-         $this->assertEqual($this->grade_items[0]->iteminfo, $grade_item->iteminfo);
- 
-         $grade_item = grade_item::fetch(array('itemtype'=>$this->grade_items[1]->itemtype, 'itemmodule'=>$this->grade_items[1]->itemmodule));
-         $this->assertEqual($this->grade_items[1]->id, $grade_item->id);
-         $this->assertEqual($this->grade_items[1]->iteminfo, $grade_item->iteminfo);
-     }
- 
-     function test_grade_item_fetch_all() {
-         $grade_item = new grade_item();
-         $this->assertTrue(method_exists($grade_item, 'fetch_all'));
- 
-         $grade_items = grade_item::fetch_all(array('courseid'=>$this->courseid));
-         $this->assertEqual(count($this->grade_items), count($grade_items)-1);
      }
  
-     /**
-      * Retrieve all final scores for a given grade_item.
-      */
      function test_grade_item_get_all_finals() {
!         $grade_item = new grade_item($this->grade_items[0]);
          $this->assertTrue(method_exists($grade_item, 'get_final'));
  
          $final_grades = $grade_item->get_final();
          $this->assertEqual(3, count($final_grades));
!     }
! 
  
-     /**
-      * Retrieve all final scores for a specific userid.
-      */
      function test_grade_item_get_final() {
!         $grade_item = new grade_item($this->grade_items[0]);
          $this->assertTrue(method_exists($grade_item, 'get_final'));
          $final_grade = $grade_item->get_final($this->userid);
          $this->assertEqual($this->grade_grades[0]->finalgrade, $final_grade->finalgrade);
      }
  
-     function test_grade_item_get_sortorder() {
-         $grade_item = new grade_item($this->grade_items[0]);
-         $this->assertTrue(method_exists($grade_item, 'get_sortorder'));
-         $sortorder = $grade_item->get_sortorder();
-         $this->assertEqual($this->grade_items[0]->sortorder, $sortorder);
-     }
- 
      function test_grade_item_set_sortorder() {
!         $grade_item = new grade_item($this->grade_items[0]);
          $this->assertTrue(method_exists($grade_item, 'set_sortorder'));
          $grade_item->set_sortorder(999);
          $this->assertEqual($grade_item->sortorder, 999);
      }
  
      function test_grade_item_move_after_sortorder() {
!         $grade_item = new grade_item($this->grade_items[0]);
          $this->assertTrue(method_exists($grade_item, 'move_after_sortorder'));
!         $grade_item->move_after_sortorder(5);
!         $this->assertEqual($grade_item->sortorder, 6);
! 
!         $grade_item = grade_item::fetch(array('id'=>$this->grade_items[0]->id));
!         $this->assertEqual($grade_item->sortorder, 6);
! 
!         $after = grade_item::fetch(array('id'=>$this->grade_items[6]->id));
!         $this->assertEqual($after->sortorder, 8);
!     }
! 
!     function test_grade_item_get_name() {
!         $grade_item = new grade_item($this->grade_items[0]);
!         $this->assertTrue(method_exists($grade_item, 'get_name'));
! 
!         $name = $grade_item->get_name();
!         $this->assertEqual($this->grade_items[0]->itemname, $name);
      }
  
      function test_grade_item_set_parent() {
-         $grade_item = new grade_item($this->grade_items[0]);
-         $this->assertTrue(method_exists($grade_item, 'set_parent'));
- 
-         $old = $grade_item->get_parent_category();
-         $new = new grade_category($this->grade_categories[3]);
-         $new_item = $new->get_grade_item();
- 
-         $this->assertTrue($grade_item->set_parent($new->id));
- 
-         $new_item->update_from_db();
-         $grade_item->update_from_db();
  
!         $this->assertEqual($grade_item->categoryid, $new->id);
      }
  
      function test_grade_item_get_parent_category() {
!         $grade_item = new grade_item($this->grade_items[0]);
!         $this->assertTrue(method_exists($grade_item, 'get_parent_category'));
! 
!         $category = $grade_item->get_parent_category();
!         $this->assertEqual($this->grade_categories[1]->fullname, $category->fullname);
      }
  
!     function test_grade_item_load_parent_category() {
!         $grade_item = new grade_item($this->grade_items[0]);
!         $this->assertTrue(method_exists($grade_item, 'load_parent_category'));
! 
!         $category = $grade_item->load_parent_category();
!         $this->assertEqual($this->grade_categories[1]->fullname, $category->fullname);
!         $this->assertEqual($this->grade_categories[1]->fullname, $grade_item->parent_category->fullname);
!     }
! 
!     function test_grade_item_get_item_category() {
!         $grade_item = new grade_item($this->grade_items[3]);
!         $this->assertTrue(method_exists($grade_item, 'get_item_category'));
! 
!         $category = $grade_item->get_item_category();
!         $this->assertEqual($this->grade_categories[0]->fullname, $category->fullname);
!     }
  
!     function test_grade_item_load_item_category() {
!         $grade_item = new grade_item($this->grade_items[3]);
!         $this->assertTrue(method_exists($grade_item, 'load_item_category'));
  
!         $category = $grade_item->load_item_category();
!         $this->assertEqual($this->grade_categories[0]->fullname, $category->fullname);
!         $this->assertEqual($this->grade_categories[0]->fullname, $grade_item->item_category->fullname);
      }
  
-     /**
-      * Test update of all final grades
-      */
-     function test_grade_item_regrade_final_grades() {
-         $grade_item = new grade_item($this->grade_items[0]);
-         $this->assertTrue(method_exists($grade_item, 'regrade_final_grades'));
-         $this->assertEqual(true, $grade_item->regrade_final_grades());
-         //TODO: add more tests
-     }
- 
-     /**
-      * Test the adjust_raw_grade method
-      */
      function test_grade_item_adjust_raw_grade() {
!         $grade_item = new grade_item($this->grade_items[0]);
!         $this->assertTrue(method_exists($grade_item, 'adjust_raw_grade'));
          $grade_raw = new stdClass();
  
          $grade_raw->rawgrade = 40;
          $grade_raw->grademax = 100;
          $grade_raw->grademin = 0;
  
          $grade_item->multfactor = 1;
          $grade_item->plusfactor = 0;
          $grade_item->grademax = 50;
--- 78,421 ----
          $grade_item->itemmodule = 'quiz';
          $grade_item->iteminfo = 'Grade item used for unit testing';
  
+         $grade_item->lib_wrapper->expectCallCount('insert_record', 2); // main insert and history table insert 
+         $grade_item->lib_wrapper->setReturnValue('insert_record', 4);
+         $grade_item->lib_wrapper->expectOnce('get_record'); // for update_from_db() method
+         $grade_item->lib_wrapper->setReturnValue('get_record', array(1));
          $grade_item->insert();
  
!         $this->assertEqual($grade_item->id, 4);
  
!         $this->assertFalse(empty($grade_item->timecreated));
!         $this->assertFalse(empty($grade_item->timemodified));
      }
  
      function test_grade_item_delete() {
!         
!         $source = 'unit tests';
!         
!         Mock::generatePartial('grade_item', 'mock_grade_item_for_delete', array('is_course_item', 'force_regrading'));
!         Mock::generatePartial('grade_grade', 'mock_grade_grade_for_item_delete', array('delete'));
!         
!         $grade_item =& new mock_grade_item_for_delete($this);
!         $grade_item->lib_wrapper = new mock_lib_wrapper();
!         $grade_item->id = 1;
!         
!         $grade_item->lib_wrapper->expectOnce('delete_records', array($grade_item->table, 'id', $grade_item->id));
!         $grade_item->lib_wrapper->setReturnValue('delete_records', true);
!         
!         $grade_grade_instance = grade_object::get_instance('grade_grade');
!         
!         $grade_grades = array();
!         $grade_grades[1] = new mock_grade_grade_for_item_delete($this);
!         $grade_grades[1]->expectOnce('delete', array($source));
!         $grade_grades[2] = new mock_grade_grade_for_item_delete($this);
!         $grade_grades[2]->expectOnce('delete', array($source));
!         $grade_grades[3] = new mock_grade_grade_for_item_delete($this);
!         $grade_grades[3]->expectOnce('delete', array($source));
!         
!         $grade_grade_instance->expectOnce('fetch_all', array(array('itemid' => $grade_item->id)));
!         $grade_grade_instance->setReturnValue('fetch_all', $grade_grades);
!          
          $this->assertTrue(method_exists($grade_item, 'delete'));
  
!         $this->assertTrue($grade_item->delete($source));
      }
  
      function test_grade_item_update() {
!         
!         Mock::generatePartial('grade_item', 'mock_grade_item_for_update', array('force_regrading', 'qualifies_for_regrading', 'load_scale'));
!         $grade_item = new mock_grade_item_for_update($this);
!         grade_object::set_properties($grade_item, $this->grade_items[0]);
          $grade_item->iteminfo = 'Updated info for this unittest grade_item';
+         $grade_item->lib_wrapper = new mock_lib_wrapper();
+         $grade_item->lib_wrapper->expectOnce('update_record', array($grade_item->table, '*'));
+         $grade_item->lib_wrapper->setReturnValue('update_record', true);
+         $this->assertTrue(method_exists($grade_item, 'update'));
  
!         $grade_item->expectOnce('load_scale', array());
!         $grade_item->expectOnce('qualifies_for_regrading', array());
!         $grade_item->setReturnValue('qualifies_for_regrading', true);
!         $grade_item->expectOnce('force_regrading', array());
!         
!         $this->assertTrue($grade_item->update()); 
      }
  
      function test_grade_item_load_scale() {
!         $grade_item = new grade_item($this->grade_items[2], false);
          $this->assertTrue(method_exists($grade_item, 'load_scale'));
!         $grade_item->lib_wrapper = new mock_lib_wrapper();
!         $grade_item->gradetype = GRADE_TYPE_VALUE; // Should return null
!         $this->assertNull($grade_item->load_scale());
! 
!         $grade_item->gradetype = GRADE_TYPE_SCALE;
!         $grade_item->scaleid = 1;
!         $grade_scale = grade_object::get_instance('grade_scale');
!         $grade_scale->expectOnce('fetch', array(array('id' => $grade_item->scaleid)));
!         $item_grade_scale = new mock_grade_scale();
!         $item_grade_scale->expectOnce('load_items', array());
!         $item_grade_scale->scale_items = array(1, 2, 3);
!         $grade_scale->setReturnValue('fetch', $item_grade_scale);
!         $grade_item->scale = $grade_scale;
!         
!         $this->assertEqual($item_grade_scale, $grade_item->load_scale());
!         $this->assertEqual(3, $grade_item->grademax);
!         $this->assertEqual(1, $grade_item->grademin);
      }
  
      function test_grade_item_load_outcome() {
!         $this->load_grade_outcomes();
!         $grade_item = new grade_item($this->grade_items[0], false);
!         $grade_item->outcomeid = 1;
          $this->assertTrue(method_exists($grade_item, 'load_outcome'));
!         $grade_item->lib_wrapper = new mock_lib_wrapper();
!         $grade_outcome = grade_object::get_instance('grade_outcome');
!         $grade_outcome->expectOnce('fetch', array(array('id' => $grade_item->outcomeid)));
!         $return_outcome = new grade_outcome($this->grade_outcomes[0], false);
!         $grade_outcome->setReturnValue('fetch', $return_outcome);
!         $this->assertEqual($return_outcome, $grade_item->load_outcome());
      }
  
      function test_grade_item_qualifies_for_regrading() {
!         // Setup
!         Mock::generatePartial('grade_item', 'mock_grade_item_for_qualifies', array('get_instance')); 
!         $grade_item = new mock_grade_item_for_qualifies($this);
          $this->assertTrue(method_exists($grade_item, 'qualifies_for_regrading'));
+         grade_object::set_properties($grade_item, $this->grade_items[0]);
  
+         // Should return false when no item->id given
+         $grade_item->id = null; 
          $this->assertFalse($grade_item->qualifies_for_regrading());
  
!         // Returns false because new record is identical to original
!         $grade_item->id = 1;
!         $grade_item->expectCallCount('get_instance', 2, array('grade_item', array('id' => $grade_item->id)));
!         $db_item = grade_object::get_instance('grade_item', $this->grade_items[0], false);
!         $grade_item->setReturnValue('get_instance', $db_item); 
!         $this->assertFalse($grade_item->qualifies_for_regrading()); 
!         
!         // Should return true when one of the fields is different
!         $grade_item->gradetype = GRADE_TYPE_NONE;
          $this->assertTrue($grade_item->qualifies_for_regrading());
      }
  
      function test_grade_item_force_regrading() {
!         $grade_item = new grade_item($this->grade_items[0], false);
!         $grade_item->lib_wrapper = new mock_lib_wrapper();
!         $grade_item->lib_wrapper->expectOnce('set_field_select', array('grade_items', 'needsupdate', 1, '*'));
          $this->assertTrue(method_exists($grade_item, 'force_regrading'));
  
          $this->assertEqual(0, $grade_item->needsupdate);
  
          $grade_item->force_regrading();
          $this->assertEqual(1, $grade_item->needsupdate);
      }
  
      function test_grade_item_get_all_finals() {
!         $grade_item = new grade_item($this->grade_items[0], false);
          $this->assertTrue(method_exists($grade_item, 'get_final'));
+         $grade_item->lib_wrapper = new mock_lib_wrapper();
+         $grade_item->lib_wrapper->expectOnce('get_records', array('grade_grades', 'itemid', $grade_item->id));
+         $grade_grades = array();
+         $grade_grades[1] = new mock_grade_grade();
+         $grade_grades[1]->userid = 1;
+         $grade_grades[2] = new mock_grade_grade();
+         $grade_grades[2]->userid = 2;
+         $grade_grades[3] = new mock_grade_grade();
+         $grade_grades[3]->userid = 3;
+         $grade_grades[4] = new mock_grade_grade(); // final grades are indexed by userid, so if 2 are given with the same userid, the last one will override the first
+         $grade_grades[4]->userid = 3;
+         $grade_item->lib_wrapper->setReturnValue('get_records', $grade_grades);
  
          $final_grades = $grade_item->get_final();
          $this->assertEqual(3, count($final_grades));
!     } 
  
      function test_grade_item_get_final() {
!         $this->load_grade_grades();
!         $grade_item = new grade_item($this->grade_items[0], false);
          $this->assertTrue(method_exists($grade_item, 'get_final'));
+         $grade_item->lib_wrapper = new mock_lib_wrapper();
+         $grade_item->lib_wrapper->expectOnce('get_record', array('grade_grades', 'itemid', $grade_item->id, 'userid', $this->userid));
+         $grade_item->lib_wrapper->setReturnValue('get_record', $this->grade_grades[0]);
          $final_grade = $grade_item->get_final($this->userid);
          $this->assertEqual($this->grade_grades[0]->finalgrade, $final_grade->finalgrade);
      }
  
      function test_grade_item_set_sortorder() {
!         Mock::generatePartial('grade_item', 'mock_grade_item_for_set_sortorder', array('update'));
! 
!         $grade_item = new mock_grade_item_for_set_sortorder($this);
          $this->assertTrue(method_exists($grade_item, 'set_sortorder'));
+         $grade_item->expectOnce('update', array());
+         $grade_item->sortorder = 1;
          $grade_item->set_sortorder(999);
          $this->assertEqual($grade_item->sortorder, 999);
      }
  
      function test_grade_item_move_after_sortorder() {
!         Mock::generatePartial('grade_item', 'mock_grade_item_for_move_after', array('set_sortorder'));
!         
!         $sortorder = 5;
!         $grade_item = new mock_grade_item_for_move_after($this);
          $this->assertTrue(method_exists($grade_item, 'move_after_sortorder'));
!         $grade_item->lib_wrapper = new mock_lib_wrapper();
!         $grade_item->lib_wrapper->expectOnce('execute_sql', array('*', false));
!         $grade_item->expectOnce('set_sortorder', array($sortorder + 1));
!         $grade_item->move_after_sortorder($sortorder);
      }
  
      function test_grade_item_set_parent() {
  
!         Mock::generatePartial('grade_item', 'mock_grade_item_for_set_parent', array('force_regrading', 'update'));
!         $grade_item = new mock_grade_item_for_set_parent($this);
!         $grade_item->lib_wrapper = new mock_lib_wrapper();
!         $this->assertTrue(method_exists($grade_item, 'set_parent'));
!     
!         // When categoryid == $parentid param, method should return true but no force_regrading or update should be called
!         $grade_item->categoryid = 1;
!         $grade_item->expectNever('update');
!         $grade_item->expectNever('force_regrading');
!         $this->assertTrue($grade_item->set_parent(1));
! 
!         // When parentid param is different from categoryid, force_regrading and update must be called
!         $grade_item = new mock_grade_item_for_set_parent($this);
!         $grade_item->categoryid = 2;
!         $grade_item->courseid = $this->courseid;
!         $parentid = 4;
!         $grade_item->expectOnce('update', array());
!         $grade_item->setReturnValue('update', true);
!         $grade_item->expectOnce('force_regrading', array());
!         $grade_category = grade_object::get_instance('grade_category');
!         $parent_category = new mock_grade_category();
!         $parent_category->id = 1;
!         $grade_category->expectOnce('fetch', array(array('id' => $parentid, 'courseid' => $this->courseid)));
!         $grade_category->setReturnValue('fetch', $parent_category);
!         $this->assertTrue($grade_item->set_parent($parentid)); 
      }
  
      function test_grade_item_get_parent_category() {
!         Mock::generatePartial('grade_item', 'mock_grade_item_for_get_parent_category', array('is_category_item', 'is_course_item', 'get_item_category'));
!         
!         // When item is a course or category item, the method should return the item category
!         $grade_item = new mock_grade_item_for_get_parent_category($this);
!         $grade_item->expectOnce('is_category_item', array());
!         $grade_item->expectOnce('is_course_item', array());
!         $grade_item->expectOnce('get_item_category', array());
!         $grade_item->setReturnValue('is_category_item', false);
!         $grade_item->setReturnValue('is_course_item', true);
!         $grade_item->setReturnValue('get_item_category', 'item_category');
!         $this->assertEqual('item_category', $grade_item->get_parent_category());
!         
!         // When the item is a normal grade item, the method should return the parent category
!         $grade_item = new mock_grade_item_for_get_parent_category($this);
!         $grade_item->expectOnce('is_category_item', array());
!         $grade_item->expectOnce('is_course_item', array());
!         $grade_item->setReturnValue('is_category_item', false);
!         $grade_item->setReturnValue('is_course_item', false);
!         $grade_item->categoryid = 4;
!         $grade_category = grade_object::get_instance('grade_category');
!         $grade_category->expectOnce('fetch', array(array('id' => $grade_item->categoryid)));
!         $grade_category->setReturnValue('fetch', true);
!         $this->assertTrue($grade_item->get_parent_category());
      }
  
!     function test_grade_item_regrade_final_grades() {
  
!         Mock::generatePartial('grade_item', 'mock_grade_item_for_regrade_final', array('is_locked', 'is_calculated', 'compute', 'is_outcome_item', 
!                 'is_category_item', 'is_course_item', 'get_item_category', 'is_manual_item', 'is_raw_used', 'get_instance', 'adjust_raw_grade')); 
  
!         // If grade_item is locked, no regrading occurs but the method returns true
!         $grade_item = new mock_grade_item_for_regrade_final($this);
!         $grade_item->expectOnce('is_locked', array());
!         $grade_item->setReturnValue('is_locked', true);
!         $grade_item->expectNever('get_item_category');
!         $this->assertTrue($grade_item->regrade_final_grades());
!         
!         // If the item is calculated and the computation is OK, no regrading occurs and the method returns true
!         $grade_item = new mock_grade_item_for_regrade_final($this);
!         $grade_item->expectOnce('is_calculated', array());
!         $grade_item->setReturnValue('is_calculated', true);
!         $grade_item->expectOnce('compute', array($this->userid));
!         $grade_item->setReturnValue('compute', true);
! 
!         $grade_item->expectNever('get_item_category');
!         $this->assertTrue($grade_item->regrade_final_grades($this->userid));
!         
!         // If the item is calculated but the grades cannot be calculated, method should return an error message
!         $grade_item = new mock_grade_item_for_regrade_final($this);
!         $grade_item->expectOnce('is_calculated', array());
!         $grade_item->setReturnValue('is_calculated', true);
!         $grade_item->expectOnce('compute', array($this->userid));
!         $grade_item->setReturnValue('compute', false);
!         $this->assertEqual("Could not calculate grades for grade item", $grade_item->regrade_final_grades($this->userid)); 
! 
!         // If the item is an outcome item, return true before regrading
!         $grade_item = new mock_grade_item_for_regrade_final($this);
!         $grade_item->expectOnce('is_outcome_item', array());
!         $grade_item->setReturnValue('is_outcome_item', true); 
!         $this->assertTrue($grade_item->regrade_final_grades($this->userid)); 
! 
!         // If the item is a category or course item, category must generate grades, then return true
!         $grade_item = new mock_grade_item_for_regrade_final($this);
!         $grade_item->expectCallCount('is_category_item', 2, array());
!         $grade_item->expectCallCount('is_course_item', 2, array());
!         $grade_item->setReturnValue('is_category_item', false); 
!         $grade_item->setReturnValue('is_course_item', true);
!         $grade_item->expectCallCount('get_item_category', 2, array());
!         $category = new mock_grade_category();
!         $category->expectCallCount('generate_grades', 2, array($this->userid));
!         $category->setReturnValueAt(0, 'generate_grades', true);
!         $category->setReturnValueAt(1, 'generate_grades', false); // if generate_grades() is false, method should return false
!         $grade_item->setReturnValue('get_item_category', $category);
!         $this->assertTrue($grade_item->regrade_final_grades($this->userid)); 
!         $this->assertEqual("Could not aggregate final grades for category:".$grade_item->id, $grade_item->regrade_final_grades($this->userid)); 
! 
!         // If the item is a manual item, method should return true before regrading
!         $grade_item = new mock_grade_item_for_regrade_final($this);
!         $grade_item->expectOnce('is_manual_item', array());
!         $grade_item->setReturnValue('is_manual_item', true); 
!         $this->assertTrue($grade_item->regrade_final_grades($this->userid)); 
! 
!         // If the item is not using raw grades, method should return true without regrading 
!         $grade_item = new mock_grade_item_for_regrade_final($this);
!         $grade_item->expectOnce('is_raw_used', array());
!         $grade_item->setReturnValue('is_raw_used', false); 
!         $this->assertTrue($grade_item->regrade_final_grades($this->userid)); 
      }
  
      function test_grade_item_adjust_raw_grade() {
!         $grade_item = new grade_item($this->grade_items[0], false);
!         $grade_scale = new mock_grade_scale();
!         $grade_scale->id = 1;
!         $grade_items->scale = $grade_scale;
!         $grade_items->scaleid = $grade_scale->id;
! 
          $grade_raw = new stdClass();
  
          $grade_raw->rawgrade = 40;
          $grade_raw->grademax = 100;
          $grade_raw->grademin = 0;
  
+         $this->assertTrue(method_exists($grade_item, 'adjust_raw_grade'));
+ 
+         $grade_item->gradetype = GRADE_TYPE_TEXT;
+         $this->assertNull($grade_item->adjust_raw_grade($grade_raw->rawgrade, $grade_raw->grademin, $grade_raw->grademax));
+         $grade_item->gradetype = GRADE_TYPE_NONE;
+         $this->assertNull($grade_item->adjust_raw_grade($grade_raw->rawgrade, $grade_raw->grademin, $grade_raw->grademax)); 
+ 
+         $grade_item->gradetype = GRADE_TYPE_SCALE;
+         $grade_item->grademax = -1;
+         $this->assertNull($grade_item->adjust_raw_grade($grade_raw->rawgrade, $grade_raw->grademin, $grade_raw->grademax));
+         $grade_item->grademax = 0;
+         $this->assertEqual(0, $grade_item->adjust_raw_grade($grade_raw->rawgrade, $grade_raw->grademin, $grade_raw->grademax));
+         
+         $grade_item->gradetype = GRADE_TYPE_VALUE;
+         $grade_item->grademax = 20;
+         $grade_item->grademin = 21;
+         $this->assertNull($grade_item->adjust_raw_grade(null, 0, 10)); // null raw = null
+         $this->assertNull($grade_item->adjust_raw_grade(20, 0, 10)); // item->min > item->max = null
+ 
          $grade_item->multfactor = 1;
          $grade_item->plusfactor = 0;
          $grade_item->grademax = 50;
***************
*** 344,373 ****
          $this->assertEqual(round(1.6), round($grade_item->adjust_raw_grade($grade_raw->rawgrade, $grade_raw->grademin, $grade_raw->grademax)));
      }
  
-     /**
-      * Test locking of grade items
-      */
      function test_grade_item_set_locked() {
!         $grade_item = new grade_item($this->grade_items[0]);
          $this->assertTrue(method_exists($grade_item, 'set_locked'));
! 
!         $grade = new grade_grade($grade_item->get_final(1));
!         $this->assertTrue(empty($grade_item->locked));
!         $this->assertTrue(empty($grade->locked));
! 
!         $this->assertTrue($grade_item->set_locked(true));
!         $grade = new grade_grade($grade_item->get_final(1));
! 
!         $this->assertFalse(empty($grade_item->locked));
!         $this->assertFalse(empty($grade->locked)); // individual grades should be locked too
! 
!         $this->assertTrue($grade_item->set_locked(false));
!         $grade = new grade_grade($grade_item->get_final(1));
! 
!         $this->assertTrue(empty($grade_item->locked));
!         $this->assertTrue(empty($grade->locked)); // individual grades should be unlocked too
      }
  
      function test_grade_item_is_locked() {
          $grade_item = new grade_item($this->grade_items[0]);
          $this->assertTrue(method_exists($grade_item, 'is_locked'));
--- 467,519 ----
          $this->assertEqual(round(1.6), round($grade_item->adjust_raw_grade($grade_raw->rawgrade, $grade_raw->grademin, $grade_raw->grademax)));
      }
  
      function test_grade_item_set_locked() {
!         Mock::generatePartial('grade_item', 'mock_grade_item_for_set_locked', array('get_final', 'update', 'get_instance', 'refresh_grades'));
!         $grade_item = new mock_grade_item_for_set_locked($this);
          $this->assertTrue(method_exists($grade_item, 'set_locked'));
!         
!         $grade_item->needsupdate = true;
!         $this->assertFalse($grade_item->set_locked(true));
!         $grade_item->needsupdate = false;
!         $grade_item->expectOnce('update', array());
!         $grade_item->expectNever('get_final');
!         $this->assertTrue($grade_item->set_locked(true, false));
!         $this->assertTrue($grade_item->locked > 0);
!         $this->assertTrue($grade_item->locked <= time());
! 
!         // Add cascading to the previous call
!         $grade_item = new mock_grade_item_for_set_locked($this);
!         $grade_item->needsupdate = false;
!         $grade = new mock_grade_grade();
!         $grade->expectCallCount('set_locked', 2, array(1, null, false));
!         $grade_item->expectOnce('update', array());
!         $grade_item->expectCallCount('get_instance', 2);
!         $grade_item->expectOnce('get_final', array());
!         $grade_item->setReturnValue('get_final', array(1, 2)); // array returned by get_final is irrelevant: grade_grade objects get instantiated using get_instance
!         $grade_item->setReturnValue('get_instance', $grade); 
!         $this->assertTrue($grade_item->set_locked(true, true));
! 
!         // Try with lock set to false
!         $grade_item = new mock_grade_item_for_set_locked($this);
!         $grade_item->locked = time() - 3600;
!         $grade_item->expectOnce('update', array());
!         $grade_item->expectNever('refresh_grades', array());
!         
!         $this->assertTrue($grade_item->set_locked(false, false, false));
!         $this->assertEqual(0, $grade_item->locktime);
!         $this->assertEqual(0, $grade_item->locked);
! 
!         // Add refresh and cascading to the previous call
!         $grade_item = new mock_grade_item_for_set_locked($this);
!         $grade_item->id = 1;
!         $grade_grade = grade_object::get_instance('grade_grade');
!         $grade_grade->expectOnce('fetch_all', array(array('itemid' => $grade_item->id)));
!         $grade = new mock_grade_grade();
!         $grade_grade->setReturnValue('fetch_all', array(clone($grade), clone($grade)));
!         $this->assertTrue($grade_item->set_locked(false, true, true));
      }
  
+ /*
      function test_grade_item_is_locked() {
          $grade_item = new grade_item($this->grade_items[0]);
          $this->assertTrue(method_exists($grade_item, 'is_locked'));
***************
*** 379,387 ****
          $this->assertTrue($grade_item->is_locked(1));
      }
  
-     /**
-      * Test hiding of grade items
-      */
      function test_grade_item_set_hidden() {
          $grade_item = new grade_item($this->grade_items[0]);
          $this->assertTrue(method_exists($grade_item, 'set_hidden'));
--- 525,530 ----
***************
*** 390,396 ****
          $this->assertEqual(0, $grade_item->hidden);
          $this->assertEqual(0, $grade->hidden);
  
!         $grade_item->set_hidden(666);
          $grade = new grade_grade($grade_item->get_final(1));
  
          $this->assertEqual(666, $grade_item->hidden);
--- 533,539 ----
          $this->assertEqual(0, $grade_item->hidden);
          $this->assertEqual(0, $grade->hidden);
  
!         $grade_item->set_hidden(666, true);
          $grade = new grade_grade($grade_item->get_final(1));
  
          $this->assertEqual(666, $grade_item->hidden);
***************
*** 511,516 ****
          $grade_grade = grade_grade::fetch(array('userid'=>$this->grade_grades[5]->userid, 'itemid'=>$this->grade_grades[5]->itemid));
          $this->assertEqual($this->grade_grades[5]->finalgrade, $grade_grade->finalgrade);
      }
! 
  }
  ?>
--- 654,659 ----
          $grade_grade = grade_grade::fetch(array('userid'=>$this->grade_grades[5]->userid, 'itemid'=>$this->grade_grades[5]->itemid));
          $this->assertEqual($this->grade_grades[5]->finalgrade, $grade_grade->finalgrade);
      }
! */
  }
  ?>
*** D:/VertrigoServ/www/moode_up/lib/grade/simpletest/testgradeoutcome.php	Thu Nov 22 07:13:19 2007
--- D:/VertrigoServ/www/moode_up/lib/grade/simpletest/testgradeoutcome_new.php	Thu Nov 22 07:13:22 2007
***************
*** 1,4 ****
! <?php // $Id: testgradeoutcome.php,v 1.7 2007/11/22 05:42:47 nicolasconnault Exp $
  
  ///////////////////////////////////////////////////////////////////////////
  //                                                                       //
--- 1,4 ----
! <?php // $Id: testgradeoutcome.php,v 1.6 2007/11/13 10:31:08 nicolasconnault Exp $
  
  ///////////////////////////////////////////////////////////////////////////
  //                                                                       //
***************
*** 38,43 ****
--- 38,51 ----
  require_once($CFG->libdir.'/simpletest/fixtures/gradetest.php');
  
  class grade_outcome_test extends grade_test {
+     function setUp() {
+         parent::setUp();
+         $this->load_grade_outcomes();
+     }
+ 
+     function tearDown() {
+         parent::tearDown();
+     }
  
      function test_grade_outcome_construct() {
          $params = new stdClass();
***************
*** 52,106 ****
  
      function test_grade_outcome_insert() {
          $grade_outcome = new grade_outcome();
          $this->assertTrue(method_exists($grade_outcome, 'insert'));
  
          $grade_outcome->courseid = $this->courseid;
          $grade_outcome->shortname = 'tw';
          $grade_outcome->fullname = 'Team work';
  
          $grade_outcome->insert();
  
!         $last_grade_outcome = end($this->grade_outcomes);
! 
!         $this->assertEqual($grade_outcome->id, $last_grade_outcome->id + 1);
          $this->assertFalse(empty($grade_outcome->timecreated));
          $this->assertFalse(empty($grade_outcome->timemodified));
      }
! 
      function test_grade_outcome_update() {
!         $grade_outcome = new grade_outcome($this->grade_outcomes[0]);
          $this->assertTrue(method_exists($grade_outcome, 'update'));
          $grade_outcome->shortname = 'Team work';
          $this->assertTrue($grade_outcome->update());
!         $shortname = get_field('grade_outcomes', 'shortname', 'id', $this->grade_outcomes[0]->id);
!         $this->assertEqual($grade_outcome->shortname, $shortname);
      }
  
      function test_grade_outcome_delete() {
!         $grade_outcome = new grade_outcome($this->grade_outcomes[0]);
!         $this->assertTrue(method_exists($grade_outcome, 'delete'));
! 
!         $this->assertTrue($grade_outcome->delete());
!         $this->assertFalse(get_record('grade_outcomes', 'id', $grade_outcome->id));
!     }
! 
!     function test_grade_outcome_fetch() {
!         $grade_outcome = new grade_outcome();
!         $this->assertTrue(method_exists($grade_outcome, 'fetch'));
  
!         $grade_outcome = grade_outcome::fetch(array('id'=>$this->grade_outcomes[0]->id));
!         $this->assertEqual($this->grade_outcomes[0]->id, $grade_outcome->id);
!         $this->assertEqual($this->grade_outcomes[0]->shortname, $grade_outcome->shortname);
  
!         $this->assertEqual($this->scale[2]->id, $grade_outcome->scale->id);
      }
  
-     function test_grade_outcome_fetch_all() {
-         $grade_outcome = new grade_outcome();
-         $this->assertTrue(method_exists($grade_outcome, 'fetch_all'));
- 
-         $grade_outcomes = grade_outcome::fetch_all(array());
-         $this->assertEqual(count($this->grade_outcomes), count($grade_outcomes));
-     }
  }
  ?>
--- 60,126 ----
  
      function test_grade_outcome_insert() {
          $grade_outcome = new grade_outcome();
+         $grade_outcome->lib_wrapper = new mock_lib_wrapper();
          $this->assertTrue(method_exists($grade_outcome, 'insert'));
  
          $grade_outcome->courseid = $this->courseid;
          $grade_outcome->shortname = 'tw';
          $grade_outcome->fullname = 'Team work';
+         
+         $grade_outcome->lib_wrapper->expectCallCount('insert_record', 3); // main insert, history table insert and grade_outcomes_courses insert
+         $grade_outcome->lib_wrapper->setReturnValue('insert_record', 1);
+         $grade_outcome->lib_wrapper->expectOnce('get_record'); // for update_from_db() method
+         $grade_outcome->lib_wrapper->setReturnValue('get_record', array(1));
  
          $grade_outcome->insert();
  
!         $this->assertEqual($grade_outcome->id, 1);
          $this->assertFalse(empty($grade_outcome->timecreated));
          $this->assertFalse(empty($grade_outcome->timemodified));
      }
!     
      function test_grade_outcome_update() {
!         $grade_outcome = new grade_outcome($this->grade_outcomes[0], false);
!         $grade_outcome->lib_wrapper = new mock_lib_wrapper();
!         $grade_outcome->timecreated = time() - 200000;
!         $grade_outcome->timemodified = $grade_outcome->timecreated;
!         $grade_outcome->timemodified = $grade_outcome->timecreated;
!         $timemodified = $grade_outcome->timemodified;
!         $timecreated = $grade_outcome->timecreated;
!         $grade_outcome->courseid = $this->courseid;
! 
          $this->assertTrue(method_exists($grade_outcome, 'update'));
          $grade_outcome->shortname = 'Team work';
+         
+         $grade_outcome->lib_wrapper->expectOnce('update_record');
+         $grade_outcome->lib_wrapper->setReturnValue('update_record', true);
+         $grade_outcome->lib_wrapper->expectOnce('get_records');
+         $grade_outcome->lib_wrapper->setReturnValue('get_records', false); // Pretend there is no record in grade_outcoms_courses table
+         $grade_outcome->lib_wrapper->expectCallCount('insert_record', 2); // 1. grade_outcome_courses, 2. grade_outcomes_history
+ 
          $this->assertTrue($grade_outcome->update());
!         
!         // We expect timecreated to be unchanged, and timemodified to be updated
!         $this->assertTrue($grade_outcome->timemodified > $timemodified);
!         $this->assertTrue($grade_outcome->timemodified > $grade_outcome->timecreated);
!         $this->assertTrue($grade_outcome->timecreated == $timecreated);
      }
  
      function test_grade_outcome_delete() {
!         $grade_outcome = new grade_outcome($this->grade_outcomes[0], false);
!         $grade_outcome->courseid = $this->courseid;
!         $grade_outcome->lib_wrapper = new mock_lib_wrapper();
!         
!         $grade_outcome->lib_wrapper->expectCallCount('delete_records', 2);
!         $grade_outcome->lib_wrapper->expectAt(0, 'delete_records', array('grade_outcomes_courses', 'outcomeid', $grade_outcome->id, 'courseid', $this->courseid));
!         $grade_outcome->lib_wrapper->expectAt(1, 'delete_records', array('grade_outcomes', 'id', $grade_outcome->id));
!         $grade_outcome->lib_wrapper->setReturnValue('delete_records', true);
  
!         $grade_outcome->lib_wrapper->expectOnce('insert_record'); // grade_history entry
  
!         $this->assertTrue(method_exists($grade_outcome, 'delete')); 
!         $this->assertTrue($grade_outcome->delete());
      }
  
  }
  ?>
*** D:/VertrigoServ/www/moode_up/lib/grade/simpletest/testgradescale.php	Thu Nov 22 07:13:55 2007
--- D:/VertrigoServ/www/moode_up/lib/grade/simpletest/testgradescale_new.php	Thu Nov 22 07:14:00 2007
***************
*** 1,4 ****
! <?php // $Id: testgradescale.php,v 1.6 2007/11/22 05:42:47 nicolasconnault Exp $
  
  ///////////////////////////////////////////////////////////////////////////
  //                                                                       //
--- 1,4 ----
! <?php // $Id: testgradescale.php,v 1.5 2007/11/13 10:31:08 nicolasconnault Exp $
  
  ///////////////////////////////////////////////////////////////////////////
  //                                                                       //
***************
*** 123,140 ****
          $grade_scale->lib_wrapper->expectOnce('insert_record'); // grade_history entry
          
          $this->assertTrue($grade_scale->delete());
-     }
- 
-     function test_grade_scale_fetch() {
-         $grade_scale = new grade_scale();
-         $grade_scale->lib_wrapper = new mock_lib_wrapper();
-         $grade_scale->lib_wrapper->expectOnce('get_records_select');
-         $grade_scale->lib_wrapper->setReturnValue('get_records_select', array($this->scale[0]));
-         $this->assertTrue(method_exists($grade_scale, 'fetch'));
- 
-         $grade_scale = $grade_scale->fetch(array('id'=>$this->scale[0]->id));
-         $this->assertEqual($this->scale[0]->id, $grade_scale->id);
-         $this->assertEqual($this->scale[0]->name, $grade_scale->name);
      }
  
      function test_scale_load_items() {
--- 123,128 ----
*** D:/VertrigoServ/www/moode_up/lib/grade/simpletest/testgradescale.php	Thu Nov 22 07:17:40 2007
--- D:/VertrigoServ/www/moode_up/lib/grade/simpletest/testgradescale_new.php	Thu Nov 22 07:17:44 2007
***************
*** 1,4 ****
! <?php // $Id: testgradescale.php,v 1.7 2007/11/22 06:17:01 nicolasconnault Exp $
  
  ///////////////////////////////////////////////////////////////////////////
  //                                                                       //
--- 1,4 ----
! <?php // $Id: testgradescale.php,v 1.6 2007/11/22 05:42:47 nicolasconnault Exp $
  
  ///////////////////////////////////////////////////////////////////////////
  //                                                                       //
***************
*** 67,74 ****
      }
  
      function test_grade_scale_insert() {
-         global $db;
          $grade_scale = new grade_scale();
          $this->assertTrue(method_exists($grade_scale, 'insert'));
  
          $grade_scale->name        = 'unittestscale3';
--- 67,75 ----
      }
  
      function test_grade_scale_insert() {
          $grade_scale = new grade_scale();
+         $grade_scale->lib_wrapper = new mock_lib_wrapper();
+ 
          $this->assertTrue(method_exists($grade_scale, 'insert'));
  
          $grade_scale->name        = 'unittestscale3';
***************
*** 77,90 ****
          $grade_scale->scale       = 'Distinction, Very Good, Good, Pass, Fail';
          $grade_scale->description = 'This scale is used to mark standard assignments.';
  
!         // Mock insert of data in history table
!         $this->rs->setReturnValue('RecordCount', 1);
!         $this->rs->fields = array(1); 
!         
!         // Mock insert of outcome object
!         $db->setReturnValue('GetInsertSQL', true);
!         $db->setReturnValue('Insert_ID', 1);
! 
          $grade_scale->insert();
  
          $this->assertEqual($grade_scale->id, 1);
--- 78,88 ----
          $grade_scale->scale       = 'Distinction, Very Good, Good, Pass, Fail';
          $grade_scale->description = 'This scale is used to mark standard assignments.';
  
!         $grade_scale->lib_wrapper->expectCallCount('insert_record', 2); // main insert and history table insert 
!         $grade_scale->lib_wrapper->setReturnValue('insert_record', 1);
!         $grade_scale->lib_wrapper->expectOnce('get_record'); // for update_from_db() method
!         $grade_scale->lib_wrapper->setReturnValue('get_record', array(1));
!         
          $grade_scale->insert();
  
          $this->assertEqual($grade_scale->id, 1);
***************
*** 93,100 ****
      }
  
      function test_grade_scale_update() {
-         global $db;
          $grade_scale = new grade_scale($this->scale[0], false);
          $this->assertTrue(method_exists($grade_scale, 'update'));
          
          $grade_scale->timecreated = time() - 200000;
--- 91,98 ----
      }
  
      function test_grade_scale_update() {
          $grade_scale = new grade_scale($this->scale[0], false);
+         $grade_scale->lib_wrapper = new mock_lib_wrapper();
          $this->assertTrue(method_exists($grade_scale, 'update'));
          
          $grade_scale->timecreated = time() - 200000;
***************
*** 102,111 ****
          $timemodified = $grade_scale->timemodified;
          $timecreated = $grade_scale->timecreated;
  
!         // Mock update: MetaColumns is first returned to compare existing data with new
!         $column = new stdClass();
!         $column->name = 'name';
!         $db->setReturnValue('MetaColumns', array($column));
          
          $grade_scale->name = 'Updated info for this unittest grade_scale';
          $this->assertTrue($grade_scale->update());
--- 100,107 ----
          $timemodified = $grade_scale->timemodified;
          $timecreated = $grade_scale->timecreated;
  
!         $grade_scale->lib_wrapper->expectOnce('update_record');
!         $grade_scale->lib_wrapper->setReturnValue('update_record', true);
          
          $grade_scale->name = 'Updated info for this unittest grade_scale';
          $this->assertTrue($grade_scale->update());
***************
*** 118,141 ****
  
      function test_grade_scale_delete() {
          $grade_scale = new grade_scale($this->scale[0], false);
          $this->assertTrue(method_exists($grade_scale, 'delete'));
  
          $this->assertTrue($grade_scale->delete());
      }
  
      function test_grade_scale_fetch() {
-         global $db;
- 
          $grade_scale = new grade_scale();
          $this->assertTrue(method_exists($grade_scale, 'fetch'));
  
!         // Mock fetch
!         $column = new stdClass();
!         $column->name = 'id';
!         $this->rs->setReturnValue('FetchField', $column); // Fetching the name of the first column
!         $this->rs->setReturnValue('GetAssoc', array($this->scale[0]->id => (array) $this->scale[0])); 
!         
!         $grade_scale = grade_scale::fetch(array('id'=>$this->scale[0]->id));
          $this->assertEqual($this->scale[0]->id, $grade_scale->id);
          $this->assertEqual($this->scale[0]->name, $grade_scale->name);
      }
--- 114,138 ----
  
      function test_grade_scale_delete() {
          $grade_scale = new grade_scale($this->scale[0], false);
+         $grade_scale->lib_wrapper = new mock_lib_wrapper();
          $this->assertTrue(method_exists($grade_scale, 'delete'));
  
+         $grade_scale->lib_wrapper->expectOnce('delete_records', array('scale', 'id', $grade_scale->id));
+         $grade_scale->lib_wrapper->setReturnValue('delete_records', true);
+         
+         $grade_scale->lib_wrapper->expectOnce('insert_record'); // grade_history entry
+         
          $this->assertTrue($grade_scale->delete());
      }
  
      function test_grade_scale_fetch() {
          $grade_scale = new grade_scale();
+         $grade_scale->lib_wrapper = new mock_lib_wrapper();
+         $grade_scale->lib_wrapper->expectOnce('get_records_select');
+         $grade_scale->lib_wrapper->setReturnValue('get_records_select', array($this->scale[0]));
          $this->assertTrue(method_exists($grade_scale, 'fetch'));
  
!         $grade_scale = $grade_scale->fetch(array('id'=>$this->scale[0]->id));
          $this->assertEqual($this->scale[0]->id, $grade_scale->id);
          $this->assertEqual($this->scale[0]->name, $grade_scale->name);
      }
*** D:/VertrigoServ/www/moode_up/lib/grade/constants.php	Thu Nov 22 07:18:51 2007
--- D:/VertrigoServ/www/moode_up/lib/grade/constants_new.php	Thu Nov 22 07:18:56 2007
***************
*** 39,45 ****
  define('GRADE_AGGREGATE_MAX', 6);
  define('GRADE_AGGREGATE_MODE', 8);
  define('GRADE_AGGREGATE_WEIGHTED_MEAN', 10);
- define('GRADE_AGGREGATE_WEIGHTED_MEAN2', 11);
  define('GRADE_AGGREGATE_EXTRACREDIT_MEAN', 12);
  define('GRADE_AGGREGATE_SUM', 13);
  
--- 39,44 ----
*** D:/VertrigoServ/www/moode_up/lib/gradelib.php	Thu Nov 22 07:19:51 2007
--- D:/VertrigoServ/www/moode_up/lib/gradelib_new.php	Thu Nov 22 07:20:12 2007
***************
*** 26,32 ****
   * Library of functions for gradebook
   *
   * @author Moodle HQ developers
!  * @version  $Id: gradelib.php,v 1.128 2007/11/22 05:42:48 nicolasconnault Exp $
   * @license http://www.gnu.org/copyleft/gpl.html GNU Public License
   * @package moodlecore
   */
--- 26,32 ----
   * Library of functions for gradebook
   *
   * @author Moodle HQ developers
!  * @version  $Id: gradelib.php,v 1.127 2007/11/21 10:04:21 nicolasconnault Exp $
   * @license http://www.gnu.org/copyleft/gpl.html GNU Public License
   * @package moodlecore
   */
***************
*** 38,43 ****
--- 38,44 ----
  require_once($CFG->libdir . '/grade/grade_grade.php');
  require_once($CFG->libdir . '/grade/grade_scale.php');
  require_once($CFG->libdir . '/grade/grade_outcome.php');
+ require_once($CFG->libdir . '/grade/lib_wrapper.php');
  
  /***** PUBLIC GRADE API - only these functions should be used in modules *****/
  
***************
*** 586,591 ****
--- 587,593 ----
          return $coursegrades;
      }
  } 
+ 
  
  /***** END OF PUBLIC API *****/
  
*** D:/VertrigoServ/www/moode_up/lib/simpletest/fixtures/gradetest.php	Thu Nov 22 07:21:08 2007
--- D:/VertrigoServ/www/moode_up/lib/simpletest/fixtures/gradetest_new.php	Thu Nov 22 07:21:13 2007
***************
*** 36,42 ****
   */
  require_once($CFG->libdir . '/gradelib.php');
  require_once($CFG->libdir . '/dmllib.php');
- require_once($CFG->libdir . '/ddllib.php');
  
  Mock::generate('grade_item', 'mock_grade_item');
  Mock::generate('grade_scale', 'mock_grade_scale');
--- 36,41 ----
***************
*** 67,87 ****
       * every test has access to these test data. The order of the following array is
       * crucial, because of the interrelationships between objects.
       */
!     var $tables = array('grade_categories',
                          'scale',
                          'grade_items',
                          'grade_grades',
!                         'grade_outcomes');
  
      var $grade_items = array();
      var $grade_categories = array();
      var $grade_grades = array();
      var $grade_outcomes = array();
      var $scale = array();
  
!     var $activities = array();
      var $courseid = 1;
      var $userid = 1;
  
      /**
       * Create temporary test tables and entries in the database for these tests.
--- 66,100 ----
       * every test has access to these test data. The order of the following array is
       * crucial, because of the interrelationships between objects.
       */
!     var $tables = array('modules',
!                         'quiz',
!                         'assignment',
!                         'forum',
!                         'course_modules',
!                         'grade_categories',
                          'scale',
                          'grade_items',
                          'grade_grades',
!                         'grade_outcomes'
!                         );
  
      var $grade_items = array();
      var $grade_categories = array();
      var $grade_grades = array();
      var $grade_outcomes = array();
      var $scale = array();
+     var $modules = array();
+     var $course_modules = array();
  
!     var $assignments = array();
!     var $quizzes = array();
!     var $forums = array();
      var $courseid = 1;
      var $userid = 1;
+ 	
+     var $loaded_tables = array(); // An array of the data tables that were loaded for a specific test. Only these will be "unloaded" at tearDown time
+ 	var $real_db;
+     var $rs;  
  
      /**
       * Create temporary test tables and entries in the database for these tests.
***************
*** 90,627 ****
       */
      function setUp() {
          // Set global category settings to -1 (not force)
!         global $CFG;
          $CFG->grade_droplow = -1;
          $CFG->grade_keephigh = -1;
          $CFG->grade_aggregation = -1;
          $CFG->grade_aggregateonlygraded = -1;
          $CFG->grade_aggregateoutcomes = -1;
          $CFG->grade_aggregatesubcats = -1;
! 
!         $CFG->old_prefix = $CFG->prefix;
!         $CFG->prefix .= 'unittest_';
!         if (!$this->prepare_test_tables()) {
!             die("Could not create all the test tables!");
!         }
! 
!         if (!$this->prepare_test_history_tables()) {
!             die("Could not create all the test tables!");
!         }
! 
!         foreach ($this->tables as $table) {
!             $function = "load_$table";
!             $this->$function();
!         }
!     }
! 
!     function prepare_test_tables() {
!         $result = true;
! 
!         /// Define table course_modules to be created
!         $table = new XMLDBTable('course_modules');
! 
!         if (!table_exists($table)) {
!             /// Adding fields to table course_modules
!             $table->addFieldInfo('id', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, XMLDB_SEQUENCE, null, null, null);
!             $table->addFieldInfo('course', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, '0');
!             $table->addFieldInfo('module', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, '0');
!             $table->addFieldInfo('instance', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, '0');
!             $table->addFieldInfo('section', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, '0');
!             $table->addFieldInfo('idnumber', XMLDB_TYPE_CHAR, '100', XMLDB_UNSIGNED, null, null, null, null, null);
!             $table->addFieldInfo('added', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, '0');
!             $table->addFieldInfo('score', XMLDB_TYPE_INTEGER, '4', null, XMLDB_NOTNULL, null, null, null, '0');
!             $table->addFieldInfo('indent', XMLDB_TYPE_INTEGER, '5', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, '0');
!             $table->addFieldInfo('visible', XMLDB_TYPE_INTEGER, '1', null, XMLDB_NOTNULL, null, null, null, '1');
!             $table->addFieldInfo('visibleold', XMLDB_TYPE_INTEGER, '1', null, XMLDB_NOTNULL, null, null, null, '1');
!             $table->addFieldInfo('groupmode', XMLDB_TYPE_INTEGER, '4', null, XMLDB_NOTNULL, null, null, null, '0');
!             $table->addFieldInfo('groupingid', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, '0');
!             $table->addFieldInfo('groupmembersonly', XMLDB_TYPE_INTEGER, '4', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, '0');
! 
!             /// Adding keys to table course_modules
!             $table->addKeyInfo('primary', XMLDB_KEY_PRIMARY, array('id'));
!             $table->addKeyInfo('groupingid', XMLDB_KEY_FOREIGN, array('groupingid'), 'groupings', array('id'));
! 
!             /// Adding indexes to table course_modules
!             $table->addIndexInfo('visible', XMLDB_INDEX_NOTUNIQUE, array('visible'));
!             $table->addIndexInfo('course', XMLDB_INDEX_NOTUNIQUE, array('course'));
!             $table->addIndexInfo('module', XMLDB_INDEX_NOTUNIQUE, array('module'));
!             $table->addIndexInfo('instance', XMLDB_INDEX_NOTUNIQUE, array('instance'));
!             $table->addIndexInfo('idnumber-course', XMLDB_INDEX_NOTUNIQUE, array('idnumber', 'course'));
! 
!             /// Launch create table for course_modules
!             $result = $result && create_table($table, true, false);
!         } else {
!             delete_records($table->name);
!         }
! 
!         /// Define table modules to be created
!         $table = new XMLDBTable('modules');
! 
!         if (!table_exists($table)) {
! 
!             /// Adding fields to table modules
!             $table->addFieldInfo('id', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, XMLDB_SEQUENCE, null, null, null);
!             $table->addFieldInfo('name', XMLDB_TYPE_CHAR, '20', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, null);
!             $table->addFieldInfo('version', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null, null, '0');
!             $table->addFieldInfo('cron', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, '0');
!             $table->addFieldInfo('lastcron', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, '0');
!             $table->addFieldInfo('search', XMLDB_TYPE_CHAR, '255', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, null);
!             $table->addFieldInfo('visible', XMLDB_TYPE_INTEGER, '1', null, XMLDB_NOTNULL, null, null, null, '1');
! 
!             /// Adding keys to table modules
!             $table->addKeyInfo('primary', XMLDB_KEY_PRIMARY, array('id'));
! 
!             /// Adding indexes to table modules
!             $table->addIndexInfo('name', XMLDB_INDEX_NOTUNIQUE, array('name'));
! 
!             /// Launch create table for modules
!             $result = $result && create_table($table, true, false);
!         } else {
!             delete_records($table->name);
!         }
! 
!         /// Define table grade_items to be created
!         $table = new XMLDBTable('grade_items');
! 
!         if (!table_exists($table)) {
!             $table->addFieldInfo('id', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, XMLDB_SEQUENCE, null, null, null);
!             $table->addFieldInfo('courseid', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, null, null, null, null, null);
!             $table->addFieldInfo('categoryid', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, null, null, null, null, null);
!             $table->addFieldInfo('itemname', XMLDB_TYPE_CHAR, '255', null, null, null, null, null, null);
!             $table->addFieldInfo('itemtype', XMLDB_TYPE_CHAR, '30', null, XMLDB_NOTNULL, null, null, null, null);
!             $table->addFieldInfo('itemmodule', XMLDB_TYPE_CHAR, '30', null, null, null, null, null, null);
!             $table->addFieldInfo('iteminstance', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, null, null, null, null, null);
!             $table->addFieldInfo('itemnumber', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, null, null, null, null, null);
!             $table->addFieldInfo('iteminfo', XMLDB_TYPE_TEXT, 'medium', null, null, null, null, null, null);
!             $table->addFieldInfo('idnumber', XMLDB_TYPE_CHAR, '255', null, null, null, null, null, null);
!             $table->addFieldInfo('calculation', XMLDB_TYPE_TEXT, 'medium', null, null, null, null, null, null);
!             $table->addFieldInfo('gradetype', XMLDB_TYPE_INTEGER, '4', null, XMLDB_NOTNULL, null, null, null, '1');
!             $table->addFieldInfo('grademax', XMLDB_TYPE_NUMBER, '10, 5', null, XMLDB_NOTNULL, null, null, null, '100');
!             $table->addFieldInfo('grademin', XMLDB_TYPE_NUMBER, '10, 5', null, XMLDB_NOTNULL, null, null, null, '0');
!             $table->addFieldInfo('scaleid', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, null, null, null, null, null);
!             $table->addFieldInfo('outcomeid', XMLDB_TYPE_INTEGER, '10', null, null, null, null, null, null);
!             $table->addFieldInfo('gradepass', XMLDB_TYPE_NUMBER, '10, 5', null, XMLDB_NOTNULL, null, null, null, '0');
!             $table->addFieldInfo('multfactor', XMLDB_TYPE_NUMBER, '10, 5', null, XMLDB_NOTNULL, null, null, null, '1.0');
!             $table->addFieldInfo('plusfactor', XMLDB_TYPE_NUMBER, '10, 5', null, XMLDB_NOTNULL, null, null, null, '0');
!             $table->addFieldInfo('sortorder', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null, null, '0');
!             $table->addFieldInfo('display', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null, null, '0');
!             $table->addFieldInfo('decimals', XMLDB_TYPE_INTEGER, '1', XMLDB_UNSIGNED, null, null, null, null, null);
!             $table->addFieldInfo('hidden', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null, null, '0');
!             $table->addFieldInfo('locked', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null, null, '0');
!             $table->addFieldInfo('locktime', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, '0');
!             $table->addFieldInfo('deleted', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, '0');
!             $table->addFieldInfo('needsupdate', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null, null, '0');
!             $table->addFieldInfo('timecreated', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, null, null, null, null, null);
!             $table->addFieldInfo('timemodified', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, null, null, null, null, null);
! 
!             $table->addKeyInfo('primary', XMLDB_KEY_PRIMARY, array('id'));
!             $table->addKeyInfo('courseid', XMLDB_KEY_FOREIGN, array('courseid'), 'course', array('id'));
!             $table->addKeyInfo('categoryid', XMLDB_KEY_FOREIGN, array('categoryid'), 'grade_categories', array('id'));
!             $table->addKeyInfo('scaleid', XMLDB_KEY_FOREIGN, array('scaleid'), 'scale', array('id'));
!             $table->addKeyInfo('outcomeid', XMLDB_KEY_FOREIGN, array('outcomeid'), 'grade_outcomes', array('id'));
! 
!             /// Launch create table for grade_items
!             $result = $result && create_table($table, true, false);
! 
!         } else {
!             delete_records($table->name);
!         }
! 
! 
!         /// Define table grade_categories to be created
!         $table = new XMLDBTable('grade_categories');
! 
!         if ($result && !table_exists($table)) {
! 
!             $table->addFieldInfo('id', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, XMLDB_SEQUENCE, null, null, null);
!             $table->addFieldInfo('courseid', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, null);
!             $table->addFieldInfo('parent', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, null, null, null, null, null);
!             $table->addFieldInfo('depth', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, '0');
!             $table->addFieldInfo('path', XMLDB_TYPE_CHAR, '255', null, null, null, null, null, null);
!             $table->addFieldInfo('fullname', XMLDB_TYPE_CHAR, '255', null, XMLDB_NOTNULL, null, null, null, null);
!             $table->addFieldInfo('aggregation', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null, null, '0');
!             $table->addFieldInfo('keephigh', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null, null, '0');
!             $table->addFieldInfo('droplow', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null, null, '0');
!             $table->addFieldInfo('aggregateonlygraded', XMLDB_TYPE_INTEGER, '1', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, '0');
!             $table->addFieldInfo('aggregateoutcomes', XMLDB_TYPE_INTEGER, '1', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, '0');
!             $table->addFieldInfo('aggregatesubcats', XMLDB_TYPE_INTEGER, '1', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, '0');
!             $table->addFieldInfo('timecreated', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, null);
!             $table->addFieldInfo('timemodified', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, null);
! 
!             $table->addKeyInfo('primary', XMLDB_KEY_PRIMARY, array('id'));
!             $table->addKeyInfo('courseid', XMLDB_KEY_FOREIGN, array('courseid'), 'course', array('id'));
!             $table->addKeyInfo('parent', XMLDB_KEY_FOREIGN, array('parent'), 'grade_categories', array('id'));
! 
!             /// Launch create table for grade_categories
!             $result = $result && create_table($table, true, false);
! 
!         } else {
!             delete_records($table->name);
!         }
! 
! 
!         /// Define table grade_grades to be created
!         $table = new XMLDBTable('grade_grades');
! 
!         if ($result && !table_exists($table)) {
! 
!             $table->addFieldInfo('id', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, XMLDB_SEQUENCE, null, null, null);
!             $table->addFieldInfo('itemid', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, null);
!             $table->addFieldInfo('userid', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, null);
!             $table->addFieldInfo('rawgrade', XMLDB_TYPE_NUMBER, '10, 5', null, null, null, null, null, null);
!             $table->addFieldInfo('rawgrademax', XMLDB_TYPE_NUMBER, '10, 5', null, XMLDB_NOTNULL, null, null, null, '100');
!             $table->addFieldInfo('rawgrademin', XMLDB_TYPE_NUMBER, '10, 5', null, XMLDB_NOTNULL, null, null, null, '0');
!             $table->addFieldInfo('rawscaleid', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, null, null, null, null, null);
!             $table->addFieldInfo('usermodified', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, null, null, null, null, null);
!             $table->addFieldInfo('finalgrade', XMLDB_TYPE_NUMBER, '10, 5', null, null, null, null, null, null);
!             $table->addFieldInfo('hidden', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, '0');
!             $table->addFieldInfo('locked', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, '0');
!             $table->addFieldInfo('locktime', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, '0');
!             $table->addFieldInfo('exported', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, '0');
!             $table->addFieldInfo('overridden', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, '0');
!             $table->addFieldInfo('excluded', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, '0');
!             $table->addFieldInfo('feedback', XMLDB_TYPE_TEXT, 'medium', XMLDB_UNSIGNED, null, null, null, null, null);
!             $table->addFieldInfo('feedbackformat', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, '0');
!             $table->addFieldInfo('information', XMLDB_TYPE_TEXT, 'medium', XMLDB_UNSIGNED, null, null, null, null, null);
!             $table->addFieldInfo('informationformat', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, '0');
!             $table->addFieldInfo('timecreated', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, null, null, null, null, null);
!             $table->addFieldInfo('timemodified', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, null, null, null, null, null);
! 
!             $table->addKeyInfo('primary', XMLDB_KEY_PRIMARY, array('id'));
!             $table->addKeyInfo('itemid', XMLDB_KEY_FOREIGN, array('itemid'), 'grade_items', array('id'));
!             $table->addKeyInfo('userid', XMLDB_KEY_FOREIGN, array('userid'), 'user', array('id'));
!             $table->addKeyInfo('rawscaleid', XMLDB_KEY_FOREIGN, array('rawscaleid'), 'scale', array('id'));
!             $table->addKeyInfo('usermodified', XMLDB_KEY_FOREIGN, array('usermodified'), 'user', array('id'));
! 
!             /// Launch create table for grade_grades
!             $result = $result && create_table($table, true, false);
! 
!         } else {
!             delete_records($table->name);
!         }
! 
! 
!         /// Define table grade_outcomes to be created
!         $table = new XMLDBTable('grade_outcomes');
! 
!         if ($result && !table_exists($table)) {
! 
!             /// Adding fields to table grade_outcomes
!             $table->addFieldInfo('id', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, XMLDB_SEQUENCE, null, null, null);
!             $table->addFieldInfo('courseid', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, null, null, null, null, null);
!             $table->addFieldInfo('shortname', XMLDB_TYPE_CHAR, '255', null, XMLDB_NOTNULL, null, null, null, null);
!             $table->addFieldInfo('fullname', XMLDB_TYPE_TEXT, 'small', null, XMLDB_NOTNULL, null, null, null, null);
!             $table->addFieldInfo('scaleid', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, null, null, null, null, null);
!             $table->addFieldInfo('timecreated', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, null, null, null, null, null);
!             $table->addFieldInfo('timemodified', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, null, null, null, null, null);
!             $table->addFieldInfo('usermodified', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, null, null, null, null, null);
! 
!             /// Adding keys to table grade_outcomes
!             $table->addKeyInfo('primary', XMLDB_KEY_PRIMARY, array('id'));
!             $table->addKeyInfo('courseid', XMLDB_KEY_FOREIGN, array('courseid'), 'course', array('id'));
!             $table->addKeyInfo('scaleid', XMLDB_KEY_FOREIGN, array('scaleid'), 'scale', array('id'));
!             $table->addKeyInfo('usermodified', XMLDB_KEY_FOREIGN, array('usermodified'), 'user', array('id'));
! 
!             /// Launch create table for grade_outcomes
!             $result = $result && create_table($table, true, false);
! 
!         } else {
!             delete_records($table->name);
!         }
! 
! 
!         /// Define table scale to be created
!         $table = new XMLDBTable('scale');
! 
!         if ($result && !table_exists($table)) {
! 
!             $table->addFieldInfo('id', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, XMLDB_SEQUENCE, null, null, null);
!             $table->addFieldInfo('courseid', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, '0');
!             $table->addFieldInfo('userid', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, '0');
!             $table->addFieldInfo('name', XMLDB_TYPE_CHAR, '255', null, XMLDB_NOTNULL, null, null, null, null);
!             $table->addFieldInfo('scale', XMLDB_TYPE_TEXT, 'small', null, XMLDB_NOTNULL, null, null, null, null);
!             $table->addFieldInfo('description', XMLDB_TYPE_TEXT, 'small', null, XMLDB_NOTNULL, null, null, null, null);
!             $table->addFieldInfo('timemodified', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, '0');
!             $table->addKeyInfo('primary', XMLDB_KEY_PRIMARY, array('id'));
!             $table->addIndexInfo('courseid', XMLDB_INDEX_NOTUNIQUE, array('courseid'));
! 
!             /// Launch create table for scale
!             $result = $result && create_table($table, true, false);
! 
!         } else {
!             delete_records($table->name);
!         }
! 
!         /// Define table quiz to be created
!         $table = new XMLDBTable('quiz');
! 
!         if ($result && !table_exists($table)) {
!             /// Adding fields to table quiz
!             $table->addFieldInfo('id', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, XMLDB_SEQUENCE, null, null, null);
!             $table->addFieldInfo('course', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, '0');
!             $table->addFieldInfo('name', XMLDB_TYPE_CHAR, '255', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, null);
!             $table->addFieldInfo('intro', XMLDB_TYPE_TEXT, 'small', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, null);
!             $table->addFieldInfo('timeopen', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, '0');
!             $table->addFieldInfo('timeclose', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, '0');
!             $table->addFieldInfo('optionflags', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, '0');
!             $table->addFieldInfo('penaltyscheme', XMLDB_TYPE_INTEGER, '4', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, '0');
!             $table->addFieldInfo('attempts', XMLDB_TYPE_INTEGER, '6', null, XMLDB_NOTNULL, null, null, null, '0');
!             $table->addFieldInfo('attemptonlast', XMLDB_TYPE_INTEGER, '4', null, XMLDB_NOTNULL, null, null, null, '0');
!             $table->addFieldInfo('grademethod', XMLDB_TYPE_INTEGER, '4', null, XMLDB_NOTNULL, null, null, null, '1');
!             $table->addFieldInfo('decimalpoints', XMLDB_TYPE_INTEGER, '4', null, XMLDB_NOTNULL, null, null, null, '2');
!             $table->addFieldInfo('review', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, '0');
!             $table->addFieldInfo('questionsperpage', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null, null, '0');
!             $table->addFieldInfo('shufflequestions', XMLDB_TYPE_INTEGER, '4', null, XMLDB_NOTNULL, null, null, null, '0');
!             $table->addFieldInfo('shuffleanswers', XMLDB_TYPE_INTEGER, '4', null, XMLDB_NOTNULL, null, null, null, '0');
!             $table->addFieldInfo('questions', XMLDB_TYPE_TEXT, 'small', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, null);
!             $table->addFieldInfo('sumgrades', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null, null, '0');
!             $table->addFieldInfo('grade', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null, null, '0');
!             $table->addFieldInfo('timecreated', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, '0');
!             $table->addFieldInfo('timemodified', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, '0');
!             $table->addFieldInfo('timelimit', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, '0');
!             $table->addFieldInfo('password', XMLDB_TYPE_CHAR, '255', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, null);
!             $table->addFieldInfo('subnet', XMLDB_TYPE_CHAR, '255', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, null);
!             $table->addFieldInfo('popup', XMLDB_TYPE_INTEGER, '4', null, XMLDB_NOTNULL, null, null, null, '0');
!             $table->addFieldInfo('delay1', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null, null, '0');
!             $table->addFieldInfo('delay2', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null, null, '0');
! 
!             /// Adding keys to table quiz
!             $table->addKeyInfo('primary', XMLDB_KEY_PRIMARY, array('id'));
! 
!             /// Adding indexes to table quiz
!             $table->addIndexInfo('course', XMLDB_INDEX_NOTUNIQUE, array('course'));
! 
!             /// Launch create table for quiz
!             $result = $result && create_table($table, true, false);
!         } else {
!             delete_records($table->name);
!         }
! 
!         return $result;
!     }
! 
! 
!     function prepare_test_history_tables() {
!         $result = true;
! 
!         /// Define table grade_items to be created
!         $table = new XMLDBTable('grade_items_history');
! 
!         if (!table_exists($table)) {
! 
!         /// Adding fields to table grade_items_history
!             $table->addFieldInfo('id', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, XMLDB_SEQUENCE, null, null, null);
!             $table->addFieldInfo('action', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null, null, '0');
!             $table->addFieldInfo('oldid', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null, null, null);
!             $table->addFieldInfo('source', XMLDB_TYPE_CHAR, '255', null, null, null, null, null, null);
!             $table->addFieldInfo('timemodified', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, null, null, null, null, null);
!             $table->addFieldInfo('loggeduser', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, null, null, null, null, null);
!             $table->addFieldInfo('courseid', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, null, null, null, null, null);
!             $table->addFieldInfo('categoryid', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, null, null, null, null, null);
!             $table->addFieldInfo('itemname', XMLDB_TYPE_CHAR, '255', null, null, null, null, null, null);
!             $table->addFieldInfo('itemtype', XMLDB_TYPE_CHAR, '30', null, XMLDB_NOTNULL, null, null, null, null);
!             $table->addFieldInfo('itemmodule', XMLDB_TYPE_CHAR, '30', null, null, null, null, null, null);
!             $table->addFieldInfo('iteminstance', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, null, null, null, null, null);
!             $table->addFieldInfo('itemnumber', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, null, null, null, null, null);
!             $table->addFieldInfo('iteminfo', XMLDB_TYPE_TEXT, 'medium', null, null, null, null, null, null);
!             $table->addFieldInfo('idnumber', XMLDB_TYPE_CHAR, '255', null, null, null, null, null, null);
!             $table->addFieldInfo('calculation', XMLDB_TYPE_TEXT, 'medium', null, null, null, null, null, null);
!             $table->addFieldInfo('gradetype', XMLDB_TYPE_INTEGER, '4', null, XMLDB_NOTNULL, null, null, null, '1');
!             $table->addFieldInfo('grademax', XMLDB_TYPE_NUMBER, '10, 5', null, XMLDB_NOTNULL, null, null, null, '100');
!             $table->addFieldInfo('grademin', XMLDB_TYPE_NUMBER, '10, 5', null, XMLDB_NOTNULL, null, null, null, '0');
!             $table->addFieldInfo('scaleid', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, null, null, null, null, null);
!             $table->addFieldInfo('outcomeid', XMLDB_TYPE_INTEGER, '10', null, null, null, null, null, null);
!             $table->addFieldInfo('gradepass', XMLDB_TYPE_NUMBER, '10, 5', null, XMLDB_NOTNULL, null, null, null, '0');
!             $table->addFieldInfo('multfactor', XMLDB_TYPE_NUMBER, '10, 5', null, XMLDB_NOTNULL, null, null, null, '1.0');
!             $table->addFieldInfo('plusfactor', XMLDB_TYPE_NUMBER, '10, 5', null, XMLDB_NOTNULL, null, null, null, '0');
!             $table->addFieldInfo('sortorder', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null, null, '0');
!             $table->addFieldInfo('display', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null, null, '0');
!             $table->addFieldInfo('decimals', XMLDB_TYPE_INTEGER, '1', XMLDB_UNSIGNED, null, null, null, null, null);
!             $table->addFieldInfo('hidden', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null, null, '0');
!             $table->addFieldInfo('locked', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null, null, '0');
!             $table->addFieldInfo('locktime', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, '0');
!             $table->addFieldInfo('needsupdate', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null, null, '0');
! 
!         /// Adding keys to table grade_items_history
!             $table->addKeyInfo('primary', XMLDB_KEY_PRIMARY, array('id'));
!             $table->addKeyInfo('oldid', XMLDB_KEY_FOREIGN, array('oldid'), 'grade_items', array('id'));
!             $table->addKeyInfo('courseid', XMLDB_KEY_FOREIGN, array('courseid'), 'course', array('id'));
!             $table->addKeyInfo('categoryid', XMLDB_KEY_FOREIGN, array('categoryid'), 'grade_categories', array('id'));
!             $table->addKeyInfo('scaleid', XMLDB_KEY_FOREIGN, array('scaleid'), 'scale', array('id'));
!             $table->addKeyInfo('outcomeid', XMLDB_KEY_FOREIGN, array('outcomeid'), 'grade_outcomes', array('id'));
! 
!         /// Adding indexes to table grade_items_history
!             $table->addIndexInfo('action', XMLDB_INDEX_NOTUNIQUE, array('action'));
! 
!         /// Launch create table for grade_items_history
!             $result = $result && create_table($table, true, false);
! 
!         } else {
!             delete_records($table->name);
!         }
! 
!         /// Define table grade_categories to be created
!         $table = new XMLDBTable('grade_categories_history');
! 
! 
!         if ($result && !table_exists($table)) {
! 
!         /// Adding fields to table grade_categories_history
!             $table->addFieldInfo('id', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, XMLDB_SEQUENCE, null, null, null);
!             $table->addFieldInfo('action', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null, null, '0');
!             $table->addFieldInfo('oldid', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null, null, null);
!             $table->addFieldInfo('source', XMLDB_TYPE_CHAR, '255', null, null, null, null, null, null);
!             $table->addFieldInfo('timemodified', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, null, null, null, null, null);
!             $table->addFieldInfo('loggeduser', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, null, null, null, null, null);
!             $table->addFieldInfo('courseid', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, null);
!             $table->addFieldInfo('parent', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, null, null, null, null, null);
!             $table->addFieldInfo('depth', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, '0');
!             $table->addFieldInfo('path', XMLDB_TYPE_CHAR, '255', null, null, null, null, null, null);
!             $table->addFieldInfo('fullname', XMLDB_TYPE_CHAR, '255', null, XMLDB_NOTNULL, null, null, null, null);
!             $table->addFieldInfo('aggregation', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null, null, '0');
!             $table->addFieldInfo('keephigh', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null, null, '0');
!             $table->addFieldInfo('droplow', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null, null, '0');
!             $table->addFieldInfo('aggregateonlygraded', XMLDB_TYPE_INTEGER, '1', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, '0');
!             $table->addFieldInfo('aggregateoutcomes', XMLDB_TYPE_INTEGER, '1', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, '0');
!             $table->addFieldInfo('aggregatesubcats', XMLDB_TYPE_INTEGER, '1', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, '0');
! 
!         /// Adding keys to table grade_categories_history
!             $table->addKeyInfo('primary', XMLDB_KEY_PRIMARY, array('id'));
!             $table->addKeyInfo('oldid', XMLDB_KEY_FOREIGN, array('oldid'), 'grade_categories', array('id'));
!             $table->addKeyInfo('courseid', XMLDB_KEY_FOREIGN, array('courseid'), 'course', array('id'));
!             $table->addKeyInfo('parent', XMLDB_KEY_FOREIGN, array('parent'), 'grade_categories', array('id'));
! 
!         /// Adding indexes to table grade_categories_history
!             $table->addIndexInfo('action', XMLDB_INDEX_NOTUNIQUE, array('action'));
! 
!         /// Launch create table for grade_categories_history
!             $result = $result && create_table($table, true, false);
! 
!         } else {
!             delete_records($table->name);
!         }
! 
! 
!         /// Define table grade_grades to be created
!         $table = new XMLDBTable('grade_grades_history');
! 
!         if ($result && !table_exists($table)) {
! 
!         /// Adding fields to table grade_grades_history
!             $table->addFieldInfo('id', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, XMLDB_SEQUENCE, null, null, null);
!             $table->addFieldInfo('action', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null, null, '0');
!             $table->addFieldInfo('oldid', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null, null, null);
!             $table->addFieldInfo('source', XMLDB_TYPE_CHAR, '255', null, null, null, null, null, null);
!             $table->addFieldInfo('timemodified', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, null, null, null, null, null);
!             $table->addFieldInfo('loggeduser', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, null, null, null, null, null);
!             $table->addFieldInfo('itemid', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, null);
!             $table->addFieldInfo('userid', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, null);
!             $table->addFieldInfo('rawgrade', XMLDB_TYPE_NUMBER, '10, 5', null, null, null, null, null, null);
!             $table->addFieldInfo('rawgrademax', XMLDB_TYPE_NUMBER, '10, 5', null, XMLDB_NOTNULL, null, null, null, '100');
!             $table->addFieldInfo('rawgrademin', XMLDB_TYPE_NUMBER, '10, 5', null, XMLDB_NOTNULL, null, null, null, '0');
!             $table->addFieldInfo('rawscaleid', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, null, null, null, null, null);
!             $table->addFieldInfo('usermodified', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, null, null, null, null, null);
!             $table->addFieldInfo('finalgrade', XMLDB_TYPE_NUMBER, '10, 5', null, null, null, null, null, null);
!             $table->addFieldInfo('hidden', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, '0');
!             $table->addFieldInfo('locked', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, '0');
!             $table->addFieldInfo('locktime', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, '0');
!             $table->addFieldInfo('exported', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, '0');
!             $table->addFieldInfo('overridden', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, '0');
!             $table->addFieldInfo('excluded', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, '0');
!             $table->addFieldInfo('feedback', XMLDB_TYPE_TEXT, 'medium', XMLDB_UNSIGNED, null, null, null, null, null);
!             $table->addFieldInfo('feedbackformat', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, '0');
!             $table->addFieldInfo('information', XMLDB_TYPE_TEXT, 'medium', XMLDB_UNSIGNED, null, null, null, null, null);
!             $table->addFieldInfo('informationformat', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, '0');
! 
!         /// Adding keys to table grade_grades_history
!             $table->addKeyInfo('primary', XMLDB_KEY_PRIMARY, array('id'));
!             $table->addKeyInfo('oldid', XMLDB_KEY_FOREIGN, array('oldid'), 'grade_grades', array('id'));
!             $table->addKeyInfo('itemid', XMLDB_KEY_FOREIGN, array('itemid'), 'grade_items', array('id'));
!             $table->addKeyInfo('userid', XMLDB_KEY_FOREIGN, array('userid'), 'user', array('id'));
!             $table->addKeyInfo('rawscaleid', XMLDB_KEY_FOREIGN, array('rawscaleid'), 'scale', array('id'));
!             $table->addKeyInfo('usermodified', XMLDB_KEY_FOREIGN, array('usermodified'), 'user', array('id'));
!             $table->addKeyInfo('loggeduser', XMLDB_KEY_FOREIGN, array('loggeduser'), 'user', array('id'));
! 
!         /// Adding indexes to table grade_grades_history
!             $table->addIndexInfo('action', XMLDB_INDEX_NOTUNIQUE, array('action'));
! 
!         /// Launch create table for grade_grades_history
!             $result = $result && create_table($table, true, false);
! 
!         } else {
!             delete_records($table->name);
!         }
! 
! 
!         /// Define table grade_outcomes to be created
!         $table = new XMLDBTable('grade_outcomes_history');
! 
!         if ($result && !table_exists($table)) {
! 
!         /// Adding fields to table grade_outcomes_history
!             $table->addFieldInfo('id', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, XMLDB_SEQUENCE, null, null, null);
!             $table->addFieldInfo('action', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null, null, '0');
!             $table->addFieldInfo('oldid', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null, null, null);
!             $table->addFieldInfo('source', XMLDB_TYPE_CHAR, '255', null, null, null, null, null, null);
!             $table->addFieldInfo('timemodified', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, null, null, null, null, null);
!             $table->addFieldInfo('loggeduser', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, null, null, null, null, null);
!             $table->addFieldInfo('courseid', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, null, null, null, null, null);
!             $table->addFieldInfo('shortname', XMLDB_TYPE_CHAR, '255', null, XMLDB_NOTNULL, null, null, null, null);
!             $table->addFieldInfo('fullname', XMLDB_TYPE_TEXT, 'small', null, XMLDB_NOTNULL, null, null, null, null);
!             $table->addFieldInfo('scaleid', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, null, null, null, null, null);
! 
!         /// Adding keys to table grade_outcomes_history
!             $table->addKeyInfo('primary', XMLDB_KEY_PRIMARY, array('id'));
!             $table->addKeyInfo('oldid', XMLDB_KEY_FOREIGN, array('oldid'), 'grade_outcomes', array('id'));
!             $table->addKeyInfo('courseid', XMLDB_KEY_FOREIGN, array('courseid'), 'course', array('id'));
!             $table->addKeyInfo('scaleid', XMLDB_KEY_FOREIGN, array('scaleid'), 'scale', array('id'));
!             $table->addKeyInfo('loggeduser', XMLDB_KEY_FOREIGN, array('loggeduser'), 'user', array('id'));
! 
!         /// Adding indexes to table grade_outcomes_history
!             $table->addIndexInfo('action', XMLDB_INDEX_NOTUNIQUE, array('action'));
! 
!         /// Launch create table for grade_outcomes_history
!             $result = $result && create_table($table, true, false);
! 
!         } else {
!             delete_records($table->name);
!         }
! 
!         /// Define table scale to be created
!         $table = new XMLDBTable('scale_history');
! 
! 
!         if ($result && !table_exists($table)) {
! 
!         /// Adding fields to table scale_history
!             $table->addFieldInfo('id', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, XMLDB_SEQUENCE, null, null, null);
!             $table->addFieldInfo('action', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null, null, '0');
!             $table->addFieldInfo('oldid', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null, null, null);
!             $table->addFieldInfo('source', XMLDB_TYPE_CHAR, '255', null, null, null, null, null, null);
!             $table->addFieldInfo('timemodified', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, null, null, null, null, null);
!             $table->addFieldInfo('loggeduser', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, null, null, null, null, null);
!             $table->addFieldInfo('courseid', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, '0');
!             $table->addFieldInfo('userid', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, '0');
!             $table->addFieldInfo('name', XMLDB_TYPE_CHAR, '255', null, XMLDB_NOTNULL, null, null, null, null);
!             $table->addFieldInfo('scale', XMLDB_TYPE_TEXT, 'small', null, XMLDB_NOTNULL, null, null, null, null);
!             $table->addFieldInfo('description', XMLDB_TYPE_TEXT, 'small', null, XMLDB_NOTNULL, null, null, null, null);
! 
!         /// Adding keys to table scale_history
!             $table->addKeyInfo('primary', XMLDB_KEY_PRIMARY, array('id'));
!             $table->addKeyInfo('oldid', XMLDB_KEY_FOREIGN, array('oldid'), 'scales', array('id'));
!             $table->addKeyInfo('courseid', XMLDB_KEY_FOREIGN, array('courseid'), 'course', array('id'));
! 
!         /// Adding indexes to table scale_history
!             $table->addIndexInfo('action', XMLDB_INDEX_NOTUNIQUE, array('action'));
! 
!         /// Launch create table for scale_history
!             $result = $result && create_table($table, true, false);
! 
!         } else {
!             delete_records($table->name);
!         }
! 
!         return $result;
      }
  
      /**
--- 103,118 ----
       */
      function setUp() {
          // Set global category settings to -1 (not force)
!         global $CFG, $db;
          $CFG->grade_droplow = -1;
          $CFG->grade_keephigh = -1;
          $CFG->grade_aggregation = -1;
          $CFG->grade_aggregateonlygraded = -1;
          $CFG->grade_aggregateoutcomes = -1;
          $CFG->grade_aggregatesubcats = -1;
!         $CFG->disablegradehistory = false;
! 		$this->real_db = fullclone($db);
!         $this->reset_mocks();
      }
  
      /**
***************
*** 629,640 ****
       * Restore original $CFG->prefix.
       */
      function tearDown() {
!         global $CFG;
!         // delete the contents of tables before the test run - the unit test might fail on fatal error and the data would not be deleted!
!         foreach ($this->tables as $table) {
              unset($this->$table);
          }
!         $CFG->prefix = $CFG->old_prefix;
      }
  
      /**
--- 120,156 ----
       * Restore original $CFG->prefix.
       */
      function tearDown() {
!         global $CFG, $db;
! 		// delete the contents of tables before the test run - the unit test might fail on fatal error and the data would not be deleted!
!         foreach ($this->loaded_tables as $table) {
              unset($this->$table);
          }
!         $this->loaded_tables = array();
! 		$db = $this->real_db; 
!     }
! 
!     function reset_mocks() {
!         global $db, $CFG;
!         $db = new mock_db();
!         $this->rs = new mock_rs();
!         $this->rs->EOF = false;
!         $db->setReturnReference('Execute', $this->rs);
!         $db->setReturnReference('SelectLimit', $this->rs); 
!         $mock_gi = new mock_grade_item_partial($this);
!         $mock_gc = new mock_grade_category_partial($this);
!         $mock_gg = new mock_grade_grade_partial($this);
!         $mock_go = new mock_grade_outcome_partial($this);
!         $mock_gs = new mock_grade_scale_partial($this);
!         $mock_gi->lib_wrapper = new mock_lib_wrapper();
!         $mock_gc->lib_wrapper = new mock_lib_wrapper();
!         $mock_gg->lib_wrapper = new mock_lib_wrapper();
!         $mock_go->lib_wrapper = new mock_lib_wrapper();
!         $mock_gs->lib_wrapper = new mock_lib_wrapper();
!         grade_object::get_instance('grade_item', null, false, true, $mock_gi);
!         grade_object::get_instance('grade_category', null, false, true, $mock_gc);
!         grade_object::get_instance('grade_grade', null, false, true, $mock_gg);
!         grade_object::get_instance('grade_outcome', null, false, true, $mock_go);
!         grade_object::get_instance('grade_scale', null, false, true, $mock_gs); 
      }
  
      /**
***************
*** 643,648 ****
--- 159,165 ----
      function load_scale() {
          $scale = new stdClass();
  
+         $scale->id          = 1;
          $scale->name        = 'unittestscale1';
          $scale->courseid    = $this->courseid;
          $scale->userid      = $this->userid;
***************
*** 650,663 ****
          $scale->description = 'This scale defines some of qualities that make posts helpful within the Moodle help forums.\n Your feedback will help others see how their posts are being received.';
          $scale->timemodified = mktime();
  
!         if ($scale->id = insert_record('scale', $scale)) {
!             $this->scale[0] = $scale;
!             $temp = explode(',', $scale->scale);
!             $this->scalemax[0] = count($temp) -1;
!         }
  
          $scale = new stdClass();
  
          $scale->name        = 'unittestscale2';
          $scale->courseid    = $this->courseid;
          $scale->userid      = $this->userid;
--- 167,179 ----
          $scale->description = 'This scale defines some of qualities that make posts helpful within the Moodle help forums.\n Your feedback will help others see how their posts are being received.';
          $scale->timemodified = mktime();
  
!         $this->scale[0] = $scale;
!         $temp = explode(',', $scale->scale);
!         $this->scalemax[0] = count($temp) -1;
  
          $scale = new stdClass();
  
+         $scale->id          = 2;
          $scale->name        = 'unittestscale2';
          $scale->courseid    = $this->courseid;
          $scale->userid      = $this->userid;
***************
*** 665,678 ****
          $scale->description = 'This scale is used to mark standard assignments.';
          $scale->timemodified = mktime();
  
!         if ($scale->id = insert_record('scale', $scale)) {
!             $this->scale[1] = $scale;
!             $temp = explode(',', $scale->scale);
!             $this->scalemax[1] = count($temp) -1;
!         }
  
          $scale = new stdClass();
  
          $scale->name        = 'unittestscale3';
          $scale->courseid    = $this->courseid;
          $scale->userid      = $this->userid;
--- 181,193 ----
          $scale->description = 'This scale is used to mark standard assignments.';
          $scale->timemodified = mktime();
  
!         $this->scale[1] = $scale;
!         $temp = explode(',', $scale->scale);
!         $this->scalemax[1] = count($temp) -1;
  
          $scale = new stdClass();
  
+         $scale->id          = 3;
          $scale->name        = 'unittestscale3';
          $scale->courseid    = $this->courseid;
          $scale->userid      = $this->userid;
***************
*** 682,693 ****
          $temp  = explode(',', $scale->scale);
          $scale->max         = count($temp) -1;
  
!         if ($scale->id = insert_record('scale', $scale)) {
!             $this->scale[2] = $scale;
!             $temp = explode(',', $scale->scale);
!             $this->scalemax[2] = count($temp) -1;
!         }
  
          $scale->name        = 'unittestscale4';
          $scale->courseid    = $this->courseid;
          $scale->userid      = $this->userid;
--- 197,207 ----
          $temp  = explode(',', $scale->scale);
          $scale->max         = count($temp) -1;
  
!         $this->scale[2] = $scale;
!         $temp = explode(',', $scale->scale);
!         $this->scalemax[2] = count($temp) -1;
  
+         $scale->id          = 4;
          $scale->name        = 'unittestscale4';
          $scale->courseid    = $this->courseid;
          $scale->userid      = $this->userid;
***************
*** 697,708 ****
          $temp  = explode(',', $scale->scale);
          $scale->max         = count($temp) -1;
  
!         if ($scale->id = insert_record('scale', $scale)) {
!             $this->scale[3] = $scale;
!             $temp = explode(',', $scale->scale);
!             $this->scalemax[3] = count($temp) -1;
!         }
  
          $scale->name        = 'unittestscale5';
          $scale->courseid    = $this->courseid;
          $scale->userid      = $this->userid;
--- 211,221 ----
          $temp  = explode(',', $scale->scale);
          $scale->max         = count($temp) -1;
  
!         $this->scale[3] = $scale;
!         $temp = explode(',', $scale->scale);
!         $this->scalemax[3] = count($temp) -1;
  
+         $scale->id          = 5;
          $scale->name        = 'unittestscale5';
          $scale->courseid    = $this->courseid;
          $scale->userid      = $this->userid;
***************
*** 712,733 ****
          $temp  = explode(',', $scale->scale);
          $scale->max         = count($temp) -1;
  
!         if ($scale->id = insert_record('scale', $scale)) {
!             $this->scale[4] = $scale;
!             $temp = explode(',', $scale->scale);
!             $this->scalemax[4] = count($temp) -1;
!         }
      }
  
      /**
       * Load grade_category data into the database, and adds the corresponding objects to this class' variable.
       */
      function load_grade_categories() {
  
!         $course_category = grade_category::fetch_course_category($this->courseid);
  
          $grade_category = new stdClass();
  
          $grade_category->fullname    = 'unittestcategory1';
          $grade_category->courseid    = $this->courseid;
          $grade_category->aggregation = GRADE_AGGREGATE_MEAN;
--- 225,257 ----
          $temp  = explode(',', $scale->scale);
          $scale->max         = count($temp) -1;
  
!         $this->scale[4] = $scale;
!         $temp = explode(',', $scale->scale);
!         $this->scalemax[4] = count($temp) -1;
! 
!         $this->loaded_tables[] = 'scale';
      }
  
      /**
       * Load grade_category data into the database, and adds the corresponding objects to this class' variable.
       */
      function load_grade_categories() {
+         $id = 1;
  
!         $course_category = new stdClass();
!         $course_category->id = $id++;
!         $course_category->courseid    = $this->courseid;
!         $course_category->fullname = "Course grade category";
!         $course_category->path = null;
!         $course_category->parent = null;
!         $course_category->aggregate = GRADE_AGGREGATE_MEAN;
!         $course_category->timecreated = $course_category->timemodified = time();
!         
!         $this->grade_categories[] = $course_category;
  
          $grade_category = new stdClass();
  
+         $grade_category->id          = $id++;
          $grade_category->fullname    = 'unittestcategory1';
          $grade_category->courseid    = $this->courseid;
          $grade_category->aggregation = GRADE_AGGREGATE_MEAN;
***************
*** 735,792 ****
          $grade_category->keephigh    = 0;
          $grade_category->droplow     = 0;
          $grade_category->parent      = $course_category->id;
!         $grade_category->timecreated = mktime();
!         $grade_category->timemodified = mktime();
          $grade_category->depth = 2;
  
!         if ($grade_category->id = insert_record('grade_categories', $grade_category)) {
!             $grade_category->path = '/'.$course_category->id.'/'.$grade_category->id.'/';
!             update_record('grade_categories', $grade_category);
!             $this->grade_categories[0] = $grade_category;
!         }
  
          $grade_category = new stdClass();
  
          $grade_category->fullname    = 'unittestcategory2';
          $grade_category->courseid    = $this->courseid;
          $grade_category->aggregation = GRADE_AGGREGATE_MEAN;
          $grade_category->aggregateonlygraded = 1;
          $grade_category->keephigh    = 0;
          $grade_category->droplow     = 0;
!         $grade_category->parent      = $this->grade_categories[0]->id;
!         $grade_category->timecreated = mktime();
!         $grade_category->timemodified = mktime();
          $grade_category->depth = 3;
  
!         if ($grade_category->id = insert_record('grade_categories', $grade_category)) {
!             $grade_category->path = $this->grade_categories[0]->path.$grade_category->id.'/';
!             update_record('grade_categories', $grade_category);
!             $this->grade_categories[1] = $grade_category;
!         }
  
          $grade_category = new stdClass();
  
          $grade_category->fullname    = 'unittestcategory3';
          $grade_category->courseid    = $this->courseid;
          $grade_category->aggregation = GRADE_AGGREGATE_MEAN;
          $grade_category->aggregateonlygraded = 1;
          $grade_category->keephigh    = 0;
          $grade_category->droplow     = 0;
!         $grade_category->parent      = $this->grade_categories[0]->id;
!         $grade_category->timecreated = mktime();
!         $grade_category->timemodified = mktime();
          $grade_category->depth = 3;
  
!         if ($grade_category->id = insert_record('grade_categories', $grade_category)) {
!             $grade_category->path = $this->grade_categories[0]->path.$grade_category->id.'/';
!             update_record('grade_categories', $grade_category);
!             $this->grade_categories[2] = $grade_category;
!         }
  
          // A category with no parent, but grade_items as children
  
          $grade_category = new stdClass();
  
          $grade_category->fullname    = 'level1category';
          $grade_category->courseid    = $this->courseid;
          $grade_category->aggregation = GRADE_AGGREGATE_MEAN;
--- 259,307 ----
          $grade_category->keephigh    = 0;
          $grade_category->droplow     = 0;
          $grade_category->parent      = $course_category->id;
!         $grade_category->timecreated = $grade_category->timemodified = mktime();
          $grade_category->depth = 2;
  
!         $grade_category->path = '/'.$course_category->id.'/'.$grade_category->id.'/';
!         $this->grade_categories[] = $grade_category;
  
          $grade_category = new stdClass();
  
+         $grade_category->id          = $id++;
          $grade_category->fullname    = 'unittestcategory2';
          $grade_category->courseid    = $this->courseid;
          $grade_category->aggregation = GRADE_AGGREGATE_MEAN;
          $grade_category->aggregateonlygraded = 1;
          $grade_category->keephigh    = 0;
          $grade_category->droplow     = 0;
!         $grade_category->parent      = $this->grade_categories[1]->id;
!         $grade_category->timecreated = $grade_category->timemodified = mktime();
          $grade_category->depth = 3;
  
!         $grade_category->path = $this->grade_categories[1]->path.$grade_category->id.'/';
!         $this->grade_categories[] = $grade_category;
  
          $grade_category = new stdClass();
  
+         $grade_category->id          = $id++;
          $grade_category->fullname    = 'unittestcategory3';
          $grade_category->courseid    = $this->courseid;
          $grade_category->aggregation = GRADE_AGGREGATE_MEAN;
          $grade_category->aggregateonlygraded = 1;
          $grade_category->keephigh    = 0;
          $grade_category->droplow     = 0;
!         $grade_category->parent      = $this->grade_categories[1]->id;
!         $grade_category->timecreated = $grade_category->timemodified = mktime();
          $grade_category->depth = 3;
  
!         $grade_category->path = $this->grade_categories[1]->path.$grade_category->id.'/';
!         $this->grade_categories[] = $grade_category;
  
          // A category with no parent, but grade_items as children
  
          $grade_category = new stdClass();
  
+         $grade_category->id          = $id++;
          $grade_category->fullname    = 'level1category';
          $grade_category->courseid    = $this->courseid;
          $grade_category->aggregation = GRADE_AGGREGATE_MEAN;
***************
*** 794,808 ****
          $grade_category->keephigh    = 0;
          $grade_category->droplow     = 0;
          $grade_category->parent      = $course_category->id;
!         $grade_category->timecreated = mktime();
!         $grade_category->timemodified = mktime();
          $grade_category->depth = 2;
  
!         if ($grade_category->id = insert_record('grade_categories', $grade_category)) {
!             $grade_category->path = '/'.$course_category->id.'/'.$grade_category->id.'/';
!             update_record('grade_categories', $grade_category);
!             $this->grade_categories[3] = $grade_category;
!         }
      }
  
      /**
--- 309,321 ----
          $grade_category->keephigh    = 0;
          $grade_category->droplow     = 0;
          $grade_category->parent      = $course_category->id;
!         $grade_category->timecreated = $grade_category->timemodified = mktime();
          $grade_category->depth = 2;
  
!         $grade_category->path = '/'.$course_category->id.'/'.$grade_category->id.'/';
!         $this->grade_categories[] = $grade_category;
! 
!         $this->loaded_tables[] = 'grade_categories';
      }
  
      /**
***************
*** 810,926 ****
       */
      function load_modules() {
          $module = new stdClass();
          $module->name = 'assignment';
!         if ($module->id = insert_record('modules', $module)) {
!             $this->modules[0] = $module;
!         }
  
          $module = new stdClass();
          $module->name = 'quiz';
!         if ($module->id = insert_record('modules', $module)) {
!             $this->modules[1] = $module;
!         }
  
          $module = new stdClass();
          $module->name = 'forum';
!         if ($module->id = insert_record('modules', $module)) {
!             $this->modules[2] = $module;
!         }
      }
  
      /**
       * Load module instance entries in course_modules table
       */
      function load_course_modules() {
!         $course_module = new stdClass();
!         $course_module->course = $this->courseid;
!         $quiz->module = 1;
!         $quiz->instance = 2;
!         if ($course_module->id = insert_record('course_modules', $course_module)) {
!             $this->course_module[0] = $course_module;
          }
  
          $course_module = new stdClass();
          $course_module->course = $this->courseid;
!         $quiz->module = 2;
!         $quiz->instance = 1;
!         if ($course_module->id = insert_record('course_modules', $course_module)) {
!             $this->course_module[0] = $course_module;
!         }
  
          $course_module = new stdClass();
          $course_module->course = $this->courseid;
!         $quiz->module = 2;
!         $quiz->instance = 5;
!         if ($course_module->id = insert_record('course_modules', $course_module)) {
!             $this->course_module[0] = $course_module;
!         }
  
          $course_module = new stdClass();
          $course_module->course = $this->courseid;
!         $quiz->module = 3;
!         $quiz->instance = 3;
!         if ($course_module->id = insert_record('course_modules', $course_module)) {
!             $this->course_module[0] = $course_module;
!         }
  
          $course_module = new stdClass();
          $course_module->course = $this->courseid;
!         $quiz->module = 3;
!         $quiz->instance = 7;
!         if ($course_module->id = insert_record('course_modules', $course_module)) {
!             $this->course_module[0] = $course_module;
!         }
  
          $course_module = new stdClass();
          $course_module->course = $this->courseid;
!         $quiz->module = 3;
!         $quiz->instance = 9;
!         if ($course_module->id = insert_record('course_modules', $course_module)) {
!             $this->course_module[0] = $course_module;
!         }
!     }
! 
!     /**
!      * Load test quiz data into the database
!      */
!     function load_quiz_activities() {
!         $quiz = new stdClass();
!         $quiz->course = $this->courseid;
!         $quiz->name = 'test quiz';
!         $quiz->intro = 'let us quiz you!';
!         $quiz->questions = '1,2';
!         if ($quiz->id = insert_record('quiz', $quiz)) {
!             $this->activities[0] = $quiz;
!         }
  
!         $quiz = new stdClass();
!         $quiz->course = $this->courseid;
!         $quiz->name = 'test quiz 2';
!         $quiz->intro = 'let us quiz you again!';
!         $quiz->questions = '1,3';
!         if ($quiz->id = insert_record('quiz', $quiz)) {
!             $this->activities[1] = $quiz;
!         }
  
      }
  
      /**
       * Load grade_item data into the database, and adds the corresponding objects to this class' variable.
       */
      function load_grade_items() {
  
-         $course_category = grade_category::fetch_course_category($this->courseid);
- 
-         // id = 0
          $grade_item = new stdClass();
  
          $grade_item->courseid = $this->courseid;
          $grade_item->categoryid = $this->grade_categories[1]->id;
          $grade_item->itemname = 'unittestgradeitem1';
          $grade_item->itemtype = 'mod';
          $grade_item->itemmodule = 'quiz';
!         $grade_item->iteminstance = 1;
          $grade_item->gradetype = GRADE_TYPE_VALUE;
          $grade_item->grademin = 30;
          $grade_item->grademax = 110;
--- 323,505 ----
       */
      function load_modules() {
          $module = new stdClass();
+         $module->id   = 1;
          $module->name = 'assignment';
!         $this->modules[] = $module;
  
          $module = new stdClass();
+         $module->id   = 2;
          $module->name = 'quiz';
!         $this->modules[] = $module;
  
          $module = new stdClass();
+         $module->id   = 3;
          $module->name = 'forum';
!         $this->modules[] = $module;
! 
!         $this->loaded_tables[] = 'modules';
!     }
! 
!     /**
!      * Load test quiz data into the database
!      */
!     function load_quiz() {
!         $quiz = new stdClass();
!         $quiz->id = 1;
!         $quiz->course = $this->courseid;
!         $quiz->name = 'test quiz';
!         $quiz->intro = 'let us quiz you!';
!         $quiz->questions = '1,2';
!         $this->quizzes[] = $quiz;
! 
!         $quiz = new stdClass();
!         $quiz->id = 2;
!         $quiz->course = $this->courseid;
!         $quiz->name = 'test quiz 2';
!         $quiz->intro = 'let us quiz you again!';
!         $quiz->questions = '1,3';
!         $this->quizzes[] = $quiz;
! 
!         $this->loaded_tables[] = 'quiz';
!     }
! 
!     /**
!      * Load test assignment data into the database
!      */
!     function load_assignment() {
!         $assignment = new stdClass();
!         $assignment->id = 1;
!         $assignment->course = $this->courseid;
!         $assignment->name = 'test assignment';
!         $assignment->description = 'What is the purpose of life?';
!         $this->assignments[] = $assignment;
! 
!         $this->loaded_tables[] = 'assignment';
!     }
! 
!     /**
!      * Load test forum data into the database
!      */
!     function load_forum() {
!         $forum = new stdClass();
!         $forum->id = 1;
!         $forum->course = $this->courseid;
!         $forum->name = 'test forum 1';
!         $forum->intro = 'Another test forum';
!         $this->forums[] = $forum;
!     
!         $forum = new stdClass();
!         $forum->id = 2;
!         $forum->course = $this->courseid;
!         $forum->name = 'test forum 2';
!         $forum->intro = 'Another test forum';
!         $this->forums[] = $forum;
!     
!         $forum = new stdClass();
!         $forum->id = 3;
!         $forum->course = $this->courseid;
!         $forum->name = 'test forum 3';
!         $forum->intro = 'Another test forum';
!         $this->forums[] = $forum;
! 
!         $this->loaded_tables[] = 'forum';
      }
  
      /**
       * Load module instance entries in course_modules table
       */
      function load_course_modules() {
!         if (!in_array('modules', $this->loaded_tables)) {
!             $this->load_modules();
!         }
!         if (!in_array('quiz', $this->loaded_tables)) {
!             $this->load_quiz();
!         }
!         if (!in_array('assignment', $this->loaded_tables)) {
!             $this->load_assignment();
!         }
!         if (!in_array('forum', $this->loaded_tables)) {
!             $this->load_forum();
          }
  
          $course_module = new stdClass();
+         $course_module->id = 1;
          $course_module->course = $this->courseid;
!         $course_module->module = $this->modules[0]->id;
!         $course_module->instance = $this->assignments[0]->id;
!         $this->course_modules[] = $course_module;
  
          $course_module = new stdClass();
+         $course_module->id = 2;
          $course_module->course = $this->courseid;
!         $course_module->module = $this->modules[1]->id;
!         $course_module->instance = $this->quizzes[0]->id;
!         $this->course_modules[] = $course_module;
  
          $course_module = new stdClass();
+         $course_module->id = 3;
          $course_module->course = $this->courseid;
!         $course_module->module = $this->modules[1]->id;
!         $course_module->instance = $this->quizzes[1]->id;
!         $this->course_modules[] = $course_module;
  
          $course_module = new stdClass();
+         $course_module->id = 4;
          $course_module->course = $this->courseid;
!         $course_module->module = $this->modules[2]->id;
!         $course_module->instance = $this->forums[0]->id;
!         $this->course_modules[] = $course_module;
  
          $course_module = new stdClass();
+         $course_module->id = 5;
          $course_module->course = $this->courseid;
!         $course_module->module = $this->modules[2]->id;
!         $course_module->instance = $this->forums[1]->id;
!         $this->course_modules[] = $course_module;
  
!         $course_module = new stdClass();
!         $course_module->id = 6;
!         $course_module->course = $this->courseid;
!         $course_module->module = $this->modules[2]->id;
!         $course_module->instance = $this->forums[2]->id;
!         $this->course_modules[] = $course_module;
  
+         $this->loaded_tables[] = 'course_modules';
      }
  
      /**
       * Load grade_item data into the database, and adds the corresponding objects to this class' variable.
       */
      function load_grade_items() {
+         if (!in_array('scale', $this->loaded_tables)) {
+             $this->load_scale();
+         }
+         if (!in_array('grade_categories', $this->loaded_tables)) {
+             $this->load_grade_categories();
+         }
+         if (!in_array('quiz', $this->loaded_tables)) {
+             $this->load_quiz();
+         }
+         if (!in_array('assignment', $this->loaded_tables)) {
+             $this->load_assignment();
+         }
+         if (!in_array('forum', $this->loaded_tables)) {
+             $this->load_forum();
+         }
+         
+         $id = 1;
+         
+         $course_category = $this->grade_categories[0];
  
          $grade_item = new stdClass();
  
+         $grade_item->id = $id++;
          $grade_item->courseid = $this->courseid;
          $grade_item->categoryid = $this->grade_categories[1]->id;
          $grade_item->itemname = 'unittestgradeitem1';
          $grade_item->itemtype = 'mod';
          $grade_item->itemmodule = 'quiz';
!         $grade_item->iteminstance = $this->quizzes[0]->id;
          $grade_item->gradetype = GRADE_TYPE_VALUE;
          $grade_item->grademin = 30;
          $grade_item->grademax = 110;
***************
*** 930,951 ****
          $grade_item->timecreated = mktime();
          $grade_item->timemodified = mktime();
          $grade_item->sortorder = 3;
  
!         if ($grade_item->id = insert_record('grade_items', $grade_item)) {
!             $this->grade_items[0] = $grade_item;
!         }
  
-         // id = 1
          $grade_item = new stdClass();
  
          $grade_item->courseid = $this->courseid;
!         $grade_item->categoryid = $this->grade_categories[1]->id;
          $grade_item->itemname = 'unittestgradeitem2';
          $grade_item->itemtype = 'import';
          $grade_item->itemmodule = 'assignment';
          $grade_item->calculation = '= ##gi'.$this->grade_items[0]->id.'## + 30 + [[item id 0]] - [[item id 0]]';
          $grade_item->gradetype = GRADE_TYPE_VALUE;
!         $grade_item->iteminstance = 2;
          $grade_item->itemnumber = null;
          $grade_item->grademin = 0;
          $grade_item->grademax = 100;
--- 509,529 ----
          $grade_item->timecreated = mktime();
          $grade_item->timemodified = mktime();
          $grade_item->sortorder = 3;
+         $grade_item->needsupdate = false;
  
!         $this->grade_items[] = $grade_item;
  
          $grade_item = new stdClass();
  
+         $grade_item->id = $id++;
          $grade_item->courseid = $this->courseid;
!         $grade_item->categoryid = $this->grade_categories[2]->id;
          $grade_item->itemname = 'unittestgradeitem2';
          $grade_item->itemtype = 'import';
          $grade_item->itemmodule = 'assignment';
          $grade_item->calculation = '= ##gi'.$this->grade_items[0]->id.'## + 30 + [[item id 0]] - [[item id 0]]';
          $grade_item->gradetype = GRADE_TYPE_VALUE;
!         $grade_item->iteminstance = $this->assignments[0]->id;
          $grade_item->itemnumber = null;
          $grade_item->grademin = 0;
          $grade_item->grademax = 100;
***************
*** 954,972 ****
          $grade_item->timemodified = mktime();
          $grade_item->sortorder = 4;
  
!         if ($grade_item->id = insert_record('grade_items', $grade_item)) {
!             $this->grade_items[1] = $grade_item;
!         }
  
-         // id = 2
          $grade_item = new stdClass();
  
          $grade_item->courseid = $this->courseid;
!         $grade_item->categoryid = $this->grade_categories[2]->id;
          $grade_item->itemname = 'unittestgradeitem3';
          $grade_item->itemtype = 'mod';
          $grade_item->itemmodule = 'forum';
!         $grade_item->iteminstance = 3;
          $grade_item->gradetype = GRADE_TYPE_SCALE;
          $grade_item->scaleid = $this->scale[0]->id;
          $grade_item->grademin = 0;
--- 532,548 ----
          $grade_item->timemodified = mktime();
          $grade_item->sortorder = 4;
  
!         $this->grade_items[] = $grade_item;
  
          $grade_item = new stdClass();
  
+         $grade_item->id = $id++;
          $grade_item->courseid = $this->courseid;
!         $grade_item->categoryid = $this->grade_categories[3]->id;
          $grade_item->itemname = 'unittestgradeitem3';
          $grade_item->itemtype = 'mod';
          $grade_item->itemmodule = 'forum';
!         $grade_item->iteminstance = $this->forums[0]->id;
          $grade_item->gradetype = GRADE_TYPE_SCALE;
          $grade_item->scaleid = $this->scale[0]->id;
          $grade_item->grademin = 0;
***************
*** 976,991 ****
          $grade_item->timemodified = mktime();
          $grade_item->sortorder = 6;
  
!         if ($grade_item->id = insert_record('grade_items', $grade_item)) {
!             $this->grade_items[2] = $grade_item;
!         }
  
          // Load grade_items associated with the 3 categories
-         // id = 3
          $grade_item = new stdClass();
  
          $grade_item->courseid = $this->courseid;
!         $grade_item->iteminstance = $this->grade_categories[0]->id;
          $grade_item->itemname = 'unittestgradeitemcategory1';
          $grade_item->needsupdate = 0;
          $grade_item->itemtype = 'category';
--- 552,565 ----
          $grade_item->timemodified = mktime();
          $grade_item->sortorder = 6;
  
!         $this->grade_items[] = $grade_item;
  
          // Load grade_items associated with the 3 categories
          $grade_item = new stdClass();
  
+         $grade_item->id = $id++;
          $grade_item->courseid = $this->courseid;
!         $grade_item->iteminstance = $this->grade_categories[1]->id;
          $grade_item->itemname = 'unittestgradeitemcategory1';
          $grade_item->needsupdate = 0;
          $grade_item->itemtype = 'category';
***************
*** 997,1011 ****
          $grade_item->timemodified = mktime();
          $grade_item->sortorder = 1;
  
!         if ($grade_item->id = insert_record('grade_items', $grade_item)) {
!             $this->grade_items[3] = $grade_item;
!         }
  
-         // id = 4
          $grade_item = new stdClass();
  
          $grade_item->courseid = $this->courseid;
!         $grade_item->iteminstance = $this->grade_categories[1]->id;
          $grade_item->itemname = 'unittestgradeitemcategory2';
          $grade_item->itemtype = 'category';
          $grade_item->gradetype = GRADE_TYPE_VALUE;
--- 571,583 ----
          $grade_item->timemodified = mktime();
          $grade_item->sortorder = 1;
  
!         $this->grade_items[] = $grade_item;
  
          $grade_item = new stdClass();
  
+         $grade_item->id = $id++;
          $grade_item->courseid = $this->courseid;
!         $grade_item->iteminstance = $this->grade_categories[2]->id;
          $grade_item->itemname = 'unittestgradeitemcategory2';
          $grade_item->itemtype = 'category';
          $grade_item->gradetype = GRADE_TYPE_VALUE;
***************
*** 1017,1031 ****
          $grade_item->timemodified = mktime();
          $grade_item->sortorder = 2;
  
!         if ($grade_item->id = insert_record('grade_items', $grade_item)) {
!             $this->grade_items[4] = $grade_item;
!         }
  
-         // id = 5
          $grade_item = new stdClass();
  
          $grade_item->courseid = $this->courseid;
!         $grade_item->iteminstance = $this->grade_categories[2]->id;
          $grade_item->itemname = 'unittestgradeitemcategory3';
          $grade_item->itemtype = 'category';
          $grade_item->gradetype = GRADE_TYPE_VALUE;
--- 589,601 ----
          $grade_item->timemodified = mktime();
          $grade_item->sortorder = 2;
  
!         $this->grade_items[] = $grade_item;
  
          $grade_item = new stdClass();
  
+         $grade_item->id = $id++;
          $grade_item->courseid = $this->courseid;
!         $grade_item->iteminstance = $this->grade_categories[3]->id;
          $grade_item->itemname = 'unittestgradeitemcategory3';
          $grade_item->itemtype = 'category';
          $grade_item->gradetype = GRADE_TYPE_VALUE;
***************
*** 1037,1056 ****
          $grade_item->timemodified = mktime();
          $grade_item->sortorder = 5;
  
!         if ($grade_item->id = insert_record('grade_items', $grade_item)) {
!             $this->grade_items[5] = $grade_item;
!         }
  
          // Orphan grade_item
-         // id = 6
          $grade_item = new stdClass();
  
          $grade_item->courseid = $this->courseid;
          $grade_item->categoryid = $course_category->id;
          $grade_item->itemname = 'unittestorphangradeitem1';
          $grade_item->itemtype = 'mod';
          $grade_item->itemmodule = 'quiz';
!         $grade_item->iteminstance = 5;
          $grade_item->itemnumber = 0;
          $grade_item->gradetype = GRADE_TYPE_VALUE;
          $grade_item->grademin = 10;
--- 607,624 ----
          $grade_item->timemodified = mktime();
          $grade_item->sortorder = 5;
  
!         $this->grade_items[] = $grade_item;
  
          // Orphan grade_item
          $grade_item = new stdClass();
  
+         $grade_item->id = $id++;
          $grade_item->courseid = $this->courseid;
          $grade_item->categoryid = $course_category->id;
          $grade_item->itemname = 'unittestorphangradeitem1';
          $grade_item->itemtype = 'mod';
          $grade_item->itemmodule = 'quiz';
!         $grade_item->iteminstance = $this->quizzes[1]->id;
          $grade_item->itemnumber = 0;
          $grade_item->gradetype = GRADE_TYPE_VALUE;
          $grade_item->grademin = 10;
***************
*** 1061,1080 ****
          $grade_item->timemodified = mktime();
          $grade_item->sortorder = 7;
  
!         if ($grade_item->id = insert_record('grade_items', $grade_item)) {
!             $this->grade_items[6] = $grade_item;
!         }
  
          // 2 grade items under level1category
-         // id = 7
          $grade_item = new stdClass();
  
          $grade_item->courseid = $this->courseid;
!         $grade_item->categoryid = $this->grade_categories[3]->id;
          $grade_item->itemname = 'singleparentitem1';
          $grade_item->itemtype = 'mod';
          $grade_item->itemmodule = 'forum';
!         $grade_item->iteminstance = 7;
          $grade_item->gradetype = GRADE_TYPE_SCALE;
          $grade_item->scaleid = $this->scale[0]->id;
          $grade_item->grademin = 0;
--- 629,646 ----
          $grade_item->timemodified = mktime();
          $grade_item->sortorder = 7;
  
!         $this->grade_items[] = $grade_item;
  
          // 2 grade items under level1category
          $grade_item = new stdClass();
  
+         $grade_item->id = $id++;
          $grade_item->courseid = $this->courseid;
!         $grade_item->categoryid = $this->grade_categories[4]->id;
          $grade_item->itemname = 'singleparentitem1';
          $grade_item->itemtype = 'mod';
          $grade_item->itemmodule = 'forum';
!         $grade_item->iteminstance = $this->forums[1]->id;
          $grade_item->gradetype = GRADE_TYPE_SCALE;
          $grade_item->scaleid = $this->scale[0]->id;
          $grade_item->grademin = 0;
***************
*** 1084,1102 ****
          $grade_item->timemodified = mktime();
          $grade_item->sortorder = 9;
  
!         if ($grade_item->id = insert_record('grade_items', $grade_item)) {
!             $this->grade_items[7] = $grade_item;
!         }
  
-         // id = 8
          $grade_item = new stdClass();
  
          $grade_item->courseid = $this->courseid;
!         $grade_item->categoryid = $this->grade_categories[3]->id;
          $grade_item->itemname = 'singleparentitem2';
          $grade_item->itemtype = 'mod';
          $grade_item->itemmodule = 'forum';
!         $grade_item->iteminstance = 9;
          $grade_item->gradetype = GRADE_TYPE_VALUE;
          $grade_item->grademin = 0;
          $grade_item->grademax = 100;
--- 650,666 ----
          $grade_item->timemodified = mktime();
          $grade_item->sortorder = 9;
  
!         $this->grade_items[] = $grade_item;
  
          $grade_item = new stdClass();
  
+         $grade_item->id = $id++;
          $grade_item->courseid = $this->courseid;
!         $grade_item->categoryid = $this->grade_categories[4]->id;
          $grade_item->itemname = 'singleparentitem2';
          $grade_item->itemtype = 'mod';
          $grade_item->itemmodule = 'forum';
!         $grade_item->iteminstance = $this->forums[2]->id;
          $grade_item->gradetype = GRADE_TYPE_VALUE;
          $grade_item->grademin = 0;
          $grade_item->grademax = 100;
***************
*** 1105,1123 ****
          $grade_item->timemodified = mktime();
          $grade_item->sortorder = 10;
  
!         if ($grade_item->id = insert_record('grade_items', $grade_item)) {
!             $this->grade_items[8] = $grade_item;
!         }
  
          // Grade_item for level1category
-         // id = 9
          $grade_item = new stdClass();
  
          $grade_item->courseid = $this->courseid;
          $grade_item->itemname = 'grade_item for level1 category';
          $grade_item->itemtype = 'category';
          $grade_item->itemmodule = 'quiz';
!         $grade_item->iteminstance = $this->grade_categories[3]->id;
          $grade_item->needsupdate = true;
          $grade_item->gradetype = GRADE_TYPE_VALUE;
          $grade_item->grademin = 0;
--- 669,685 ----
          $grade_item->timemodified = mktime();
          $grade_item->sortorder = 10;
  
!         $this->grade_items[] = $grade_item;
  
          // Grade_item for level1category
          $grade_item = new stdClass();
  
+         $grade_item->id = $id++;
          $grade_item->courseid = $this->courseid;
          $grade_item->itemname = 'grade_item for level1 category';
          $grade_item->itemtype = 'category';
          $grade_item->itemmodule = 'quiz';
!         $grade_item->iteminstance = $this->grade_categories[4]->id;
          $grade_item->needsupdate = true;
          $grade_item->gradetype = GRADE_TYPE_VALUE;
          $grade_item->grademin = 0;
***************
*** 1127,1140 ****
          $grade_item->timemodified = mktime();
          $grade_item->sortorder = 8;
  
!         if ($grade_item->id = insert_record('grade_items', $grade_item)) {
!             $this->grade_items[9] = $grade_item;
!         }
  
          // Manual grade_item
-         // id = 10
          $grade_item = new stdClass();
  
          $grade_item->courseid = $this->courseid;
          $grade_item->categoryid = $course_category->id;
          $grade_item->itemname = 'manual grade_item';
--- 689,700 ----
          $grade_item->timemodified = mktime();
          $grade_item->sortorder = 8;
  
!         $this->grade_items[] = $grade_item;
  
          // Manual grade_item
          $grade_item = new stdClass();
  
+         $grade_item->id = $id++;
          $grade_item->courseid = $this->courseid;
          $grade_item->categoryid = $course_category->id;
          $grade_item->itemname = 'manual grade_item';
***************
*** 1148,1156 ****
          $grade_item->timecreated = mktime();
          $grade_item->timemodified = mktime();
  
!         if ($grade_item->id = insert_record('grade_items', $grade_item)) {
!             $this->grade_items[10] = $grade_item;
!         }
  
      }
  
--- 708,716 ----
          $grade_item->timecreated = mktime();
          $grade_item->timemodified = mktime();
  
!         $this->grade_items[] = $grade_item;
! 
!         $this->loaded_tables[] = 'grade_items';
  
      }
  
***************
*** 1158,1167 ****
--- 718,736 ----
       * Load grade_grades data into the database, and adds the corresponding objects to this class' variable.
       */
      function load_grade_grades() {
+         if (!in_array('grade_items', $this->loaded_tables)) {
+             $this->load_grade_items();
+         }
+         $id = 1;
+         $course_category = $this->grade_categories[0];
+ 
          // Grades for grade_item 1
          $grade = new stdClass();
+         $grade->id = $id++;
          $grade->itemid = $this->grade_items[0]->id;
+         $grade->grade_item = $this->grade_items[0];
          $grade->userid = 1;
+         $grade->parent = $course_category->id;
          $grade->rawgrade = 15; // too small
          $grade->finalgrade = 30;
          $grade->timecreated = mktime();
***************
*** 1171,1244 ****
          $grade->feedback = 'Good, but not good enough..';
          $grade->feedbackformat = FORMAT_PLAIN;
  
!         if ($grade->id = insert_record('grade_grades', $grade)) {
!             $this->grade_grades[0] = $grade;
!         }
  
          $grade = new stdClass();
          $grade->itemid = $this->grade_items[0]->id;
          $grade->userid = 2;
          $grade->rawgrade = 40;
          $grade->finalgrade = 40;
          $grade->timecreated = mktime();
          $grade->timemodified = mktime();
  
!         if ($grade->id = insert_record('grade_grades', $grade)) {
!             $this->grade_grades[1] = $grade;
!         }
  
          $grade = new stdClass();
          $grade->itemid = $this->grade_items[0]->id;
          $grade->userid = 3;
          $grade->rawgrade = 170; // too big
          $grade->finalgrade = 110;
          $grade->timecreated = mktime();
          $grade->timemodified = mktime();
  
!         if ($grade->id = insert_record('grade_grades', $grade)) {
!             $this->grade_grades[2] = $grade;
!         }
  
  
          // No raw grades for grade_item 2 - it is calculated
  
          $grade = new stdClass();
          $grade->itemid = $this->grade_items[1]->id;
          $grade->userid = 1;
          $grade->finalgrade = 60;
          $grade->timecreated = mktime();
          $grade->timemodified = mktime();
  
!         if ($grade->id = insert_record('grade_grades', $grade)) {
!             $this->grade_grades[3] = $grade;
!         }
  
          $grade = new stdClass();
          $grade->itemid = $this->grade_items[1]->id;
          $grade->userid = 2;
          $grade->finalgrade = 70;
          $grade->timecreated = mktime();
          $grade->timemodified = mktime();
  
!         if ($grade->id = insert_record('grade_grades', $grade)) {
!             $this->grade_grades[4] = $grade;
!         }
  
          $grade = new stdClass();
          $grade->itemid = $this->grade_items[1]->id;
          $grade->userid = 3;
          $grade->finalgrade = 100;
          $grade->timecreated = mktime();
          $grade->timemodified = mktime();
  
!         if ($grade->id = insert_record('grade_grades', $grade)) {
!             $this->grade_grades[5] = $grade;
!         }
  
  
          // Grades for grade_item 3
  
          $grade = new stdClass();
          $grade->itemid = $this->grade_items[2]->id;
          $grade->userid = 1;
          $grade->rawgrade = 2;
--- 740,809 ----
          $grade->feedback = 'Good, but not good enough..';
          $grade->feedbackformat = FORMAT_PLAIN;
  
!         $this->grade_grades[] = $grade;
  
          $grade = new stdClass();
+         $grade->id = $id++;
          $grade->itemid = $this->grade_items[0]->id;
+         $grade->parent = $course_category->id;
          $grade->userid = 2;
          $grade->rawgrade = 40;
          $grade->finalgrade = 40;
          $grade->timecreated = mktime();
          $grade->timemodified = mktime();
  
!         $this->grade_grades[] = $grade;
  
          $grade = new stdClass();
+         $grade->id = $id++;
          $grade->itemid = $this->grade_items[0]->id;
+         $grade->parent = $course_category->id;
          $grade->userid = 3;
          $grade->rawgrade = 170; // too big
          $grade->finalgrade = 110;
          $grade->timecreated = mktime();
          $grade->timemodified = mktime();
  
!         $this->grade_grades[] = $grade;
  
  
          // No raw grades for grade_item 2 - it is calculated
  
          $grade = new stdClass();
+         $grade->id = $id++;
          $grade->itemid = $this->grade_items[1]->id;
          $grade->userid = 1;
          $grade->finalgrade = 60;
          $grade->timecreated = mktime();
          $grade->timemodified = mktime();
  
!         $this->grade_grades[] = $grade;
  
          $grade = new stdClass();
+         $grade->id = $id++;
          $grade->itemid = $this->grade_items[1]->id;
          $grade->userid = 2;
          $grade->finalgrade = 70;
          $grade->timecreated = mktime();
          $grade->timemodified = mktime();
  
!         $this->grade_grades[] = $grade;
  
          $grade = new stdClass();
+         $grade->id = $id++;
          $grade->itemid = $this->grade_items[1]->id;
          $grade->userid = 3;
          $grade->finalgrade = 100;
          $grade->timecreated = mktime();
          $grade->timemodified = mktime();
  
!         $this->grade_grades[] = $grade;
  
  
          // Grades for grade_item 3
  
          $grade = new stdClass();
+         $grade->id = $id++;
          $grade->itemid = $this->grade_items[2]->id;
          $grade->userid = 1;
          $grade->rawgrade = 2;
***************
*** 1247,1257 ****
          $grade->timecreated = mktime();
          $grade->timemodified = mktime();
  
!         if ($grade->id = insert_record('grade_grades', $grade)) {
!             $this->grade_grades[6] = $grade;
!         }
  
          $grade = new stdClass();
          $grade->itemid = $this->grade_items[2]->id;
          $grade->userid = 2;
          $grade->rawgrade = 3;
--- 812,821 ----
          $grade->timecreated = mktime();
          $grade->timemodified = mktime();
  
!         $this->grade_grades[] = $grade;
  
          $grade = new stdClass();
+         $grade->id = $id++;
          $grade->itemid = $this->grade_items[2]->id;
          $grade->userid = 2;
          $grade->rawgrade = 3;
***************
*** 1260,1270 ****
          $grade->timecreated = mktime();
          $grade->timemodified = mktime();
  
!         if ($grade->id = insert_record('grade_grades', $grade)) {
!             $this->grade_grades[] = $grade;
!         }
  
          $grade = new stdClass();
          $grade->itemid = $this->grade_items[2]->id;
          $grade->userid = 3;
          $grade->rawgrade = 1;
--- 824,833 ----
          $grade->timecreated = mktime();
          $grade->timemodified = mktime();
  
!         $this->grade_grades[] = $grade;
  
          $grade = new stdClass();
+         $grade->id = $id++;
          $grade->itemid = $this->grade_items[2]->id;
          $grade->userid = 3;
          $grade->rawgrade = 1;
***************
*** 1273,1285 ****
          $grade->timecreated = mktime();
          $grade->timemodified = mktime();
  
!         if ($grade->id = insert_record('grade_grades', $grade)) {
!             $this->grade_grades[] = $grade;
!         }
  
          // Grades for grade_item 7
  
          $grade = new stdClass();
          $grade->itemid = $this->grade_items[6]->id;
          $grade->userid = 1;
          $grade->rawgrade = 97;
--- 836,847 ----
          $grade->timecreated = mktime();
          $grade->timemodified = mktime();
  
!         $this->grade_grades[] = $grade;
  
          // Grades for grade_item 7
  
          $grade = new stdClass();
+         $grade->id = $id++;
          $grade->itemid = $this->grade_items[6]->id;
          $grade->userid = 1;
          $grade->rawgrade = 97;
***************
*** 1287,1297 ****
          $grade->timecreated = mktime();
          $grade->timemodified = mktime();
  
!         if ($grade->id = insert_record('grade_grades', $grade)) {
!             $this->grade_grades[] = $grade;
!         }
  
          $grade = new stdClass();
          $grade->itemid = $this->grade_items[6]->id;
          $grade->userid = 2;
          $grade->rawgrade = 49;
--- 849,858 ----
          $grade->timecreated = mktime();
          $grade->timemodified = mktime();
  
!         $this->grade_grades[] = $grade;
  
          $grade = new stdClass();
+         $grade->id = $id++;
          $grade->itemid = $this->grade_items[6]->id;
          $grade->userid = 2;
          $grade->rawgrade = 49;
***************
*** 1299,1309 ****
          $grade->timecreated = mktime();
          $grade->timemodified = mktime();
  
!         if ($grade->id = insert_record('grade_grades', $grade)) {
!             $this->grade_grades[] = $grade;
!         }
  
          $grade = new stdClass();
          $grade->itemid = $this->grade_items[6]->id;
          $grade->userid = 3;
          $grade->rawgrade = 67;
--- 860,869 ----
          $grade->timecreated = mktime();
          $grade->timemodified = mktime();
  
!         $this->grade_grades[] = $grade;
  
          $grade = new stdClass();
+         $grade->id = $id++;
          $grade->itemid = $this->grade_items[6]->id;
          $grade->userid = 3;
          $grade->rawgrade = 67;
***************
*** 1311,1323 ****
          $grade->timecreated = mktime();
          $grade->timemodified = mktime();
  
!         if ($grade->id = insert_record('grade_grades', $grade)) {
!             $this->grade_grades[] = $grade;
!         }
  
          // Grades for grade_item 8
  
          $grade = new stdClass();
          $grade->itemid = $this->grade_items[7]->id;
          $grade->userid = 2;
          $grade->rawgrade = 3;
--- 871,882 ----
          $grade->timecreated = mktime();
          $grade->timemodified = mktime();
  
!         $this->grade_grades[] = $grade;
  
          // Grades for grade_item 8
  
          $grade = new stdClass();
+         $grade->id = $id++;
          $grade->itemid = $this->grade_items[7]->id;
          $grade->userid = 2;
          $grade->rawgrade = 3;
***************
*** 1325,1335 ****
          $grade->timecreated = mktime();
          $grade->timemodified = mktime();
  
!         if ($grade->id = insert_record('grade_grades', $grade)) {
!             $this->grade_grades[] = $grade;
!         }
  
          $grade = new stdClass();
          $grade->itemid = $this->grade_items[7]->id;
          $grade->userid = 3;
          $grade->rawgrade = 6;
--- 884,893 ----
          $grade->timecreated = mktime();
          $grade->timemodified = mktime();
  
!         $this->grade_grades[] = $grade;
  
          $grade = new stdClass();
+         $grade->id = $id++;
          $grade->itemid = $this->grade_items[7]->id;
          $grade->userid = 3;
          $grade->rawgrade = 6;
***************
*** 1337,1349 ****
          $grade->timecreated = mktime();
          $grade->timemodified = mktime();
  
!         if ($grade->id = insert_record('grade_grades', $grade)) {
!             $this->grade_grades[] = $grade;
!         }
  
          // Grades for grade_item 9
  
          $grade = new stdClass();
          $grade->itemid = $this->grade_items[8]->id;
          $grade->userid = 1;
          $grade->rawgrade = 20;
--- 895,906 ----
          $grade->timecreated = mktime();
          $grade->timemodified = mktime();
  
!         $this->grade_grades[] = $grade;
  
          // Grades for grade_item 9
  
          $grade = new stdClass();
+         $grade->id = $id++;
          $grade->itemid = $this->grade_items[8]->id;
          $grade->userid = 1;
          $grade->rawgrade = 20;
***************
*** 1351,1361 ****
          $grade->timecreated = mktime();
          $grade->timemodified = mktime();
  
!         if ($grade->id = insert_record('grade_grades', $grade)) {
!             $this->grade_grades[] = $grade;
!         }
  
          $grade = new stdClass();
          $grade->itemid = $this->grade_items[8]->id;
          $grade->userid = 2;
          $grade->rawgrade = 50;
--- 908,917 ----
          $grade->timecreated = mktime();
          $grade->timemodified = mktime();
  
!         $this->grade_grades[] = $grade;
  
          $grade = new stdClass();
+         $grade->id = $id++;
          $grade->itemid = $this->grade_items[8]->id;
          $grade->userid = 2;
          $grade->rawgrade = 50;
***************
*** 1363,1373 ****
          $grade->timecreated = mktime();
          $grade->timemodified = mktime();
  
!         if ($grade->id = insert_record('grade_grades', $grade)) {
!             $this->grade_grades[] = $grade;
!         }
  
          $grade = new stdClass();
          $grade->itemid = $this->grade_items[7]->id;
          $grade->userid = 3;
          $grade->rawgrade = 100;
--- 919,928 ----
          $grade->timecreated = mktime();
          $grade->timemodified = mktime();
  
!         $this->grade_grades[] = $grade;
  
          $grade = new stdClass();
+         $grade->id = $id++;
          $grade->itemid = $this->grade_items[7]->id;
          $grade->userid = 3;
          $grade->rawgrade = 100;
***************
*** 1375,1421 ****
          $grade->timecreated = mktime();
          $grade->timemodified = mktime();
  
!         if ($grade->id = insert_record('grade_grades', $grade)) {
!             $this->grade_grades[] = $grade;
!         }
      }
  
      /**
       * Load grade_outcome data into the database, and adds the corresponding objects to this class' variable.
       */
      function load_grade_outcomes() {
          // Calculation for grade_item 1
          $grade_outcome = new stdClass();
          $grade_outcome->shortname = 'Team work';
          $grade_outcome->timecreated = mktime();
          $grade_outcome->timemodified = mktime();
          $grade_outcome->scaleid = $this->scale[2]->id;
  
!         if ($grade_outcome->id = insert_record('grade_outcomes', $grade_outcome)) {
!             $this->grade_outcomes[] = $grade_outcome;
!         }
  
          // Calculation for grade_item 2
          $grade_outcome = new stdClass();
          $grade_outcome->shortname = 'Complete circuit board';
          $grade_outcome->timecreated = mktime();
          $grade_outcome->timemodified = mktime();
          $grade_outcome->scaleid = $this->scale[3]->id;
  
!         if ($grade_outcome->id = insert_record('grade_outcomes', $grade_outcome)) {
!             $this->grade_outcomes[] = $grade_outcome;
!         }
  
          // Calculation for grade_item 3
          $grade_outcome = new stdClass();
          $grade_outcome->shortname = 'Debug Java program';
          $grade_outcome->timecreated = mktime();
          $grade_outcome->timemodified = mktime();
          $grade_outcome->scaleid = $this->scale[4]->id;
  
!         if ($grade_outcome->id = insert_record('grade_outcomes', $grade_outcome)) {
!             $this->grade_outcomes[] = $grade_outcome;
!         }
      }
  
  /**
--- 930,980 ----
          $grade->timecreated = mktime();
          $grade->timemodified = mktime();
  
!         $this->grade_grades[] = $grade;
! 
!         $this->loaded_tables[] = 'grade_grades';
      }
  
      /**
       * Load grade_outcome data into the database, and adds the corresponding objects to this class' variable.
       */
      function load_grade_outcomes() {
+         if (!in_array('scale', $this->loaded_tables)) {
+             $this->load_scale();
+         }
+         $id = 1;
+         
          // Calculation for grade_item 1
          $grade_outcome = new stdClass();
+         $grade_outcome->id = $id++;
          $grade_outcome->shortname = 'Team work';
          $grade_outcome->timecreated = mktime();
          $grade_outcome->timemodified = mktime();
          $grade_outcome->scaleid = $this->scale[2]->id;
  
!         $this->grade_outcomes[] = $grade_outcome;
  
          // Calculation for grade_item 2
          $grade_outcome = new stdClass();
+         $grade_outcome->id = $id++;
          $grade_outcome->shortname = 'Complete circuit board';
          $grade_outcome->timecreated = mktime();
          $grade_outcome->timemodified = mktime();
          $grade_outcome->scaleid = $this->scale[3]->id;
  
!         $this->grade_outcomes[] = $grade_outcome;
  
          // Calculation for grade_item 3
          $grade_outcome = new stdClass();
+         $grade_outcome->id = $id++;
          $grade_outcome->shortname = 'Debug Java program';
          $grade_outcome->timecreated = mktime();
          $grade_outcome->timemodified = mktime();
          $grade_outcome->scaleid = $this->scale[4]->id;
  
!         $this->grade_outcomes[] = $grade_outcome;
! 
!         $this->loaded_tables[] = 'grade_outcomes';
      }
  
  /**
