]> git.mjollnir.org Git - moodle.git/commitdiff
MDL-10365 Improved handling of history when inserting/updating/deleting in new grade...
authorskodak <skodak>
Fri, 6 Jul 2007 12:49:28 +0000 (12:49 +0000)
committerskodak <skodak>
Fri, 6 Jul 2007 12:49:28 +0000 (12:49 +0000)
20 files changed:
backup/backuplib.php
backup/restorelib.php
grade/export/xml/grade_export_xml.php
lib/db/install.xml
lib/db/upgrade.php
lib/grade/grade_category.php
lib/grade/grade_grades.php
lib/grade/grade_grades_text.php
lib/grade/grade_history.php [deleted file]
lib/grade/grade_item.php
lib/grade/grade_object.php
lib/grade/grade_outcome.php
lib/grade/grade_scale.php
lib/grade/grade_tree.php
lib/gradelib.php
lib/simpletest/fixtures/gradetest.php
lib/simpletest/grade/simpletest/testgradegradestext.php
lib/simpletest/grade/simpletest/testgradehistory.php [deleted file]
lib/simpletest/testgradelib.php
version.php

index 5e825f105a1f0c57bd133177708dba11c1b2a747..46a6b33a4ade5d9d417967651a6d61481a37c9e0 100644 (file)
 
                 // back up the other stuff here                
                 $status = backup_gradebook_grades_info($bf,$preferences,$grade_item->id);
-                $status = backup_gradebook_grades_history_info($bf,$preferences,$grade_item->id);
                 $status = backup_gradebook_grades_text_info($bf,$preferences,$grade_item->id);
 
                 //End grade_item
         }
         return $status;
     }
-    
-    function backup_gradebook_grades_history_info($bf, $preferences, $itemid) {
-
-        global $CFG;
-
-        $status = true;
-        
-        // find all grade history belonging to this item
-        if ($histories = get_records('grade_history', 'itemid', $itemid)) {
-            fwrite ($bf,start_tag("GRADE_GRADES_HISTORY",5,true));
-            foreach ($histories as $history) {
-                fwrite ($bf,start_tag("GRADE_HISTORY",6,true));
-                fwrite ($bf,full_tag("ID",7,false,$history->id));
-                fwrite ($bf,full_tag("USERID",7,false,$history->userid));
-                fwrite ($bf,full_tag("OLDGRADE",7,false,$history->oldgrade));                
-                fwrite ($bf,full_tag("NEWGRADE",7,false,$history->newgrade));
-                fwrite ($bf,full_tag("NOTE",7,false,$history->note));
-                fwrite ($bf,full_tag("HOWMODIFIED",7,false,$history->howmodified));
-                fwrite ($bf,full_tag("USERMODIFIED",7,false,$history->usermodified));
-                fwrite ($bf,end_tag("GRADE_HISTORY",6,true));
-            }
-            $stauts = fwrite ($bf,end_tag("GRADE_GRADES_HISTORY",5,true));
-        }
-        return $status;
-    }
 
     //Backup scales info (common and course scales)
     function backup_scales_info($bf,$preferences) {
index d38cfd08e6392e1af1f80e8f2913e8ca7057fdb2..b8497803470126765a27f7ff908f05b445a1bd22 100644 (file)
             }
         }
         
-        // Process grade items (grade_raw, grade_final, grade_history and grade_text)
+        // Process grade items (grade_raw, grade_final, and grade_text)
         if ($itemscount && $continue) {
             if (!defined('RESTORE_SILENTLY')) {
                 echo '<li>'.get_string('gradeitems','grades').'</li>';
 
                             $itemid = insert_record('grade_items',$dbrec);
                             
-                            /// now, restore grade_grades, grade_text, and grade_history
+                            /// now, restore grade_grades, grade_text
                             if (!empty($info['GRADE_ITEM']['#']['GRADE_GRADES']['0']['#']) && ($grades = $info['GRADE_ITEM']['#']['GRADE_GRADES']['0']['#']['GRADE'])) {
                                 //Iterate over items
                                 for($i = 0; $i < sizeof($grades); $i++) {
                                     }
                                 }
                             }                                                   
-
-                            /// processing grade_history
-                            if (!empty($info['GRADE_ITEM']['#']['GRADE_GRADES_HISTORY']['0']['#']) && ($histories = $info['GRADE_ITEM']['#']['GRADE_GRADES_HISTORY']['0']['#']['GRADE_HISTORY'])) {
-                                //Iterate over items
-                                for($i = 0; $i < sizeof($histories); $i++) {
-                                    $ite_info = $histories[$i];
-                                    //traverse_xmlize($ite_info);                                                                 //Debug
-                                    //print_object ($GLOBALS['traverse_array']);                                                  //Debug
-                                    //$GLOBALS['traverse_array']="";                                                              //Debug
-                                    $history->itemid       = $itemid;
-                                    $user = backup_getid($restore->backup_unique_code,"user", backup_todb($ite_info['#']['USERID']['0']['#']));
-                                    $history->userid = $user->new_id;
-                                    $history->oldgrade = backup_todb($ite_info['#']['OLDGRADE']['0']['#']);
-                                    $history->newgrade = backup_todb($ite_info['#']['NEWGRADE']['0']['#']);
-                                    $history->note = backup_todb($ite_info['#']['NOTE']['0']['#']);
-                                    $history->howmodified = backup_todb($ite_info['#']['HOWMODIFIED']['0']['#']);                                                                        
-                                    $modifier = backup_getid($restore->backup_unique_code,"user", backup_todb($ite_info['#']['USERMODIFIED']['0']['#']));
-                                    $history->usermodified = $modifier->new_id;
-                                    insert_record('grade_history', $history);
-                                    
-                                    $counter++;
-                                    if ($counter % 20 == 0) {
-                                        if (!defined('RESTORE_SILENTLY')) {
-                                            echo ".";
-                                            if ($counter % 400 == 0) {
-                                                echo "<br />";
-                                            }
-                                        }
-                                        backup_flush(300);
-                                    }
-                                }
-                            }
                         }
                     $counteritems++; // increment item count
                     }
index 51425f0d1814e6600184032625839745a42c8ecf..26670dd0af7a4dafaa7cb172e04d480f2b02617a 100755 (executable)
@@ -83,11 +83,12 @@ class grade_export_xml extends grade_export {
                     
                 // if exported, check grade_history, if modified after export, set state to regrade
                 if (!empty($grade_grades->exported)) {
-                    if (record_exists_select('grade_history', 'itemid = '.$gradeitem->id.' AND userid = '.$studentid.' AND timemodified > '.$grade_grades->exported)) {
+                    //TODO: use timemodified or something else instead
+/*                    if (record_exists_select('grade_history', 'itemid = '.$gradeitem->id.' AND userid = '.$studentid.' AND timemodified > '.$grade_grades->exported)) {
                         $status = 'regrade';  
                     } else {
                         $status = 'new';  
-                    }
+                    }*/
                 } else { 
                     // never exported
                     $status = 'new'; 
index e142e8dd0621ac4dbcf08c905c13f3cc33ce80eb..673f2ca9c993f7e344ccb3d69a8dbbfdac7315f6 100644 (file)
@@ -1,5 +1,5 @@
 <?xml version="1.0" encoding="UTF-8" ?>
-<XMLDB PATH="lib/db" VERSION="20070630" COMMENT="XMLDB file for core Moodle tables"
+<XMLDB PATH="lib/db" VERSION="20070706" COMMENT="XMLDB file for core Moodle tables"
     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
     xsi:noNamespaceSchemaLocation="../../lib/xmldb/xmldb.xsd"
 >
         <FIELD NAME="sortorder" TYPE="int" LENGTH="10" NOTNULL="true" UNSIGNED="false" DEFAULT="0" SEQUENCE="false" ENUM="false" COMMENT="Sorting order of the columns" PREVIOUS="plusfactor" NEXT="hidden"/>
         <FIELD NAME="hidden" TYPE="int" LENGTH="10" NOTNULL="true" UNSIGNED="false" DEFAULT="0" SEQUENCE="false" ENUM="false" COMMENT="1 is hidden, &amp;gt; 1 is a date to hide until (prevents viewing)" PREVIOUS="sortorder" NEXT="locked"/>
         <FIELD NAME="locked" TYPE="int" LENGTH="10" NOTNULL="true" UNSIGNED="false" DEFAULT="0" SEQUENCE="false" ENUM="false" COMMENT="1 is locked, &amp;gt; 1 is a date to lock until (prevents update)" PREVIOUS="hidden" NEXT="locktime"/>
-        <FIELD NAME="locktime" TYPE="int" LENGTH="10" NOTNULL="true" UNSIGNED="true" DEFAULT="0" SEQUENCE="false" ENUM="false" COMMENT="lock all final grades after this date" PREVIOUS="locked" NEXT="deleted"/>
-        <FIELD NAME="deleted" TYPE="int" LENGTH="10" NOTNULL="true" UNSIGNED="true" DEFAULT="0" SEQUENCE="false" ENUM="false" COMMENT="1 means the associated module instance has been deleted" PREVIOUS="locktime" NEXT="needsupdate"/>
-        <FIELD NAME="needsupdate" TYPE="int" LENGTH="10" NOTNULL="true" UNSIGNED="false" DEFAULT="0" SEQUENCE="false" ENUM="false" COMMENT="If this flag is set, then the whole column will be recalculated" PREVIOUS="deleted" NEXT="timecreated"/>
+        <FIELD NAME="locktime" TYPE="int" LENGTH="10" NOTNULL="true" UNSIGNED="true" DEFAULT="0" SEQUENCE="false" ENUM="false" COMMENT="lock all final grades after this date" PREVIOUS="locked" NEXT="needsupdate"/>
+        <FIELD NAME="needsupdate" TYPE="int" LENGTH="10" NOTNULL="true" UNSIGNED="false" DEFAULT="0" SEQUENCE="false" ENUM="false" COMMENT="If this flag is set, then the whole column will be recalculated" PREVIOUS="locktime" NEXT="timecreated"/>
         <FIELD NAME="timecreated" TYPE="int" LENGTH="10" NOTNULL="false" UNSIGNED="true" SEQUENCE="false" ENUM="false" COMMENT="The first time this grade_item was created" PREVIOUS="needsupdate" NEXT="timemodified"/>
         <FIELD NAME="timemodified" TYPE="int" LENGTH="10" NOTNULL="false" UNSIGNED="true" SEQUENCE="false" ENUM="false" COMMENT="The last time this grade_item was modified" PREVIOUS="timecreated"/>
       </FIELDS>
         <KEY NAME="usermodified" TYPE="foreign" FIELDS="usermodified" REFTABLE="user" REFFIELDS="id" PREVIOUS="gradeid"/>
       </KEYS>
     </TABLE>
-    <TABLE NAME="grade_outcomes" COMMENT="This table describes the outcomes used in the system. An outcome is a statement tied to a rubric scale from low to high, such as “Not met, Borderline, Met” (stored as 0,1 or 2)" PREVIOUS="grade_grades_text" NEXT="grade_history">
+    <TABLE NAME="grade_outcomes" COMMENT="This table describes the outcomes used in the system. An outcome is a statement tied to a rubric scale from low to high, such as “Not met, Borderline, Met” (stored as 0,1 or 2)" PREVIOUS="grade_grades_text" NEXT="grade_items_history">
       <FIELDS>
         <FIELD NAME="id" TYPE="int" LENGTH="10" NOTNULL="true" UNSIGNED="false" SEQUENCE="true" ENUM="false" COMMENT="id of the table, please edit me" NEXT="courseid"/>
         <FIELD NAME="courseid" TYPE="int" LENGTH="10" NOTNULL="false" UNSIGNED="true" SEQUENCE="false" ENUM="false" COMMENT="Mostly these are defined site wide ie NULL" PREVIOUS="id" NEXT="shortname"/>
         <KEY NAME="usermodified" TYPE="foreign" FIELDS="usermodified" REFTABLE="user" REFFIELDS="id" PREVIOUS="scaleid"/>
       </KEYS>
     </TABLE>
-    <TABLE NAME="grade_history" COMMENT="This table keeps track of grade changes. Using this it should be possible to reconstruct the grades at any point in time in the past, or to audit grade changes over time. It should be quicker to use this table for that, rather than storing this information in the main Moodle log.  Note we use itemid and userid as a key rather than grade_grade id, just in case one of the things we want to log here is the deletion of a grade entirely." PREVIOUS="grade_outcomes" NEXT="grade_import_values">
+    <TABLE NAME="grade_items_history" COMMENT="History of grade_items" PREVIOUS="grade_outcomes" NEXT="grade_categories_history">
       <FIELDS>
-        <FIELD NAME="id" TYPE="int" LENGTH="10" NOTNULL="true" UNSIGNED="false" SEQUENCE="true" ENUM="false" COMMENT="id of the table, please edit me" NEXT="itemid"/>
-        <FIELD NAME="itemid" TYPE="int" LENGTH="10" NOTNULL="true" UNSIGNED="true" SEQUENCE="false" ENUM="false" COMMENT="The grade_item the grade is from" PREVIOUS="id" NEXT="userid"/>
-        <FIELD NAME="userid" TYPE="int" LENGTH="10" NOTNULL="true" UNSIGNED="false" SEQUENCE="false" ENUM="false" COMMENT="The user that the grade belongs to" PREVIOUS="itemid" NEXT="oldgrade"/>
-        <FIELD NAME="oldgrade" TYPE="number" LENGTH="10" NOTNULL="false" UNSIGNED="false" SEQUENCE="false" ENUM="false" DECIMALS="5" COMMENT="The original grade before the change" PREVIOUS="userid" NEXT="newgrade"/>
-        <FIELD NAME="newgrade" TYPE="number" LENGTH="10" NOTNULL="false" UNSIGNED="false" SEQUENCE="false" ENUM="false" DECIMALS="5" COMMENT="The new grade after the change" PREVIOUS="oldgrade" NEXT="note"/>
-        <FIELD NAME="note" TYPE="text" LENGTH="small" NOTNULL="false" SEQUENCE="false" ENUM="false" COMMENT="An optional note about why this change was made" PREVIOUS="newgrade" NEXT="howmodified"/>
-        <FIELD NAME="howmodified" TYPE="char" LENGTH="255" NOTNULL="true" DEFAULT="manual" SEQUENCE="false" ENUM="false" COMMENT="What caused the modification? manual/module/import/..." PREVIOUS="note" NEXT="usermodified"/>
-        <FIELD NAME="usermodified" TYPE="int" LENGTH="10" NOTNULL="false" UNSIGNED="true" SEQUENCE="false" ENUM="false" COMMENT="The user id of the person who made the change" PREVIOUS="howmodified" NEXT="timemodified"/>
-        <FIELD NAME="timemodified" TYPE="int" LENGTH="10" NOTNULL="false" UNSIGNED="true" SEQUENCE="false" ENUM="false" COMMENT="The exact time this change was made" PREVIOUS="usermodified"/>
+        <FIELD NAME="id" TYPE="int" LENGTH="10" NOTNULL="true" UNSIGNED="false" SEQUENCE="true" ENUM="false" COMMENT="id of the table, please edit me" NEXT="action"/>
+        <FIELD NAME="action" TYPE="int" LENGTH="10" NOTNULL="true" UNSIGNED="false" DEFAULT="0" SEQUENCE="false" ENUM="false" COMMENT="created/modified/deleted constants" PREVIOUS="id" NEXT="oldid"/>
+        <FIELD NAME="oldid" TYPE="int" LENGTH="10" NOTNULL="true" UNSIGNED="false" SEQUENCE="false" ENUM="false" COMMENT="id of the table, please edit me" PREVIOUS="action" NEXT="source"/>
+        <FIELD NAME="source" TYPE="char" LENGTH="255" NOTNULL="false" SEQUENCE="false" ENUM="false" COMMENT="What caused the modification? manual/module/import/..." PREVIOUS="oldid" NEXT="timemodified"/>
+        <FIELD NAME="timemodified" TYPE="int" LENGTH="10" NOTNULL="false" UNSIGNED="true" SEQUENCE="false" ENUM="false" COMMENT="The last time this grade_item was modified" PREVIOUS="source" NEXT="loggeduser"/>
+        <FIELD NAME="loggeduser" TYPE="int" LENGTH="10" NOTNULL="false" UNSIGNED="true" SEQUENCE="false" ENUM="false" COMMENT="the userid of the person who last modified this outcome" PREVIOUS="timemodified" NEXT="courseid"/>
+        <FIELD NAME="courseid" TYPE="int" LENGTH="10" NOTNULL="false" UNSIGNED="true" SEQUENCE="false" ENUM="false" COMMENT="The course this item is part of" PREVIOUS="loggeduser" NEXT="categoryid"/>
+        <FIELD NAME="categoryid" TYPE="int" LENGTH="10" NOTNULL="false" UNSIGNED="true" SEQUENCE="false" ENUM="false" COMMENT="(optional) the category group this item belongs to" PREVIOUS="courseid" NEXT="itemname"/>
+        <FIELD NAME="itemname" TYPE="char" LENGTH="255" NOTNULL="false" SEQUENCE="false" ENUM="false" COMMENT="The name of this item (pushed in by the module)" PREVIOUS="categoryid" NEXT="itemtype"/>
+        <FIELD NAME="itemtype" TYPE="char" LENGTH="30" NOTNULL="true" SEQUENCE="false" ENUM="false" COMMENT="'mod', 'blocks', 'import', 'calculated' etc" PREVIOUS="itemname" NEXT="itemmodule"/>
+        <FIELD NAME="itemmodule" TYPE="char" LENGTH="30" NOTNULL="false" SEQUENCE="false" ENUM="false" COMMENT="'forum', 'quiz', 'csv', etc" PREVIOUS="itemtype" NEXT="iteminstance"/>
+        <FIELD NAME="iteminstance" TYPE="int" LENGTH="10" NOTNULL="false" UNSIGNED="true" SEQUENCE="false" ENUM="false" COMMENT="id of the item module" PREVIOUS="itemmodule" NEXT="itemnumber"/>
+        <FIELD NAME="itemnumber" TYPE="int" LENGTH="10" NOTNULL="false" UNSIGNED="true" SEQUENCE="false" ENUM="false" COMMENT="Can be used to distinguish multiple grades for an activity" PREVIOUS="iteminstance" NEXT="iteminfo"/>
+        <FIELD NAME="iteminfo" TYPE="text" LENGTH="medium" NOTNULL="false" SEQUENCE="false" ENUM="false" COMMENT="Info and notes about this item XXX" PREVIOUS="itemnumber" NEXT="idnumber"/>
+        <FIELD NAME="idnumber" TYPE="char" LENGTH="255" NOTNULL="false" SEQUENCE="false" ENUM="false" COMMENT="Arbitrary idnumber provided by the module responsible" PREVIOUS="iteminfo" NEXT="calculation"/>
+        <FIELD NAME="calculation" TYPE="text" LENGTH="medium" NOTNULL="false" SEQUENCE="false" ENUM="false" COMMENT="Formula describing how to derive this grade from other items, referring to them using giXXX where XXX is grade item id ... eg something like: =sin(square([#gi20#])) + [#gi30#]" PREVIOUS="idnumber" NEXT="gradetype"/>
+        <FIELD NAME="gradetype" TYPE="int" LENGTH="4" NOTNULL="true" UNSIGNED="false" DEFAULT="1" SEQUENCE="false" ENUM="false" COMMENT="0 = none, 1 = value, 2 = scale, 3 = text" PREVIOUS="calculation" NEXT="grademax"/>
+        <FIELD NAME="grademax" TYPE="number" LENGTH="10" NOTNULL="true" UNSIGNED="false" DEFAULT="100" SEQUENCE="false" ENUM="false" DECIMALS="5" COMMENT="What is the maximum allowable grade?" PREVIOUS="gradetype" NEXT="grademin"/>
+        <FIELD NAME="grademin" TYPE="number" LENGTH="10" NOTNULL="true" UNSIGNED="false" DEFAULT="0" SEQUENCE="false" ENUM="false" DECIMALS="5" COMMENT="What is the minimum allowable grade?" PREVIOUS="grademax" NEXT="scaleid"/>
+        <FIELD NAME="scaleid" TYPE="int" LENGTH="10" NOTNULL="false" UNSIGNED="true" SEQUENCE="false" ENUM="false" COMMENT="If this grade is based on a scale, which one is it?" PREVIOUS="grademin" NEXT="outcomeid"/>
+        <FIELD NAME="outcomeid" TYPE="int" LENGTH="10" NOTNULL="false" UNSIGNED="false" SEQUENCE="false" ENUM="false" COMMENT="If this grade is related to an outcome, which one is it?" PREVIOUS="scaleid" NEXT="gradepass"/>
+        <FIELD NAME="gradepass" TYPE="number" LENGTH="10" NOTNULL="true" UNSIGNED="false" DEFAULT="0" SEQUENCE="false" ENUM="false" DECIMALS="5" COMMENT="What grade is needed to pass? grademin &amp;lt; gradepass &amp;lt;= grademax" PREVIOUS="outcomeid" NEXT="multfactor"/>
+        <FIELD NAME="multfactor" TYPE="number" LENGTH="10" NOTNULL="true" UNSIGNED="false" DEFAULT="1.0" SEQUENCE="false" ENUM="false" DECIMALS="5" COMMENT="Multiply all grades by this" PREVIOUS="gradepass" NEXT="plusfactor"/>
+        <FIELD NAME="plusfactor" TYPE="number" LENGTH="10" NOTNULL="true" UNSIGNED="false" DEFAULT="0" SEQUENCE="false" ENUM="false" DECIMALS="5" COMMENT="Add this to all grades" PREVIOUS="multfactor" NEXT="sortorder"/>
+        <FIELD NAME="sortorder" TYPE="int" LENGTH="10" NOTNULL="true" UNSIGNED="false" DEFAULT="0" SEQUENCE="false" ENUM="false" COMMENT="Sorting order of the columns" PREVIOUS="plusfactor" NEXT="hidden"/>
+        <FIELD NAME="hidden" TYPE="int" LENGTH="10" NOTNULL="true" UNSIGNED="false" DEFAULT="0" SEQUENCE="false" ENUM="false" COMMENT="1 is hidden, &amp;gt; 1 is a date to hide until (prevents viewing)" PREVIOUS="sortorder" NEXT="locked"/>
+        <FIELD NAME="locked" TYPE="int" LENGTH="10" NOTNULL="true" UNSIGNED="false" DEFAULT="0" SEQUENCE="false" ENUM="false" COMMENT="1 is locked, &amp;gt; 1 is a date to lock until (prevents update)" PREVIOUS="hidden" NEXT="locktime"/>
+        <FIELD NAME="locktime" TYPE="int" LENGTH="10" NOTNULL="true" UNSIGNED="true" DEFAULT="0" SEQUENCE="false" ENUM="false" COMMENT="lock all final grades after this date" PREVIOUS="locked" NEXT="needsupdate"/>
+        <FIELD NAME="needsupdate" TYPE="int" LENGTH="10" NOTNULL="true" UNSIGNED="false" DEFAULT="0" SEQUENCE="false" ENUM="false" COMMENT="If this flag is set, then the whole column will be recalculated" PREVIOUS="locktime"/>
       </FIELDS>
       <KEYS>
-        <KEY NAME="primary" TYPE="primary" FIELDS="id" COMMENT="primary key of the table, please edit me" NEXT="itemid"/>
-        <KEY NAME="itemid" TYPE="foreign" FIELDS="itemid" REFTABLE="grade_items" REFFIELDS="id" PREVIOUS="primary" NEXT="userid"/>
-        <KEY NAME="userid" TYPE="foreign" FIELDS="userid" REFTABLE="user" REFFIELDS="id" PREVIOUS="itemid" NEXT="usermodified"/>
-        <KEY NAME="usermodified" TYPE="foreign" FIELDS="usermodified" REFTABLE="user" REFFIELDS="id" PREVIOUS="userid"/>
+        <KEY NAME="primary" TYPE="primary" FIELDS="id" COMMENT="primary key of the table, please edit me" NEXT="oldid"/>
+        <KEY NAME="oldid" TYPE="foreign" FIELDS="oldid" REFTABLE="grade_items" REFFIELDS="id" PREVIOUS="primary" NEXT="courseid"/>
+        <KEY NAME="courseid" TYPE="foreign" FIELDS="courseid" REFTABLE="course" REFFIELDS="id" PREVIOUS="oldid" NEXT="categoryid"/>
+        <KEY NAME="categoryid" TYPE="foreign" FIELDS="categoryid" REFTABLE="grade_categories" REFFIELDS="id" PREVIOUS="courseid" NEXT="scaleid"/>
+        <KEY NAME="scaleid" TYPE="foreign" FIELDS="scaleid" REFTABLE="scale" REFFIELDS="id" PREVIOUS="categoryid" NEXT="outcomeid"/>
+        <KEY NAME="outcomeid" TYPE="foreign" FIELDS="outcomeid" REFTABLE="grade_outcomes" REFFIELDS="id" PREVIOUS="scaleid"/>
+      </KEYS>
+      <INDEXES>
+        <INDEX NAME="action" UNIQUE="false" FIELDS="action" COMMENT="insert/update/delete"/>
+      </INDEXES>
+    </TABLE>
+    <TABLE NAME="grade_categories_history" COMMENT="History of grade_categories" PREVIOUS="grade_items_history" NEXT="grade_grades_history">
+      <FIELDS>
+        <FIELD NAME="id" TYPE="int" LENGTH="10" NOTNULL="true" UNSIGNED="false" SEQUENCE="true" ENUM="false" COMMENT="id of the table, please edit me" NEXT="action"/>
+        <FIELD NAME="action" TYPE="int" LENGTH="10" NOTNULL="true" UNSIGNED="false" DEFAULT="0" SEQUENCE="false" ENUM="false" COMMENT="created/modified/deleted constants" PREVIOUS="id" NEXT="oldid"/>
+        <FIELD NAME="oldid" TYPE="int" LENGTH="10" NOTNULL="true" UNSIGNED="false" SEQUENCE="false" ENUM="false" COMMENT="id of the table, please edit me" PREVIOUS="action" NEXT="source"/>
+        <FIELD NAME="source" TYPE="char" LENGTH="255" NOTNULL="false" SEQUENCE="false" ENUM="false" COMMENT="What caused the modification? manual/module/import/..." PREVIOUS="oldid" NEXT="timemodified"/>
+        <FIELD NAME="timemodified" TYPE="int" LENGTH="10" NOTNULL="false" UNSIGNED="true" SEQUENCE="false" ENUM="false" COMMENT="The last time this grade_item was modified" PREVIOUS="source" NEXT="loggeduser"/>
+        <FIELD NAME="loggeduser" TYPE="int" LENGTH="10" NOTNULL="false" UNSIGNED="true" SEQUENCE="false" ENUM="false" COMMENT="the userid of the person who last modified this outcome" PREVIOUS="timemodified" NEXT="courseid"/>
+        <FIELD NAME="courseid" TYPE="int" LENGTH="10" NOTNULL="true" UNSIGNED="true" SEQUENCE="false" ENUM="false" COMMENT="The course this grade category is part of" PREVIOUS="loggeduser" NEXT="parent"/>
+        <FIELD NAME="parent" TYPE="int" LENGTH="10" NOTNULL="false" UNSIGNED="true" SEQUENCE="false" ENUM="false" COMMENT="Categories can be hierarchical" PREVIOUS="courseid" NEXT="depth"/>
+        <FIELD NAME="depth" TYPE="int" LENGTH="10" NOTNULL="true" UNSIGNED="true" DEFAULT="0" SEQUENCE="false" ENUM="false" COMMENT="How many parents does this category have?" PREVIOUS="parent" NEXT="path"/>
+        <FIELD NAME="path" TYPE="char" LENGTH="255" NOTNULL="false" SEQUENCE="false" ENUM="false" COMMENT="shows the path as /1/2/3 (like course_categories)" PREVIOUS="depth" NEXT="fullname"/>
+        <FIELD NAME="fullname" TYPE="char" LENGTH="255" NOTNULL="true" SEQUENCE="false" ENUM="false" COMMENT="The name of this grade category" PREVIOUS="path" NEXT="aggregation"/>
+        <FIELD NAME="aggregation" TYPE="int" LENGTH="10" NOTNULL="true" UNSIGNED="false" DEFAULT="0" SEQUENCE="false" ENUM="false" COMMENT="A constant pointing to one of the predefined aggregation strategies (none, mean,median,sum, etc)" PREVIOUS="fullname" NEXT="keephigh"/>
+        <FIELD NAME="keephigh" TYPE="int" LENGTH="10" NOTNULL="true" UNSIGNED="false" DEFAULT="0" SEQUENCE="false" ENUM="false" COMMENT="Keep only the X highest items" PREVIOUS="aggregation" NEXT="droplow"/>
+        <FIELD NAME="droplow" TYPE="int" LENGTH="10" NOTNULL="true" UNSIGNED="false" DEFAULT="0" SEQUENCE="false" ENUM="false" COMMENT="Drop the X lowest items" PREVIOUS="keephigh"/>
+      </FIELDS>
+      <KEYS>
+        <KEY NAME="primary" TYPE="primary" FIELDS="id" COMMENT="primary key of the table, please edit me" NEXT="oldid"/>
+        <KEY NAME="oldid" TYPE="foreign" FIELDS="oldid" REFTABLE="grade_categories" REFFIELDS="id" PREVIOUS="primary" NEXT="courseid"/>
+        <KEY NAME="courseid" TYPE="foreign" FIELDS="courseid" REFTABLE="course" REFFIELDS="id" PREVIOUS="oldid" NEXT="parent"/>
+        <KEY NAME="parent" TYPE="foreign" FIELDS="parent" REFTABLE="grade_categories" REFFIELDS="id" PREVIOUS="courseid"/>
+      </KEYS>
+      <INDEXES>
+        <INDEX NAME="action" UNIQUE="false" FIELDS="action" COMMENT="insert/update/delete"/>
+      </INDEXES>
+    </TABLE>
+    <TABLE NAME="grade_grades_history" COMMENT="History table" PREVIOUS="grade_categories_history" NEXT="grade_grades_text_history">
+      <FIELDS>
+        <FIELD NAME="id" TYPE="int" LENGTH="10" NOTNULL="true" UNSIGNED="false" SEQUENCE="true" ENUM="false" COMMENT="id of the table, please edit me" NEXT="action"/>
+        <FIELD NAME="action" TYPE="int" LENGTH="10" NOTNULL="true" UNSIGNED="false" DEFAULT="0" SEQUENCE="false" ENUM="false" COMMENT="created/modified/deleted constants" PREVIOUS="id" NEXT="oldid"/>
+        <FIELD NAME="oldid" TYPE="int" LENGTH="10" NOTNULL="true" UNSIGNED="false" SEQUENCE="false" ENUM="false" COMMENT="id of the table, please edit me" PREVIOUS="action" NEXT="source"/>
+        <FIELD NAME="source" TYPE="char" LENGTH="255" NOTNULL="false" SEQUENCE="false" ENUM="false" COMMENT="What caused the modification? manual/module/import/..." PREVIOUS="oldid" NEXT="timemodified"/>
+        <FIELD NAME="timemodified" TYPE="int" LENGTH="10" NOTNULL="false" UNSIGNED="true" SEQUENCE="false" ENUM="false" COMMENT="The last time this grade_item was modified" PREVIOUS="source" NEXT="loggeduser"/>
+        <FIELD NAME="loggeduser" TYPE="int" LENGTH="10" NOTNULL="false" UNSIGNED="true" SEQUENCE="false" ENUM="false" COMMENT="the userid of the person who last modified this outcome" PREVIOUS="timemodified" NEXT="itemid"/>
+        <FIELD NAME="itemid" TYPE="int" LENGTH="10" NOTNULL="true" UNSIGNED="true" SEQUENCE="false" ENUM="false" COMMENT="The item this grade belongs to" PREVIOUS="loggeduser" NEXT="userid"/>
+        <FIELD NAME="userid" TYPE="int" LENGTH="10" NOTNULL="true" UNSIGNED="true" SEQUENCE="false" ENUM="false" COMMENT="The user who this grade is for" PREVIOUS="itemid" NEXT="rawgrade"/>
+        <FIELD NAME="rawgrade" TYPE="number" LENGTH="10" NOTNULL="false" UNSIGNED="false" SEQUENCE="false" ENUM="false" DECIMALS="5" COMMENT="If the grade is a float value (or has been converted to one)" PREVIOUS="userid" NEXT="rawgrademax"/>
+        <FIELD NAME="rawgrademax" TYPE="number" LENGTH="10" NOTNULL="true" UNSIGNED="false" DEFAULT="100" SEQUENCE="false" ENUM="false" DECIMALS="5" COMMENT="The maximum allowable grade when this was created" PREVIOUS="rawgrade" NEXT="rawgrademin"/>
+        <FIELD NAME="rawgrademin" TYPE="number" LENGTH="10" NOTNULL="true" UNSIGNED="false" DEFAULT="0" SEQUENCE="false" ENUM="false" DECIMALS="5" COMMENT="The minimum allowable grade when this was created" PREVIOUS="rawgrademax" NEXT="rawscaleid"/>
+        <FIELD NAME="rawscaleid" TYPE="int" LENGTH="10" NOTNULL="false" UNSIGNED="true" SEQUENCE="false" ENUM="false" COMMENT="If this grade is based on a scale, which one was it?" PREVIOUS="rawgrademin" NEXT="usermodified"/>
+        <FIELD NAME="usermodified" TYPE="int" LENGTH="10" NOTNULL="false" UNSIGNED="true" SEQUENCE="false" ENUM="false" COMMENT="the userid of the person who last modified this grade" PREVIOUS="rawscaleid" NEXT="finalgrade"/>
+        <FIELD NAME="finalgrade" TYPE="number" LENGTH="10" NOTNULL="false" UNSIGNED="false" SEQUENCE="false" ENUM="false" DECIMALS="5" COMMENT="The final grade (cached) after all calculations are made" PREVIOUS="usermodified" NEXT="hidden"/>
+        <FIELD NAME="hidden" TYPE="int" LENGTH="10" NOTNULL="true" UNSIGNED="true" DEFAULT="0" SEQUENCE="false" ENUM="false" COMMENT="show 0, hide 1 or hide until date" PREVIOUS="finalgrade" NEXT="locked"/>
+        <FIELD NAME="locked" TYPE="int" LENGTH="10" NOTNULL="true" UNSIGNED="true" DEFAULT="0" SEQUENCE="false" ENUM="false" COMMENT="not locked 0, locked from date" PREVIOUS="hidden" NEXT="locktime"/>
+        <FIELD NAME="locktime" TYPE="int" LENGTH="10" NOTNULL="true" UNSIGNED="true" DEFAULT="0" SEQUENCE="false" ENUM="false" COMMENT="automatic locking of final grade, 0 means none, date otherwise" PREVIOUS="locked" NEXT="exported"/>
+        <FIELD NAME="exported" TYPE="int" LENGTH="10" NOTNULL="true" UNSIGNED="true" DEFAULT="0" SEQUENCE="false" ENUM="false" COMMENT="date of last grade export, 0 if none" PREVIOUS="locktime"/>
+      </FIELDS>
+      <KEYS>
+        <KEY NAME="primary" TYPE="primary" FIELDS="id" COMMENT="primary key of the table, please edit me" NEXT="oldid"/>
+        <KEY NAME="oldid" TYPE="foreign" FIELDS="oldid" REFTABLE="grade_grades" REFFIELDS="id" PREVIOUS="primary" NEXT="itemid"/>
+        <KEY NAME="itemid" TYPE="foreign" FIELDS="itemid" REFTABLE="grade_items" REFFIELDS="id" PREVIOUS="oldid" NEXT="userid"/>
+        <KEY NAME="userid" TYPE="foreign" FIELDS="userid" REFTABLE="user" REFFIELDS="id" PREVIOUS="itemid" NEXT="rawscaleid"/>
+        <KEY NAME="rawscaleid" TYPE="foreign" FIELDS="rawscaleid" REFTABLE="scale" REFFIELDS="id" PREVIOUS="userid" NEXT="usermodified"/>
+        <KEY NAME="usermodified" TYPE="foreign" FIELDS="usermodified" REFTABLE="user" REFFIELDS="id" PREVIOUS="rawscaleid" NEXT="loggeduser"/>
+        <KEY NAME="loggeduser" TYPE="foreign" FIELDS="loggeduser" REFTABLE="user" REFFIELDS="id" PREVIOUS="usermodified"/>
       </KEYS>
+      <INDEXES>
+        <INDEX NAME="action" UNIQUE="false" FIELDS="action" COMMENT="insert/update/delete"/>
+      </INDEXES>
+    </TABLE>
+    <TABLE NAME="grade_grades_text_history" COMMENT="History table" PREVIOUS="grade_grades_history" NEXT="grade_outcomes_history">
+      <FIELDS>
+        <FIELD NAME="id" TYPE="int" LENGTH="10" NOTNULL="true" UNSIGNED="false" SEQUENCE="true" ENUM="false" COMMENT="id of the table, please edit me" NEXT="action"/>
+        <FIELD NAME="action" TYPE="int" LENGTH="10" NOTNULL="true" UNSIGNED="false" DEFAULT="0" SEQUENCE="false" ENUM="false" COMMENT="created/modified/deleted constants" PREVIOUS="id" NEXT="oldid"/>
+        <FIELD NAME="oldid" TYPE="int" LENGTH="10" NOTNULL="true" UNSIGNED="false" SEQUENCE="false" ENUM="false" COMMENT="id of the table, please edit me" PREVIOUS="action" NEXT="source"/>
+        <FIELD NAME="source" TYPE="char" LENGTH="255" NOTNULL="false" SEQUENCE="false" ENUM="false" COMMENT="What caused the modification? manual/module/import/..." PREVIOUS="oldid" NEXT="timemodified"/>
+        <FIELD NAME="timemodified" TYPE="int" LENGTH="10" NOTNULL="false" UNSIGNED="true" SEQUENCE="false" ENUM="false" COMMENT="The last time this grade_item was modified" PREVIOUS="source" NEXT="loggeduser"/>
+        <FIELD NAME="loggeduser" TYPE="int" LENGTH="10" NOTNULL="false" UNSIGNED="true" SEQUENCE="false" ENUM="false" COMMENT="the userid of the person who last modified this outcome" PREVIOUS="timemodified" NEXT="gradeid"/>
+        <FIELD NAME="gradeid" TYPE="int" LENGTH="10" NOTNULL="true" UNSIGNED="true" SEQUENCE="false" ENUM="false" PREVIOUS="loggeduser" NEXT="information"/>
+        <FIELD NAME="information" TYPE="text" LENGTH="medium" NOTNULL="false" SEQUENCE="false" ENUM="false" COMMENT="Further information like forum rating distribution 4/5/7/0/1" PREVIOUS="gradeid" NEXT="informationformat"/>
+        <FIELD NAME="informationformat" TYPE="int" LENGTH="10" NOTNULL="true" UNSIGNED="false" DEFAULT="0" SEQUENCE="false" ENUM="false" COMMENT="Text format for information" PREVIOUS="information" NEXT="feedback"/>
+        <FIELD NAME="feedback" TYPE="text" LENGTH="medium" NOTNULL="false" SEQUENCE="false" ENUM="false" COMMENT="Manual feedback from the teacher. Could be a code like 'mi'." PREVIOUS="informationformat" NEXT="feedbackformat"/>
+        <FIELD NAME="feedbackformat" TYPE="int" LENGTH="10" NOTNULL="true" UNSIGNED="true" DEFAULT="0" SEQUENCE="false" ENUM="false" COMMENT="Text format for feedback" PREVIOUS="feedback" NEXT="usermodified"/>
+        <FIELD NAME="usermodified" TYPE="int" LENGTH="10" NOTNULL="false" UNSIGNED="true" SEQUENCE="false" ENUM="false" COMMENT="the userid of the person who last modified this grade" PREVIOUS="feedbackformat"/>
+      </FIELDS>
+      <KEYS>
+        <KEY NAME="primary" TYPE="primary" FIELDS="id" COMMENT="primary key of the table, please edit me" NEXT="oldid"/>
+        <KEY NAME="oldid" TYPE="foreign" FIELDS="oldid" REFTABLE="grade_grades_text" REFFIELDS="id" PREVIOUS="primary" NEXT="gradeid"/>
+        <KEY NAME="gradeid" TYPE="foreign" FIELDS="gradeid" REFTABLE="grade_grades" REFFIELDS="id" PREVIOUS="oldid" NEXT="loggeduser"/>
+        <KEY NAME="loggeduser" TYPE="foreign" FIELDS="loggeduser" REFTABLE="user" REFFIELDS="id" PREVIOUS="gradeid" NEXT="usermodified"/>
+        <KEY NAME="usermodified" TYPE="foreign" FIELDS="usermodified" REFTABLE="user" REFFIELDS="id" PREVIOUS="loggeduser"/>
+      </KEYS>
+      <INDEXES>
+        <INDEX NAME="action" UNIQUE="false" FIELDS="action" COMMENT="insert/update/delete"/>
+      </INDEXES>
+    </TABLE>
+    <TABLE NAME="grade_outcomes_history" COMMENT="History table" PREVIOUS="grade_grades_text_history" NEXT="scale_history">
+      <FIELDS>
+        <FIELD NAME="id" TYPE="int" LENGTH="10" NOTNULL="true" UNSIGNED="false" SEQUENCE="true" ENUM="false" COMMENT="id of the table, please edit me" NEXT="action"/>
+        <FIELD NAME="action" TYPE="int" LENGTH="10" NOTNULL="true" UNSIGNED="false" DEFAULT="0" SEQUENCE="false" ENUM="false" COMMENT="created/modified/deleted constants" PREVIOUS="id" NEXT="oldid"/>
+        <FIELD NAME="oldid" TYPE="int" LENGTH="10" NOTNULL="true" UNSIGNED="false" SEQUENCE="false" ENUM="false" COMMENT="id of the table, please edit me" PREVIOUS="action" NEXT="source"/>
+        <FIELD NAME="source" TYPE="char" LENGTH="255" NOTNULL="false" SEQUENCE="false" ENUM="false" COMMENT="What caused the modification? manual/module/import/..." PREVIOUS="oldid" NEXT="timemodified"/>
+        <FIELD NAME="timemodified" TYPE="int" LENGTH="10" NOTNULL="false" UNSIGNED="true" SEQUENCE="false" ENUM="false" COMMENT="The last time this grade_item was modified" PREVIOUS="source" NEXT="loggeduser"/>
+        <FIELD NAME="loggeduser" TYPE="int" LENGTH="10" NOTNULL="false" UNSIGNED="true" SEQUENCE="false" ENUM="false" COMMENT="the userid of the person who last modified this outcome" PREVIOUS="timemodified" NEXT="courseid"/>
+        <FIELD NAME="courseid" TYPE="int" LENGTH="10" NOTNULL="false" UNSIGNED="true" SEQUENCE="false" ENUM="false" COMMENT="Mostly these are defined site wide ie NULL" PREVIOUS="loggeduser" NEXT="shortname"/>
+        <FIELD NAME="shortname" TYPE="char" LENGTH="255" NOTNULL="true" SEQUENCE="false" ENUM="false" COMMENT="The short name or code for this outcome statement" PREVIOUS="courseid" NEXT="fullname"/>
+        <FIELD NAME="fullname" TYPE="text" LENGTH="small" NOTNULL="true" SEQUENCE="false" ENUM="false" COMMENT="The full description of the outcome (usually 1 sentence)" PREVIOUS="shortname" NEXT="scaleid"/>
+        <FIELD NAME="scaleid" TYPE="int" LENGTH="10" NOTNULL="false" UNSIGNED="true" SEQUENCE="false" ENUM="false" COMMENT="The recommended scale for this outcome." PREVIOUS="fullname"/>
+      </FIELDS>
+      <KEYS>
+        <KEY NAME="primary" TYPE="primary" FIELDS="id" COMMENT="primary key of the table, please edit me" NEXT="oldid"/>
+        <KEY NAME="oldid" TYPE="foreign" FIELDS="oldid" REFTABLE="grade_outcomes" REFFIELDS="id" PREVIOUS="primary" NEXT="courseid"/>
+        <KEY NAME="courseid" TYPE="foreign" FIELDS="courseid" REFTABLE="course" REFFIELDS="id" PREVIOUS="oldid" NEXT="scaleid"/>
+        <KEY NAME="scaleid" TYPE="foreign" FIELDS="scaleid" REFTABLE="scale" REFFIELDS="id" PREVIOUS="courseid" NEXT="loggeduser"/>
+        <KEY NAME="loggeduser" TYPE="foreign" FIELDS="loggeduser" REFTABLE="user" REFFIELDS="id" PREVIOUS="scaleid"/>
+      </KEYS>
+      <INDEXES>
+        <INDEX NAME="action" UNIQUE="false" FIELDS="action" COMMENT="insert/update/delete"/>
+      </INDEXES>
+    </TABLE>
+    <TABLE NAME="scale_history" COMMENT="History table" PREVIOUS="grade_outcomes_history" NEXT="grade_import_values">
+      <FIELDS>
+        <FIELD NAME="id" TYPE="int" LENGTH="10" NOTNULL="true" UNSIGNED="true" SEQUENCE="true" ENUM="false" NEXT="action"/>
+        <FIELD NAME="action" TYPE="int" LENGTH="10" NOTNULL="true" UNSIGNED="false" DEFAULT="0" SEQUENCE="false" ENUM="false" COMMENT="created/modified/deleted constants" PREVIOUS="id" NEXT="oldid"/>
+        <FIELD NAME="oldid" TYPE="int" LENGTH="10" NOTNULL="true" UNSIGNED="false" SEQUENCE="false" ENUM="false" COMMENT="id of the table, please edit me" PREVIOUS="action" NEXT="source"/>
+        <FIELD NAME="source" TYPE="char" LENGTH="255" NOTNULL="false" SEQUENCE="false" ENUM="false" COMMENT="What caused the modification? manual/module/import/..." PREVIOUS="oldid" NEXT="timemodified"/>
+        <FIELD NAME="timemodified" TYPE="int" LENGTH="10" NOTNULL="false" UNSIGNED="true" SEQUENCE="false" ENUM="false" COMMENT="The last time this grade_item was modified" PREVIOUS="source" NEXT="loggeduser"/>
+        <FIELD NAME="loggeduser" TYPE="int" LENGTH="10" NOTNULL="false" UNSIGNED="true" SEQUENCE="false" ENUM="false" COMMENT="the userid of the person who last modified this outcome" PREVIOUS="timemodified" NEXT="courseid"/>
+        <FIELD NAME="courseid" TYPE="int" LENGTH="10" NOTNULL="true" UNSIGNED="true" DEFAULT="0" SEQUENCE="false" ENUM="false" PREVIOUS="loggeduser" NEXT="userid"/>
+        <FIELD NAME="userid" TYPE="int" LENGTH="10" NOTNULL="true" UNSIGNED="true" DEFAULT="0" SEQUENCE="false" ENUM="false" PREVIOUS="courseid" NEXT="name"/>
+        <FIELD NAME="name" TYPE="char" LENGTH="255" NOTNULL="true" SEQUENCE="false" ENUM="false" PREVIOUS="userid" NEXT="scale"/>
+        <FIELD NAME="scale" TYPE="text" LENGTH="small" NOTNULL="true" SEQUENCE="false" ENUM="false" PREVIOUS="name" NEXT="description"/>
+        <FIELD NAME="description" TYPE="text" LENGTH="small" NOTNULL="true" SEQUENCE="false" ENUM="false" PREVIOUS="scale"/>
+      </FIELDS>
+      <KEYS>
+        <KEY NAME="primary" TYPE="primary" FIELDS="id" COMMENT="primary key of the table, please edit me" NEXT="oldid"/>
+        <KEY NAME="oldid" TYPE="foreign" FIELDS="oldid" REFTABLE="scales" REFFIELDS="id" PREVIOUS="primary" NEXT="courseid"/>
+        <KEY NAME="courseid" TYPE="foreign" FIELDS="courseid" REFTABLE="course" REFFIELDS="id" PREVIOUS="oldid"/>
+      </KEYS>
+      <INDEXES>
+        <INDEX NAME="action" UNIQUE="false" FIELDS="action" COMMENT="insert/update/delete"/>
+      </INDEXES>
     </TABLE>
-    <TABLE NAME="grade_import_values" COMMENT="Temporary table for importing grades" PREVIOUS="grade_history" NEXT="grade_import_newitem">
+    <TABLE NAME="grade_import_values" COMMENT="Temporary table for importing grades" PREVIOUS="scale_history" NEXT="grade_import_newitem">
       <FIELDS>
         <FIELD NAME="id" TYPE="int" LENGTH="10" NOTNULL="true" UNSIGNED="false" SEQUENCE="true" ENUM="false" COMMENT="id of the table, please edit me" NEXT="itemid"/>
         <FIELD NAME="itemid" TYPE="int" LENGTH="10" NOTNULL="false" UNSIGNED="true" SEQUENCE="false" ENUM="false" COMMENT="if set, this points to existing grade_items id" PREVIOUS="id" NEXT="newgradeitem"/>
index ad8787e65797059610e0c732c318a5de9138a602..d9ba7aecdf5cbe396444672826087a483a2c3162 100644 (file)
@@ -953,24 +953,6 @@ function xmldb_main_upgrade($oldversion=0) {
 
 /// clenaup and recreate tables for course grade
     if ($result && $oldversion < 2007063000) {
-        /// Remove obsoleted unitt tests tables - they will be recreated automatically
-        $tables = array('grade_categories',
-                        'scale',
-                        'grade_items',
-                        'grade_calculations',
-                        'grade_grades',
-                        'grade_grades_raw',
-                        'grade_grades_final',
-                        'grade_grades_text',
-                        'grade_outcomes',
-                        'grade_history');
-
-        foreach ($tables as $table) {
-            $table = new XMLDBTable('unittest_'.$table);
-            if (table_exists($table)) {
-                drop_table($table);
-            }
-        }
 
         /// Remove the all grade tables - we need empty db for course grade to work properly
         $tables = array('grade_categories',
@@ -1018,7 +1000,6 @@ function xmldb_main_upgrade($oldversion=0) {
         $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);
@@ -1135,30 +1116,6 @@ function xmldb_main_upgrade($oldversion=0) {
     /// Launch create table for grade_outcomes
         $result = $result && create_table($table);
 
-
-    /// Define table grade_history to be created
-        $table = new XMLDBTable('grade_history');
-
-    /// Adding fields to table grade_history
-        $table->addFieldInfo('id', XMLDB_TYPE_INTEGER, '10', null, 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', null, XMLDB_NOTNULL, null, null, null, null);
-        $table->addFieldInfo('oldgrade', XMLDB_TYPE_NUMBER, '10, 5', null, null, null, null, null, null);
-        $table->addFieldInfo('newgrade', XMLDB_TYPE_NUMBER, '10, 5', null, null, null, null, null, null);
-        $table->addFieldInfo('note', XMLDB_TYPE_TEXT, 'small', null, null, null, null, null, null);
-        $table->addFieldInfo('howmodified', XMLDB_TYPE_CHAR, '255', null, XMLDB_NOTNULL, null, null, null, 'manual');
-        $table->addFieldInfo('usermodified', 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);
-
-    /// Adding keys to table grade_history
-        $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('usermodified', XMLDB_KEY_FOREIGN, array('usermodified'), 'user', array('id'));
-
-    /// Launch create table for grade_history
-        $result = $result && create_table($table);
-
     }
 
     // add foreign key that was forgotten in last commit
@@ -1188,6 +1145,253 @@ function xmldb_main_upgrade($oldversion=0) {
         set_config('grade_report_feedbackformat', '0'); 
     }
 
+    if ($result && $oldversion < 2007070602) {
+    /// Remove obsoleted unitt tests tables - they will be recreated automatically
+        $tables = array('grade_categories',
+                        'scale',
+                        'grade_items',
+                        'grade_calculations',
+                        'grade_grades',
+                        'grade_grades_raw',
+                        'grade_grades_final',
+                        'grade_grades_text',
+                        'grade_outcomes',
+                        'grade_history');
+
+        foreach ($tables as $table) {
+            $table = new XMLDBTable('unittest_'.$table);
+            if (table_exists($table)) {
+                drop_table($table);
+            }
+        }
+
+    /// drop old grade history table
+        $table = new XMLDBTable('grade_history');
+        if (table_exists($table)) {
+            drop_table($table);
+        }
+
+    /// drop old deleted field
+        $table  = new XMLDBTable('grade_items');
+        $field = new XMLDBField('deleted');
+        if (field_exists($table, $field)) {
+            drop_field($table, $field);
+        }
+
+
+    /// Define table grade_items_history to be created
+        $table = new XMLDBTable('grade_items_history');
+
+    /// Adding fields to table grade_items_history
+        $table->addFieldInfo('id', XMLDB_TYPE_INTEGER, '10', null, 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('userlogged', 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('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);
+
+
+    /// Define table grade_categories_history to be created
+        $table = new XMLDBTable('grade_categories_history');
+
+    /// Adding fields to table grade_categories_history
+        $table->addFieldInfo('id', XMLDB_TYPE_INTEGER, '10', null, 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('userlogged', 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');
+
+    /// 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);
+
+
+    /// Define table grade_grades_history to be created
+        $table = new XMLDBTable('grade_grades_history');
+
+    /// Adding fields to table grade_grades_history
+        $table->addFieldInfo('id', XMLDB_TYPE_INTEGER, '10', null, 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('userlogged', 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');
+
+    /// 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('userlogged', XMLDB_KEY_FOREIGN, array('userlogged'), '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);
+
+
+    /// Define table grade_grades_text_history to be created
+        $table = new XMLDBTable('grade_grades_text_history');
+
+    /// Adding fields to table grade_grades_text_history
+        $table->addFieldInfo('id', XMLDB_TYPE_INTEGER, '10', null, 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('userlogged', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, null, null, null, null, null);
+        $table->addFieldInfo('gradeid', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, null);
+        $table->addFieldInfo('information', XMLDB_TYPE_TEXT, 'medium', null, null, null, null, null, null);
+        $table->addFieldInfo('informationformat', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null, null, '0');
+        $table->addFieldInfo('feedback', XMLDB_TYPE_TEXT, 'medium', null, null, null, null, null, null);
+        $table->addFieldInfo('feedbackformat', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, '0');
+        $table->addFieldInfo('usermodified', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, null, null, null, null, null);
+
+    /// Adding keys to table grade_grades_text_history
+        $table->addKeyInfo('primary', XMLDB_KEY_PRIMARY, array('id'));
+        $table->addKeyInfo('oldid', XMLDB_KEY_FOREIGN, array('oldid'), 'grade_grades_text', array('id'));
+        $table->addKeyInfo('gradeid', XMLDB_KEY_FOREIGN, array('gradeid'), 'grade_grades', array('id'));
+        $table->addKeyInfo('usermodified', XMLDB_KEY_FOREIGN, array('usermodified'), 'user', array('id'));
+        $table->addKeyInfo('userlogged', XMLDB_KEY_FOREIGN, array('userlogged'), 'user', array('id'));
+
+    /// Adding indexes to table grade_grades_text_history
+        $table->addIndexInfo('action', XMLDB_INDEX_NOTUNIQUE, array('action'));
+
+    /// Launch create table for grade_grades_text_history
+        $result = $result && create_table($table);
+
+
+    /// Define table grade_outcomes_history to be created
+        $table = new XMLDBTable('grade_outcomes_history');
+
+    /// Adding fields to table grade_outcomes_history
+        $table->addFieldInfo('id', XMLDB_TYPE_INTEGER, '10', null, 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('userlogged', 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);
+        $table->addFieldInfo('usermodified', 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('usermodified', XMLDB_KEY_FOREIGN, array('usermodified'), 'user', array('id'));
+        $table->addKeyInfo('userlogged', XMLDB_KEY_FOREIGN, array('userlogged'), '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);
+
+
+    /// Define table scale_history to be created
+        $table = new XMLDBTable('scale_history');
+
+    /// 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('userlogged', 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'));
+        $table->addKeyInfo('userlogged', XMLDB_KEY_FOREIGN, array('userlogged'), 'user', 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);
+
+    }
+
+
     return $result;
 }
 
index f4c6524a7326676a2f2417c58fc95f8d5d0715e9..781fd44a0fe47c491f625167871afc0cfaad22bd 100644 (file)
@@ -36,7 +36,7 @@ class grade_category extends grade_object {
      * Array of class variables that are not part of the DB table fields
      * @var array $nonfields
      */
-    var $nonfields = array('table', 'nonfields', 'children', 'all_children', 'grade_item', 'parent_category', 'sortorder');
+    var $nonfields = array('table', 'required_fields', 'nonfields', 'children', 'all_children', 'grade_item', 'parent_category', 'sortorder');
 
     /**
      * The course this category belongs to.
@@ -161,8 +161,10 @@ class grade_category extends grade_object {
 
     /**
      * In addition to update() as defined in grade_object, call force_regrading of parent categories, if applicable.
+     * @param string $source from where was the object updated (mod/forum, manual, etc.)
+     * @return boolean success
      */
-    function update() {
+    function update($source=null) {
         // load the grade item or create a new one
         $this->load_grade_item();
 
@@ -175,22 +177,23 @@ class grade_category extends grade_object {
 
         // Recalculate grades if needed
         if ($this->qualifies_for_regrading()) {
-            if (!parent::update()) {
+            if (!parent::update($source)) {
                 return false;
             }
-            $this->grade_item->force_regrading();
+            $this->grade_item->force_regrading($source);
             return true;
 
         } else {
-            return parent::update();
+            return parent::update($source);
         }
     }
 
     /**
      * If parent::delete() is successful, send force_regrading message to parent category.
-     * @return boolean Success or failure.
+     * @param string $source from where was the object deleted (mod/forum, manual, etc.)
+     * @return boolean success
      */
-    function delete() {
+    function delete($source=null) {
         if ($this->is_course_category()) {
             debuggin('Can not delete top course category!');
             return false;
@@ -200,19 +203,22 @@ class grade_category extends grade_object {
         $parent = $this->load_parent_category();
 
         // Update children's categoryid/parent field first
-        $set_field_result = set_field('grade_items', 'categoryid', $parent->id, 'categoryid', $this->id);
-        $set_field_result = set_field('grade_categories', 'parent', $parent->id, 'parent', $this->id);
+        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);
+            }
+        }
 
-        // first delete the attached grade item
-        $grade_item->delete();
+        // first delete the attached grade item and grades
+        $grade_item->delete($source);
 
         // delete category itself
-        $result = parent::delete();
-
-        // force regrading of parent
-        $parent->force_regrading();
-
-        return $result;
+        return parent::delete($source);
     }
 
     /**
@@ -221,8 +227,10 @@ class grade_category extends grade_object {
      * be done here instead of in the constructor, is that they both need to know the record's
      * id number, which only gets created at insertion time.
      * This method also creates an associated grade_item if this wasn't done during construction.
+     * @param string $source from where was the object inserted (mod/forum, manual, etc.)
+     * @return int PK ID if successful, false otherwise
      */
-    function insert() {
+    function insert($source=null) {
 
         if (empty($this->courseid)) {
             error('Can not insert grade category without course id!');
@@ -231,20 +239,19 @@ class grade_category extends grade_object {
         if (empty($this->parent)) {
             $course_category = grade_category::fetch_course_category($this->courseid);
             $this->parent = $course_category->id;
-
         }
 
         $this->path = null;
 
-        if (!parent::insert()) {
+        if (!parent::insert($source)) {
             debugging("Could not insert this category: " . print_r($this, true));
             return false;
         }
 
         // build path and depth
-        $this->update();
+        $this->update($source);
 
-        return true;
+        return $this->id;
     }
 
     function insert_course_category($courseid) {
@@ -253,15 +260,15 @@ class grade_category extends grade_object {
         $this->path     = null;
         $this->parent   = null;
 
-        if (!parent::insert()) {
+        if (!parent::insert('system')) {
             debugging("Could not insert this category: " . print_r($this, true));
             return false;
         }
 
         // build path and depth
-        $this->update();
+        $this->update('system');
 
-        return true;
+        return $this->id;
     }
 
     /**
@@ -292,9 +299,10 @@ class grade_category extends grade_object {
      * levels until it reaches the top category. This is then used to determine whether or not
      * to regenerate the raw and final grades for each category grade_item. This is accomplished
      * thanks to the path variable, so we don't need to use recursion.
+     * @param string $source from where was the object updated (mod/forum, manual, etc.)
      * @return boolean Success or failure
      */
-    function force_regrading() {
+    function force_regrading($source=null) {
         if (empty($this->id)) {
             debugging("Needsupdate requested before inserting grade category.");
             return true;
index cd662276db864117bbcfd13c7af3c3006646134c..6c383a015eae88c9e2311ca07c8975d71b888f7a 100644 (file)
@@ -37,7 +37,7 @@ class grade_grades extends grade_object {
      * Array of class variables that are not part of the DB table fields
      * @var array $nonfields
      */
-    var $nonfields = array('table', 'nonfields', 'grade_grades_text', 'grade_item');
+    var $nonfields = array('table', 'nonfields', 'required_fields', 'grade_grades_text', 'grade_item');
 
     /**
      * The id of the grade_item this grade belongs to.
@@ -248,6 +248,19 @@ class grade_grades extends grade_object {
         return grade_object::fetch_all_helper('grade_grades', 'grade_grades', $params);
     }
 
+
+    /**
+     * Delete grade together with feedback.
+     * @param string $source from where was the object deleted (mod/forum, manual, etc.)
+     * @return boolean success
+     */
+    function delete($source=null) {
+        if ($text = $this->load_text()) {
+            $text->delete($source);
+        }
+        return parent::delete($source);
+    }
+
     /**
      * Updates this grade with the given textual information. This will create a new grade_grades_text entry
      * if none was previously in DB for this raw grade, or will update the existing one.
@@ -288,15 +301,22 @@ class grade_grades extends grade_object {
      * @param int $feedbackformat Text format for the feedback
      * @return boolean Success or Failure
      */
-    function update_feedback($feedback, $feedbackformat) {
+    function update_feedback($feedback, $feedbackformat, $usermodified=null) {
+        global $USER;
+
         $this->load_text();
 
+        if (empty($usermodified)) {
+            $usermodified = $USER->id;
+        }
+
         if (empty($this->grade_grades_text->id)) {
             $this->grade_grades_text = new grade_grades_text();
 
             $this->grade_grades_text->gradeid        = $this->id;
             $this->grade_grades_text->feedback       = $feedback;
             $this->grade_grades_text->feedbackformat = $feedbackformat;
+            $this->grade_grades_text->usermodified   = $usermodified;
 
             return $this->grade_grades_text->insert();
 
@@ -306,6 +326,8 @@ class grade_grades extends grade_object {
 
                 $this->grade_grades_text->feedback       = $feedback;
                 $this->grade_grades_text->feedbackformat = $feedbackformat;
+                $this->grade_grades_text->usermodified   = $usermodified;
+
                 return  $this->grade_grades_text->update();
             } else {
                 return true;
index abed8ebcaa31a1c8eef34bf8c3dbe2eacc1e2857..02dd303ade30145987618f30698f80c19459d957 100644 (file)
@@ -40,7 +40,7 @@ class grade_grades_text extends grade_object {
      * Array of class variables that are not part of the DB table fields
      * @var array $nonfields
      */
-    var $nonfields = array('table', 'nonfields');
+    var $nonfields = array('table', 'required_fields', 'nonfields');
 
     /**
      * The grade_grades.id this text refers to.
diff --git a/lib/grade/grade_history.php b/lib/grade/grade_history.php
deleted file mode 100644 (file)
index 47f77de..0000000
+++ /dev/null
@@ -1,132 +0,0 @@
-<?php // $Id$
-
-///////////////////////////////////////////////////////////////////////////
-//                                                                       //
-// NOTICE OF COPYRIGHT                                                   //
-//                                                                       //
-// Moodle - Modular Object-Oriented Dynamic Learning Environment         //
-//          http://moodle.com                                            //
-//                                                                       //
-// Copyright (C) 2001-2003  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                         //
-//                                                                       //
-///////////////////////////////////////////////////////////////////////////
-
-require_once('grade_object.php');
-
-/**
- * Class representing a grade history. It is responsible for handling its DB representation,
- * modifying and returning its metadata.
- */
-class grade_history extends grade_object {
-    /**
-     * DB Table (used by grade_object).
-     * @var string $table
-     */
-    var $table = 'grade_history';
-
-    /**
-     * Array of class variables that are not part of the DB table fields
-     * @var array $nonfields
-     */
-    var $nonfields = array('table', 'nonfields');
-
-    /**
-     * The grade_item whose raw grade is being changed.
-     * @var int $itemid
-     */
-    var $itemid;
-
-    /**
-     * The user whose raw grade is being changed.
-     * @var int $userid
-     */
-    var $userid;
-
-    /**
-     * The value of the grade before the change.
-     * @var float $oldgrade
-     */
-    var $oldgrade;
-
-    /**
-     * The value of the grade after the change.
-     * @var float $newgrade
-     */
-    var $newgrade;
-
-    /**
-     * An optional annotation to explain the change.
-     * @var string $note
-     */
-    var $note;
-
-    /**
-     * Which user account did the modification.
-     * @var string $usermodified
-     */
-    var $usermodified;
-
-    /**
-     * How the grade was modified ('manual', 'module', 'import' etc...).
-     * @var string $howmodified
-     */
-    var $howmodified = 'manual';
-
-    /**
-     * Finds and returns a grade_history instance based on params.
-     * @static
-     *
-     * @param array $params associative arrays varname=>value
-     * @return object grade_history instance or false if none found.
-     */
-    function fetch($params) {
-        return grade_object::fetch_helper('grade_history', 'grade_history', $params);
-    }
-
-    /**
-     * Finds and returns all grade_history instances based on params.
-     * @static
-     *
-     * @param array $params associative arrays varname=>value
-     * @return array array of grade_history insatnces or false if none found.
-     */
-    function fetch_all($params) {
-        return grade_object::fetch_all_helper('grade_history', 'grade_history', $params);
-    }
-
-    /**
-     * Given a info about changed raw grade and some other parameters, records the
-     * change of grade value for this object, and associated data.
-     * @static
-     * @param object $grade_raw
-     * @param float $oldgrade
-     * @param string $note
-     * @param string $howmodified
-     * @return boolean Success or Failure
-     */
-    function insert_change($userid, $itemid, $newgrade, $oldgrade, $howmodified='manual', $note=NULL) {
-        global $USER;
-        $history = new grade_history();
-        $history->itemid       = $itemid;
-        $history->userid       = $userid;
-        $history->oldgrade     = $oldgrade;
-        $history->newgrade     = $newgrade;
-        $history->note         = $note;
-        $history->howmodified  = $howmodified;
-
-        return $history->insert();
-    }
-}
-?>
index 6b532389723dc4cfe2c9be3ecbf9fee64d493bef..75d4722c77b21ed553e7a987e0bd390b92d2dc63 100644 (file)
@@ -40,7 +40,7 @@ class grade_item extends grade_object {
      * Array of class variables that are not part of the DB table fields
      * @var array $nonfields
      */
-    var $nonfields = array('table', 'nonfields', 'formula', 'calculation_normalized', 'scale', 'item_category', 'parent_category', 'outcome');
+    var $nonfields = array('table', 'nonfields', 'required_fields', 'formula', 'calculation_normalized', 'scale', 'item_category', 'parent_category', 'outcome');
 
     /**
      * The course this grade_item belongs to.
@@ -225,10 +225,10 @@ class grade_item extends grade_object {
     /**
      * In addition to update() as defined in grade_object, handle the grade_outcome and grade_scale objects.
      * Force regrading if necessary
-     *
+     * @param string $source from where was the object inserted (mod/forum, manual, etc.)
      * @return boolean success
      */
-    function update() {
+    function update($source=null) {
         // Retrieve scale and infer grademax/min from it if needed
         $this->load_scale();
 
@@ -236,7 +236,7 @@ class grade_item extends grade_object {
             return $this->force_regrading();
 
         } else {
-            return parent::update();
+            return parent::update($source);
         }
     }
 
@@ -295,27 +295,35 @@ class grade_item extends grade_object {
     }
 
     /**
-     * If parent::delete() is successful, send force_regrading message to parent category.
-     * @return boolean Success or failure.
+     * Delete all grades and force_regrading of parent category.
+     * @param string $source from where was the object deleted (mod/forum, manual, etc.)
+     * @return boolean success
      */
-    function delete() {
+    function delete($source=null) {
         if ($this->is_course_item()) {
             debuggin('Can not delete course or category item!');
             return false;
         }
 
         if (!$this->is_category_item() and $category = $this->get_parent_category()) {
-            $category->force_regrading();
+            $category->force_regrading($source);
+        }
+
+        if ($grades = grade_grades::fetch_all(array('itemid'=>$this->id))) {
+            foreach ($grades as $grade) {
+                $grade->delete($source);
+            }
         }
 
-        return parent::delete();;
+        return parent::delete($source);
     }
 
     /**
      * In addition to perform parent::insert(), this calls the grade_item's category's (if applicable) force_regrading() method.
-     * @return int ID of the new grade_item record.
+     * @param string $source from where was the object inserted (mod/forum, manual, etc.)
+     * @return int PK ID if successful, false otherwise
      */
-    function insert() {
+    function insert($source=null) {
         global $CFG;
 
         if (empty($this->courseid)) {
@@ -359,12 +367,10 @@ class grade_item extends grade_object {
             }
         }
 
-        $result = parent::insert();
-
-        if ($result) {
+        if (parent::insert($source)) {
             // force regrading of items if needed
             $this->force_regrading();
-            return true;
+            return $this->id;
 
         } else {
             debugging("Could not insert this grade_item in the database!");
@@ -679,12 +685,13 @@ class grade_item extends grade_object {
      * for this grade_item to require an update. The flag needs to be propagated up all
      * levels until it reaches the top category. This is then used to determine whether or not
      * to regenerate the raw and final grades for each category grade_item.
+     * @param string $source from where was the object updated (mod/forum, manual, etc.)
      * @return boolean Success or failure
      */
-    function force_regrading() {
+    function force_regrading($source=null) {
         $this->needsupdate = true;
 
-        if (!parent::update()) {
+        if (!parent::update($source)) {
             return false;
         }
 
@@ -693,7 +700,7 @@ class grade_item extends grade_object {
 
         } else {
             $parent = $this->load_parent_category();
-            $parent->force_regrading();
+            $parent->force_regrading($source);
 
         }
 
@@ -950,7 +957,7 @@ class grade_item extends grade_object {
         $sql = "UPDATE {$CFG->prefix}grade_items
                    SET sortorder = sortorder + 1
                  WHERE sortorder > $sortorder AND courseid = {$this->courseid}";
-        execute_sql($sql);
+        execute_sql($sql, false);
 
         $this->set_sortorder($sortorder + 1);
     }
@@ -1058,10 +1065,14 @@ class grade_item extends grade_object {
      * @param int $feedbackformat
      * @return mixed grade_grades object if ok, false if error
      */
-    function update_raw_grade($userid, $rawgrade=false, $source='manual', $note=NULL, $feedback=false, $feedbackformat=FORMAT_MOODLE) {
-        global $CFG;
+    function update_raw_grade($userid, $rawgrade=false, $source='manual', $note=NULL, $feedback=false, $feedbackformat=FORMAT_MOODLE, $usermodified=null) {
+        global $CFG, $USER;
         require_once($CFG->libdir.'/eventslib.php');
 
+        if (empty($usermodified)) {
+            $usermodified = $USER->id;
+        }
+
         // calculated grades can not be updated
         if ($this->is_calculated()) {
             return false;
@@ -1072,7 +1083,7 @@ class grade_item extends grade_object {
             return false;
         }
 
-        $grade = new grade_grades(array('itemid'=>$this->id, 'userid'=>$userid));
+        $grade = new grade_grades(array('itemid'=>$this->id, 'userid'=>$userid, 'usermodified'=>$usermodified));
         $grade->grade_item =& $this; // prevent db fetching of cached grade_item
 
         if (!empty($grade->id)) {
@@ -1101,12 +1112,12 @@ class grade_item extends grade_object {
             if (empty($grade->id)) {
                 $oldgrade = null;
                 $grade->rawgrade = $rawgrade;
-                $result = $grade->insert();
+                $result = $grade->insert($source);
 
             } else {
                 $oldgrade = $grade->rawgrade;
                 $grade->rawgrade = $rawgrade;
-                $result = $grade->update();
+                $result = $grade->update($source);
             }
         }
 
@@ -1115,13 +1126,12 @@ class grade_item extends grade_object {
             if (empty($grade->id)) {
                 // create new grade
                 $oldgrade = null;
-                $result = $grade->insert();
+                $result = $grade->insert($source);
             }
-            $result = $result && $grade->update_feedback($feedback, $feedbackformat);
+            $result = $result && $grade->update_feedback($feedback, $feedbackformat, $usermodified);
         }
 
         // TODO Handle history recording error, such as displaying a notice, but still return true
-        grade_history::insert_change($userid, $this->id, $grade->rawgrade, $oldgrade, $source, $note);
 
         // This grade item needs update
         $this->force_regrading();
index 4f0beb6299e251a93c835a7b35124c83628aabd2..adb0f243e35e612f0dadbe8e9769091336a669f0 100644 (file)
@@ -166,43 +166,81 @@ class grade_object {
 
     /**
      * Updates this object in the Database, based on its object variables. ID must be set.
-     *
-     * @return boolean
+     * @param string $source from where was the object updated (mod/forum, manual, etc.)
+     * @return boolean success
      */
-    function update() {
+    function update($source=null) {
         global $USER;
 
         $this->timemodified = time();
 
-        if (array_key_exists('usermodified', $this)) {
-            $this->usermodified = $USER->id;
-        }
-
         // we need to do this to prevent infinite loops in addslashes_recursive - grade_item -> category ->grade_item
         $data = new object();
         foreach ($this as $var=>$value) {
             if (!in_array($var, $this->nonfields)) {
-                $data->$var = addslashes_recursive($value);
+                if (is_object($value) or is_array($value)) {
+                    debugging("Incorrect property '$var' found when updating grade object");
+                } else {
+                    $data->$var = $value;
+                }
             }
         }
 
-        return update_record($this->table, $data);
+        if(!update_record($this->table, addslashes_recursive($data))) {
+            return false;
+        }
+
+        // track history
+        // TODO: add history disable switch
+        unset($data->timecreated);
+        $data->action     = GRADE_HISTORY_UPDATE;
+        $data->oldid      = $this->id;
+        $data->source     = $source;
+        $data->userlogged = $USER->id;
+        insert_record($this->table.'_history', addslashes_recursive($data));
+
+        return true;
     }
 
     /**
      * Deletes this object from the database.
+     * @param string $source from where was the object deleted (mod/forum, manual, etc.)
+     * @return boolean success
      */
-    function delete() {
-        return delete_records($this->table, 'id', $this->id);
+    function delete($source=null) {
+        global $USER;
+
+        // track history
+        // TODO: add history disable switch
+        if ($data = get_record($this->table, 'id', $this->id)) {
+            unset($data->id);
+            unset($data->timecreated);
+            $data->action       = GRADE_HISTORY_DELETE;
+            $data->oldid        = $this->id;
+            $data->source       = $source;
+            $data->timemodified = time();
+            $data->userlogged   = $USER->id;
+        }
+
+        if (delete_records($this->table, 'id', $this->id)) {
+            if ($data) {
+                insert_record($this->table.'_history', addslashes_recursive($data));
+            }
+            return true;
+
+        } else {
+            return false;
+        }
     }
 
     /**
      * Records this object in the Database, sets its id to the returned value, and returns that value.
      * If successful this function also fetches the new object data from database and stores it
      * in object properties.
+     * @param string $source from where was the object inserted (mod/forum, manual, etc.)
      * @return int PK ID if successful, false otherwise
      */
-    function insert() {
+    function insert($source=null) {
         global $USER;
 
         if (!empty($this->id)) {
@@ -212,15 +250,15 @@ class grade_object {
 
         $this->timecreated = $this->timemodified = time();
 
-        if (array_key_exists('usermodified', $this)) {
-            $this->usermodified = $USER->id;
-        }
-
         // we need to do this to prevent infinite loops in addslashes_recursive - grade_item -> category ->grade_item
         $data = new object();
         foreach ($this as $var=>$value) {
             if (!in_array($var, $this->nonfields)) {
-                $data->$var = addslashes_recursive($value);
+                if (is_object($value) or is_array($value)) {
+                    debugging("Incorrect property '$var' found when inserting grade object");
+                } else {
+                    $data->$var = $value;
+                }
             }
         }
 
@@ -232,6 +270,15 @@ class grade_object {
         // set all object properties from real db data
         $this->update_from_db();
 
+        // track history
+        // TODO: add history disable switch
+        unset($data->timecreated);
+        $data->action     = GRADE_HISTORY_INSERT;
+        $data->oldid      = $this->id;
+        $data->source     = $source;
+        $data->userlogged = $USER->id;
+        insert_record($this->table.'_history', addslashes_recursive($data));
+
         return $this->id;
     }
 
index 1127f101f740ff5084eec291848b3b936de9dd58..6eff9d27e29bbb2a3fffdd3248656cafd249cd90 100644 (file)
@@ -40,7 +40,7 @@ class grade_outcome extends grade_object {
      * Array of class variables that are not part of the DB table fields
      * @var array $nonfields
      */
-    var $nonfields = array('table', 'nonfields', 'scale');
+    var $nonfields = array('table', 'nonfields', 'required_fields', 'scale');
 
     /**
      * The course this outcome belongs to.
index d49986626d715ceabe160c50e9dfd5152da08943..e21a4f0fed69ed564f31c8be2bc566fc05cba284 100644 (file)
@@ -40,7 +40,7 @@ class grade_scale extends grade_object {
      * Array of class variables that are not part of the DB table fields
      * @var array $nonfields
      */
-    var $nonfields = array('table', 'nonfields', 'scale_items');
+    var $nonfields = array('table', 'nonfields', 'required_fields', 'scale_items');
 
     /**
      * The course this scale belongs to.
index 0e344b0f1439670e846b9bafef3a87aa6b5a609b..d737371d524d8dd02772713fd433825d9c871e55 100644 (file)
@@ -66,7 +66,7 @@ class grade_tree {
      * @param boolean $category_grade_last category grade item is the last child
      * @param boolean $aggregation_view Either full view (0) or compact view (1)
      */
-    function grade_tree($courseid, $fillers=true, $include_grades=false, $category_grade_last=true, 
+    function grade_tree($courseid, $fillers=true, $include_grades=false, $category_grade_last=true,
                         $aggregation_view=GRADER_REPORT_AGGREGATION_VIEW_FULL) {
         global $USER;
 
index b1ea495dac32fa24787d4b10a5b42a1f01fff5b7..ca1af68032b1be15c1dbe8f7e535a0956fb3a35d 100644 (file)
@@ -59,6 +59,11 @@ define('GRADE_UPDATE_MULTIPLE', 2);
 define('GRADE_UPDATE_ITEM_DELETED', 3);
 define('GRADE_UPDATE_ITEM_LOCKED', 4);
 
+// Grate teables history tracking actions
+define('GRADE_HISTORY_INSERT', 1);
+define('GRADE_HISTORY_UPDATE', 2);
+define('GRADE_HISTORY_DELETE', 3);
+
 // Set up constants for report preferences
 define('GRADER_REPORT_AGGREGATION_POSITION_LEFT', 0);
 define('GRADER_REPORT_AGGREGATION_POSITION_RIGHT', 1);
@@ -75,7 +80,6 @@ require_once($CFG->libdir . '/grade/grade_item.php');
 require_once($CFG->libdir . '/grade/grade_grades.php');
 require_once($CFG->libdir . '/grade/grade_scale.php');
 require_once($CFG->libdir . '/grade/grade_outcome.php');
-require_once($CFG->libdir . '/grade/grade_history.php');
 require_once($CFG->libdir . '/grade/grade_grades_text.php');
 require_once($CFG->libdir . '/grade/grade_tree.php');
 
@@ -99,6 +103,7 @@ require_once($CFG->libdir . '/grade/grade_tree.php');
  * @param mixed $itemdetails object or array describing the grading item, NULL if no change
  */
 function grade_update($source, $courseid, $itemtype, $itemmodule, $iteminstance, $itemnumber, $grades=NULL, $itemdetails=NULL) {
+    global $USER;
 
     // only following grade_item properties can be changed in this function
     $allowed = array('itemname', 'idnumber', 'gradetype', 'grademax', 'grademin', 'scaleid', 'multfactor', 'plusfactor', 'deleted');
@@ -124,6 +129,17 @@ function grade_update($source, $courseid, $itemtype, $itemmodule, $iteminstance,
         return GRADE_UPDATE_MULTIPLE;
     }
 
+    if (!empty($itemdetails['deleted'])) {
+        if ($grade_item) {
+            if ($grade_item->delete($source)) {
+                return GRADE_UPDATE_OK;
+            } else {
+                return GRADE_UPDATE_FAILED;
+            }
+        }
+        return GRADE_UPDATE_OK;
+    }
+
 /// Create or update the grade_item if needed
     if (!$grade_item) {
         if ($itemdetails) {
@@ -188,12 +204,6 @@ function grade_update($source, $courseid, $itemtype, $itemmodule, $iteminstance,
         return GRADE_UPDATE_OK;
     }
 
-    // no grading in deleted items
-    if ($grade_item->deleted) {
-        debugging('Grade item was already deleted!');
-        return GRADE_UPDATE_ITEM_DELETED;
-    }
-
 /// Finally start processing of grades
     if (is_object($grades)) {
         $grades = array($grades);
@@ -230,8 +240,14 @@ function grade_update($source, $courseid, $itemtype, $itemmodule, $iteminstance,
             $feedbackformat = $grade['feedbackformat'];
         }
 
+        if (array_key_exists('usermodified', $grade)) {
+            $usermodified = $grade['usermodified'];
+        } else {
+            $usermodified = $USER->id;
+        }
+
         // update or insert the grade
-        if (!$grade_item->update_raw_grade($userid, $rawgrade, $source, null, $feedback, $feedbackformat)) {
+        if (!$grade_item->update_raw_grade($userid, $rawgrade, $source, null, $feedback, $feedbackformat, $usermodified)) {
             $failed = true;
         }
     }
@@ -709,7 +725,7 @@ function grade_oldgradebook_upgrade($courseid) {
 function grade_get_icons($element, $tree) {
     global $CFG;
     global $USER;
-    
+
     // Load language strings
     $straddfeedback    = get_string("addfeedback", 'grades');
     $stredit           = get_string("edit");
@@ -738,7 +754,7 @@ function grade_get_icons($element, $tree) {
     $object = $element['object'];
     $type   = $element['type'];
 
-    // Load user preferences 
+    // Load user preferences
     $aggregationview = get_user_preferences('grade_report_aggregationview', $CFG->grade_report_aggregationview);
 
     // Icons shown when edit mode is on
@@ -780,12 +796,12 @@ function grade_get_icons($element, $tree) {
         if ($type == 'grade' and $USER->gradefeedback) {
             // Display Edit/Add feedback icon
             if (empty($object->feedback)) {
-                $html .= '<a href="report/grader/edit_feedback.php?id=' . $object->id 
+                $html .= '<a href="report/grader/edit_feedback.php?id=' . $object->id
                       . "&amp;action=add&amp;courseid=$object->courseid\">\n";
                 $html .= '<img src="'.$CFG->pixpath.'/t/feedback_add.gif" class="iconsmall" alt="'.$straddfeedback.'" '
                       . 'title="'.$straddfeedback.'" /></a>'. "\n";
             } else {
-                $html .= '<a href="report/grader/edit_feedback.php?id=' . $object->id 
+                $html .= '<a href="report/grader/edit_feedback.php?id=' . $object->id
                       . "&amp;action=edit&amp;courseid=$object->courseid\">\n";
                 $html .= '<img src="'.$CFG->pixpath.'/t/feedback.gif" class="iconsmall" alt="'.$streditfeedback.'" '
                       . 'title="'.$streditfeedback.'" onmouseover="return overlib(\''.$object->feedback.'\', CAPTION, \''
@@ -830,7 +846,7 @@ function grade_get_icons($element, $tree) {
         if ($USER->gradefeedback) {
             // Display view feedback icon
             if (!empty($object->feedback)) {
-                $html .= '<a href="report/grader/edit_feedback.php?id=' . $object->id 
+                $html .= '<a href="report/grader/edit_feedback.php?id=' . $object->id
                       . "&amp;action=view&amp;courseid=$object->courseid\">\n";
                 $html .= '<img onmouseover="return overlib(\''.$object->feedback.'\', CAPTION, \''
                       . $strfeedback.'\');" onmouseout="return nd();" '
index 640ebc6058de9d0820d21d53c0b6d7e753a0f79a..3954111c5c2f5bff6915278777ccec68efb5aafc 100644 (file)
@@ -56,15 +56,13 @@ class grade_test extends UnitTestCase {
                         'grade_items',
                         'grade_grades',
                         'grade_grades_text',
-                        'grade_outcomes',
-                        'grade_history');
+                        'grade_outcomes');
 
     var $grade_items = array();
     var $grade_categories = array();
     var $grade_grades = array();
     var $grade_grades_text = array();
     var $grade_outcomes = array();
-    var $grade_history = array();
     var $scale = array();
 
     var $courseid = 1;
@@ -83,6 +81,10 @@ class grade_test extends UnitTestCase {
             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();
@@ -137,6 +139,7 @@ class grade_test extends UnitTestCase {
             delete_records($table->name);
         }
 
+
         /// Define table grade_categories to be created
         $table = new XMLDBTable('grade_categories');
 
@@ -165,6 +168,42 @@ class grade_test extends UnitTestCase {
             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', null, 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('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_grades_text to be created
         $table = new XMLDBTable('grade_grades_text');
 
@@ -186,12 +225,13 @@ class grade_test extends UnitTestCase {
             $table->addKeyInfo('usermodified', XMLDB_KEY_FOREIGN, array('usermodified'), 'user', array('id'));
 
         /// Launch create table for grade_grades_text
-            $result = $result && create_table($table);
+            $result = $result && create_table($table, true, false);
 
         } else {
             delete_records($table->name);
         }
 
+
         /// Define table grade_outcomes to be created
         $table = new XMLDBTable('grade_outcomes');
 
@@ -220,41 +260,142 @@ class grade_test extends UnitTestCase {
             delete_records($table->name);
         }
 
-        /// Define table grade_history to be created
-        $table = new XMLDBTable('grade_history');
+
+        /// Define table scale to be created
+        $table = new XMLDBTable('scale');
 
         if ($result && !table_exists($table)) {
 
-            /// Adding fields to table grade_history
+            $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);
+        }
+
+
+        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', null, 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', null, XMLDB_NOTNULL, null, null, null, null);
-            $table->addFieldInfo('oldgrade', XMLDB_TYPE_NUMBER, '10, 5', null, null, null, null, null, null);
-            $table->addFieldInfo('newgrade', XMLDB_TYPE_NUMBER, '10, 5', null, null, null, null, null, null);
-            $table->addFieldInfo('note', XMLDB_TYPE_TEXT, 'small', null, null, null, null, null, null);
-            $table->addFieldInfo('howmodified', XMLDB_TYPE_CHAR, '255', null, XMLDB_NOTNULL, null, null, null, 'manual');
-            $table->addFieldInfo('usermodified', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, null, null, 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('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_history
+        /// Adding keys to table grade_items_history
             $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('usermodified', XMLDB_KEY_FOREIGN, array('usermodified'), 'user', 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', null, 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');
+
+        /// 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'));
 
-            /// Launch create table for grade_history
+        /// 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');
+        $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', null, 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);
@@ -267,16 +408,92 @@ class grade_test extends UnitTestCase {
             $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('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);
 
+        /// 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'));
 
-            /// Launch create table for grade_grades
+        /// 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_grades_text to be created
+        $table = new XMLDBTable('grade_grades_text_history');
+
+        if ($result && !table_exists($table)) {
+
+        /// Adding fields to table grade_grades_text_history
+            $table->addFieldInfo('id', XMLDB_TYPE_INTEGER, '10', null, 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('gradeid', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, null);
+            $table->addFieldInfo('information', XMLDB_TYPE_TEXT, 'medium', null, null, null, null, null, null);
+            $table->addFieldInfo('informationformat', XMLDB_TYPE_INTEGER, '10', null, XMLDB_NOTNULL, null, null, null, '0');
+            $table->addFieldInfo('feedback', XMLDB_TYPE_TEXT, 'medium', null, null, null, null, null, null);
+            $table->addFieldInfo('feedbackformat', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, '0');
+            $table->addFieldInfo('usermodified', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, null, null, null, null, null);
+
+        /// Adding keys to table grade_grades_text_history
+            $table->addKeyInfo('primary', XMLDB_KEY_PRIMARY, array('id'));
+            $table->addKeyInfo('oldid', XMLDB_KEY_FOREIGN, array('oldid'), 'grade_grades_text', array('id'));
+            $table->addKeyInfo('gradeid', XMLDB_KEY_FOREIGN, array('gradeid'), 'grade_grades', array('id'));
+            $table->addKeyInfo('loggeduser', XMLDB_KEY_FOREIGN, array('loggeduser'), 'user', array('id'));
+            $table->addKeyInfo('usermodified', XMLDB_KEY_FOREIGN, array('usermodified'), 'user', array('id'));
+
+        /// Adding indexes to table grade_grades_text_history
+            $table->addIndexInfo('action', XMLDB_INDEX_NOTUNIQUE, array('action'));
+
+        /// Launch create table for grade_grades_text_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', null, 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 {
@@ -284,21 +501,33 @@ class grade_test extends UnitTestCase {
         }
 
         /// Define table scale to be created
-        $table = new XMLDBTable('scale');
+        $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);
-            $table->addFieldInfo('timemodified', XMLDB_TYPE_INTEGER, '10', XMLDB_UNSIGNED, XMLDB_NOTNULL, null, null, null, '0');
+
+        /// Adding keys to table scale_history
             $table->addKeyInfo('primary', XMLDB_KEY_PRIMARY, array('id'));
-            $table->addIndexInfo('courseid', XMLDB_INDEX_NOTUNIQUE, array('courseid'));
+            $table->addKeyInfo('oldid', XMLDB_KEY_FOREIGN, array('oldid'), 'scales', array('id'));
+            $table->addKeyInfo('courseid', XMLDB_KEY_FOREIGN, array('courseid'), 'course', array('id'));
 
-            /// Launch create table for scale
+        /// 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 {
@@ -1011,23 +1240,6 @@ class grade_test extends UnitTestCase {
         }
     }
 
-    /**
-     * Load grade_history data into the database, and adds the corresponding objects to this class' variable.
-     */
-    function load_grade_history() {
-        $grade_history = new stdClass();
-
-        $grade_history->itemid = $this->grade_items[0]->id;
-        $grade_history->userid = 1;
-        $grade_history->oldgrade = 88;
-        $grade_history->newgrade = 90;
-        $grade_history->note = 'Modified manually in testgradehistory.php';
-        $grade_history->howmodified = 'manual';
-
-        if ($grade_history->id = insert_record('grade_history', $grade_history)) {
-            $this->grade_history[] = $grade_history;
-        }
-    }
 /**
  * No unit tests here
  */
index 8f65c7669e6d7c93a15baa889a9164418405b25f..b576b89db976abbd39294e3e3080b7b4175a2862 100755 (executable)
@@ -57,6 +57,8 @@ class grade_text_test extends grade_test {
     }
 
     function test_grade_grades_text_insert() {
+        global $USER;
+
         $grade_grades_text = new grade_grades_text();
         $this->assertTrue(method_exists($grade_grades_text, 'insert'));
 
@@ -65,13 +67,12 @@ class grade_text_test extends grade_test {
         $grade_grades_text->informationformat = FORMAT_PLAIN;
         $grade_grades_text->feedback = 'Good, but not good enough..';
         $grade_grades_text->feedbackformat = FORMAT_PLAIN;
+        $grade_grades_text->usermodified = $USER->id;
 
         $grade_grades_text->insert();
 
         $last_grade_grades_text = end($this->grade_grades_text);
 
-        global $USER;
-
         $this->assertEqual($grade_grades_text->id, $last_grade_grades_text->id + 1);
         $this->assertFalse(empty($grade_grades_text->timecreated));
         $this->assertFalse(empty($grade_grades_text->timemodified));
diff --git a/lib/simpletest/grade/simpletest/testgradehistory.php b/lib/simpletest/grade/simpletest/testgradehistory.php
deleted file mode 100644 (file)
index d9cb433..0000000
+++ /dev/null
@@ -1,112 +0,0 @@
-<?php // $Id$
-
-///////////////////////////////////////////////////////////////////////////
-//                                                                       //
-// NOTICE OF COPYRIGHT                                                   //
-//                                                                       //
-// Moodle - Modular Object-Oriented Dynamic Learning Environment         //
-//          http://moodle.org                                            //
-//                                                                       //
-// Copyright (C) 1999-2004  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                         //
-//                                                                       //
-///////////////////////////////////////////////////////////////////////////
-
-/**
- * Unit tests for grade_history object.
- *
- * @author nicolas@moodle.com
- * @license http://www.gnu.org/copyleft/gpl.html GNU Public License
- * @package moodlecore
- */
-
-if (!defined('MOODLE_INTERNAL')) {
-    die('Direct access to this script is forbidden.');    ///  It must be included from a Moodle page
-}
-
-require_once($CFG->libdir.'/simpletest/fixtures/gradetest.php');
-
-class grade_history_test extends grade_test {
-
-    function test_grade_history_construct() {
-        $params = new stdClass();
-
-        $params->itemid = $this->grade_items[0]->id;
-        $params->userid = 1;
-        $params->oldgrade = 88;
-        $params->newgrade = 90;
-        $params->note = 'Modified manually in testgradehistory.php';
-        $params->howmodified = 'manual';
-
-        $grade_history = new grade_history($params, false);
-        $this->assertEqual($params->itemid, $grade_history->itemid);
-        $this->assertEqual($params->note, $grade_history->note);
-    }
-
-    function test_grade_history_insert() {
-        $grade_history = new grade_history();
-        $this->assertTrue(method_exists($grade_history, 'insert'));
-
-        $grade_history->itemid = $this->grade_items[0]->id;
-        $grade_history->userid = 1;
-        $grade_history->oldgrade = 88;
-        $grade_history->newgrade = 90;
-        $grade_history->note = 'Modified manually in testgradehistory.php';
-        $grade_history->howmodified = 'manual';
-
-        $grade_history->insert();
-
-        $last_grade_history = end($this->grade_history);
-
-        $this->assertEqual($grade_history->id, $last_grade_history->id + 1);
-        $this->assertFalse(empty($grade_history->timecreated));
-        $this->assertFalse(empty($grade_history->timemodified));
-    }
-
-    function test_grade_history_update() {
-        $grade_history = new grade_history($this->grade_history[0]);
-        $this->assertTrue(method_exists($grade_history, 'update'));
-        $grade_history->note = 'Modified manually in testgradehistory.php';
-        $this->assertTrue($grade_history->update());
-        $note = get_field('grade_history', 'note', 'id', $this->grade_history[0]->id);
-        $this->assertEqual($grade_history->note, $note);
-    }
-
-    function test_grade_history_delete() {
-        $grade_history = new grade_history($this->grade_history[0]);
-        $this->assertTrue(method_exists($grade_history, 'delete'));
-
-        $this->assertTrue($grade_history->delete());
-        $this->assertFalse(get_record('grade_history', 'id', $grade_history->id));
-    }
-
-    function test_grade_history_fetch() {
-        $grade_history = new grade_history();
-        $this->assertTrue(method_exists($grade_history, 'fetch'));
-
-        $grade_history = grade_history::fetch(array('id'=>$this->grade_history[0]->id));
-        $this->assertEqual($this->grade_history[0]->id, $grade_history->id);
-        $this->assertEqual($this->grade_history[0]->note, $grade_history->note);
-    }
-
-    function test_grade_history_fetch_all() {
-        $grade_history = new grade_history();
-        $this->assertTrue(method_exists($grade_history, 'fetch_all'));
-
-        $histories = grade_history::fetch(array());
-        $this->assertEqual(count($this->grade_history), count($histories));
-    }
-
-}
-?>
index 8f5dc9411173510e52f1e7778f224a2d7e3095de..eae24b277dd264ad717d82c8417151c549e7ecf3 100644 (file)
@@ -37,19 +37,12 @@ if (!defined('MOODLE_INTERNAL')) {
 
 require_once($CFG->libdir.'/simpletest/fixtures/gradetest.php');
 
-/**
- * Here is a brief explanation of the test data set up in these unit tests.
- * category1 => array(category2 => array(grade_item1, grade_item2), category3 => array(grade_item3))
- * 3 users for 3 grade_items
- */
 class gradelib_test extends grade_test {
     function test_grade_is_locked() {
-        if (get_class($this) == 'gradelib_test') {
-            $grade_item = $this->grade_items[0];
-            $this->assertFalse(grade_is_locked($grade_item->courseid, $grade_item->itemtype, $grade_item->itemmodule, $grade_item->iteminstance, $grade_item->itemnumber));
-            $grade_item = $this->grade_items[6];
-            $this->assertTrue(grade_is_locked($grade_item->courseid, $grade_item->itemtype, $grade_item->itemmodule, $grade_item->iteminstance, $grade_item->itemnumber));
-        }
+        $grade_item = $this->grade_items[0];
+        $this->assertFalse(grade_is_locked($grade_item->courseid, $grade_item->itemtype, $grade_item->itemmodule, $grade_item->iteminstance, $grade_item->itemnumber));
+        $grade_item = $this->grade_items[6];
+        $this->assertTrue(grade_is_locked($grade_item->courseid, $grade_item->itemtype, $grade_item->itemmodule, $grade_item->iteminstance, $grade_item->itemnumber));
     }
 }
 
index ffe7f5f7958d638843532c37f79f34f8f4c4cfe6..352dc5468f75e2319696f3e04b6c2061d21b1fa4 100644 (file)
@@ -6,7 +6,7 @@
 // This is compared against the values stored in the database to determine
 // whether upgrades should be performed (see lib/db/*.php)
 
-   $version = 2007070601;  // YYYYMMDD = date
+   $version = 2007070602;  // YYYYMMDD = date
                            //       XY = increments within a single day
 
    $release = '1.9 dev';    // Human-friendly version name