4 * This file is used for special upgrade functions - for example groups and gradebook.
5 * These functions must use SQL and dabase related functions only- no other Moodle API,
6 * because it might depend on db structures that are not yet present during upgrade.
7 * (Do not use functions from accesslib.php, grades classes or group functions at all!)
12 * This function is used to migrade old data and settings from old gradebook into new grading system.
13 * It is executed only once for each course during upgrade to 1.9, all grade tables must be empty initially.
14 * @param int $courseid
16 function upgrade_18_gradebook($courseid) {
19 require_once($CFG->libdir
.'/gradelib.php'); // we need constants only
21 // get all grade items with mod details and categories
22 $sql = "SELECT gi.*, cm.idnumber as cmidnumber, m.name as modname
23 FROM {$CFG->prefix}grade_item gi, {$CFG->prefix}course_modules cm, {$CFG->prefix}modules m
24 WHERE gi.courseid=$courseid AND m.id=gi.modid AND cm.instance=gi.cminstance
25 ORDER BY gi.sort_order ASC";
27 if (!$olditems = get_records_sql($sql)) {
28 //nothing to do - no items present in old gradebook
32 if (!$oldcats = get_records('grade_category', 'courseid', $courseid, 'id')) {
33 //there should be at least uncategorised category - hmm, nothing to do
39 // create course category
40 $course_category = new object();
41 $course_category->courseid
= $courseid;
42 $course_category->fullname
= 'course grade category';
43 $course_category->parent
= null;
44 $course_category->aggregation
= GRADE_AGGREGATE_MEAN_ALL
;
45 $course_category->timemodified
= $course_category->timecreated
= time();
46 if (!$course_category->id
= insert_record('grade_categories', $course_category)) {
49 $course_category->depth
= 1;
50 $course_category->path
= '/'.$course_category->id
;
51 if (!update_record('grade_categories', $course_category)) {
56 $course_item = new object();
57 $course_item->courseid
= $courseid;
58 $course_item->itemtype
= 'course';
59 $course_item->iteminstance
= $course_category->id
;
60 $course_item->gradetype
= GRADE_TYPE_VALUE
;
61 $course_item->sortorder
= $order++
;
62 $course_item->timemodified
= $course_item->timecreated
= $course_category->timemodified
;
63 $course_item->needsupdate
= 1;
64 if (!insert_record('grade_items', $course_item)) {
68 // existing categories
69 $categories = array();
70 $hiddenoldcats = array();
71 if (count($oldcats) == 1) {
72 $oldcat = reset($oldcats);
73 if ($oldcat->drop_x_lowest
) {
74 $course_category->droplow
= $oldcat->drop_x_lowest
;
75 update_record('grade_categories', $course_category);
77 $categories[$oldcat->id
] = $course_category;
80 foreach ($oldcats as $oldcat) {
81 $category = new object();
82 $category->courseid
= $courseid;
83 $category->fullname
= addslashes($oldcat->name
);
84 $category->parent
= $course_category->id
;
85 $category->droplow
= $oldcat->drop_x_lowest
;
86 $category->aggregation
= GRADE_AGGREGATE_MEAN_ALL
;
87 $category->timemodified
= $category->timecreated
= time();
88 if (!$category->id
= insert_record('grade_categories', $category)) {
92 $category->path
= '/'.$course_category->id
.'/'.$category->id
;
93 if (!update_record('grade_categories', $category)) {
97 $categories[$oldcat->id
] = $category;
100 $item->courseid
= $courseid;
101 $item->itemtype
= 'category';
102 $item->iteminstance
= $category->id
;
103 $item->gradetype
= GRADE_TYPE_VALUE
;
104 $item->plusfactor
= $oldcat->bonus_points
;
105 $item->hidden
= $oldcat->hidden
;
106 $item->aggregationcoef
= $oldcat->weight
;
107 $item->sortorder
= $order++
;
108 $item->timemodified
= $item->timecreated
= $category->timemodified
;
109 $item->needsupdate
= 1;
110 if (!insert_record('grade_items', $item)) {
114 $hiddenoldcats[] = $oldcat->id
;
118 $course_category->aggregation
= GRADE_AGGREGATE_WEIGHTED_MEAN_ALL
;
119 update_record('grade_categories', $course_category);
125 foreach ($olditems as $olditem) {
126 if (empty($categories[$olditem->category
])) {
127 continue; // faulty record
129 // proper data are set during activity upgrade or legacy grade fetching
130 $item = new object();
131 $item->courseid
= $courseid;
132 $item->itemtype
= 'mod';
133 $item->itemmodule
= $olditem->modname
;
134 $item->iteminstance
= $olditem->cminstance
;
135 $item->itemname
= NULL;
136 $item->itemnumber
= 0;
137 $item->gradetype
= GRADE_TYPE_VALUE
;
138 $item->multfactor
= $olditem->scale_grade
;
139 $item->hidden
= (int)in_array($olditem->category
, $hiddenoldcats);
140 $item->aggregationcoef
= $olditem->extra_credit
;
141 $item->sortorder
= $order++
;
142 $item->timemodified
= $item->timecreated
= time();
143 $item->needsupdate
= 1;
144 $item->categoryid
= $categories[$olditem->category
]->id
;
145 if (!$item->id
= insert_record('grade_items', $item)) {
149 $newitems[$olditem->id
] = $item;
151 if ($olditem->extra_credit
and $categories[$olditem->category
]->aggregation
!= GRADE_AGGREGATE_EXTRACREDIT_MEAN_ALL
) {
152 $categories[$olditem->category
]->aggregation
= GRADE_AGGREGATE_EXTRACREDIT_MEAN_ALL
;
153 update_record('grade_categories', $categories[$olditem->category
]);
158 // setup up exception handling - exclude grade from aggregation
159 if ($exceptions = get_records('grade_exceptions', 'courseid', $courseid)) {
160 foreach ($exceptions as $exception) {
161 if (!array_key_exists($exception->grade_itemid
, $newitems)) {
162 continue; // broken record
164 $grade = new object();
165 $grade->excluded
= time();
166 $grade->itemid
= $newitems[$exception->grade_itemid
]->id
;
167 $grade->userid
= $exception->userid
;
168 $grade->timemodified
= $grade->timecreated
= $grade->excluded
;
169 insert_record('grade_grades', $grade);