string files should be XHTML compliant now
[moodle.git] / grade / lib.php
CommitLineData
cbff94ba 1<?php // $Id$
2
3require_once('../config.php');
4require_once($CFG->dirroot.'/course/lib.php');
5
281ffa4a 6define('UNCATEGORISED', 'uncategorised');
7
8$GRADEPREFS = array('use_advanced', // Only add new preferences to the end of this array!
9 'use_weighted_for_letter', // as the order counts and will affect backward compatibility
10 'display_weighted',
11 'display_points',
12 'display_percent',
b623ea5e 13 'display_letters',
281ffa4a 14 'reprint_headers',
15 'show_hidden',
16 );
17
18
19$GRADEPREFSDEFAULTS = array('use_advanced' => 0,
20 'use_weighted_for_letter' => 0,
21 'display_weighted' => 0,
b623ea5e 22 'display_points' => 2,
281ffa4a 23 'display_percent' => 1,
b623ea5e 24 'display_letters' => 0,
281ffa4a 25 'reprint_headers' => 0,
26 'show_hidden' => 1
27 );
cbff94ba 28
29
cbff94ba 30//******************************************************************
31// SQL FUNCTIONS
32//******************************************************************
33
34function grade_get_category_weight($course, $category) {
35 global $CFG;
36 $sql = "SELECT id, weight, drop_x_lowest, bonus_points, hidden, c.id cat_id
37 FROM {$CFG->prefix}grade_category c
38 WHERE c.courseid=$course
39 AND c.name='$category'";
40 $temp = get_record_sql($sql);
41 return $temp;
42}
43
44function grade_get_grade_items($course) {
45 global $CFG;
46 $sql = "SELECT i.id, c.name as cname, i.modid, mm.name as modname, i.cminstance, c.hidden, cm.visible, i.sort_order
47 FROM {$CFG->prefix}grade_item i,
48 {$CFG->prefix}grade_category c,
49 {$CFG->prefix}course_modules cm,
50 {$CFG->prefix}modules mm
51 WHERE c.id=i.category
52 AND i.courseid=c.courseid
53 AND c.courseid=$course
54 AND cm.course=c.courseid
55 AND cm.module=mm.id
56 AND i.modid=mm.id
57 AND cm.instance=i.cminstance";
58 $temp = get_records_sql($sql);
59 return $temp;
60}
61
62function grade_get_module_link($course, $cminstance, $modid) {
63 global $CFG;
64 $sql = "SELECT cm.id FROM {$CFG->prefix}course_modules cm, {$CFG->prefix}modules mm, {$CFG->prefix}grade_item i
65 WHERE i.modid='".$modid."'
66 AND i.modid=mm.id
67 AND cm.instance = i.cminstance
68 AND i.cminstance=".$cminstance."
69 AND i.courseid=cm.course AND cm.module=mm.id AND i.courseid=$course";
70 $temp = get_record_sql($sql);
71 return $temp;
72}
73
74function grade_get_grade_letter($course, $grade) {
75 global $CFG;
76 $sql = "SELECT id, letter FROM {$CFG->prefix}grade_letter WHERE courseid=$course AND grade_high >= $grade AND grade_low <= $grade";
77 $temp = get_record_sql($sql);
78 return $temp;
79}
80
81function grade_get_exceptions($course) {
82 global $CFG;
83 $sql = "SELECT e.id, e.userid, gi.cminstance, gi.modid, c.name as catname, mm.name as modname
84 FROM {$CFG->prefix}grade_exceptions e,
85 {$CFG->prefix}grade_item gi,
86 {$CFG->prefix}grade_category c,
87 {$CFG->prefix}course_modules cm,
88 {$CFG->prefix}modules mm
89 WHERE e.courseid=$course
90 AND gi.id = e.grade_itemid
91 AND c.id = gi.category
92 AND cm.course=c.courseid
93 AND cm.module=mm.id
94 AND gi.modid=mm.id";
95
96 $temp = get_records_sql($sql);
97 return $temp;
98}
99
100function grade_letters_set($course) {
101 global $CFG;
102 $sql = "SELECT * FROM {$CFG->prefix}grade_letter WHERE courseid=$course";
103 $letters_set = get_records_sql($sql);
104 if ($letters_set) {
105 return true;
106 }
107 else {
108 return false;
109 }
110}
111
112function grade_get_users_by_group($course, $group) {
113 global $CFG;
114 $sql = "SELECT userid FROM {$CFG->prefix}groups_members WHERE courseid=$course AND groupid = $group";
115 $members = get_records_sql($sql);
116 if ($members) {
117 foreach($members as $member) {
118 $group->$userid = true;
119 }
120 return $group;
121 }
122 else {
123 return NULL;
124 }
125}
126
127//******************************************************************
128// END SQL FUNCTIONS
129//******************************************************************
130
131function grade_get_formatted_grades() {
132 global $CFG;
133 global $course;
134 global $preferences;
135 $i = 1;
136 $grades = grade_get_grades();
137 if (isset($grades)) {
138 // iterate through all students
139 foreach($grades as $cur_category=>$grade_category) {
140 // $cur_category holds the value of the current category name
141 // $grade_category holds an array of all the mod types that are in this category
142 if (isset($grade_category)) {
143 foreach($grade_category as $cur_mod=>$mod_category) {
144 // $cur_mod is the id of the current moodle module type
145 // $mod_category holds the grades for $cur_mod (current mod type)
146 $module_info = get_record('modules', 'id', $cur_mod);
147 $cur_modname = $module_info->name;
148 if (isset($mod_category)) {
149 foreach($mod_category as $cur_cminstance=>$students_grade) {
150 // $cur_cminstance is the course module instance for the cur_mod
151 $instance = get_record($cur_modname, 'id',$cur_cminstance, 'course',$course->id);
152 // it's necessary to check if the name is blank because some mods don't clean up the grades when the instance is deleted
153 // this is a bug. as it is plausible that some item could get created and have old data from a previous mod laying around
154 if ($instance->name != '') {
155 // duplicate grade item name, the user should know better than to name to things by the same name, but to make sure grades don't disappear lets modify the name slightly
156 if (isset($all_categories["$cur_category"]["$instance->name"])) {
157 $instance->name= $instance->name.' *'.$i.'*';
158 }
159
160 if (isset($students_grade->grades) && $students_grade->grades != '') {
161 foreach($students_grade->grades as $student=>$grade) {
162 // add an entry for any student that has a grade
163 $grades_by_student["$student"]["$cur_category"]["$instance->name"]['grade'] = $grade;
164 $grades_by_student["$student"]["$cur_category"]["$instance->name"]['sort_order'] = $students_grade->sort_order;
165
166 if (!isset($grades_by_student["$student"]["$cur_category"]['stats'])) {
167 $grades_by_student["$student"]["$cur_category"]['stats'] = array();
168 }
169
170 if (!isset($grades_by_student["$student"]["$cur_category"]['stats']['points'])) {
171 $grades_by_student["$student"]["$cur_category"]['stats']['points'] = $grade;
172 }
173 else {
174 $grades_by_student["$student"]["$cur_category"]['stats']['points'] = $grades_by_student["$student"]["$cur_category"]['stats']['points'] + $grade;
175 }
176
177 // This next block just creates a comma seperated list of all grades for the category
178 if (isset($grades_by_student["$student"]["$cur_category"]['stats']['allgrades'])) {
179 $grades_by_student["$student"]["$cur_category"]['stats']['allgrades'] .= ','.$grade;
180 }
181 else {
182 $grades_by_student["$student"]["$cur_category"]['stats']['allgrades'] = $grade;
183 }
184 }
185 }
186 // set up a list of all categories and assignments (adjusting things for extra credit where necessary)
187 $all_categories["$cur_category"]["$instance->name"]['hidden'] = $students_grade->hidden;
188 $all_categories["$cur_category"]["$instance->name"]['sort_order'] = $students_grade->sort_order;
189
190 $all_categories["$cur_category"]["$instance->name"]['extra_credit'] = $students_grade->extra_credit;
191
192 if ($all_categories["$cur_category"]["$instance->name"]['extra_credit'] != 1) {
193 $all_categories["$cur_category"]["$instance->name"]['maxgrade'] = $students_grade->maxgrade;
194 }
195 else {
196 $all_categories["$cur_category"]["$instance->name"]['maxgrade'] = 0;
197 }
198 $all_categories["$cur_category"]["$instance->name"]['scale_grade'] = $students_grade->scale_grade;
199 if ($students_grade->scale_grade != 0) {
200 $all_categories["$cur_category"]["$instance->name"]['scaled_max'] = round($all_categories["$cur_category"]["$instance->name"]['maxgrade']/$students_grade->scale_grade);
201 }
202 else {
203 // avoids divide by zero... scale_grade shouldn't be set to 0 anyway
204 $all_categories["$cur_category"]["$instance->name"]['scaled_max'] = $all_categories["$cur_category"]["$instance->name"]['maxgrade'];
205 $all_categories["$cur_category"]["$instance->name"]['scale_grade'] = 1.0;
206 }
207 if (! isset($all_categories["$cur_category"]['stats']) ) {
208 $all_categories["$cur_category"]['stats'] = array();
209 }
210 $all_categories["$cur_category"]["$instance->name"]['grade_against'] = $all_categories["$cur_category"]["$instance->name"]['scaled_max'];
211 if (!isset($all_categories["$cur_category"]['stats']['weight'])) {
212 $weight = grade_get_category_weight($course->id, $cur_category);
213 $all_categories["$cur_category"]['stats']['weight'] = $weight->weight;
214 }
215
216 $all_categories["$cur_category"]["$instance->name"]['cminstance'] = $cur_cminstance;
217 $all_categories["$cur_category"]["$instance->name"]['modid'] = $cur_mod;
218 $modname = get_record('modules','id',$cur_mod);
219 $all_categories["$cur_category"]["$instance->name"]['modname'] = $modname->name;
220
221 // get bonus points and drop the x lowest
222 $drop = get_record('grade_category', 'courseid', $course->id, 'name', $cur_category);
223 $all_categories["$cur_category"]['stats']['drop'] = $drop->drop_x_lowest;
224 $all_categories["$cur_category"]['stats']['bonus_points'] = $drop->bonus_points;
225 }
226 }
227 }
228 }
229 }
230 }
231
232 // set the students name under student_data (this has the added bonus of creating an entry for students who do not have any grades)
233 $students = get_course_students($course->id);
234 if (isset($students) && $students) {
235 foreach ($students as $userid => $student) {
236 $grades_by_student["$userid"]['student_data']['firstname'] = $student->firstname;
237 $grades_by_student["$userid"]['student_data']['lastname'] = $student->lastname;
238 $grades_by_student["$userid"]['student_data']['email'] = $student->email;
239 if (isset($student->location)) {
240 $grades_by_student["$userid"]['student_data']['location'] = $student->location;
241 }
242 $grades_by_student["$userid"]['student_data']['department'] = $student->department;
243 $grades_by_student["$userid"]['student_data']['idnumber'] = $student->idnumber;
244 }
245 }
246
247 // unset any item that has a "" for a name at this point this inludes instructors who have grades or any student formerly enrolled.
248 if (isset($grades_by_student)) {
249 foreach ($grades_by_student as $student => $assignments) {
250 if (!isset($grades_by_student["$student"]['student_data']['firstname']) && !isset($grades_by_student["$student"]['student_data']['lastname'])) {
251 unset($grades_by_student["$student"]);
252 }
253 }
254 }
255
256
257 // set the totalpoints for each category taking into account drop_x_lowest
258 // also set the number of grade items for the category to make calculating grades for students who have not taken anything easier
259 foreach($all_categories as $category => $assignments) {
260 $dropcount = 0;
261 $all_categories["$category"]['stats']['totalpoints'] = 0;
262 $all_categories["$category"]['stats']['grade_items'] = 0;
263 if (isset($assignments)) {
264 foreach($assignments as $assignment=>$grade) {
265 if ($assignment != 'stats') {
266 if ($dropcount < $all_categories["$category"]['stats']['drop']) {
267 // skip a grade in the total
268 $dropcount++;
269 }
270 else {
271 // make sure the current assignment is not extra credit and then add it to the totalpoints
272 if ($all_categories["$category"][$assignment]['extra_credit'] != 1) {
273 $all_categories["$category"]['stats']['totalpoints'] = $all_categories["$category"]['stats']['totalpoints'] + $assignments["$assignment"]['grade_against'];
274 $all_categories["$category"]['stats']['grade_items'] = $all_categories["$category"]['stats']['grade_items'] + 1;
275 }
276 }
277 }
278 }
279 }
280 }
281
282 if (isset($_REQUEST['group'])) {
283 $group = clean_param($_REQUEST['group'], PARAM_INT);
284 }
285 // if the user has selected a group to view by get the group members
286 if (isset($group) && $group != 0) {
287 $groupmembers = get_group_users($group);
288 }
289
290 // this next block catches any students who do not have a grade for any item in a particular category
291 foreach($all_categories as $category => $main_category) {
292 // make sure each student has an entry for each category
293 if (isset($grades_by_student)) {
294 foreach($grades_by_student as $student=>$categories) {
295 if ( (isset($groupmembers) && isset($groupmembers[$student])) || !isset($groupmembers)) {
296 $grades_by_student["$student"]["$category"]['stats']['totalpoints'] = $main_category['stats']['totalpoints'];
297 $grades_by_student["$student"]["$category"]['stats']['weight'] = $main_category['stats']['weight'];
298 $grades_by_student["$student"]["$category"]['stats']['grade_items'] = $main_category['stats']['grade_items'];
299 if (!isset($grades_by_student["$student"]["$category"]['stats']['points'])) {
300 $grades_by_student["$student"]["$category"]['stats']['points'] = '-';
301 }
302 else {
303 // points are set... see if the current category is using drop the x lowest and do so
304 if ($main_category['stats']['drop'] != 0) {
305 $grades_by_student["$student"]["$category"]['stats']['allgrades'] = grade_drop_lowest($grades_by_student["$student"]["$category"]['stats']['allgrades'], $main_category['stats']['drop'], $main_category['stats']['grade_items']);
306 if ($grades_by_student["$student"]["$category"]['stats']['points'] != '-') {
307 $cat_points = 0;
308 $count_grades = explode(',',$grades_by_student["$student"]["$category"]['stats']['allgrades']);
309 foreach($count_grades as $grade) {
310 $cat_points = $cat_points + $grade;
311 }
312 $grades_by_student["$student"]["$category"]['stats']['points'] = $cat_points;
313 }
314 }
315 }
316
317 // add any bonus points for the category
318 if ($all_categories["$category"]['stats']['bonus_points'] != 0) {
319 $grades_by_student["$student"]["$category"]['stats']['points'] = $grades_by_student["$student"]["$category"]['stats']['points'] + $all_categories["$category"]['stats']['bonus_points'];
320 }
321
322 foreach($main_category as $assignment => $items) {
323 if ($assignment != 'stats') {
324 if(!isset($grades_by_student["$student"]["$category"]["$assignment"]['maxgrade'])) {
325 $grades_by_student["$student"]["$category"]["$assignment"]['maxgrade'] = $all_categories["$category"]["$assignment"]['grade_against'];
326 }
327 if(!isset($grades_by_student["$student"]["$category"]["$assignment"]['grade'])) {
328 $grades_by_student["$student"]["$category"]["$assignment"]['grade'] = '-';
329 $grades_by_student["$student"]["$category"]["$assignment"]['sort_order'] = $all_categories["$category"]["$assignment"]['sort_order'];
330 }
331 }
332 }
333 } // end groupmember if
334 else {
335 // unset grade since they are not in the selected group.
336 unset($grades_by_student["$student"]);
337 }
338 }
339 }
340 }
341
342 // set the total coursepoints
343 $all_categories['stats']['weight'] = 0;
344 $all_categories['stats']['totalpoints'] = 0;
345 foreach($all_categories as $category => $info) {
346 if ($category != 'stats') {
347 $all_categories['stats']['weight'] = $all_categories['stats']['weight'] + $all_categories["$category"]['stats']['weight'];
348 $all_categories['stats']['totalpoints'] = $all_categories['stats']['totalpoints'] + $all_categories["$category"]['stats']['totalpoints'];
349 }
350 }
351
352 // set each individuals total points by category so we can then exclude some grades if set to use exceptions
353 if (isset($grades_by_student)) {
354 foreach($grades_by_student as $student => $categories) {
355 foreach($all_categories as $category => $assignments) {
356 if ($category != 'stats') {
357 $grades_by_student["$student"]["$category"]['stats']['totalpoints'] = $all_categories["$category"]['stats']['totalpoints'];
358 }
359 }
360 $grades_by_student["$student"]['student_data']['totalpoints'] = $all_categories['stats']['totalpoints'];
361 }
362 }
363
364 // take into account any excluded grade_items
365 $strexcluded = get_string('excluded', 'grades');
366 $exceptions = grade_get_exceptions($course->id);
367 if (isset($exceptions) && $exceptions) {
368 foreach($exceptions as $exception) {
369 if (isset($grades_by_student["$exception->userid"])) {
370 if ($grades_by_student["$exception->userid"]["$exception->catname"]) {
371 $assgn = get_record($exception->modname, 'id', $exception->cminstance, 'course', $course->id);
372 $grades_by_student["$exception->userid"]['student_data']['totalpoints'] = $grades_by_student["$exception->userid"]['student_data']['totalpoints'] - $all_categories["$exception->catname"]["$assgn->name"]['maxgrade'];
373 $grades_by_student["$exception->userid"]["$exception->catname"]['stats']['totalpoints'] = $grades_by_student["$exception->userid"]["$exception->catname"]['stats']['totalpoints'] - $all_categories["$exception->catname"]["$assgn->name"]['grade_against'];
374 $grades_by_student["$exception->userid"]["$exception->catname"]['stats']['grade_items'] = $grades_by_student["$exception->userid"]["$exception->catname"]['stats']['grade_items'] - 1;
375 if ($grades_by_student["$exception->userid"]["$exception->catname"]['stats']['grade_items'] < 0) {
376 $grades_by_student["$exception->userid"]["$exception->catname"]['stats']['grade_items'] = 0;
377 }
378 $grades_by_student["$exception->userid"]["$exception->catname"]['stats']['points'] = $grades_by_student["$exception->userid"]["$exception->catname"]['stats']['points'] - $grades_by_student["$exception->userid"]["$exception->catname"]["$assgn->name"]['grade'];
379 $grades_by_student["$exception->userid"]["$exception->catname"]["$assgn->name"]['maxgrade'] = $strexcluded;
380 $grades_by_student["$exception->userid"]["$exception->catname"]["$assgn->name"]['grade'] = $strexcluded;
381 // see if they are excluded entirely from a category
382 if ($grades_by_student["$exception->userid"]["$exception->catname"]['stats']['totalpoints'] == 0) {
383 $grades_by_student["$exception->userid"]["$exception->catname"]['stats']['totalpoints'] = $strexcluded;
384 $grades_by_student["$exception->userid"]["$exception->catname"]['stats']['percent'] = $strexcluded;
385 $grades_by_student["$exception->userid"]["$exception->catname"]['stats']['points'] = $strexcluded;
386 $grades_by_student["$exception->userid"]["$exception->catname"]['stats']['weight'] = $strexcluded;
387 $grades_by_student["$exception->userid"]["$exception->catname"]['stats']['weighted'] = $strexcluded;
388 }
389 }
390 }
391 else {
392 // the user had exceptions, but was unenrolled from the course... we could delete it here, but we will leave it because the user may be re-added to the course
393 }
394 }
395 }
396
397 if (isset($grades_by_student)) {
398 foreach($grades_by_student as $student => $categories) {
399 $grades_by_student["$student"]['student_data']['points'] = '-';
400 $grades_by_student["$student"]['student_data']['totalpoints'] = 0;
401 $grades_by_student["$student"]['student_data']['weight'] = 0;
402 $grades_by_student["$student"]['student_data']['weighted'] = 0;
403 foreach($categories as $category => $assignments) {
404 if ($category != 'student_data') {
405 // set the student's total points earned
406 if ($grades_by_student["$student"]["$category"]['stats']['points'] != $strexcluded) {
407 if ($grades_by_student["$student"]["$category"]['stats']['points'] != '-') {
408 $grades_by_student["$student"]['student_data']['points'] = $grades_by_student["$student"]['student_data']['points'] + $grades_by_student["$student"]["$category"]['stats']['points'];
409 }
410 $grades_by_student["$student"]['student_data']['totalpoints'] = $grades_by_student["$student"]['student_data']['totalpoints'] + $grades_by_student["$student"]["$category"]['stats']['totalpoints'];
411 }
412
413 // set percents and weights for each assignment
414 foreach($assignments as $assignment => $info) {
415 if ($assignment != 'stats') {
416 if ($grades_by_student["$student"]["$category"]["$assignment"]['grade'] != $strexcluded) {
417 if ($grades_by_student["$student"]["$category"]["$assignment"]['maxgrade'] != 0) {
418 $grades_by_student["$student"]["$category"]["$assignment"]['percent'] = round($grades_by_student["$student"]["$category"]["$assignment"]['grade']/$grades_by_student["$student"]["$category"]["$assignment"]['maxgrade']*100,2);
419 }
420 else {
421 $grades_by_student["$student"]["$category"]["$assignment"]['percent'] = 0;
422 }
423 if ($grades_by_student["$student"]["$category"]['stats']['totalpoints'] != 0) {
424 $grades_by_student["$student"]["$category"]["$assignment"]['weight'] = round($all_categories["$category"]['stats']['weight']*($grades_by_student["$student"]["$category"]["$assignment"]['maxgrade']/$grades_by_student["$student"]["$category"]['stats']['totalpoints']),2);
425 }
426 else {
427 $grades_by_student["$student"]["$category"]["$assignment"]['weight'] = 0.00;
428 }
429 if ($grades_by_student["$student"]["$category"]["$assignment"]['weight'] != 0) {
430 $grades_by_student["$student"]["$category"]["$assignment"]['weighted'] = round($grades_by_student["$student"]["$category"]["$assignment"]['percent']*$grades_by_student["$student"]["$category"]["$assignment"]['weight']/100,2);
431 }
432 else {
433 // should only be here if this is extra credit
434 $grades_by_student["$student"]["$category"]["$assignment"]['weighted'] = 0.00;
435 }
436 }
437 else {
438 $grades_by_student["$student"]["$category"]["$assignment"]['percent'] = $strexcluded;
439 $grades_by_student["$student"]["$category"]["$assignment"]['weight'] = $strexcluded;
440 $grades_by_student["$student"]["$category"]["$assignment"]['weighted'] = $strexcluded;
441 }
442 }
443 }
444 // set the percent and weight per category
445 if ($grades_by_student["$student"]["$category"]['stats']['totalpoints'] != 0 ) {
446 $grades_by_student["$student"]["$category"]['stats']['percent'] = round($grades_by_student["$student"]["$category"]['stats']['points']/$grades_by_student["$student"]["$category"]['stats']['totalpoints']*100,2);
447 $grades_by_student["$student"]["$category"]['stats']['weighted'] = round($grades_by_student["$student"]["$category"]['stats']['points']/$grades_by_student["$student"]["$category"]['stats']['totalpoints']*$grades_by_student["$student"]["$category"]['stats']['weight'],2);
448 }
449 else {
450 if ($grades_by_student["$student"]["$category"]['stats']['totalpoints'] != $strexcluded) {
451 $grades_by_student["$student"]["$category"]['stats']['percent'] = 0.00;
452 $grades_by_student["$student"]["$category"]['stats']['weighted'] = 0.00;
453 }
454 }
455
456 // set students overall weight (this is what percent they will be graded against)
457 if ($grades_by_student["$student"]["$category"]['stats']['weight'] != $strexcluded) {
458 $grades_by_student["$student"]['student_data']['weight'] = $grades_by_student["$student"]['student_data']['weight'] + $grades_by_student["$student"]["$category"]['stats']['weight'];
459 }
460
461 // set the students total categories towards point total we have to defer the percent calculation until we know what total weight they should be graded against since they may
462 // be excluded from a whole category.
463 if ($all_categories["$category"]['stats']['totalpoints'] != 0) {
464 $grades_by_student["$student"]['student_data']['weighted'] = $grades_by_student["$student"]['student_data']['weighted'] + $grades_by_student["$student"]["$category"]['stats']['weighted'];
465 }
466 }
467
468
469 }
470
471 // set the percent and weight overall
472 if ($grades_by_student["$student"]['student_data']['totalpoints'] != 0 && $grades_by_student["$student"]['student_data']['totalpoints'] != $strexcluded) {
473 $grades_by_student["$student"]['student_data']['percent'] = round($grades_by_student["$student"]['student_data']['points']/$grades_by_student["$student"]['student_data']['totalpoints']*100,2);
474 if ($grades_by_student["$student"]['student_data']['weight'] != 0) {
475 $grades_by_student["$student"]['student_data']['weighted'] = round($grades_by_student["$student"]['student_data']['weighted']/$grades_by_student["$student"]['student_data']['weight']*100,2);
476 }
477 else {
478 $grades_by_student["$student"]['student_data']['weighted'] = 0.00;
479 }
480 }
481 else if ($grades_by_student["$student"]['student_data']['totalpoints'] == 0) {
482 $grades_by_student["$student"]['student_data']['percent'] = 0.00;
483 }
484
485 }
486 }
487
488 if (isset($grades_by_student)) {
489 $sort = optional_param('sort','default');
490
491 switch ($sort) {
492 case 'highgrade_category':
493 uasort($grades_by_student, 'grade_sort_by_highgrade_category');
494 break;
495 case 'highgrade_category_asc':
496 uasort($grades_by_student, 'grade_sort_by_highgrade_category_asc');
497 break;
498 case 'highgrade':
499 {
500 if ($preferences->use_weighted_for_letter == 1) {
501 uasort($grades_by_student, 'grade_sort_by_weighted');
502 }
503 else {
504 uasort($grades_by_student, 'grade_sort_by_percent');
505 }
506 break;
507 }
508 case 'points':
509 uasort($grades_by_student, 'grade_sort_by_points');
510 break;
511 case 'points_asc':
512 uasort($grades_by_student, 'grade_sort_by_points_asc');
513 break;
514 case 'weighted':
515 uasort($grades_by_student, 'grade_sort_by_weighted');
516 break;
517 case 'weighted_asc':
518 uasort($grades_by_student, 'grade_sort_by_weighted_asc');
519 break;
520 case 'percent':
521 uasort($grades_by_student, 'grade_sort_by_percent');
522 break;
523 case 'percent_asc':
524 uasort($grades_by_student, 'grade_sort_by_percent_asc');
525 break;
526 case 'highgrade_asc':
527 {
528 if ($preferences->use_weighted_for_letter == 1) {
529 uasort($grades_by_student, 'grade_sort_by_weighted_asc');
530 }
531 else {
532 uasort($grades_by_student, 'grade_sort_by_percent_asc');
533 }
534 break;
535 }
536 case 'firstname':
537 uasort($grades_by_student, 'grade_sort_by_firstname');
538 break;
539 default:
540 uasort($grades_by_student, 'grade_sort_by_lastname');
541 }
542 }
543 else {
544 $grades_by_student = 0;
545 }
546 //print_object($grades_by_student);
547 //print_object($all_categories);
548 $retval = array($grades_by_student, $all_categories);
549 }
550 else {
551 $retval = array(0,0);
281ffa4a 552 // echo "<center><font color=red>Could not find any graded items for this course.</font></center>";
cbff94ba 553 }
554 return $retval;
555}
556
557function grade_drop_lowest($grades, $drop, $total) {
558 // drops the lowest $drop numbers from the comma seperated $grades making sure that if $grades has
559 // fewer items than $total that we don't drop too many
560 $grade_array = explode(',',$grades);
561
562 $actually_drop = (count($grade_array) - $total);
563 if ($actually_drop > 0) {
564 rsort($grade_array);
565
566 for($i=0; $i < (count($grade_array) - $actually_drop); $i++) {
567 $ret_grades["$i"] = $grade_array["$i"];
568 }
569 if ($ret_grades) {
570 $grades = implode(',',$ret_grades);
571 }
572 else {
573 // set grades to 0... they decided to drop too many
574 $grades = 0;
575 }
576 }
577 return $grades;
578}
579
580function grade_get_grades() {
581 global $CFG;
582 global $course;
583 $mods = grade_get_grade_items($course->id);
281ffa4a 584 $preferences = grade_get_preferences($course->id);
cbff94ba 585
586 if ($mods) {
587 foreach ($mods as $mod) {
588 // hidden is a gradebook setting for an assignment and visible is a course_module setting
589 if (($mod->hidden != 1 && $mod->visible==1) or (isteacher($course->id) && $preferences->show_hidden==1)) {
590 $libfile = "$CFG->dirroot/mod/$mod->modname/lib.php";
591 if (file_exists($libfile)) {
592 require_once($libfile);
593 $gradefunction = $mod->modname."_grades";
594 if ($grades["$mod->cname"]["$mod->modid"]["$mod->cminstance"] = $gradefunction($mod->cminstance)) {
595 // added grades for particular mod
596 // now get the grade_item modifiers ie. scale_grade and extra credit
597 $scale_grade = get_record('grade_item', 'courseid', $course->id, 'cminstance', $mod->cminstance, 'modid', $mod->modid);
598
599 if (isset($scale_grade)) {
600 $grades["$mod->cname"]["$mod->modid"]["$mod->cminstance"]->scale_grade = $scale_grade->scale_grade;
601 $grades["$mod->cname"]["$mod->modid"]["$mod->cminstance"]->extra_credit = $scale_grade->extra_credit;
602 }
603 else {
604 $grades["$mod->cname"]["$mod->modid"]["$mod->cminstance"]->scale_grade = 1.00;
605 $grades["$mod->cname"]["$mod->modid"]["$mod->cminstance"]->extra_credit = 0;
606 }
607
608 if ($mod->hidden != 1 && $mod->visible==1) {
609 $grades["$mod->cname"]["$mod->modid"]["$mod->cminstance"]->hidden = 0;
610 }
611 else {
612 $grades["$mod->cname"]["$mod->modid"]["$mod->cminstance"]->hidden = 1;
613 }
614
615 $grades["$mod->cname"]["$mod->modid"]["$mod->cminstance"]->sort_order = $scale_grade->sort_order;
616
617 // I don't think this should be necessary but it appears that the forum doesn't follow the grades API properly it returns blank or NULL when it
618 // should return a value for maxgrade according to the moodle API... so if it doesn't want to give us a grade let's not use it.
619 // this happens when grading is set to a non-numeric for a forum ie. uses "seperate and connected ways of knowing"
620 if ($grades["$mod->cname"]["$mod->modid"]["$mod->cminstance"]->maxgrade == '')
621 {
622 $grades["$mod->cname"]["$mod->modid"]["$mod->cminstance"]->maxgrade = 100;
623 //unset($grades["$mod->cname"]["$mod->modid"]["$mod->cminstance"]);
624 }
625 }
626 else {
627 // delete this item from the grade_item table since it was deleted through the mod interface
628 delete_records('grade_item', 'modid', $mods->modid, 'courseid', $course->id);
629 }
630 }
631 else {
281ffa4a 632 //echo "<center><font color=red>Could not find lib file for $mod->modid</font></center>";
cbff94ba 633 }
634 }
635 }
636 }
637 else {
638 // Do something here for no grades
281ffa4a 639 //echo "<center><font color=red>No grades returned. It appears that there are no items with grades for this course.</font></center>";
cbff94ba 640 }
641 if (isset($grades)) {
642 return $grades;
643 }
644 else {
645 return NULL;
646 }
647}
648
649function grade_set_uncategorized() {
650 // this function checks to see if any mods have not been assigned a category and sets them to uncategorized.
651 global $CFG;
652 global $course;
281ffa4a 653 $uncat = UNCATEGORISED;
cbff94ba 654
655 $uncat_id = get_record('grade_category', 'courseid', $course->id, 'name', $uncat);
656
657 if (!$uncat_id) {
658 // insert the uncategorized category
659 $temp->name=$uncat;
660 $temp->courseid=$course->id;
661 $temp->drop_x_lowest = 0;
662 $temp->bonus_points = 0;
663 $temp->hidden = 0;
664 $temp->weight = 100.00;
665
666 insert_record('grade_category', $temp);
667 $uncat_id = get_record('grade_category', 'courseid', $course->id, 'name', $uncat);
668 if (!$uncat_id) {
669 error(get_string('errornocategorizedid','grades'));
670 exit(0);
671 }
672 }
673
674
675 /// Collect modules data
676 get_all_mods($course->id, $mods, $modnames, $modnamesplural, $modnamesused);
677 $itemcount = 0;
678
679 // this will let us establish the order for gradebook item display
680 $sort = 0;
681
682 /// Search through all the modules, pulling out grade data
683 $sections = get_all_sections($course->id); // Sort everything the same as the course
684 for ($i=0; $i<=$course->numsections; $i++) {
685 if (isset($sections["$i"])) { // should always be true
686 $section = $sections["$i"];
687 if ($section->sequence) {
688 $sectionmods = explode(",", $section->sequence);
689 foreach ($sectionmods as $sectionmod) {
690 if (isset($mods["$sectionmod"])) {
691 $mod = $mods["$sectionmod"];
692 $instance = get_record("$mod->modname", "id", "$mod->instance");
693 $libfile = "$CFG->dirroot/mod/$mod->modname/lib.php";
694 if (file_exists($libfile)) {
695 require_once($libfile);
696 $gradefunction = $mod->modname."_grades";
697 if (function_exists($gradefunction)) { // Skip modules without grade function
698 if ($modgrades = $gradefunction($mod->instance)) {
699 $itemcount++;
700 //modgrades contains student information with associated grade
281ffa4a 701 //echo "<b>modname: $mod->modname id: $mod->id course: $mod->course</b><br>";
cbff94ba 702 // get instance name from db.
703 $instance = get_record($mod->modname, 'id', $mod->instance);
704 // see if the item is already in the category table and if it is call category select with the id so it is selected
705 get_record('modules', 'name', $mod->modname);
706 $item = get_record('grade_item', 'courseid', $course->id, 'modid', $mod->module, 'cminstance', $mod->instance);
707 if (!$item) {
708 // set the item to uncategorized in grade_item
709 $item->courseid = $course->id;
710 $item->category = $uncat_id->id;
711 $item->modid = $mod->module;
712 $item->cminstance = $mod->instance;
713 $item->id = insert_record('grade_item', $item);
714 }
715 else if ($item->category == 0) {
716 // this catches any errors where they may have some wierd category set
717 set_field('grade_item', 'category', $uncat_id->id, 'id', $item->id);
718 }
719 set_field('grade_item', 'sort_order', $sort, 'id', $item->id);
720 $sort++;
721 }
722 }
723 }
724 }
725 }
726 }
727 }
728 }
729}
730
731// sorting functions for grades
732function grade_sort_by_lastname($x,$y)
733{
734 //$grades_by_student["$student->userid"]['student_data']['firstname'] = $student->firstname;
735 //$grades_by_student["$student->userid"]['student_data']['lastname'] = $student->lastname;
736 if (strnatcasecmp($x['student_data']['lastname'],$y['student_data']['lastname']) == 0) {
737 return strnatcasecmp($x['student_data']['firstname'],$y['student_data']['firstname']);
738 }
739 else {
740 return strnatcasecmp($x['student_data']['lastname'],$y['student_data']['lastname']);
741 }
742}
743
744function grade_sort_by_firstname($x,$y)
745{
746 //$grades_by_student["$student->userid"]['student_data']['firstname'] = $student->firstname;
747 //$grades_by_student["$student->userid"]['student_data']['lastname'] = $student->lastname;
748 if (strnatcasecmp($x['student_data']['firstname'],$y['student_data']['firstname']) == 0) {
749 return strnatcasecmp($x['student_data']['lastname'],$y['student_data']['lastname']);
750 }
751 else {
752 return strnatcasecmp($x['student_data']['firstname'],$y['student_data']['firstname']);
753 }
754}
755
756function grade_sort_by_points($x,$y) {
757 if ($x['student_data']['points'] == $y['student_data']['points']) {
758 return grade_sort_by_lastname($x,$y);
759 }
760 else {
761 if ($x['student_data']['points'] > $y['student_data']['points'])
762 return -1;
763 else
764 return 1;
765 }
766}
767
768function grade_sort_by_points_asc($x,$y) {
769 if ($x['student_data']['points'] == $y['student_data']['points']) {
770 return grade_sort_by_lastname($x,$y);
771 }
772 else {
773 if ($x['student_data']['points'] < $y['student_data']['points'])
774 return -1;
775 else
776 return 1;
777 }
778}
779
780function grade_sort_by_weighted($x,$y) {
781 if ($x['student_data']['weighted'] == $y['student_data']['weighted']) {
782 return grade_sort_by_lastname($x,$y);
783 }
784 else {
785 if ($x['student_data']['weighted'] > $y['student_data']['weighted'])
786 return -1;
787 else
788 return 1;
789 }
790}
791
792function grade_sort_by_percent($x,$y) {
793 if ($x['student_data']['percent'] == $y['student_data']['percent']) {
794 return grade_sort_by_lastname($x,$y);
795 }
796 else {
797 if ($x['student_data']['percent'] > $y['student_data']['percent'])
798 return -1;
799 else
800 return 1;
801 }
802}
803
804function grade_sort_by_percent_asc($x,$y) {
805 if ($x['student_data']['percent'] == $y['student_data']['percent']) {
806 return grade_sort_by_lastname($x,$y);
807 }
808 else {
809 if ($x['student_data']['percent'] < $y['student_data']['percent'])
810 return -1;
811 else
812 return 1;
813 }
814}
815
816function grade_sort_by_weighted_asc($x,$y) {
817 if ($x['student_data']['weighted'] == $y['student_data']['weighted']) {
818 return grade_sort_by_lastname($x,$y);
819 }
820 else {
821 if ($x['student_data']['weighted'] < $y['student_data']['weighted'])
822 return -1;
823 else
824 return 1;
825 }
826}
827
828function grade_sort_by_highgrade_category($x,$y) {
829 global $cview;
830
831 if(!$cview) {
832 $cview = optional_param('cview');
833 }
834
835 if ($x["$cview"]['stats']['points'] == $y["$cview"]['stats']['points']) {
836 return grade_sort_by_lastname($x,$y);
837 }
838 else {
839 return ($y["$cview"]['stats']['points'] - $x["$cview"]['stats']['points']);
840 }
841}
842
843function grade_sort_by_highgrade_category_asc($x,$y) {
844 global $cview;
845
846 if(!$cview)
847 $cview = optional_param('cview');
848
849 if ($x["$cview"]['stats']['points'] == $y["$cview"]['stats']['points']) {
850 return grade_sort_by_lastname($x,$y);
851 }
852 else {
853 return ($x["$cview"]['stats']['points'] - $y["$cview"]['stats']['points']);
854 }
855}
856
857
281ffa4a 858function grade_set_preference($courseid, $name, $value) {
859 global $GRADEPREFS;
cbff94ba 860
281ffa4a 861 if (false !== ($key = array_search($name, $GRADEPREFS))) {
862 if ($record = get_record('grade_preferences', 'courseid', $courseid, 'preference', $key)) {
863 $record->value = $value;
864 update_record('grade_preferences', $record);
865 } else { // Make a new one
866 $record->preference = $key;
867 $record->courseid = $courseid;
868 $record->value = $value;
869 insert_record('grade_preferences', $record);
870 }
871 }
872}
873
874function grade_get_preference($courseid, $name) {
875 global $GRADEPREFS;
876
877 if (false !== ($key = array_search($name, $GRADEPREFS))) {
878 if ($record = get_record('grade_preferences', 'courseid', $courseid, 'preference', $key)) {
879 return $record->value;
880 } else { // Make a new one
881 $record->preference = $key;
882 $record->courseid = $courseid;
883 $record->value = $value;
884 insert_record('grade_preferences', $record);
885 }
886 }
887 return NULL;
888}
889
890function grade_get_preferences($courseid) {
cbff94ba 891 global $CFG;
281ffa4a 892 global $GRADEPREFS, $GRADEPREFSDEFAULTS;
893
894 $preferences = NULL;
895
cbff94ba 896 // Get the preferences for the course.
281ffa4a 897 if ($rawprefs = get_records('grade_preferences', 'courseid', $courseid)) {
898 foreach ($rawprefs as $pref) {
899 if (isset($GRADEPREFS[$pref->preference])) { // Valid pref
900 $name = $GRADEPREFS[$pref->preference];
901 $preferences->$name = $pref->value;
902 }
903 }
cbff94ba 904 }
281ffa4a 905
906 // Check for any missing ones and create them from defaults
907 // We don't save them in the database so we save space
908 foreach ($GRADEPREFS as $number => $name) {
909 if (!isset($preferences->$name)) {
910 $preferences->$name = $GRADEPREFSDEFAULTS[$name];
911 }
cbff94ba 912 }
281ffa4a 913
b623ea5e 914 // Construct some other ones about which fields are shown
281ffa4a 915
916 $isteacher = isteacher($courseid);
917
b623ea5e 918 $preferences->show_weighted = (($preferences->display_weighted > 0 && $isteacher) ||
919 ($preferences->display_weighted > 1 && !$isteacher));
cbff94ba 920
b623ea5e 921 $preferences->show_points = (($preferences->display_points > 0 && $isteacher) ||
922 ($preferences->display_points > 1 && !$isteacher));
cbff94ba 923
b623ea5e 924 $preferences->show_percent = (($preferences->display_percent > 0 && $isteacher) ||
925 ($preferences->display_percent > 1 && !$isteacher));
281ffa4a 926
b623ea5e 927 $preferences->show_letters = (($preferences->display_letters > 0 && $isteacher) ||
928 ($preferences->display_letters > 1 && !$isteacher));
281ffa4a 929
cbff94ba 930 return $preferences;
931}
932
281ffa4a 933
934function grade_set_preferences($course, $newprefs) {
cbff94ba 935
281ffa4a 936 if (!isset($newprefs->use_advanced) or ($newprefs->use_advanced == 1)) {
937 foreach ($newprefs as $name => $value) { /// Just save them all
938 grade_set_preference($course->id, $name, $value);
cbff94ba 939 }
281ffa4a 940 return true;
941 }
cbff94ba 942
281ffa4a 943/// We don't need advanced features, and we need to unset all extra features
944/// So they don't affect grades (This approach should be revisited because it resets everything!!)
cbff94ba 945
281ffa4a 946 grade_set_preference($course->id, 'use_advanced', 0);
947 grade_set_preference($course->id, 'use_weighted_for_letter', 0);
948 grade_set_preference($course->id, 'display_weighted', 0);
b623ea5e 949 grade_set_preference($course->id, 'display_points', 2);
281ffa4a 950 grade_set_preference($course->id, 'display_percent', 0);
b623ea5e 951 grade_set_preference($course->id, 'display_letters', 0);
cbff94ba 952
281ffa4a 953/// Lose all exceptions
954 delete_records('grade_exceptions', 'courseid', $course->id);
955
956 if (!$uncat = get_record('grade_category', 'courseid', $course->id, 'name', UNCATEGORISED)) {
957 /// Make a category for uncategorised stuff
958 $uncat->name=UNCATEGORISED;
959 $uncat->courseid=$course->id;
960 if (!$uncat->id = insert_record('grade_category', $uncat)) {
961 error(get_string('errornocategorizedid','grades'));
cbff94ba 962 }
cbff94ba 963 }
281ffa4a 964
965 set_field('grade_item', 'category', $uncat->id, 'courseid', $course->id);
966 set_field('grade_item', 'scale_grade', 1.00, 'courseid', $course->id);
967 set_field('grade_item', 'extra_credit', 0, 'courseid', $course->id);
968
969 set_field('grade_category', 'weight', 100.0, 'courseid', $course->id, 'id', $uncat->id);
970 set_field('grade_category', 'bonus_points', '0', 'courseid', $course->id);
cbff94ba 971}
972
cbff94ba 973
281ffa4a 974function grade_preferences_menu($action, $course, $group=0) {
975
976 if (!isteacher($course->id)) {
977 return;
978 }
979
980 // remap some actions to simplify later code
981 switch ($action) {
982 case 'prefs':
983 case 'set_grade_preferences':
984 $curraction = 'prefs';
985 break;
986 case 'cats':
987 case 'vcats':
988 case 'insert_category':
989 case 'assign_categories':
990 case 'delete_category':
991 $curraction = 'cats';
992 break;
993 case 'set_grade_weights':
994 case 'weights':
995 $curraction = 'weights';
996 break;
997 case 'letters':
998 case 'set_letter_grades':
999 $curraction = 'letters';
1000 break;
1001 case 'view_student_grades':
1002 case 'view_student_category_grades':
1003 case 'grades':
1004 $curraction = 'grades';
1005 break;
1006 case 'excepts':
1007 $curraction = 'excepts';
1008 break;
1009
1010 default:
1011 $curraction = 'grades';
1012 }
1013
1014 $tabs = $row = array();
1015 $row[] = new tabobject('grades', 'index.php?id='.$course->id,
1016 get_string('viewgrades', 'grades'));
1017 $row[] = new tabobject('prefs', 'index.php?id='.$course->id.'&amp;action=prefs',
1018 get_string('setpreferences', 'grades'));
1019 $row[] = new tabobject('cats', 'index.php?id='.$course->id.'&amp;action=cats',
1020 get_string('setcategories', 'grades'));
1021 $row[] = new tabobject('weights', 'index.php?id='.$course->id.'&amp;action=weights',
1022 get_string('setweights', 'grades'));
1023 $row[] = new tabobject('letters', 'index.php?id='.$course->id.'&amp;action=letters',
1024 get_string('setgradeletters', 'grades'));
1025 $row[] = new tabobject('excepts', 'exceptions.php?id='.$course->id.'&amp;action=excepts',
1026 get_string('gradeexceptions', 'grades'));
1027 $tabs[] = $row;
1028
1029 print_tabs($tabs, $curraction);
cbff94ba 1030}
1031
281ffa4a 1032
a983b6ec 1033function grade_nav($course, $action='grades') {
cbff94ba 1034 global $CFG;
1035 global $USER;
1036 global $cview;
1037
cbff94ba 1038 $strgrades = get_string('grades', 'grades');
a983b6ec 1039 $gradenav = "<a href=\"$CFG->wwwroot/course/view.php?id=$course->id\">$course->shortname</a>";
1040
1041 if (isteacher($course->id)) {
cbff94ba 1042 switch ($action) {
1043 case 'prefs':
1044 case 'set_grade_preferences':
1045 $strcurpage = get_string('setpreferences','grades');
1046 break;
1047 case 'cats':
1048 case 'delete_category':
1049 case 'cats':
1050 case 'insert_category':
1051 case 'assign_categories':
1052 $strcurpage = get_string('setcategories','grades');
1053 break;
1054 case 'weights':
1055 case 'set_grade_weights':
1056 $strcurpage = get_string('setweights','grades');
1057 break;
1058 case 'set_letter_grades':
1059 case 'letters':
1060 $strcurpage = get_string('setgradeletters','grades');
1061 break;
1062 case 'excepts':
1063 $strcurpage = get_string('gradeexceptions', 'grades');
1064 break;
1065 default:
1066 unset($strcurpage);
1067 break;
1068 }
cbff94ba 1069
cbff94ba 1070 if ($action=='grades') {
a983b6ec 1071 $gradenav .= " -> $strgrades";
1072 } else {
1073 $gradenav .= " -> <a href=\"index.php?id=$course->id&amp;action=grades\">$strgrades</a>";
cbff94ba 1074 }
1075
cbff94ba 1076 // if we are on a grades sub-page provide a link back (including grade preferences and grade items
cbff94ba 1077
1078 if (isset($strcurpage)) {
a983b6ec 1079 $gradenav .= " -> $strcurpage";
1080 } else if($action =='vcats') {
cbff94ba 1081 // show sub category
1082 if (isset($cview)) {
a983b6ec 1083 $gradenav .= " -> $cview";
cbff94ba 1084 }
1085 }
a983b6ec 1086
1087 } else {
1088 $gradenav .= " -> $strgrades";
cbff94ba 1089 }
1090
a983b6ec 1091 return $gradenav;
cbff94ba 1092}
1093
1094function grade_download_excel() {
1095 global $CFG;
1096 global $course;
1097
1098 require_once("../lib/excel/Worksheet.php");
1099 require_once("../lib/excel/Workbook.php");
1100
1101 $strgrades = get_string("grades");
1102
1103 if (isteacher($course->id)) {
1104 // HTTP headers
1105 header("Content-type: application/vnd.ms-excel");
1106 $downloadfilename = clean_filename("$course->shortname $strgrades");
1107 header("Content-Disposition: attachment; filename=\"$downloadfilename.xls\"");
1108 header("Expires: 0");
1109 header("Cache-Control: must-revalidate,post-check=0,pre-check=0");
1110 header("Pragma: public");
1111
1112 /// Creating a workbook
1113 $workbook = new Workbook("-");
1114 $myxls =& $workbook->add_worksheet($strgrades);
1115 $first = 0;
1116 /// Print names of all the fields
1117 list($grades_by_student, $all_categories) = grade_get_formatted_grades();
1118 if ($grades_by_student != 0 && $all_categories != 0) {
1119 $j = 1;
1120 foreach($grades_by_student as $student => $categories) {
1121 if ($first == 0) {
1122 ksort($categories);
1123 $myxls->write_string(0,0,get_string("firstname"));
1124 $myxls->write_string(0,1,get_string("lastname"));
1125 $myxls->write_string(0,2,get_string("idnumber"));
1126 $myxls->write_string(0,3,get_string("institution"));
1127 $myxls->write_string(0,4,get_string("department"));
1128 $myxls->write_string(0,5,get_string("email"));
1129 $i = 6;
1130 foreach ($categories as $category => $assignments) {
1131 if ($category != 'student_data') {
1132 foreach ($assignments as $assignment => $info) {
1133 if ($assignment != 'stats') {
1134 $myxls->write_string(0,$i,$assignment);
1135 $i++;
1136 }
1137 }
1138 }
1139 }
1140 $first++;
1141 }
1142 }
1143 foreach($grades_by_student as $student => $categories) {
1144 $myxls->write_string($j,0,$grades_by_student["$student"]['student_data']['firstname']);
1145 $myxls->write_string($j,1,$grades_by_student["$student"]['student_data']['lastname']);
1146 $myxls->write_string($j,2,$grades_by_student["$student"]['student_data']['idnumber']);
1147 if (isset($grades_by_student["$student"]['student_data']['institution'])) {
1148 $myxls->write_string($j,3,$grades_by_student["$student"]['student_data']['institution']);
1149 }
1150 $myxls->write_string($j,4,$grades_by_student["$student"]['student_data']['department']);
1151 $myxls->write_string($j,5,$grades_by_student["$student"]['student_data']['email']);
1152 $i = 6;
1153 foreach($categories as $category => $assignments) {
1154 if ($category != 'student_data') {
1155 foreach ($assignments as $assignment => $info) {
1156 if ($assignment != 'stats') {
1157 // account for excluded and untaken items
1158 if (is_numeric($info['grade'])) {
1159 $myxls->write_number($j,$i,$info['grade']);
1160 }
1161 else {
1162 $myxls->write_string($j,$i,$info['grade']);
1163 }
1164 $i++;
1165 }
1166 }
1167 }
1168 }
1169 $j++;
1170 }
1171 }
1172 $workbook->close();
1173 exit;
1174 }
1175}
1176
1177
1178function grade_download_text() {
1179 global $CFG;
1180 global $course;
1181
1182 $strgrades = get_string("grades");
1183
1184 if (isteacher($course->id)) {
1185 // HTTP headers
1186 header("Content-type: text/plain");
1187 $downloadfilename = clean_filename("$course->shortname $strgrades");
1188 header("Content-Disposition: attachment; filename=\"$downloadfilename.txt\"");
1189 $first = 0;
1190
1191 /// Print names of all the fields
1192 list($grades_by_student, $all_categories) = grade_get_formatted_grades();
1193 if ($grades_by_student != 0 && $all_categories != 0) {
1194 foreach($grades_by_student as $student => $categories) {
1195 if ($first == 0) {
1196 $first++;
1197 ksort($categories);
281ffa4a 1198 print_string('firstname')."\t";
1199 print_string('lastname')."\t";
1200 print_string('idnumber')."\t";
1201 print_string('institution')."\t";
1202 print_string('department')."\t";
1203 print_string('email')."\t";
cbff94ba 1204 foreach ($categories as $category => $assignments) {
1205 if ($category != 'student_data') {
1206 foreach ($assignments as $assignment => $info) {
1207 if ($assignment != 'stats') {
281ffa4a 1208 echo $assignment."\t";
cbff94ba 1209 }
1210 }
1211 }
1212 }
281ffa4a 1213 echo "\n";
cbff94ba 1214 }
1215
1216 }
1217 foreach($grades_by_student as $student => $categories) {
281ffa4a 1218 echo $grades_by_student["$student"]['student_data']['firstname']."\t";
1219 echo $grades_by_student["$student"]['student_data']['lastname']."\t";
1220 echo $grades_by_student["$student"]['student_data']['idnumber']."\t";
cbff94ba 1221 if (isset($grades_by_student["$student"]['student_data']['institution'])) {
281ffa4a 1222 echo $grades_by_student["$student"]['student_data']['institution'];
cbff94ba 1223 }
281ffa4a 1224 echo "\t";
1225 echo $grades_by_student["$student"]['student_data']['department']."\t";
1226 echo $grades_by_student["$student"]['student_data']['email']."\t";
cbff94ba 1227 foreach($categories as $category => $assignments) {
1228 if ($category != 'student_data') {
1229 foreach ($assignments as $assignment => $info) {
1230 if ($assignment != 'stats') {
1231 // account for excluded and untaken items
281ffa4a 1232 echo $info['grade']."\t";
cbff94ba 1233 }
1234 }
1235 }
1236 }
281ffa4a 1237 echo "\n";
cbff94ba 1238 }
1239 }
1240 exit;
1241 }
1242}
1243
1244function grade_get_stats($category='all') {
1245 list($grades_by_student, $all_categories) = grade_get_formatted_grades();
1246
1247 if ($grades_by_student != 0 && $all_categories != 0) {
1248 switch($category) {
1249 case 'all':
1250 {
1251 //populate the sum of student points, # items and totalpoints for each category
1252 foreach($grades_by_student as $student=>$categories) {
1253 foreach($categories as $cur_category=>$assignments) {
1254 if($category != 'student_data') {
1255 if (isset($assignments['stats'])) {
1256 if (isset($stats[$cur_category]['sum'])) {
1257 $stats[$cur_category]['sum'] = $stats[$cur_category]['sum'] + $assignments['stats']['points'];
1258 }
1259 else {
1260 $stats[$cur_category]['sum'] = $assignments['stats']['points'];
1261 }
1262 $stats[$cur_category]['items'] = $assignments['stats']['grade_items'];
1263 $stats[$cur_category]['totalpoints'] = $assignments['stats']['totalpoints'];
1264 $stats[$cur_category]['weight'] = $all_categories[$cur_category]['stats']['weight'];
1265 }
1266 }
1267 }
1268 }
1269 // populate the overall sum,items and totalpoints
1270 foreach($stats as $cur_category=>$info) {
1271 if($cur_category != 'all' && $cur_category != 'student_data') {
1272 if (isset($stats['all'])) {
1273 $stats['all']['sum'] = $stats['all']['sum'] + $stats[$cur_category]['sum'];
1274 $stats['all']['items'] = $stats['all']['items'] + $stats[$cur_category]['items'];
1275 $stats['all']['totalpoints'] = $stats['all']['totalpoints'] + $stats[$cur_category]['totalpoints'];
1276 $stats['all']['weighted_sum'] = $stats['all']['weighted_sum'] + ($stats[$cur_category]['sum']/($stats[$cur_category]['totalpoints']))*$stats[$cur_category]['weight'];
1277 }
1278 else {
1279 $stats['all']['sum'] = $stats[$cur_category]['sum'];
1280 $stats['all']['items'] = $stats[$cur_category]['items'];
1281 $stats['all']['totalpoints'] = $stats[$cur_category]['totalpoints'];
1282 $stats['all']['weighted_sum'] = ($stats[$cur_category]['sum']/($stats[$cur_category]['totalpoints']))*$stats[$cur_category]['weight'];
1283 }
1284 }
1285 }
1286 $stats['all']['students'] = count($grades_by_student);
1287 $stats['all']['average'] = $stats['all']['sum'] / $stats['all']['students'];
1288 $stats['all']['average_weighted'] = $stats['all']['weighted_sum']/$stats['all']['students'];
1289
1290 // calculate the average squared deviation and populate a list of all scores while we're at it
1291 $stats['all']['avgsqddev'] = 0;
1292 $stats['all']['avgsqddev_weighted'] = 0;
1293 foreach($grades_by_student as $student=>$categories) {
1294 foreach($categories as $cur_category=>$assignments) {
1295 if ($cur_category != 'student_data') {
1296 $stats['all']['avgsqddev'] = $stats['all']['avgsqddev'] + pow(($grades_by_student[$student]['student_data']['points']-$stats['all']['average']),2);
1297 $stats['all']['avgsqddev_weighted'] = $stats['all']['avgsqddev_weighted'] + pow(($grades_by_student[$student]['student_data']['weighted']-$stats['all']['average_weighted']),2);
1298 }
1299 }
1300 if (isset($stats['all']['all_scores'])) {
1301 $stats['all']['all_scores'] .= ','.$grades_by_student[$student]['student_data']['points'];
1302 $stats['all']['all_scores_weighted'] .= ','.$grades_by_student[$student]['student_data']['weighted'];
1303 }
1304 else {
1305 $stats['all']['all_scores'] = $grades_by_student[$student]['student_data']['points'];
1306 $stats['all']['all_scores_weighted'] = $grades_by_student[$student]['student_data']['weighted'];
1307 }
1308 }
1309 $stats['all']['avgsqddev']=$stats['all']['avgsqddev']/$stats['all']['students'];
1310 $stats['all']['avgsqddev_weighted']=$stats['all']['avgsqddev_weighted']/$stats['all']['students'];
1311 $stats['all']['stddev'] = sqrt($stats['all']['avgsqddev']);
1312 $stats['all']['stddev_weighted'] = sqrt($stats['all']['avgsqddev_weighted']);
1313 $stats['all']['mode'] = grade_mode($stats['all']['all_scores']);
1314 $stats['all']['mode_weighted'] = grade_mode($stats['all']['all_scores_weighted']);
1315
1316 // make sure the mode is not set to every score
1317 if(count($stats['all']['mode']) == count($grades_by_student)) {
1318 $stats['all']['mode'] = get_string('nomode','grade');
1319 }
1320 if(count($stats['all']['mode_weighted']) == count($grades_by_student)) {
1321 $stats['all']['mode_weighted'] = get_string('nomode','grade');
1322 }
1323 break;
1324 }
1325 default:
1326 {
1327 // get the stats for category
1328 //populate the sum of student points, # items and totalpoints for each category
1329 foreach($grades_by_student as $student=>$categories) {
1330 if(isset($grades_by_student[$student][$category]['stats'])) {
1331 if (isset($stats[$category]['sum'])) {
1332 $stats[$category]['sum'] = $stats[$category]['sum'] + $grades_by_student[$student][$category]['stats']['points'];
1333 }
1334 else {
1335 $stats[$category]['sum'] = $grades_by_student[$student][$category]['stats']['points'];
1336 }
1337 $stats[$category]['items'] = $grades_by_student[$student][$category]['stats']['grade_items'];
1338 $stats[$category]['totalpoints'] = $grades_by_student[$student][$category]['stats']['totalpoints'];
1339 }
1340 }
1341 $stats[$category]['students'] = count($grades_by_student);
1342 $stats[$category]['average'] = $stats[$category]['sum']/$stats[$category]['students'];
1343
1344 // calculate the average squared deviation and populate a list of all scores too
1345 $stats[$category]['avgsqddev'] = 0;
1346 foreach($grades_by_student as $student=>$categories) {
1347 foreach($categories as $cur_category=>$assignment) {
1348 if ($cur_category != 'student_data') {
1349 if ($grades_by_student[$student][$category]['stats']['points'] == '-' || $grades_by_student[$student][$category]['stats']['points'] == get_string('grades','excluded')) {
1350 // count grade as a zero
1351 $stats[$category]['avgsqddev'] = $stats[$category]['avgsqddev'] + pow(($stats[$category]['average']),2);
1352 }
1353 else {
1354 $stats[$category]['avgsqddev'] = $stats[$category]['avgsqddev'] + pow(($grades_by_student[$student][$category]['stats']['points']-$stats[$category]['average']),2);
1355 }
1356 }
1357 }
1358
1359 if (isset($stats[$category]['all_scores'])) {
1360 $stats[$category]['all_scores'] .= ','.$grades_by_student[$student][$category]['stats']['points'];
1361 }
1362 else {
1363 $stats[$category]['all_scores'] = $grades_by_student[$student][$category]['stats']['points'];
1364 }
1365 }
1366 $stats[$category]['avgsqddev'] = $stats[$category]['avgsqddev']/$stats[$category]['students'];
1367 $stats[$category]['stddev'] = sqrt($stats[$category]['avgsqddev']);
1368 $stats[$category]['mode'] = grade_mode($stats[$category]['all_scores']);
1369 break;
1370 }
1371 } // end switch
1372 // do a little cleanup
1373 $stats[$category]['stddev'] = sprintf("%0.2f", $stats[$category]['stddev']);
1374 $stats[$category]['average'] = sprintf("%0.2f", $stats[$category]['average']);
1375 $stats[$category]['max'] = max(explode(',',$stats[$category]['all_scores']));
1376 $stats[$category]['min'] = min(explode(',',$stats[$category]['all_scores']));
1377 $stats[$category]['median'] = explode(',',$stats[$category]['all_scores']);
1378
1379 if (isset($stats[$category]['stddev_weighted'])) {
1380 $stats[$category]['stddev_weighted'] = sprintf("%0.2f", $stats[$category]['stddev_weighted']);
1381 }
1382 if (isset($stats[$category]['average_weighted'])) {
1383 $stats[$category]['average_weighted'] = sprintf("%0.2f", $stats[$category]['average_weighted']);
1384 }
1385 if (isset($stats[$category]['max_weighted'])) {
1386 $stats[$category]['max_weighted'] = max(explode(',',$stats[$category]['all_scores_weighted']));
1387 }
1388 if (isset($stats[$category]['min_weighted'])) {
1389 $stats[$category]['min_weighted'] = min(explode(',',$stats[$category]['all_scores_weighted']));
1390 }
1391
1392 if (isset($stats[$category]['all_scores_weighted'])) {
1393 $stats[$category]['median_weighted'] = explode(',',$stats[$category]['all_scores_weighted']);
1394 }
1395 else {
1396
1397 }
1398
1399
1400 sort($stats[$category]['median']);
1401
1402 if (count($stats[$category]['median'])/2 == floor(count($stats[$category]['median'])/2) ) {
1403 // even number of scores
1404 $temp = $stats[$category]['median'][count($stats[$category]['median'])/2-1] + $stats[$category]['median'][count($stats[$category]['median'])/2];
1405 $temp = $temp/2;
1406 }
1407 else {
1408 // odd number of scores
1409 $temp = $stats[$category]['median'][floor(count($stats[$category]['median'])/2)];
1410 }
1411 unset($stats[$category]['median']);
1412 $stats[$category]['median'] = $temp;
1413
1414 if (isset($stats[$category]['median_weighted'])) {
1415 if (count($stats[$category]['median_weighted'])/2 == floor(count($stats[$category]['median_weighted'])/2)) {
1416 // even number of scores
1417 $temp = $stats[$category]['median_weighted'][count($stats[$category]['median_weighted'])/2-1] + $stats[$category]['median_weighted'][count($stats[$category]['median_weighted'])/2+1];
1418 $temp = $temp/2;
1419 }
1420 else {
1421 // odd number of scores
1422 $temp = $stats[$category]['median_weighted'][floor(count($stats[$category]['median_weighted'])/2)];
1423 }
1424 unset($stats[$category]['median_weighted']);
1425 $stats[$category]['median_weighted'] = $temp;
1426 }
1427 }
1428 return $stats;
1429}
1430
1431// returns a comma seperated list of the most common values in $items, $items is expected to be a comma sperated list of numbers
1432function grade_mode($items) {
1433 $all_scores = explode(',',$items);
1434 foreach($all_scores as $value) {
1435 if (isset($frequency[$value])) {
1436 $frequency[$value]++;
1437 }
1438 else {
1439 $frequency[$value] = 1;
1440 }
1441 }
1442 $max = max($frequency);
1443 foreach($frequency as $key=>$value) {
1444 if ($value == $max) {
1445 if (isset($retval)) {
1446 $retval .= ', '.$key;
1447 }
1448 else {
1449 $retval = $key;
1450 }
1451 }
1452 }
1453 return $retval;
1454}
1455
1456
1457function grade_stats() {
1458 global $CFG;
1459 global $course;
1460 global $USER;
1461 global $preferences;
1462
1463 if (!isset($category)) {
1464 $category = clean_param($_REQUEST['category'], PARAM_CLEAN);
1465 }
1466
1467 $stats = grade_get_stats($category);
1468
1469 // output our data
1470 print_header();
281ffa4a 1471 echo '<table align="center"><tr><th colspan="3">'.$category.' '.get_string('stats','grades').'</th></tr>';
cbff94ba 1472 if ($preferences->show_weighted == 1 && $preferences->use_weighted_for_letter == 1 && $category== 'all') {
281ffa4a 1473 echo '<tr><th>&nbsp;</th><th>'.get_string('points','grades').'<th>'.get_string('weight','grades').'</th></tr>';
cbff94ba 1474 }
1475
281ffa4a 1476 echo '<tr><td align="right">'.get_string('max','grades').':</td><td align="right">'.$stats[$category]['max'].'</td>';
cbff94ba 1477 if ($preferences->show_weighted == 1 && $preferences->use_weighted_for_letter == 1 && $category== 'all') {
281ffa4a 1478 echo '<td align="right">'.$stats[$category]['max_weighted'].'</td>';
cbff94ba 1479 }
281ffa4a 1480 echo '</tr>';
cbff94ba 1481
281ffa4a 1482 echo '<tr><td align="right">'.get_string('min','grades').':</td><td align="right">'.$stats[$category]['min'].'</td>';
cbff94ba 1483 if ($preferences->show_weighted == 1 && $preferences->use_weighted_for_letter == 1 && $category== 'all') {
281ffa4a 1484 echo '<td align="right">'.$stats[$category]['min_weighted'].'</td>';
cbff94ba 1485 }
281ffa4a 1486 echo '</tr>';
cbff94ba 1487
281ffa4a 1488 echo '<tr><td align="right">'.get_string('average','grades').':</td><td align="right">'.$stats[$category]['average'].'</td>';
cbff94ba 1489 if ($preferences->show_weighted == 1 && $preferences->use_weighted_for_letter == 1 && $category== 'all') {
281ffa4a 1490 echo '<td align="right">'.$stats[$category]['average_weighted'].'</td>';
cbff94ba 1491 }
281ffa4a 1492 echo '</tr>';
cbff94ba 1493
281ffa4a 1494 echo '<tr><td align="right">'.get_string('median','grades').':</td><td align="right">'.$stats[$category]['median'].'</td>';
cbff94ba 1495 if ($preferences->show_weighted == 1 && $preferences->use_weighted_for_letter == 1 && $category== 'all') {
281ffa4a 1496 echo '<td align="right">'.$stats[$category]['median_weighted'].'</td>';
cbff94ba 1497 }
281ffa4a 1498 echo '</tr>';
cbff94ba 1499
281ffa4a 1500 echo '<tr><td align="right">'.get_string('mode','grades').':</td><td align="right">'.$stats[$category]['mode'].'</td>';
cbff94ba 1501 if ($preferences->show_weighted == 1 && $preferences->use_weighted_for_letter == 1 && $category== 'all') {
281ffa4a 1502 echo '<td align="right">'.$stats[$category]['mode_weighted'].'</td>';
cbff94ba 1503 }
281ffa4a 1504 echo '</tr>';
cbff94ba 1505
281ffa4a 1506 echo '<tr><td align="right">'.get_string('standarddeviation','grades').':</td><td align="right">'.$stats[$category]['stddev'].'</td>';
cbff94ba 1507 if ($preferences->show_weighted == 1 && $preferences->use_weighted_for_letter == 1 && $category== 'all') {
281ffa4a 1508 echo '<td align="right">'.$stats[$category]['stddev_weighted'].'</td>';
cbff94ba 1509 }
281ffa4a 1510 echo '</tr>';
1511 echo '</table>';
cbff94ba 1512 //print_footer();
1513}
1514
1515function grade_view_category_grades($view_by_student) {
1516 global $CFG;
1517 global $course;
1518 global $USER;
1519 global $preferences;
1520 global $group;
cbff94ba 1521
1522 if (!isteacher($course->id)) {
1523 $view_by_student = $USER->id;
1524 }
1525
1526 if ($preferences->use_advanced == 0) {
281ffa4a 1527 $cview = UNCATEGORISED;
cbff94ba 1528 }
1529 else {
1530 $cview=clean_param($_REQUEST['cview'], PARAM_CLEAN);
1531 }
1532
1533 if ($cview) {
1534 list($grades_by_student, $all_categories) = grade_get_formatted_grades();
1535
1536 if ($grades_by_student != 0 && $all_categories != 0) {
1537 // output a form for the user to download the grades.
1538 grade_download_form();
1539
1540 if ($view_by_student != -1) {
1541 // unset all grades except for this student
1542 foreach ($grades_by_student as $student=>$junk) {
1543 if($student != $view_by_student) {
1544 unset($grades_by_student[$student]);
1545 }
1546 }
1547 }
1548
b623ea5e 1549 $grade_columns = $preferences->show_weighted + $preferences->show_points + $preferences->show_percent;
cbff94ba 1550
1551 $first = 0;
1552 //$maxpoints = 0;
1553 $maxpercent = 0;
1554 $reprint = 0;
1555 if (isteacher($course->id)) {
1556 $student_heading_link = get_string('student','grades');
1557 //only set sorting links if more than one student displayed.
1558 if ($view_by_student == -1) {
1559 $student_heading_link .='<br /><a href="?id='.$course->id.'&amp;group='.$group.'&amp;action=vcats&amp;cview='.$cview.'&amp;sort=lastname"><font size=-2>'.get_string('sortbylastname','grades').'</font></a>';
1560 $student_heading_link .= '<br /><a href="?id='.$course->id.'&amp;group='.$group.'&amp;action=vcats&amp;cview='.$cview.'&amp;sort=firstname"><font size=-2>'.get_string('sortbyfirstname','grades').'</font></a>';
1561 }
1562 else {
1563 $student_heading_link .= '<br /><a href="?id='.$course->id.'&amp;group='.$group.'&amp;action=vcats&amp;cview='.$cview.'"><font size="-2">'.get_string('showallstudents','grades').'</font></a>';
1564 }
1565 }
281ffa4a 1566 echo '<table align="center" border="1">';
cbff94ba 1567 if (isteacher($course->id)) {
1568 $header = '<tr><th rowspan="2">'.$student_heading_link.'</th>';
1569 }
1570 else {
1571 $header = '<tr>';
1572 }
1573 $header1 = '<tr>';
1574
1575 // to keep track of what we've output
1576 $colcount = 0;
1577 $rowcount = 0;
1578 $reprint = 0;
1579
1580 // this next section is to display the items in the course order
1581 foreach($grades_by_student as $student => $categories) {
1582 if (isset($item_order)) {
1583 // we already have the sort order let's jump out
1584 break;
1585 }
1586 $item_order = array();
1587 foreach($categories as $category => $items) {
1588 if ($category == $cview) {
1589 foreach ($items as $assignment=>$points) {
1590 if ($assignment != 'stats') {
1591 $temp = $points['sort_order'];
1592 $item_order[$temp] = $assignment;
1593 }
1594 }
1595 }
1596 }
1597 }
1598 ksort($item_order);
1599
1600 foreach($grades_by_student as $student => $categories) {
1601
1602 if ($preferences->reprint_headers != 0 && $reprint >= $preferences->reprint_headers) {
281ffa4a 1603 echo $header.$header1;
cbff94ba 1604 $reprint=0;
1605 }
1606
1607 // highlight every 3 rows for readability
1608 if ($rowcount < 3) {
1609 $row = '<tr class="header">';
1610 $rowcount ++;
1611 }
1612 else {
1613 $row = '<tr>';
1614 $rowcount++;
1615 if ($rowcount >= 6) {
1616 $rowcount = 0;
1617 }
1618 }
1619 // set the links to student information based on multiview or individual... if individual go to student info... if many go to individual grades view.
1620 if (isteacher($course->id)) {
1621 if ($view_by_student != -1) {
1622 $student_link = '<a href="'.$CFG->wwwroot.'/user/view.php?id='.$student.'&amp;course='.$course->id.'">';
1623 }
1624 else {
5305e2eb 1625 $student_link = '<a href="?id='.$course->id.'&amp;group='.$group.'&amp;action=vcats&amp;user='.$student.'&amp;cview='.$cview.'">';
cbff94ba 1626 }
1627 $student_link .= $grades_by_student[$student]['student_data']['lastname'].', '.$grades_by_student[$student]['student_data']['firstname'].'</a>';
1628 $row .= '<td>'.$student_link.'</td>';
1629 }
1630
1631 foreach($categories as $category => $items) {
1632 if ($category == $cview) {
1633 // make sure that the grades come out in the same order
1634 foreach($item_order as $order=>$assignment)
1635 {
1636 if ($assignment != 'stats') {
1637 if ($first == 0) {
1638 $colcount++;
1639 $link_id = grade_get_module_link($course->id, $all_categories[$category][$assignment]['cminstance'], $all_categories[$category][$assignment]['modid']);
1640
1641 $link = $CFG->wwwroot.'/mod/'.$all_categories[$category][$assignment]['modname'].'/view.php?id='.$link_id->id;
1642 if ($all_categories[$category][$assignment]['hidden'] == 0) {
1643 $header .= '<th colspan="'.$grade_columns.'"><a href="'.$link.'">'.$assignment.'</a>';
1644 }
1645 else {
1646 $header .= '<th style="background: #FFFFFF;" colspan="'.$grade_columns.'"><a class="dimmed" href="'.$link.'">'.$assignment.'</a>';
1647 }
1648 if ($all_categories[$category][$assignment]['extra_credit'] == 1) {
1649 $header .= '<font size ="-2">('.get_string('extracredit','grades').')</font>';
1650 }
1651 $header .='</th>';
1652 if ($preferences->show_points) {
b623ea5e 1653 $header1 .= '<th>'. $all_categories[$category][$assignment]['maxgrade'];
cbff94ba 1654 if ($all_categories[$category][$assignment]['grade_against'] != $all_categories[$category][$assignment]['maxgrade']) {
b623ea5e 1655 $header1 .= '('. $all_categories[$category][$assignment]['grade_against'].')';
cbff94ba 1656 }
b623ea5e 1657 $header1 .= '</th>';
cbff94ba 1658 }
1659
1660 if($preferences->show_percent) {
1661 if ($all_categories[$category][$assignment]['grade_against'] != $all_categories[$category][$assignment]['maxgrade']) {
1662 $header1 .= '<th>'.get_string('scaledpct','grades').'</td>';
1663 }
1664 else {
1665 $header1 .= '<th>'.get_string('rawpct','grades').'</th>';
1666 }
1667 }
1668 if ($preferences->show_weighted) {
1669 if ($all_categories[$category]['stats']['totalpoints'] != 0) {
1670 $cur_weighted_max = sprintf("%0.2f", $all_categories[$category][$assignment]['grade_against']/$all_categories[$category]['stats']['totalpoints']*$all_categories[$category]['stats']['weight']);
1671 }
1672 else {
1673 $cur_weighted_max = 0;
1674 }
1675 $header1 .= '<th>'.$cur_weighted_max.get_string('pctoftotalgrade','grades').'</th>';
1676 }
1677 }
1678
1679 // display points
1680 if ($preferences->show_points) {
1681 $row .= '<td align="right">' . $items[$assignment]['grade'] . '</td>';
1682 }
1683
1684 if ($preferences->show_percent) {
1685 $row .= '<td align="right">'. $items[$assignment]['percent'].'%</td>';
1686 }
1687
1688 if ($preferences->show_weighted) {
1689 $row .= '<td align="right">'.$items[$assignment]['weighted'].'%</td>';
1690 }
1691 }
1692 }
1693 }
1694 }
1695
1696 if ($first == 0) {
1697 if (isteacher($course->id) && $view_by_student == -1) {
1698 $total_sort_link = '<a href="?id='.$course->id.'&amp;group='.$group.'&amp;action=vcats&amp;cview='.$cview.'&amp;sort=highgrade_category"><img src="'.$CFG->wwwroot.'/pix/t/down.gif" alt="'.get_string('highgradedescending','grades').'" /></a>';
1699 $total_sort_link .= '<a href="?id='.$course->id.'&amp;group='.$group.'&amp;action=vcats&amp;cview='.$cview.'&amp;sort=highgrade_category_asc"><img src="'.$CFG->wwwroot.'/pix/t/up.gif" alt="'.get_string('highgradeascending','grades').'" /></a>';
1700 }
1701 else {
1702 $total_sort_link = '';
1703 }
1704
1705 $stats_link = '<a href="javascript:void(0)"onclick="window.open(\'?id='.$course->id.'&amp;action=stats&amp;group='.$group.'&amp;category='.$cview.'\',\''.get_string('statslink','grades').'\',\'height=200,width=300,scrollbars=no\')"><font size=-2>'.get_string('statslink','grades').'</font></a>';
1706 if ($all_categories[$cview]['stats']['drop'] != 0) {
1707 $header .= '<th colspan="'.$grade_columns.'">'.get_string('total','grades').'&nbsp; (Lowest '. $all_categories[$cview]['stats']['drop']. ' Dropped)'.$total_sort_link.' '.$stats_link.'</th>';
1708 }
1709 else {
1710 $header .= '<th colspan="'.$grade_columns.'">'.get_string('total','grades').'&nbsp;'.$total_sort_link.' '.$stats_link.'</th>';
1711 }
1712
1713 if ($preferences->show_points) {
b623ea5e 1714 $header1 .= '<th>'.$all_categories[$cview]['stats']['totalpoints'];
cbff94ba 1715 if ($all_categories[$cview]['stats']['bonus_points'] != 0) {
1716 $header1 .='(+'.$all_categories[$cview]['stats']['bonus_points'].')';
1717 }
1718 $header1 .='</th>';
1719 }
1720 if ($preferences->show_percent) {
1721 $header1 .= '<th>'.get_string('percent','grades').'</th>';
1722 }
1723
1724
1725 if ($preferences->show_weighted) {
1726 $header1 .= '<th>'.$all_categories[$cview]['stats']['weight'].get_string('pctoftotalgrade','grades').'</th>';
1727 }
1728
1729 if (isteacher($course->id) ) {
1730 $header .= '<th rowspan="2">'.$student_heading_link.'</th></tr>';
1731 }
1732 else {
1733 $header .= '</tr>';
1734 }
1735
1736 //adjust colcount to reflect the actual number of columns output
1737 $colcount++; // total column
1738 $colcount = $colcount*$grade_columns + 2;
281ffa4a 1739 echo '<tr><th colspan="'.$colcount.'"><font size="+1">';
cbff94ba 1740 if ($preferences->use_advanced != 0) {
281ffa4a 1741 echo $cview.' '.get_string('grades','grades');
cbff94ba 1742 }
1743 else {
281ffa4a 1744 echo get_string('grades','grades');
cbff94ba 1745 }
1746
281ffa4a 1747 echo '</font>';
cbff94ba 1748
1749 if (isteacher($course->id)) {
1750 helpbutton('coursegradeteacher', get_string('gradehelp','grades'), 'gradebook');
1751 }
1752 else {
1753 helpbutton('coursegradestudent', get_string('gradehelp','grades'), 'gradebook');
1754 }
281ffa4a 1755 echo '</th></tr>';
1756 echo $header;
1757 echo $header1;
cbff94ba 1758 $first = 1;
1759 }
1760
1761 // total points for category
1762 if ($preferences->show_points) {
1763 $row .= '<td align="right">'.$grades_by_student[$student][$cview]['stats']['points'].'</td>';
1764 }
1765
1766 // total percent for category
1767 if ($preferences->show_percent) {
1768 $row .= '<td align="right">'.$grades_by_student[$student][$cview]['stats']['percent'].'%</td>';
1769 }
1770
1771
1772 // total weighted for category
1773 if ($preferences->show_weighted) {
1774 $row .= '<td align="right">'.$grades_by_student[$student][$cview]['stats']['weighted'].'%</td>';
1775 }
1776
1777 if (isteacher($course->id) ) {
1778 $row .= '<td>'.$student_link.'</td>';
1779 }
1780 $row .= '</tr>';
281ffa4a 1781 echo $row;
cbff94ba 1782 $reprint++;
1783 }
281ffa4a 1784 echo '</table>';
cbff94ba 1785 }
1786 else { // no grades returned
1787 error(get_string('nogradesreturned','grades'));
1788 }
1789 }
1790 else {
1791 error(get_string('nocategoryview','grades'));
1792 }
1793}
1794
1795function grade_view_all_grades($view_by_student) {
1796// displays all grades for the course
1797 global $CFG;
1798 global $course;
1799 global $preferences;
1800 global $USER;
cbff94ba 1801
1802 if (!isteacher($course->id)) {
1803 $view_by_student = $USER->id;
1804 }
1805
1806 list($grades_by_student, $all_categories) = grade_get_formatted_grades();
1807
1808 if ($grades_by_student != 0 && $all_categories != 0) {
1809 // output a form for the user to download the grades.
1810 grade_download_form();
1811
1812 if ($view_by_student != -1) {
1813 // unset all grades except for this student
1814 foreach ($grades_by_student as $student=>$junk) {
1815 if($student != $view_by_student) {
1816 unset($grades_by_student[$student]);
1817 }
1818 }
1819 }
b623ea5e 1820 $grade_columns = $preferences->show_weighted + $preferences->show_points + $preferences->show_percent;
cbff94ba 1821
1822 $first = 0;
1823 $total_course_points = 0;
1824 $maxpercent = 0;
1825 $reprint=0;
1826
281ffa4a 1827 echo '<table align="center" border="1">';
cbff94ba 1828 if (isteacher($course->id) ) {
1829 $student_heading_link = get_string('student','grades');
1830 if ($view_by_student == -1) {
b623ea5e 1831 $student_heading_link .='<a href="?id='.$course->id.'&amp;action=grades&amp;sort=lastname"><br /><font size="-2">'.get_string('sortbylastname','grades').'</font></a>';
1832 $student_heading_link .= '<a href="?id='.$course->id.'&amp;action=grades&amp;sort=firstname"><br /><font size="-2">'.get_string('sortbyfirstname','grades').'</font></a>';
cbff94ba 1833 }
1834 else {
b623ea5e 1835 $student_heading_link .= '<br /><a href="?id='.$course->id.'&amp;&amp;action=grades"><font size="-2">'.get_string('showallstudents','grades').'</font></a>';
cbff94ba 1836 }
1837 $header = '<tr><th rowspan="2">'.$student_heading_link.'</th>';
1838 }
1839 else {
1840 $header = '</tr>';
1841 }
1842 $header1 = '<tr>';
1843
1844 $rowcount = 0;
1845 $colcount = 0;
1846 foreach($grades_by_student as $student => $categories) {
1847 $totalpoints = 0;
1848 $totalgrade = 0;
1849 $total_bonus_points = 0;
1850 if ($preferences->reprint_headers != 0 && $reprint >= $preferences->reprint_headers) {
281ffa4a 1851 echo $header.$header1;
cbff94ba 1852 $reprint=0;
1853 }
1854 if ($rowcount < 3) {
1855 $row = '<tr class="header">';
1856 $rowcount ++;
1857 }
1858 else {
1859 $row = '<tr>';
1860 $rowcount++;
1861 if ($rowcount >= 6) {
1862 $rowcount = 0;
1863 }
1864 }
1865 // set the links to student information based on multiview or individual... if individual go to student info... if many go to individual grades view.
1866 if (isteacher($course->id)) {
1867 if ($view_by_student != -1) {
b623ea5e 1868 $studentviewlink = '<a href="'.$CFG->wwwroot.'/user/view.php?id='.$student.'&amp;course='.$course->id.'">'.$grades_by_student[$student]['student_data']['lastname'].', '.$grades_by_student[$student]['student_data']['firstname'].'</a>';
cbff94ba 1869 }
1870 else {
b623ea5e 1871 $studentviewlink = '<a href="?id='.$course->id.'&amp;action=view_student_grades&amp;user='.$student.'">'.$grades_by_student[$student]['student_data']['lastname'].', '.$grades_by_student[$student]['student_data']['firstname'].'</a>';
cbff94ba 1872 }
1873 $row .= '<td>'. $studentviewlink .'</td>';
1874 }
1875 ksort($categories);
1876 foreach($categories as $category => $items) {
1877 if ($category != 'student_data') {
1878 if ($first == 0) {
1879 $colcount++;
a0a83fca 1880 if ($category == UNCATEGORISED) {
1881 $categoryname = get_string(UNCATEGORISED, 'grades');
1882 } else {
1883 $categoryname = $category;
1884 }
cbff94ba 1885 // only print the category headers if something is displayed for them
1886 if ($preferences->show_weighted || $preferences->show_percent || $preferences->show_points) {
b623ea5e 1887 $stats_link = '<a href="javascript:void(0)"onclick="window.open(\'?id='.$course->id.'&amp;action=stats&amp;category='.$category.'\',\''.get_string('statslink','grades').'\',\'height=200,width=300,scrollbars=no\')"><font size=-2>'.get_string('statslink','grades').'</font></a>';
1888 $header .= '<th colspan="'.$grade_columns.'"><a href="?id='.$course->id.'&amp;action=vcats&amp;cview='.$category;
cbff94ba 1889 if ($view_by_student != -1) {
5305e2eb 1890 $header .= '&amp;user='.$view_by_student;
cbff94ba 1891 }
a0a83fca 1892 $header .='">'. $categoryname .' '.$stats_link.'</a>';
cbff94ba 1893 }
1894 if ($preferences->display_weighted != 0) {
1895 $header .= '('. $all_categories[$category]['stats']['weight'] . '%)';
1896 }
1897 $header .= '</th>';
1898 if ($preferences->show_points) {
1899 $header1 .= '<th>'.get_string('points','grades').'('.$all_categories[$category]['stats']['totalpoints'].')';
1900 if ($all_categories[$category]['stats']['bonus_points'] != 0) {
1901 $header1 .='(+'.$all_categories[$category]['stats']['bonus_points'].')';
1902 }
1903 $header1 .='</th>';
1904 }
1905 if ($preferences->show_percent) {
1906 $header1 .= '<th>'.get_string('percent','grades').'</th>';
1907 }
1908 if ($preferences->show_weighted) {
1909 $header1 .= '<th>'.get_string('weightedpctcontribution','grades').'</th>';
1910 }
1911 $maxpercent = $all_categories["$category"]['stats']['weight'] + $maxpercent;
1912 //$total_course_points = $all_categories[$category]['stats']['totalpoints']+ $total_course_points;
1913 //$total_course_points = $all_categories[$category]['stats']['totalpoints']+ $total_course_points;
1914 }
1915
1916
1917 if ($preferences->show_points) {
1918 $row .= '<td align="right">' . $items['stats']['points'] . '</td>';
1919 }
1920 if ($preferences->show_percent) {
1921 $row .= '<td align="right">'. $items['stats']['percent'].'%</td>';
1922 }
1923
1924 if ($preferences->show_weighted) {
1925 $row .= '<td align="right">'. $items['stats']['weighted'] . '%</td>';
1926 }
1927 $total_bonus_points = $all_categories[$category]['stats']['bonus_points'];
1928 }
1929 }
1930 if ($first == 0) {
b623ea5e 1931 if ($preferences->show_letters) {
cbff94ba 1932 $total_columns = $grade_columns + 1;
1933 }
1934 else {
1935 $total_columns = $grade_columns;
1936 }
1937
1938 if (isteacher($course->id) && $view_by_student == -1) {
b623ea5e 1939 $grade_sort_link = '<a href="?id='.$course->id.'&amp;action=grades&amp;sort=highgrade"><img src="'.$CFG->wwwroot.'/pix/t/down.gif" alt="'.get_string('highgradedescending','grades').'" /></a>';
1940 $grade_sort_link .= '<a href="?id='.$course->id.'&amp;action=grades&amp;sort=highgrade_asc"><img src="'.$CFG->wwwroot.'/pix/t/up.gif" alt="'.get_string('highgradeascending','grades').'" /></a>';
1941 $points_sort_link = '<a href="?id='.$course->id.'&amp;action=grades&amp;sort=points"><img src="'.$CFG->wwwroot.'/pix/t/down.gif" alt="'.get_string('pointsdescending','grades').'" /></a>';
1942 $points_sort_link .= '<a href="?id='.$course->id.'&amp;action=grades&amp;sort=points_asc"><img src="'.$CFG->wwwroot.'/pix/t/up.gif" alt="'.get_string('pointsascending','grades').'" /></a>';
1943 $weighted_sort_link = '<a href="?id='.$course->id.'&amp;action=grades&amp;sort=weighted"><img src="'.$CFG->wwwroot.'/pix/t/down.gif" alt="'.get_string('weighteddescending','grades').'" /></a>';
1944 $weighted_sort_link .= '<a href="?id='.$course->id.'&amp;action=grades&amp;sort=weighted_asc"><img src="'.$CFG->wwwroot.'/pix/t/up.gif" alt="'.get_string('weightedascending','grades').'" /></a>';
1945 $percent_sort_link = '<a href="?id='.$course->id.'&amp;action=grades&amp;sort=percent"><img src="'.$CFG->wwwroot.'/pix/t/down.gif" alt="'.get_string('percentdescending','grades').'" /></a>';
1946 $percent_sort_link .= '<a href="?id='.$course->id.'&amp;action=grades&amp;sort=percent_asc"><img src="'.$CFG->wwwroot.'/pix/t/up.gif" alt="'.get_string('percentascending','grades').'" /></a>';
1947 }
1948 $stats_link = '<a href="javascript:void(0)"onclick="window.open(\'?id='.$course->id.'&amp;action=stats&amp;category=all\',\''.get_string('statslink','grades').'\',\'height=200,width=300,scrollbars=no\')"><font size=-2>'.get_string('statslink','grades').'</font></a>';
cbff94ba 1949 $header .= '<th colspan="'.$total_columns.'">'.get_string('total','grades').'&nbsp;'.$stats_link.'</th>';
1950 if (isteacher($course->id) && $view_by_student == -1) {
1951 if ($preferences->show_points) {
1952 $header1 .= '<th>'.get_string('points','grades').'('.$all_categories['stats']['totalpoints'].')';
1953 if ($category != 'student_data' && $all_categories[$category]['stats']['bonus_points'] != 0) {
1954
1955 $header1 .='(+'.$total_bonus_points.')';
1956 }
1957 $header1 .= '<br />'.$points_sort_link.' '.'</th>';
1958 }
1959 if ($preferences->show_percent) {
1960 $header1 .= '<th>'.get_string('percentshort','grades').'<br />'.$percent_sort_link.' '.'</th>';
1961 }
1962 if ($preferences->show_weighted) {
1963 $header1 .= '<th>'.get_string('weightedpct','grades').'('.$all_categories['stats']['weight'].')'.'<br />'.$weighted_sort_link.' '.'</th>';
1964 }
b623ea5e 1965 if ($preferences->show_letters) {
cbff94ba 1966 $header1 .= '<th>'.get_string('lettergrade','grades').'<br />'.$grade_sort_link.' '.'</th>';
1967 }
1968 $header1 .= '</tr>';
1969 }
1970 else {
1971 if ($preferences->show_points) {
1972 $header1 .= '<th>'.get_string('points','grades').'('.$all_categories['stats']['totalpoints'].')';
1973 if ($category != 'student_data' && $all_categories[$category]['stats']['bonus_points'] != 0) {
1974 $header1 .='(+'.$total_bonus_points.')';
1975 }
1976 $header1 .= '</th>';
1977 }
1978 if ($preferences->show_percent) {
1979 $header1 .= '<th>'.get_string('percentshort','grades').'</th>';
1980 }
1981 if ($preferences->show_weighted) {
1982 $header1 .= '<th>'.get_string('weightedpct','grades').'('.$all_categories['stats']['weight'].')</th>';
1983 }
b623ea5e 1984 if ($preferences->show_letters) {
cbff94ba 1985 $header1 .= '<th>'.get_string('lettergrade','grades').'</th>';
1986 }
1987 $header1 .= '</tr>';
1988 }
1989 if (isteacher($course->id)) {
1990 $header .= '<th rowspan="2">'.$student_heading_link.'</th></tr>';
1991 }
1992 // adjust colcount to reflect actual number of columns output
1993 $colcount = $colcount * $grade_columns + $total_columns + 2;
1994
281ffa4a 1995 echo '<tr><th colspan="'.$colcount.'"><font size="+1">'.get_string('allgrades','grades').'</font>';
cbff94ba 1996 if (isteacher($course->id)) {
1997 helpbutton('coursegradeteacher', get_string('gradehelp','grades'), 'gradebook');
1998 }
1999 else {
2000 helpbutton('coursegradestudent', get_string('gradehelp','grades'), 'gradebook');
2001 }
281ffa4a 2002 echo '</th></tr>';
cbff94ba 2003
2004
281ffa4a 2005 echo $header;
2006 echo $header1;
cbff94ba 2007 $first = 1;
2008 }
2009 if ($preferences->show_points) {
2010 $row .= '<td align="right">'.$grades_by_student[$student]['student_data']['points'].'</td>';
2011 }
2012 if ($preferences->show_percent) {
2013 $row .= '<td align="right">'.$grades_by_student[$student]['student_data']['percent'].'%</td>';
2014 }
2015 if ($preferences->show_weighted) {
2016 $row .= '<td align=right>'.$grades_by_student[$student]['student_data']['weighted'].'%</td>';
2017 }
b623ea5e 2018 if ($preferences->show_letters) {
cbff94ba 2019 if ($preferences->use_weighted_for_letter == 1) {
2020 $grade = $grades_by_student[$student]['student_data']['weighted'];
2021 }
2022 else {
2023 $grade = $grades_by_student[$student]['student_data']['percent'];
2024 }
2025 $letter_grade = grade_get_grade_letter($course->id, $grade);
2026 if ($letter_grade) {
2027 $row .= '<td align="right">'.$letter_grade->letter.'</td>';
2028 }
2029 else {
2030 // there wasn't an appropriate entry to use in the gradebook.
2031 if (grade_letters_set($course->id)) {
2032 $row .= '<td align="right">'.get_string('nolettergrade','grades').' '.$grade.'</td>';
2033 }
2034 else {
2035 $row .= '<td align="right">'.get_string('nogradeletters','grades').'</td>';
2036 }
2037 }
2038 }
2039 if (isteacher($course->id) ) {
2040 $row .= '<td>'. $studentviewlink .'</td></tr>';
2041 }
2042 else {
2043 $row .= '</tr>';
2044 }
281ffa4a 2045 echo $row;
cbff94ba 2046 $reprint++;
2047 }
281ffa4a 2048 echo '</table>';
cbff94ba 2049 }
2050 else { // no grades returned
2051 error(get_string('nogradesreturned','grades'));
2052 }
2053}
2054
cbff94ba 2055
2056function grade_set_grade_weights() {
2057// set the grade weights as submitted from the form generated by display_grade_weights
2058 global $CFG;
2059 global $course;
2060 global $USER;
2061
2062 if (!empty($USER->id)) {
2063 if (!confirm_sesskey()) {
2064 error(get_string('confirmsesskeybad', 'error'));
2065 }
2066 }
2067
2068 // get list of all categories
2069 $categories = get_records('grade_category', 'courseid', $course->id);
2070 if ($categories) {
2071 foreach ($categories as $category) {
2072 $form_catname = str_replace(' ', '_', $category->name);
2073
2074 $submitted_category = optional_param($form_catname);
2075 if (is_numeric($submitted_category)) {
2076 // see if there is a weight if so see if it needs to be updated
2077 $weight = grade_get_category_weight($course->id, $category->name);
2078 if ($weight) {
2079 if ($weight->weight != $submitted_category)
2080 {
2081 set_field('grade_category', 'weight', $submitted_category, 'id', $weight->id);
2082 }
2083
2084 $cur_drop = optional_param("drop_x_lowest$form_catname");
2085 $cur_bonus_points = optional_param("bonus_points$form_catname");
2086 $cur_hidden = optional_param("hidden$form_catname");
2087 if ($cur_hidden) {
2088 $cur_hidden = true;
2089 }
2090 else {
2091 $cur_hidden = false;
2092 }
2093
2094 if ($weight->drop_x_lowest != $cur_drop) {
2095 set_field('grade_category', 'drop_x_lowest', $cur_drop, 'id', $weight->cat_id);
2096 }
2097 if ($weight->bonus_points != $cur_bonus_points) {
2098 set_field('grade_category', 'bonus_points', $cur_bonus_points, 'id', $weight->cat_id);
2099 }
2100 if ($cur_hidden) {
2101 set_field('grade_category', 'hidden', 1, 'id', $weight->cat_id);
2102 }
2103 else {
2104 set_field('grade_category', 'hidden', 0, 'id', $weight->cat_id);
2105 }
2106 }
2107 else {
2108 // insert the new record... we shouldn't reach this point anymore
2109 //$new_weight->course = $course->id;
2110 //$new_weight->category = $category->id;
2111 //$new_weight->weight = $submitted_category;
2112 //insert_record('grade_weight', $new_weight);
2113 }
2114 }
2115 else {
281ffa4a 2116 echo '<center><font color="red">'.get_string('nonumericweight','grades').$category->name.': "'.$submitted_category.'"</font></center><br />';
cbff94ba 2117 }
2118 }
2119 }
2120}
2121
2122function grade_display_grade_weights() {
2123// get all categories with weights
2124// then set and display that entry.
2125 global $CFG;
2126 global $course;
2127 global $USER;
2128
2129 $categories = get_records('grade_category', 'courseid', $course->id);
2130 if ($categories) {
281ffa4a 2131 echo '<table align=center><tr><th colspan="5">'.get_string('setweights','grades');
cbff94ba 2132 helpbutton('coursegradeweight', get_string('gradeweighthelp','grades'), 'gradebook');
281ffa4a 2133 echo '</th></tr>';
2134 echo '<tr><th>'.get_string('category','grades').'</th><th>'.get_string('weight','grades').'</th><th>'.get_string('dropxlowest','grades').'</th><th>'.get_string('bonuspoints','grades').'</th><th>'.get_string('hidecategory','grades').'</th></tr>';
2135 echo '<form name="grade_weights" action="./index.php" method="post">';
2136 echo '<input type="hidden" name="id" value="'.$course->id.'" />';
2137 echo '<input type="hidden" name="action" value="set_grade_weights" />';
2138 echo '<input type="hidden" name="sesskey" value="'.$USER->sesskey.'" />';
cbff94ba 2139
2140 $sum = 0;
2141
2142 foreach($categories as $category) {
2143 $val = $category->weight;
2144 $sum = $sum + $val;
2145
2146 // make names form safe
2147 $form_catname = str_replace(' ', '_', $category->name);
281ffa4a 2148 echo '<tr><td>'.$category->name.'</td>';
2149 echo '<td align="right"><input type="text" size="5" name="'.$form_catname.'" value="'.$val.'" /></td>';
2150 echo '<td align="right"><input type="text" size="5" name="drop_x_lowest'.$form_catname.'" value="'.$category->drop_x_lowest.'" /></td>';
2151 echo '<td align="right"><input type="text" size="5" name="bonus_points'.$form_catname.'" value="'.$category->bonus_points.'" /></td>';
2152 echo '<td align="right"><input type="checkbox" name="hidden'.$form_catname.'" ';
cbff94ba 2153 if ($category->hidden == 1) {
281ffa4a 2154 echo ' checked="checked"';
cbff94ba 2155 }
281ffa4a 2156 echo ' /></td>';
cbff94ba 2157 }
281ffa4a 2158 echo '<tr><td colspan="5" align="center"><input type="submit" value="'.get_string('savechanges','grades').'" /></td></tr></form>';
cbff94ba 2159 if ($sum != 100) {
281ffa4a 2160 echo '<tr><td colspan="5" align="center"><font color="red">'.get_string('totalweightnot100','grades').'</font></td></tr>';
cbff94ba 2161 }
2162 else {
281ffa4a 2163 echo '<tr><td colspan="5" align="center"><font color="green">'.get_string('totalweight100','grades').'</font></td></tr>';
cbff94ba 2164 }
2165 }
2166 else {
2167 /// maybe this should just do the default population of the categories instead?
281ffa4a 2168 echo '<font color="red">'.get_string('setcategorieserror','grades').'</font>';
cbff94ba 2169 }
281ffa4a 2170 echo '</table>';
2171 echo '<center>'.get_string('dropxlowestwarning','grades').'</center><br />';
cbff94ba 2172}
2173
2174function grade_set_categories() {
2175 global $CFG;
2176 global $course;
2177 global $USER;
2178
2179
2180 /// Collect modules data
2181 get_all_mods($course->id, $mods, $modnames, $modnamesplural, $modnamesused);
2182
281ffa4a 2183 echo '<table align="center"><tr><th colspan="5">'.get_string('setcategories','grades');
cbff94ba 2184 helpbutton('coursegradecategory', get_string('gradecategoryhelp','grades'), 'gradebook');
281ffa4a 2185 echo '<tr><th>'.get_string('gradeitem','grades').'</th><th>'.get_string('category','grades').'</th><th>'.get_string('maxgrade','grades').'</th><th>'.get_string('curveto','grades').'</th><th>'.get_string('extracredit','grades').'</th></tr>';
2186 echo '<form name="set_categories" method="post" action="./index.php" >';
2187 echo '<input type="hidden" name="action" value="assign_categories" />';
2188 echo '<input type="hidden" name="id" value="'.$course->id.'" />';
2189 echo '<input type="hidden" name="sesskey" value="'.$USER->sesskey.'" />';
cbff94ba 2190
2191 $itemcount = 0;
2192
2193 /// Search through all the modules, pulling out grade data
2194 $sections = get_all_sections($course->id); // Sort everything the same as the course
2195 for ($i=0; $i<=$course->numsections; $i++) {
2196 if (isset($sections[$i])) { // should always be true
2197 $section = $sections[$i];
2198 if ($section->sequence) {
2199 $sectionmods = explode(",", $section->sequence);
2200 foreach ($sectionmods as $sectionmod) {
2201 $mod = $mods[$sectionmod];
2202 $instance = get_record("$mod->modname", "id", "$mod->instance");
2203 $libfile = "$CFG->dirroot/mod/$mod->modname/lib.php";
2204 if (file_exists($libfile)) {
2205 require_once($libfile);
2206 $gradefunction = $mod->modname."_grades";
2207 if (function_exists($gradefunction)) { // Skip modules without grade function
2208 if ($modgrades = $gradefunction($mod->instance)) {
2209
2210 if ($modgrades->maxgrade != '')
2211 // this block traps out broken modules that don't return a maxgrade according to the moodle API
2212 {
2213 $itemcount++;
2214 //modgrades contains student information with associated grade
281ffa4a 2215 //echo "<b>modname: $mod->modname id: $mod->id course: $mod->course</b><br />";
2216 echo '<input type="hidden" name="modname'.$itemcount.'" value="'.$mod->modname.'" />';
2217 echo '<input type="hidden" name="mod'.$itemcount.'" value="'.$mod->instance.'" />';
2218 echo '<input type="hidden" name="course'.$itemcount.'" value="'.$mod->course.'" />';
2219 echo '<tr><td>';
cbff94ba 2220 // get instance name from db.
2221 $instance = get_record($mod->modname, 'id', $mod->instance);
281ffa4a 2222 echo "$instance->name</td>";
cbff94ba 2223 // see if the item is already in the category table and if it is call category select with the id so it is selected
281ffa4a 2224 echo '<td><select name="category'.$itemcount.'">';
cbff94ba 2225 $item_cat_id = get_record('grade_item', 'modid', $mod->module, 'courseid', $course->id, 'cminstance', $mod->instance);
2226 //print_object($item_cat_id);
2227 if (isset($item_cat_id)) {
2228 grade_category_select($item_cat_id->category);
2229 }
2230 else {
2231 grade_category_select(-1);
2232 }
281ffa4a 2233 echo '</select></td><td align="right">'.$modgrades->maxgrade.'<input type="hidden" name="maxgrade'.$itemcount.'" value="'.$modgrades->maxgrade.'" /></td>';
cbff94ba 2234
2235 if (isset($item_cat_id)) {
2236 // the value held in scale_grade is a scaling percent. The next line just formats it so it is easier for the user (they just enter the point value they want to be 100%)
2237 if ($item_cat_id->scale_grade == '' || $item_cat_id->scale_grade == 0)
2238 $scale_to = $modgrades->maxgrade;
2239 else
2240 $scale_to = round($modgrades->maxgrade/$item_cat_id->scale_grade);
281ffa4a 2241 echo '<td><input type="text" size="5" name="scale_grade'.$itemcount.'" value="'.$scale_to.'" /></td>';
cbff94ba 2242 }
2243 else {
281ffa4a 2244 echo '<td><input type="text" size="5" name="scale_grade'.$itemcount.'" value="'.$modgrades->maxgrade.'" /></td>';
cbff94ba 2245 }
2246
281ffa4a 2247 echo '<td align="right"><input type="checkbox" name="extra_credit'.$itemcount.'" ';
cbff94ba 2248 if ($item_cat_id->extra_credit == 1) {
281ffa4a 2249 echo ' checked="checked"';
cbff94ba 2250 }
281ffa4a 2251 echo ' /></td></tr>';
cbff94ba 2252 }
2253 }
2254 }
2255 }
2256 }
2257 }
2258 }
2259 }
281ffa4a 2260 echo '<input type="hidden" name="totalitems" value="'.$itemcount.'" />';
2261 echo '<tr><td colspan="5" align="center"><input type="submit" value="'.get_string('savechanges','grades').'" /></td></tr>';
2262 echo '</form>';
2263 echo '<tr><td colspan="5" align="center">';
cbff94ba 2264 grade_add_category_form();
281ffa4a 2265 echo '</td></tr><tr><td colspan="5" align="center">';
cbff94ba 2266 grade_delete_category_form();
281ffa4a 2267 echo '</td></tr><tr><td colspan="5">'.get_string('extracreditwarning','grades').'</td></tr></table>';
cbff94ba 2268}
2269
2270function grade_delete_category() {
2271 global $CFG;
2272 global $course;
2273 global $USER;
2274
2275 if (!empty($USER->id)) {
2276 if (!confirm_sesskey()) {
2277 error(get_string('confirmsesskeybad', 'error'));
2278 }
2279 }
2280
2281 $cat_id = optional_param('category_id');
2282 if ($cat_id != 'blank') {
2283 // delete the record
2284 delete_records('grade_category', 'id', $cat_id, 'courseid', $course->id);
2285 // set grade_item category field=0 where it was the deleted category (set uncategorized will clean this up)
2286 set_field('grade_item', 'category', 0, 'category', $cat_id);
2287 }
2288}
2289
2290function grade_assign_categories() {
2291 global $CFG;
2292 global $course;
2293 global $USER;
2294 $num_categories = optional_param('totalitems');
2295
2296 if (!empty($USER->id)) {
2297 if (!confirm_sesskey()) {
2298 error(get_string('confirmsesskeybad', 'error'));
2299 }
2300 }
2301
2302 for ($i = 1; $i <= $num_categories; $i++) {
2303
2304 // these next sets of lines are a bit obtuse, but it lets there be a dynamic number of grade items
2305 // in the grade category form (maybe there's a better way?)
2306 $cur_cat_id = '$_REQUEST[\'category'.$i.'\'];';
2307 eval( "\$cur_cat_id = $cur_cat_id;" );
2308 $cur_modname = '$_REQUEST[\'modname'.$i.'\'];';
2309 eval( "\$cur_modname = $cur_modname;" );
2310 $cur_mod = '$_REQUEST[\'mod'.$i.'\'];';
2311 eval( "\$cur_mod = $cur_mod;" );
2312 $cur_maxgrade = '$_REQUEST[\'maxgrade'.$i.'\'];';
2313 eval( "\$cur_maxgrade = $cur_maxgrade;" );
2314 $cur_scale_grade = '$_REQUEST[\'scale_grade'.$i.'\'];';
2315 eval( "\$cur_scale_grade = $cur_scale_grade;" );
2316 $cur_extra_credit = '$_REQUEST[\'extra_credit'.$i.'\'];';
2317 $temp = 'extra_credit'.$i;
2318 $junk = get_record('modules','name',$cur_modname);
2319 $cur_modid = $junk->id;
2320 if (isset($_REQUEST[$temp])) {
2321 eval( "\$cur_extra_credit = $cur_extra_credit;" );
2322 }
2323 else {
2324 $cur_extra_credit = false;
2325 }
2326
2327 if ($cur_scale_grade == 0 || $cur_scale_grade == '') {
2328 $cur_scale_grade = 1.0;
2329 }
2330
2331 $db_cat = get_record('grade_item', 'modid', $cur_modid, 'cminstance', $cur_mod, 'courseid', $course->id);
2332 if ( $db_cat ) {
2333 if ($db_cat->category != $cur_cat_id) {
2334 // item doesn't match in the db so update it to point to the new category
2335 set_field('grade_item', 'category', $cur_cat_id, 'id', $db_cat->id);
2336 }
2337
2338 if ($db_cat->scale_grade != $cur_maxgrade/$cur_scale_grade) {
2339 // scale_grade doesn't match
2340 set_field('grade_item', 'scale_grade', ($cur_maxgrade/$cur_scale_grade), 'id', $db_cat->id);
2341 }
2342
2343 if ($cur_extra_credit) {
2344 set_field('grade_item', 'extra_credit', 1, 'id', $db_cat->id);
2345 }
2346 else {
2347 set_field('grade_item', 'extra_credit', 0, 'id', $db_cat->id);
2348 }
2349 }
2350 else {
2351 // add a new record
2352 $item->courseid = $course->id;
2353 $item->category = $cur_cat_id;
2354 $item->modid = $cur_modid;
2355 $item->cminstance = $cur_mod;
2356 $item->scale_grade = $cur_scale_grade;
2357 $item->extra_credit = $cur_extra_credit;
2358 insert_record('grade_item', $item);
2359 }
2360 }
2361}
2362
2363function grade_add_category_form() {
2364 /// outputs a form to add a category
2365 /// just a simple text box with submit
2366 global $course;
2367 global $USER;
281ffa4a 2368 echo '<form name="new_category">';
2369 echo get_string('addcategory','grades').':<input type="text" name="name" size="20" />';
2370 echo '<input type="hidden" name="id" value="'.$course->id.'" />';
2371 echo '<input type="hidden" name="action" value="insert_category" />';
2372 echo '<input type="hidden" name="sesskey" value="'.$USER->sesskey.'" />';
2373 echo '<input type="submit" value="'.get_string('addcategory','grades').'" />';
2374 echo '</form>';
cbff94ba 2375}
2376
2377function grade_delete_category_form() {
2378 // outputs a form to delete a category
2379 global $course;
2380 global $USER;
281ffa4a 2381 echo '<form name="delete_category">';
2382 echo get_string('deletecategory','grades').': <select name="category_id">';
cbff94ba 2383 grade_category_select();
281ffa4a 2384 echo '</select><input type="hidden" name="id" value="'.$course->id.'" />';
2385 echo '<input type="hidden" name="sesskey" value="'.$USER->sesskey.'" />';
2386 echo '<input type="hidden" name="action" value="delete_category" />';
2387 echo '<input type="submit" value="'.get_string('deletecategory','grades').'" /></form>';
cbff94ba 2388}
2389
2390function grade_insert_category() {
2391 global $CFG;
2392 global $course;
2393 global $USER;
2394
2395 $category->name=optional_param('name');
2396 $category->courseid=$course->id;
2397
2398 if (!empty($USER->id)) {
2399 if (!confirm_sesskey()) {
2400 error(get_string('confirmsesskeybad', 'error'));
2401 }
2402 }
2403
2404 // make sure the record isn't already there and insert if okay
2405 if (record_exists('grade_category', 'name', $category->name, 'courseid', $category->course)) {
2406 // category already exists
2407 }
2408 elseif ($category->name != ''){
2409 if (!insert_record('grade_category', $category) ) {
281ffa4a 2410 echo '<font color="red">'.get_string('addcategoryerror','grades').'</font>';
cbff94ba 2411 }
2412 }
2413}
2414
2415function grade_category_select($id_selected) {
2416 /// prints out a select box containing categories.
2417 global $CFG;
2418 global $course;
2419
2420
281ffa4a 2421 echo '<option value="blank">'.get_string('choosecategory','grades').'</option>';
cbff94ba 2422
2423 $categories = get_records('grade_category', 'courseid', $course->id, 'name');
2424
2425 if (!isset($categories)) {
2426 error(get_string("nocategories"));
2427 }
2428 else {
2429 foreach($categories as $category) {
281ffa4a 2430 if ($category->name == UNCATEGORISED) {
2431 $category->name = get_string('uncategorised', 'grades');
2432 }
cbff94ba 2433 if ($category->id == $id_selected) {
281ffa4a 2434 echo '<option value="'.$category->id.'" selected="selected">'.$category->name.'</option>';
cbff94ba 2435 }
2436 else {
281ffa4a 2437 echo '<option value="'.$category->id.'">'.$category->name.'</option>';
cbff94ba 2438 }
2439 }
2440 }
2441}
2442
b623ea5e 2443function grade_display_grade_preferences($course, $preferences) {
cbff94ba 2444 global $CFG;
cbff94ba 2445 global $USER;
2446
b623ea5e 2447 print_heading_with_help(get_string('setpreferences','grades'), 'coursegradepreferences', 'grades');
2448
2449 echo '<table align="center" class="gradeprefs">';
281ffa4a 2450 echo '<form name="set_grade_preferences" method="post" action="./index.php">';
2451 echo '<input type="hidden" name="action" value="set_grade_preferences" />';
2452 echo '<input type="hidden" name="id" value='.$course->id.' />';
b623ea5e 2453 echo '<input type="hidden" name="sesskey" value="'.sesskey().'" />';
cbff94ba 2454
b623ea5e 2455 $optionsyesno = NULL;
2456 $optionsyesno[0] = get_string('no');
2457 $optionsyesno[1] = get_string('yes');
2458
2459 echo '<tr><td class="c0">'.get_string('useadvanced','grades').'</td>';
2460 echo '<td class="c1">';
2461 choose_from_menu($optionsyesno, 'use_advanced', $preferences->use_advanced, '');
2462 echo '</td></tr>';
cbff94ba 2463
b623ea5e 2464 if ($preferences->use_advanced) {
2465 $options = NULL;
2466 $options[0] = get_string('no');
2467 $options[1] = get_string('toonly', 'moodle', $course->teachers);
2468 $options[2] = get_string('toeveryone', 'moodle');
2469
cbff94ba 2470 // display grade weights
b623ea5e 2471 echo '<tr><td class="c0">'.get_string('displayweighted','grades').':</td>';
2472 echo '<td class="c1">';
2473 choose_from_menu($options, 'display_weighted', $preferences->display_weighted, '');
2474 echo '</td></tr>';
cbff94ba 2475
2476 // display points
b623ea5e 2477 echo '<tr><td class="c0">'.get_string('displaypoints','grades').':</td>';
2478 echo '<td class="c1">';
2479 choose_from_menu($options, 'display_points', $preferences->display_points, '');
2480 echo '</td></tr>';
2481
cbff94ba 2482 // display percent
b623ea5e 2483 echo '<tr><td class="c0">'.get_string('displaypercent','grades').':</td>';
2484 echo '<td class="c1">';
2485 choose_from_menu($options, 'display_percent', $preferences->display_percent, '');
2486 echo '</td></tr>';
cbff94ba 2487
2488 // display letter grade
b623ea5e 2489 echo '<tr><td class="c0">'.get_string('displaylettergrade','grades').':</td>';
2490 echo '<td class="c1">';
2491 choose_from_menu($options, 'display_letters', $preferences->display_letters, '');
2492 echo '</td></tr>';
2493
cbff94ba 2494 // letter grade uses weighted percent
b623ea5e 2495 $options = NULL;
2496 $options[0] = get_string('usepercent','grades');
2497 $options[1] = get_string('useweighted','grades');
2498
2499 echo '<tr><td class="c0">'.get_string('lettergrade','grades').':</td>';
2500 echo '<td class="c1">';
2501 choose_from_menu($options, 'use_weighted_for_letter', $preferences->use_weighted_for_letter, '');
2502 echo '</td></tr>';
281ffa4a 2503 }
2504
2505 $headerlist[0] = get_string('none');
2506 for ($i=1; $i<=100; $i++) {
2507 $headerlist[$i] = $i;
cbff94ba 2508 }
2509
2510 // reprint headers every n lines default n=0
b623ea5e 2511 echo '<tr><td class="c0">'.get_string('reprintheaders','grades').':</td>';
2512 echo '<td class="c1">';
281ffa4a 2513 choose_from_menu($headerlist, 'reprint_headers', $preferences->reprint_headers, '');
2514 echo '</td></tr>';
cbff94ba 2515
2516 // show hidden grade items to teacher
b623ea5e 2517 echo '<tr><td class="c0">'.get_string('showhiddenitems','grades').'</td>';
2518 echo '<td class="c1">';
2519 choose_from_menu($optionsyesno, 'show_hidden', $preferences->show_hidden, '');
281ffa4a 2520 echo '</td></tr>';
cbff94ba 2521
281ffa4a 2522 echo '<tr><td colspan="3" align="center"><input type="submit" value="'.get_string('savepreferences','grades').'" /></td></tr></form></table>';
cbff94ba 2523}
2524
cbff94ba 2525
2526
2527function grade_display_letter_grades() {
2528 global $CFG;
2529 global $course;
2530 global $USER;
2531
2532 $db_letters = get_records('grade_letter', 'courseid', $course->id, 'grade_high DESC');
2533
2534 if ($db_letters) {
2535 $using_defaults = false;
2536 foreach ($db_letters as $letter) {
2537 $letters[$letter->id]->letter = $letter->letter;
2538 $letters[$letter->id]->grade_low = $letter->grade_low;
2539 $letters[$letter->id]->grade_high = $letter->grade_high;
2540 $letters[$letter->id]->courseid = $course->id;
2541 }
2542 }
2543 else {
2544 $using_defaults = true;
2545 // default A
2546 $letters[0]->letter='A';
2547 $letters[0]->grade_low=93.00;
2548 $letters[0]->grade_high=100.00;
2549 $letters[0]->courseid = $course->id;
2550 // default A-
2551 $letters[1]->letter='A-';
2552 $letters[1]->grade_low=90.00;
2553 $letters[1]->grade_high=92.99;
2554 $letters[1]->courseid = $course->id;
2555 // default B+
2556 $letters[2]->letter='B+';
2557 $letters[2]->grade_low=87.00;
2558 $letters[2]->grade_high=89.99;
2559 $letters[2]->courseid = $course->id;
2560 // default B
2561 $letters[3]->letter='B';
2562 $letters[3]->grade_low=83.00;
2563 $letters[3]->grade_high=86.99;
2564 $letters[3]->courseid = $course->id;
2565 // default B-
2566 $letters[4]->letter='B-';
2567 $letters[4]->grade_low=80.00;
2568 $letters[4]->grade_high=82.99;
2569 $letters[4]->courseid = $course->id;
2570 // default C+
2571 $letters[5]->letter='C+';
2572 $letters[5]->grade_low=77.00;
2573 $letters[5]->grade_high=79.99;
2574 $letters[5]->courseid = $course->id;
2575 // default C
2576 $letters[6]->letter='C';
2577 $letters[6]->grade_low=73.00;
2578 $letters[6]->grade_high=76.99;
2579 $letters[6]->courseid = $course->id;
2580 // default C-
2581 $letters[7]->letter='C-';
2582 $letters[7]->grade_low=70.00;
2583 $letters[7]->grade_high=72.99;
2584 $letters[7]->courseid = $course->id;
2585 // default D+
2586 $letters[8]->letter='D+';
2587 $letters[8]->grade_low=67.00;
2588 $letters[8]->grade_high=69.99;
2589 $letters[8]->courseid = $course->id;
2590 // default D
2591 $letters[9]->letter='D';
2592 $letters[9]->grade_low=60.00;
2593 $letters[9]->grade_high=66.99;
2594 $letters[9]->courseid = $course->id;
2595 // default F
2596 $letters[10]->letter='F';
2597 $letters[10]->grade_low=0.00;
2598 $letters[10]->grade_high=59.99;
2599 $letters[10]->courseid = $course->id;
2600 }
2601
281ffa4a 2602 echo '<table align="center"><tr><th colspan="3">'.get_string('setgradeletters','grades');
cbff94ba 2603 helpbutton('coursegradeletter', get_string('gradeletterhelp','grades'), 'gradebook');
281ffa4a 2604 echo '</th></tr><tr><th>'.get_string('gradeletter','grades').'</th><th>'.get_string('lowgradeletter','grades').'</th><th>'.get_string('highgradeletter','grades').'</th></tr>';
2605 echo '<form name="grade_letter"><input type="hidden" name="id" value="'.$course->id.'" />';
2606 echo '<input type="hidden" name="action" value="set_letter_grades" />';
2607 echo '<input type="hidden" name="sesskey" value="'.$USER->sesskey.'" />';
cbff94ba 2608 $i=0;
2609 foreach ($letters as $id=>$items) {
2610 if ($id !='' && !$using_defaults) {
2611 // send the record id so if the user deletes the values we can delete the row.
281ffa4a 2612 echo '<input type="hidden" name="id'.$i.'" value="'.$id.'" />';
cbff94ba 2613 }
281ffa4a 2614 echo '<tr><td><input size="8" type="text" name="letter'.$i.'" value="'.$items->letter.'" /></td>'."\n";
2615 echo '<td><input size="8" type="text" name="grade_low'.$i.'" value="'.$items->grade_low.'" /></td>'."\n";
2616 echo '<td><input size="8" type="text" name="grade_high'.$i.'" value="'.$items->grade_high.'" /></td></tr>'."\n";
cbff94ba 2617 $i++;
2618 }
281ffa4a 2619 echo '<tr><td><input size="8" type="text" name="letter'.$i.'" value="" /></td><td><input size="8" type="text" name="grade_low'.$i.'" value="" /></td><td><input type="text" size="8" name="grade_high'.$i.'" value="" /></td></tr>';
2620 echo '<tr><td colspan="3" align="center"><input type="submit" value="'.get_string('savechanges','grades').'" /></td></tr>';
2621 echo '<input type="hidden" name="totalitems" value="'.$i.'" />';
2622 echo '</form><tr><td colspan="3">'.get_string('gradeletternote','grades').'</table>';
cbff94ba 2623}
2624
2625function grade_set_letter_grades() {
2626 global $CFG;
2627 global $course;
2628 global $USER;
2629
2630 if (!empty($USER->id)) {
2631 if (!confirm_sesskey()) {
2632 error(get_string('confirmsesskeybad', 'error'));
2633 }
2634 }
2635
2636 $totalitems= clean_param($_REQUEST['totalitems'], PARAM_CLEAN);
2637
2638 for($i=0; $i<=$totalitems; $i++) {
2639 if (isset($_REQUEST["id$i"])) {
2640 // item submitted was already in database
2641 $letterid = $_REQUEST["id$i"];
2642 $updateletters[$letterid]->letter = clean_param($_REQUEST["letter$i"], PARAM_CLEAN);
2643 $updateletters[$letterid]->grade_low = clean_param($_REQUEST["grade_low$i"], PARAM_CLEAN);
2644 $updateletters[$letterid]->grade_high = clean_param($_REQUEST["grade_high$i"], PARAM_CLEAN);
2645 $updateletters[$letterid]->id = $letterid;
2646 }
2647 else {
2648 // its a new item
2649 $newletter->letter = clean_param($_REQUEST["letter$i"], PARAM_CLEAN);
2650 $newletter->grade_low = clean_param($_REQUEST["grade_low$i"], PARAM_CLEAN);
2651 $newletter->grade_high = clean_param($_REQUEST["grade_high$i"], PARAM_CLEAN);
2652 $newletter->courseid = $course->id;
2653 if (is_numeric($newletter->grade_high) && is_numeric($newletter->grade_low)) {
2654 insert_record('grade_letter', $newletter);
2655 }
2656 else {
2657 if ($i < $totalitems) {
2658 if ($newletter->grade_high != '' or $newletter->grade_low != '') {
281ffa4a 2659 echo '<center>'.get_string('lettergradenonnumber','grades').' '.$newletter->letter.' item number: '.$i.'<br /></center>';
cbff94ba 2660 }
2661 }
2662 }
2663 }
2664 }
2665
2666 if (isset($updateletters)) {
2667 foreach($updateletters as $id=>$items) {
2668 // see if any of the values are blank... if so delete them
2669 if ($items->letter == '' || $items->grade_low == '' || $items->grade_high == '') {
2670 delete_records('grade_letter', 'id', $id);
2671 }
2672 else {
2673 if (is_numeric($items->grade_high) && is_numeric($items->grade_low)) {
2674 update_record('grade_letter', $items);
2675 }
2676 else {
281ffa4a 2677 echo '<center><font color="red">'.get_string('errorgradevaluenonnumeric','grades').$letter.'</font></center>';
cbff94ba 2678 }
2679 }
2680 }
2681 }
2682}
2683
cbff94ba 2684function grade_download_form($type='both') {
2685 global $course;
2686 if ($type != 'both' || $type != 'excel' || $type != 'text') {
2687 $type = 'both';
2688 }
2689
2690 if (isteacher($course->id)) {
281ffa4a 2691 echo '<table align="center"><tr>';
cbff94ba 2692 $options['id'] = $course->id;
2693
2694 if ($type = 'both' || $type == 'excel') {
2695 $options['action'] = 'excel';
281ffa4a 2696 echo '<td align="center">';
cbff94ba 2697 print_single_button("index.php", $options, get_string("downloadexcel"));
281ffa4a 2698 echo '</td>';
cbff94ba 2699 }
2700 if ($type = 'both' || $type == 'text') {
2701 $options['action'] = 'text';
281ffa4a 2702 echo '<td align="center">';
cbff94ba 2703 print_single_button("index.php", $options, get_string("downloadtext"));
281ffa4a 2704 echo '</td>';
cbff94ba 2705 }
b623ea5e 2706 echo '<td>';
2707 setup_and_print_groups($course, $course->groupmode, 'index.php?id='.$course->id);
2708 echo '</td>';
2709
281ffa4a 2710 echo '</tr></table>';
cbff94ba 2711 }
2712}
2713
2714?>