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