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