3 require_once('../config.php');
4 require_once($CFG->dirroot
.'/course/lib.php');
6 define('UNCATEGORISED', 'uncategorised');
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
19 $GRADEPREFSDEFAULTS = array('use_advanced' => 0,
20 'use_weighted_for_letter' => 0,
21 'display_weighted' => 0,
22 'display_points' => 2,
23 'display_percent' => 1,
24 'display_letters' => 0,
25 'reprint_headers' => 0,
30 //******************************************************************
32 //******************************************************************
34 function grade_get_category_weight($course, $category) {
36 $sql = "SELECT id, weight, drop_x_lowest, bonus_points, hidden, c.id AS cat_id
37 FROM {$CFG->prefix}grade_category c
38 WHERE c.courseid=$course
39 AND c.name='$category'";
40 $temp = get_record_sql($sql);
44 function grade_get_grade_items($course) {
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
52 AND i.courseid=c.courseid
53 AND c.courseid=$course
54 AND cm.course=c.courseid
57 AND cm.instance=i.cminstance";
58 $temp = get_records_sql($sql);
62 function grade_get_module_link($course, $cminstance, $modid) {
64 $sql = "SELECT cm.id, 1 FROM {$CFG->prefix}course_modules cm, {$CFG->prefix}modules mm, {$CFG->prefix}grade_item i
65 WHERE i.modid='".$modid."'
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);
74 function grade_get_grade_letter($course, $grade) {
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);
81 function grade_get_exceptions($course) {
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
96 $temp = get_records_sql($sql);
100 function grade_letters_set($course) {
102 $sql = "SELECT * FROM {$CFG->prefix}grade_letter WHERE courseid=$course";
103 $letters_set = get_records_sql($sql);
112 function grade_get_users_by_group($course, $group) {
114 $sql = "SELECT userid FROM {$CFG->prefix}groups_members WHERE courseid=$course AND groupid = $group";
115 $members = get_records_sql($sql);
117 foreach($members as $member) {
118 $group->$userid = true;
127 //******************************************************************
129 //******************************************************************
131 function grade_get_formatted_grades() {
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.'*';
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
;
166 if (!isset($grades_by_student["$student"]["$cur_category"]['stats'])) {
167 $grades_by_student["$student"]["$cur_category"]['stats'] = array();
170 if (!isset($grades_by_student["$student"]["$cur_category"]['stats']['points'])) {
171 $grades_by_student["$student"]["$cur_category"]['stats']['points'] = $grade;
174 $grades_by_student["$student"]["$cur_category"]['stats']['points'] = $grades_by_student["$student"]["$cur_category"]['stats']['points'] +
$grade;
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;
182 $grades_by_student["$student"]["$cur_category"]['stats']['allgrades'] = $grade;
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
;
190 $all_categories["$cur_category"]["$instance->name"]['extra_credit'] = $students_grade->extra_credit
;
192 if ($all_categories["$cur_category"]["$instance->name"]['extra_credit'] != 1) {
193 $all_categories["$cur_category"]["$instance->name"]['maxgrade'] = $students_grade->maxgrade
;
196 $all_categories["$cur_category"]["$instance->name"]['maxgrade'] = 0;
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
);
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;
207 if (! isset($all_categories["$cur_category"]['stats']) ) {
208 $all_categories["$cur_category"]['stats'] = array();
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
;
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
;
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
;
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
;
242 $grades_by_student["$userid"]['student_data']['department'] = $student->department
;
243 $grades_by_student["$userid"]['student_data']['idnumber'] = $student->idnumber
;
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"]);
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) {
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
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;
282 if (isset($_REQUEST['group'])) {
283 $group = clean_param($_REQUEST['group'], PARAM_INT
);
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);
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'] = '-';
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'] != '-') {
308 $count_grades = explode(',',$grades_by_student["$student"]["$category"]['stats']['allgrades']);
309 foreach($count_grades as $grade) {
310 $cat_points = $cat_points +
$grade;
312 $grades_by_student["$student"]["$category"]['stats']['points'] = $cat_points;
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'];
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'];
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'];
333 } // end groupmember if
335 // unset grade since they are not in the selected group.
336 unset($grades_by_student["$student"]);
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'];
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'];
360 $grades_by_student["$student"]['student_data']['totalpoints'] = $all_categories['stats']['totalpoints'];
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;
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;
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
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'];
410 $grades_by_student["$student"]['student_data']['totalpoints'] = $grades_by_student["$student"]['student_data']['totalpoints'] +
$grades_by_student["$student"]["$category"]['stats']['totalpoints'];
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);
421 $grades_by_student["$student"]["$category"]["$assignment"]['percent'] = 0;
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);
427 $grades_by_student["$student"]["$category"]["$assignment"]['weight'] = 0.00;
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);
433 // should only be here if this is extra credit
434 $grades_by_student["$student"]["$category"]["$assignment"]['weighted'] = 0.00;
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;
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);
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;
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'];
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'];
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);
478 $grades_by_student["$student"]['student_data']['weighted'] = 0.00;
481 else if ($grades_by_student["$student"]['student_data']['totalpoints'] == 0) {
482 $grades_by_student["$student"]['student_data']['percent'] = 0.00;
488 if (isset($grades_by_student)) {
489 $sort = optional_param('sort','default');
492 case 'highgrade_category':
493 uasort($grades_by_student, 'grade_sort_by_highgrade_category');
495 case 'highgrade_category_asc':
496 uasort($grades_by_student, 'grade_sort_by_highgrade_category_asc');
500 if ($preferences->use_weighted_for_letter
== 1) {
501 uasort($grades_by_student, 'grade_sort_by_weighted');
504 uasort($grades_by_student, 'grade_sort_by_percent');
509 uasort($grades_by_student, 'grade_sort_by_points');
512 uasort($grades_by_student, 'grade_sort_by_points_asc');
515 uasort($grades_by_student, 'grade_sort_by_weighted');
518 uasort($grades_by_student, 'grade_sort_by_weighted_asc');
521 uasort($grades_by_student, 'grade_sort_by_percent');
524 uasort($grades_by_student, 'grade_sort_by_percent_asc');
526 case 'highgrade_asc':
528 if ($preferences->use_weighted_for_letter
== 1) {
529 uasort($grades_by_student, 'grade_sort_by_weighted_asc');
532 uasort($grades_by_student, 'grade_sort_by_percent_asc');
537 uasort($grades_by_student, 'grade_sort_by_firstname');
540 uasort($grades_by_student, 'grade_sort_by_lastname');
544 $grades_by_student = 0;
546 //print_object($grades_by_student);
547 //print_object($all_categories);
548 $retval = array($grades_by_student, $all_categories);
551 $retval = array(0,0);
552 // echo "<center><font color=red>Could not find any graded items for this course.</font></center>";
557 function 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);
562 $actually_drop = (count($grade_array) - $total);
563 if ($actually_drop > 0) {
566 for($i=0; $i < (count($grade_array) - $actually_drop); $i++
) {
567 $ret_grades["$i"] = $grade_array["$i"];
570 $grades = implode(',',$ret_grades);
573 // set grades to 0... they decided to drop too many
580 function grade_get_grades() {
583 $mods = grade_get_grade_items($course->id
);
584 $preferences = grade_get_preferences($course->id
);
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
);
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
;
604 $grades["$mod->cname"]["$mod->modid"]["$mod->cminstance"]->scale_grade
= 1.00;
605 $grades["$mod->cname"]["$mod->modid"]["$mod->cminstance"]->extra_credit
= 0;
608 if ($mod->hidden
!= 1 && $mod->visible
==1) {
609 $grades["$mod->cname"]["$mod->modid"]["$mod->cminstance"]->hidden
= 0;
612 $grades["$mod->cname"]["$mod->modid"]["$mod->cminstance"]->hidden
= 1;
615 $grades["$mod->cname"]["$mod->modid"]["$mod->cminstance"]->sort_order
= $scale_grade->sort_order
;
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
== '')
622 $grades["$mod->cname"]["$mod->modid"]["$mod->cminstance"]->maxgrade
= 100;
623 //unset($grades["$mod->cname"]["$mod->modid"]["$mod->cminstance"]);
627 // delete this item from the grade_item table since it was deleted through the mod interface
628 delete_records('grade_item', 'modid', $mods->modid
, 'courseid', $course->id
);
629 delete_records('grade_exceptions', 'grade_itemid', $mod->id
, 'courseid', $course->id
);
633 //echo "<center><font color=red>Could not find lib file for $mod->modid</font></center>";
639 // Do something here for no grades
640 //echo "<center><font color=red>No grades returned. It appears that there are no items with grades for this course.</font></center>";
642 if (isset($grades)) {
650 function grade_set_uncategorized() {
651 // this function checks to see if any mods have not been assigned a category and sets them to uncategorized.
654 $uncat = UNCATEGORISED
;
656 $uncat_id = get_record('grade_category', 'courseid', $course->id
, 'name', $uncat);
659 // insert the uncategorized category
661 $temp->courseid
=$course->id
;
662 $temp->drop_x_lowest
= 0;
663 $temp->bonus_points
= 0;
665 $temp->weight
= 100.00;
667 insert_record('grade_category', $temp);
668 $uncat_id = get_record('grade_category', 'courseid', $course->id
, 'name', $uncat);
670 error(get_string('errornocategorizedid','grades'));
676 /// Collect modules data
677 get_all_mods($course->id
, $mods, $modnames, $modnamesplural, $modnamesused);
680 // this will let us establish the order for gradebook item display
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
)) {
701 //modgrades contains student information with associated grade
702 //echo "<b>modname: $mod->modname id: $mod->id course: $mod->course</b><br>";
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
);
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);
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
);
720 set_field('grade_item', 'sort_order', $sort, 'id', $item->id
);
732 // sorting functions for grades
733 function grade_sort_by_lastname($x,$y)
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']);
741 return strnatcasecmp($x['student_data']['lastname'],$y['student_data']['lastname']);
745 function grade_sort_by_firstname($x,$y)
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']);
753 return strnatcasecmp($x['student_data']['firstname'],$y['student_data']['firstname']);
757 function grade_sort_by_points($x,$y) {
758 if ($x['student_data']['points'] == $y['student_data']['points']) {
759 return grade_sort_by_lastname($x,$y);
762 if ($x['student_data']['points'] > $y['student_data']['points'])
769 function 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);
774 if ($x['student_data']['points'] < $y['student_data']['points'])
781 function grade_sort_by_weighted($x,$y) {
782 if ($x['student_data']['weighted'] == $y['student_data']['weighted']) {
783 return grade_sort_by_lastname($x,$y);
786 if ($x['student_data']['weighted'] > $y['student_data']['weighted'])
793 function grade_sort_by_percent($x,$y) {
794 if ($x['student_data']['percent'] == $y['student_data']['percent']) {
795 return grade_sort_by_lastname($x,$y);
798 if ($x['student_data']['percent'] > $y['student_data']['percent'])
805 function 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);
810 if ($x['student_data']['percent'] < $y['student_data']['percent'])
817 function 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);
822 if ($x['student_data']['weighted'] < $y['student_data']['weighted'])
829 function grade_sort_by_highgrade_category($x,$y) {
833 $cview = optional_param('cview');
836 if ($x["$cview"]['stats']['points'] == $y["$cview"]['stats']['points']) {
837 return grade_sort_by_lastname($x,$y);
840 return ($y["$cview"]['stats']['points'] - $x["$cview"]['stats']['points']);
844 function grade_sort_by_highgrade_category_asc($x,$y) {
848 $cview = optional_param('cview');
850 if ($x["$cview"]['stats']['points'] == $y["$cview"]['stats']['points']) {
851 return grade_sort_by_lastname($x,$y);
854 return ($x["$cview"]['stats']['points'] - $y["$cview"]['stats']['points']);
859 function grade_set_preference($courseid, $name, $value) {
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);
875 function grade_get_preference($courseid, $name) {
876 global $GRADEPREFS, $GRADEPREFSDEFAULTS;
878 if (false !== ($key = array_search($name, $GRADEPREFS))) {
879 if (!($record = get_record('grade_preferences', 'courseid', $courseid, 'preference', $key))) {
881 $record->preference
= $key;
882 $record->courseid
= $courseid;
883 $record->value
= $GRADEPREFSDEFAULTS[$name];
884 insert_record('grade_preferences', $record);
886 return $record->value
;
891 function grade_get_preferences($courseid) {
893 global $GRADEPREFS, $GRADEPREFSDEFAULTS;
897 // Get the preferences for the course.
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
;
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];
915 // Construct some other ones about which fields are shown
917 $isteacher = isteacher($courseid);
919 $preferences->show_weighted
= (($preferences->display_weighted
> 0 && $isteacher) ||
920 ($preferences->display_weighted
> 1 && !$isteacher));
922 $preferences->show_points
= (($preferences->display_points
> 0 && $isteacher) ||
923 ($preferences->display_points
> 1 && !$isteacher));
925 $preferences->show_percent
= (($preferences->display_percent
> 0 && $isteacher) ||
926 ($preferences->display_percent
> 1 && !$isteacher));
928 $preferences->show_letters
= (($preferences->display_letters
> 0 && $isteacher) ||
929 ($preferences->display_letters
> 1 && !$isteacher));
935 function grade_set_preferences($course, $newprefs) {
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);
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!!)
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);
950 grade_set_preference($course->id
, 'display_points', 2);
951 grade_set_preference($course->id
, 'display_percent', 0);
952 grade_set_preference($course->id
, 'display_letters', 0);
954 /// Lose all exceptions
955 delete_records('grade_exceptions', 'courseid', $course->id
);
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'));
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
);
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
);
975 function grade_preferences_menu($action, $course, $group=0) {
977 if (!isteacher($course->id
)) {
981 // remap some actions to simplify later code
984 case 'set_grade_preferences':
985 $curraction = 'prefs';
989 case 'insert_category':
990 case 'assign_categories':
991 case 'delete_category':
992 $curraction = 'cats';
994 case 'set_grade_weights':
996 $curraction = 'weights';
999 case 'set_letter_grades':
1000 $curraction = 'letters';
1002 case 'view_student_grades':
1003 case 'view_student_category_grades':
1005 $curraction = 'grades';
1008 $curraction = 'excepts';
1012 $curraction = 'grades';
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
.'&action=prefs',
1019 get_string('setpreferences', 'grades'));
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
.'&action=cats',
1023 get_string('setcategories', 'grades'));
1024 $row[] = new tabobject('weights', 'index.php?id='.$course->id
.'&action=weights',
1025 get_string('setweights', 'grades'));
1026 $row[] = new tabobject('letters', 'index.php?id='.$course->id
.'&action=letters',
1027 get_string('setgradeletters', 'grades'));
1028 $row[] = new tabobject('excepts', 'exceptions.php?id='.$course->id
.'&action=excepts',
1029 get_string('gradeexceptions', 'grades'));
1033 print_tabs($tabs, $curraction);
1037 function grade_nav($course, $action='grades') {
1042 $strgrades = get_string('grades', 'grades');
1043 $gradenav = "<a href=\"$CFG->wwwroot/course/view.php?id=$course->id\">$course->shortname</a>";
1045 if (isteacher($course->id
)) {
1048 case 'set_grade_preferences':
1049 $strcurpage = get_string('setpreferences','grades');
1052 case 'delete_category':
1054 case 'insert_category':
1055 case 'assign_categories':
1056 $strcurpage = get_string('setcategories','grades');
1059 case 'set_grade_weights':
1060 $strcurpage = get_string('setweights','grades');
1062 case 'set_letter_grades':
1064 $strcurpage = get_string('setgradeletters','grades');
1067 $strcurpage = get_string('gradeexceptions', 'grades');
1074 if ($action=='grades') {
1075 $gradenav .= " -> $strgrades";
1077 $gradenav .= " -> <a href=\"index.php?id=$course->id&action=grades\">$strgrades</a>";
1080 // if we are on a grades sub-page provide a link back (including grade preferences and grade items
1082 if (isset($strcurpage)) {
1083 $gradenav .= " -> $strcurpage";
1084 } else if($action =='vcats') {
1085 // show sub category
1086 if (isset($cview)) {
1087 $gradenav .= " -> $cview";
1092 $gradenav .= " -> $strgrades";
1098 function grade_download($download, $id) {
1101 require_variable($id); // course id
1102 optional_variable($download, ""); // to download data
1106 if (! $course = get_record("course", "id", $id)) {
1107 error("Course ID was incorrect");
1110 if (!isteacher($course->id
)) {
1111 error("Only teachers can use this page!");
1114 $strgrades = get_string("grades");
1115 $strgrade = get_string("grade");
1116 $strmax = get_string("maximumshort");
1117 $stractivityreport = get_string("activityreport");
1119 /// Check to see if groups are being used in this course
1120 if ($groupmode = groupmode($course)) { // Groups are being used
1121 if (isset($_GET['group'])) {
1122 $changegroup = $_GET['group']; /// 0 or higher
1124 $changegroup = -1; /// This means no group change was specified
1127 $currentgroup = get_and_set_current_group($course, $groupmode, $changegroup);
1129 $currentgroup = false;
1132 if ($currentgroup) {
1133 $students = get_group_students($currentgroup, "u.lastname ASC");
1135 $students = get_course_students($course->id
, "u.lastname ASC");
1138 foreach ($students as $student) {
1139 $grades[$student->id
] = array(); // Collect all grades in this array
1140 $gradeshtml[$student->id
] = array(); // Collect all grades html formatted in this array
1141 $totals[$student->id
] = array(); // Collect all totals in this array
1143 $columns = array(); // Accumulate column names in this array.
1144 $columnhtml = array(); // Accumulate column html in this array.
1147 /// Collect modules data
1148 get_all_mods($course->id
, $mods, $modnames, $modnamesplural, $modnamesused);
1150 /// Search through all the modules, pulling out grade data
1151 $sections = get_all_sections($course->id
); // Sort everything the same as the course
1152 for ($i=0; $i<=$course->numsections
; $i++
) {
1153 if (isset($sections[$i])) { // should always be true
1154 $section = $sections[$i];
1155 if ($section->sequence
) {
1156 $sectionmods = explode(",", $section->sequence
);
1157 foreach ($sectionmods as $sectionmod) {
1158 $mod = $mods[$sectionmod];
1159 $instance = get_record("$mod->modname", "id", "$mod->instance");
1160 $libfile = "$CFG->dirroot/mod/$mod->modname/lib.php";
1162 if (file_exists($libfile)) {
1163 require_once($libfile);
1164 $gradefunction = $mod->modname
."_grades";
1165 if (function_exists($gradefunction)) { // Skip modules without grade function
1166 if ($modgrades = $gradefunction($mod->instance
)) {
1167 if (!empty($modgrades->maxgrade
)) {
1168 if ($mod->visible
) {
1169 $maxgrade = "$strmax: $modgrades->maxgrade";
1171 $maxgrade = "$strmax: $modgrades->maxgrade";
1177 $columns[] = "$mod->modfullname: ".format_string($instance->name
,true)." - $maxgrade";
1179 foreach ($students as $student) {
1180 if (!empty($modgrades->grades
[$student->id
])) {
1181 $grades[$student->id
][] = $currentstudentgrade = $modgrades->grades
[$student->id
];
1183 $grades[$student->id
][] = $currentstudentgrade = "";
1184 $gradeshtml[$student->id
][] = "";
1186 if (!empty($modgrades->maxgrade
)) {
1187 $totals[$student->id
] = (float)($totals[$student->id
]) +
(float)($currentstudentgrade);
1189 $totals[$student->id
] = (float)($totals[$student->id
]) +
0;
1198 } // a new Moodle nesting record? ;-)
1200 /// OK, we have all the data, now present it to the user
1201 if ($download == "xls" and confirm_sesskey()) {
1202 require_once("../lib/excel/Worksheet.php");
1203 require_once("../lib/excel/Workbook.php");
1206 header("Content-type: application/vnd.ms-excel");
1207 $downloadfilename = clean_filename("$course->shortname $strgrades");
1208 header("Content-Disposition: attachment; filename=\"$downloadfilename.xls\"");
1209 header("Expires: 0");
1210 header("Cache-Control: must-revalidate,post-check=0,pre-check=0");
1211 header("Pragma: public");
1213 /// Creating a workbook
1214 $workbook = new Workbook("-");
1215 $myxls =& $workbook->add_worksheet($strgrades);
1217 /// Print names of all the fields
1219 $myxls->write_string(0,0,get_string("firstname"));
1220 $myxls->write_string(0,1,get_string("lastname"));
1221 $myxls->write_string(0,2,get_string("idnumber"));
1222 $myxls->write_string(0,3,get_string("institution"));
1223 $myxls->write_string(0,4,get_string("department"));
1224 $myxls->write_string(0,5,get_string("email"));
1226 foreach ($columns as $column) {
1227 $myxls->write_string(0,$pos++
,strip_tags($column));
1229 $myxls->write_string(0,$pos,get_string("total"));
1232 /// Print all the lines of data.
1235 foreach ($grades as $studentid => $studentgrades) {
1237 $student = $students[$studentid];
1238 if (empty($totals[$student->id
])) {
1239 $totals[$student->id
] = '';
1242 $myxls->write_string($i,0,$student->firstname
);
1243 $myxls->write_string($i,1,$student->lastname
);
1244 $myxls->write_string($i,2,$student->idnumber
);
1245 $myxls->write_string($i,3,$student->institution
);
1246 $myxls->write_string($i,4,$student->department
);
1247 $myxls->write_string($i,5,$student->email
);
1249 foreach ($studentgrades as $grade) {
1250 if (is_numeric($grades)) {
1251 $myxls->write_number($i,$j++
,strip_tags($grade));
1254 $myxls->write_string($i,$j++
,strip_tags($grade));
1257 $myxls->write_number($i,$j,$totals[$student->id
]);
1264 } else if ($download == "txt" and confirm_sesskey()) {
1266 /// Print header to force download
1268 header("Content-Type: application/download\n");
1269 $downloadfilename = clean_filename("$course->shortname $strgrades");
1270 header("Content-Disposition: attachment; filename=\"$downloadfilename.txt\"");
1272 /// Print names of all the fields
1274 echo get_string("firstname")."\t".
1275 get_string("lastname")."\t".
1276 get_string("idnumber")."\t".
1277 get_string("institution")."\t".
1278 get_string("department")."\t".
1279 get_string("email");
1280 foreach ($columns as $column) {
1281 $column = strip_tags($column);
1284 echo "\t".get_string("total")."\n";
1286 /// Print all the lines of data.
1287 foreach ($grades as $studentid => $studentgrades) {
1288 $student = $students[$studentid];
1289 if (empty($totals[$student->id
])) {
1290 $totals[$student->id
] = '';
1292 echo "$student->firstname\t$student->lastname\t$student->idnumber\t$student->institution\t$student->department\t$student->email";
1293 foreach ($studentgrades as $grade) {
1294 $grade = strip_tags($grade);
1297 echo "\t".$totals[$student->id
];
1306 function grade_get_stats($category='all') {
1307 list($grades_by_student, $all_categories) = grade_get_formatted_grades();
1309 if ($grades_by_student != 0 && $all_categories != 0) {
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'];
1322 $stats[$cur_category]['sum'] = $assignments['stats']['points'];
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'];
1331 // populate the overall sum,items and totalpoints
1332 foreach($stats as $cur_category=>$info) {
1333 if($cur_category != 'all' && $cur_category != 'student_data') {
1334 if (isset($stats['all'])) {
1335 $stats['all']['sum'] = $stats['all']['sum'] +
$stats[$cur_category]['sum'];
1336 $stats['all']['items'] = $stats['all']['items'] +
$stats[$cur_category]['items'];
1337 $stats['all']['totalpoints'] = $stats['all']['totalpoints'] +
$stats[$cur_category]['totalpoints'];
1338 $stats['all']['weighted_sum'] = $stats['all']['weighted_sum'] +
($stats[$cur_category]['sum']/($stats[$cur_category]['totalpoints']))*$stats[$cur_category]['weight'];
1341 $stats['all']['sum'] = $stats[$cur_category]['sum'];
1342 $stats['all']['items'] = $stats[$cur_category]['items'];
1343 $stats['all']['totalpoints'] = $stats[$cur_category]['totalpoints'];
1344 $stats['all']['weighted_sum'] = ($stats[$cur_category]['sum']/($stats[$cur_category]['totalpoints']))*$stats[$cur_category]['weight'];
1348 $stats['all']['students'] = count($grades_by_student);
1349 $stats['all']['average'] = $stats['all']['sum'] / $stats['all']['students'];
1350 $stats['all']['average_weighted'] = $stats['all']['weighted_sum']/$stats['all']['students'];
1352 // calculate the average squared deviation and populate a list of all scores while we're at it
1353 $stats['all']['avgsqddev'] = 0;
1354 $stats['all']['avgsqddev_weighted'] = 0;
1355 foreach($grades_by_student as $student=>$categories) {
1356 foreach($categories as $cur_category=>$assignments) {
1357 if ($cur_category != 'student_data') {
1358 $stats['all']['avgsqddev'] = $stats['all']['avgsqddev'] +
pow(($grades_by_student[$student]['student_data']['points']-$stats['all']['average']),2);
1359 $stats['all']['avgsqddev_weighted'] = $stats['all']['avgsqddev_weighted'] +
pow(($grades_by_student[$student]['student_data']['weighted']-$stats['all']['average_weighted']),2);
1362 if (isset($stats['all']['all_scores'])) {
1363 $stats['all']['all_scores'] .= ','.$grades_by_student[$student]['student_data']['points'];
1364 $stats['all']['all_scores_weighted'] .= ','.$grades_by_student[$student]['student_data']['weighted'];
1367 $stats['all']['all_scores'] = $grades_by_student[$student]['student_data']['points'];
1368 $stats['all']['all_scores_weighted'] = $grades_by_student[$student]['student_data']['weighted'];
1371 $stats['all']['avgsqddev']=$stats['all']['avgsqddev']/$stats['all']['students'];
1372 $stats['all']['avgsqddev_weighted']=$stats['all']['avgsqddev_weighted']/$stats['all']['students'];
1373 $stats['all']['stddev'] = sqrt($stats['all']['avgsqddev']);
1374 $stats['all']['stddev_weighted'] = sqrt($stats['all']['avgsqddev_weighted']);
1375 $stats['all']['mode'] = grade_mode($stats['all']['all_scores']);
1376 $stats['all']['mode_weighted'] = grade_mode($stats['all']['all_scores_weighted']);
1378 // make sure the mode is not set to every score
1379 if(count($stats['all']['mode']) == count($grades_by_student)) {
1380 $stats['all']['mode'] = get_string('nomode','grade');
1382 if(count($stats['all']['mode_weighted']) == count($grades_by_student)) {
1383 $stats['all']['mode_weighted'] = get_string('nomode','grade');
1389 // get the stats for category
1390 //populate the sum of student points, # items and totalpoints for each category
1391 foreach($grades_by_student as $student=>$categories) {
1392 if(isset($grades_by_student[$student][$category]['stats'])) {
1393 if (isset($stats[$category]['sum'])) {
1394 $stats[$category]['sum'] = $stats[$category]['sum'] +
$grades_by_student[$student][$category]['stats']['points'];
1397 $stats[$category]['sum'] = $grades_by_student[$student][$category]['stats']['points'];
1399 $stats[$category]['items'] = $grades_by_student[$student][$category]['stats']['grade_items'];
1400 $stats[$category]['totalpoints'] = $grades_by_student[$student][$category]['stats']['totalpoints'];
1403 $stats[$category]['students'] = count($grades_by_student);
1404 $stats[$category]['average'] = $stats[$category]['sum']/$stats[$category]['students'];
1406 // calculate the average squared deviation and populate a list of all scores too
1407 $stats[$category]['avgsqddev'] = 0;
1408 foreach($grades_by_student as $student=>$categories) {
1409 foreach($categories as $cur_category=>$assignment) {
1410 if ($cur_category != 'student_data') {
1411 if ($grades_by_student[$student][$category]['stats']['points'] == '-' ||
$grades_by_student[$student][$category]['stats']['points'] == get_string('grades','excluded')) {
1412 // count grade as a zero
1413 $stats[$category]['avgsqddev'] = $stats[$category]['avgsqddev'] +
pow(($stats[$category]['average']),2);
1416 $stats[$category]['avgsqddev'] = $stats[$category]['avgsqddev'] +
pow(($grades_by_student[$student][$category]['stats']['points']-$stats[$category]['average']),2);
1421 if (isset($stats[$category]['all_scores'])) {
1422 $stats[$category]['all_scores'] .= ','.$grades_by_student[$student][$category]['stats']['points'];
1425 $stats[$category]['all_scores'] = $grades_by_student[$student][$category]['stats']['points'];
1428 $stats[$category]['avgsqddev'] = $stats[$category]['avgsqddev']/$stats[$category]['students'];
1429 $stats[$category]['stddev'] = sqrt($stats[$category]['avgsqddev']);
1430 $stats[$category]['mode'] = grade_mode($stats[$category]['all_scores']);
1434 // do a little cleanup
1435 $stats[$category]['stddev'] = sprintf("%0.2f", $stats[$category]['stddev']);
1436 $stats[$category]['average'] = sprintf("%0.2f", $stats[$category]['average']);
1437 $stats[$category]['max'] = max(explode(',',$stats[$category]['all_scores']));
1438 $stats[$category]['min'] = min(explode(',',$stats[$category]['all_scores']));
1439 $stats[$category]['median'] = explode(',',$stats[$category]['all_scores']);
1441 if (isset($stats[$category]['stddev_weighted'])) {
1442 $stats[$category]['stddev_weighted'] = sprintf("%0.2f", $stats[$category]['stddev_weighted']);
1444 if (isset($stats[$category]['average_weighted'])) {
1445 $stats[$category]['average_weighted'] = sprintf("%0.2f", $stats[$category]['average_weighted']);
1447 if (isset($stats[$category]['max_weighted'])) {
1448 $stats[$category]['max_weighted'] = max(explode(',',$stats[$category]['all_scores_weighted']));
1450 if (isset($stats[$category]['min_weighted'])) {
1451 $stats[$category]['min_weighted'] = min(explode(',',$stats[$category]['all_scores_weighted']));
1454 if (isset($stats[$category]['all_scores_weighted'])) {
1455 $stats[$category]['median_weighted'] = explode(',',$stats[$category]['all_scores_weighted']);
1462 sort($stats[$category]['median']);
1464 if (count($stats[$category]['median'])/2 == floor(count($stats[$category]['median'])/2) ) {
1465 // even number of scores
1466 $temp = $stats[$category]['median'][count($stats[$category]['median'])/2-1] +
$stats[$category]['median'][count($stats[$category]['median'])/2];
1470 // odd number of scores
1471 $temp = $stats[$category]['median'][floor(count($stats[$category]['median'])/2)];
1473 unset($stats[$category]['median']);
1474 $stats[$category]['median'] = $temp;
1476 if (isset($stats[$category]['median_weighted'])) {
1477 if (count($stats[$category]['median_weighted'])/2 == floor(count($stats[$category]['median_weighted'])/2)) {
1478 // even number of scores
1479 $temp = $stats[$category]['median_weighted'][count($stats[$category]['median_weighted'])/2-1] +
$stats[$category]['median_weighted'][count($stats[$category]['median_weighted'])/2+
1];
1483 // odd number of scores
1484 $temp = $stats[$category]['median_weighted'][floor(count($stats[$category]['median_weighted'])/2)];
1486 unset($stats[$category]['median_weighted']);
1487 $stats[$category]['median_weighted'] = $temp;
1493 // returns a comma seperated list of the most common values in $items, $items is expected to be a comma sperated list of numbers
1494 function grade_mode($items) {
1495 $all_scores = explode(',',$items);
1496 foreach($all_scores as $value) {
1497 if (isset($frequency[$value])) {
1498 $frequency[$value]++
;
1501 $frequency[$value] = 1;
1504 $max = max($frequency);
1505 foreach($frequency as $key=>$value) {
1506 if ($value == $max) {
1507 if (isset($retval)) {
1508 $retval .= ', '.$key;
1519 function grade_stats() {
1523 global $preferences;
1525 if (!isset($category)) {
1526 $category = clean_param($_REQUEST['category'], PARAM_CLEAN
);
1529 $stats = grade_get_stats($category);
1533 echo '<table align="center"><tr><th colspan="3">'.$category.' '.get_string('stats','grades').'</th></tr>';
1534 if ($preferences->show_weighted
== 1 && $preferences->use_weighted_for_letter
== 1 && $category== 'all') {
1535 echo '<tr><th> </th><th>'.get_string('points','grades').'<th>'.get_string('weight','grades').'</th></tr>';
1538 echo '<tr><td align="right">'.get_string('max','grades').':</td><td align="right">'.$stats[$category]['max'].'</td>';
1539 if ($preferences->show_weighted
== 1 && $preferences->use_weighted_for_letter
== 1 && $category== 'all') {
1540 echo '<td align="right">'.$stats[$category]['max_weighted'].'</td>';
1544 echo '<tr><td align="right">'.get_string('min','grades').':</td><td align="right">'.$stats[$category]['min'].'</td>';
1545 if ($preferences->show_weighted
== 1 && $preferences->use_weighted_for_letter
== 1 && $category== 'all') {
1546 echo '<td align="right">'.$stats[$category]['min_weighted'].'</td>';
1550 echo '<tr><td align="right">'.get_string('average','grades').':</td><td align="right">'.$stats[$category]['average'].'</td>';
1551 if ($preferences->show_weighted
== 1 && $preferences->use_weighted_for_letter
== 1 && $category== 'all') {
1552 echo '<td align="right">'.$stats[$category]['average_weighted'].'</td>';
1556 echo '<tr><td align="right">'.get_string('median','grades').':</td><td align="right">'.$stats[$category]['median'].'</td>';
1557 if ($preferences->show_weighted
== 1 && $preferences->use_weighted_for_letter
== 1 && $category== 'all') {
1558 echo '<td align="right">'.$stats[$category]['median_weighted'].'</td>';
1562 echo '<tr><td align="right">'.get_string('mode','grades').':</td><td align="right">'.$stats[$category]['mode'].'</td>';
1563 if ($preferences->show_weighted
== 1 && $preferences->use_weighted_for_letter
== 1 && $category== 'all') {
1564 echo '<td align="right">'.$stats[$category]['mode_weighted'].'</td>';
1568 echo '<tr><td align="right">'.get_string('standarddeviation','grades').':</td><td align="right">'.$stats[$category]['stddev'].'</td>';
1569 if ($preferences->show_weighted
== 1 && $preferences->use_weighted_for_letter
== 1 && $category== 'all') {
1570 echo '<td align="right">'.$stats[$category]['stddev_weighted'].'</td>';
1577 function grade_view_category_grades($view_by_student) {
1581 global $preferences;
1583 if (!isteacher($course->id
)) {
1584 $view_by_student = $USER->id
;
1587 if ($preferences->use_advanced
== 0) {
1588 $cview = UNCATEGORISED
;
1591 $cview=clean_param($_REQUEST['cview'], PARAM_CLEAN
);
1595 list($grades_by_student, $all_categories) = grade_get_formatted_grades();
1597 if ($grades_by_student != 0 && $all_categories != 0) {
1598 // output a form for the user to download the grades.
1599 grade_download_form();
1601 if ($view_by_student != -1) {
1602 // unset all grades except for this student
1603 foreach ($grades_by_student as $student=>$junk) {
1604 if($student != $view_by_student) {
1605 unset($grades_by_student[$student]);
1610 $grade_columns = $preferences->show_weighted +
$preferences->show_points +
$preferences->show_percent
;
1616 if (isteacher($course->id
)) {
1617 $student_heading_link = get_string('student','grades');
1618 //only set sorting links if more than one student displayed.
1619 if ($view_by_student == -1) {
1620 $student_heading_link .='<br /><a href="?id='.$course->id
.'&group='.$group.'&action=vcats&cview='.$cview.'&sort=lastname">'.get_string('sortbylastname','grades').'</a>';
1621 $student_heading_link .= '<br /><a href="?id='.$course->id
.'&group='.$group.'&action=vcats&cview='.$cview.'&sort=firstname">'.get_string('sortbyfirstname','grades').'</a>';
1624 $student_heading_link .= '<br /><a href="?id='.$course->id
.'&group='.$group.'&action=vcats&cview='.$cview.'">'.get_string('showallstudents','grades').'</a>';
1627 echo '<table align="center" class="grades">';
1628 if (isteacher($course->id
)) {
1629 $header = '<tr class="header"><th rowspan="2">'.$student_heading_link.'</th>';
1632 $header = '<tr class="header">';
1634 $header1 = '<tr class="header">';
1636 // to keep track of what we've output
1641 // this next section is to display the items in the course order
1642 foreach($grades_by_student as $student => $categories) {
1643 if (isset($item_order)) {
1644 // we already have the sort order let's jump out
1647 $item_order = array();
1648 foreach($categories as $category => $items) {
1649 if ($category == $cview) {
1650 foreach ($items as $assignment=>$points) {
1651 if ($assignment != 'stats') {
1652 $temp = $points['sort_order'];
1653 $item_order[$temp] = $assignment;
1659 /// Make sure $item_order is initialised (bug 3424)
1660 if (empty($item_order)) $item_order = array();
1664 foreach($grades_by_student as $student => $categories) {
1666 if ($preferences->reprint_headers
!= 0 && $reprint >= $preferences->reprint_headers
) {
1667 echo $header.$header1.'</tr>';
1671 // alternate row classes
1672 $row = ($oddrow) ?
'<tr class="r0">' : '<tr class="r1">';
1675 // reset the col classes
1679 // set the links to student information based on multiview or individual... if individual go to student info... if many go to individual grades view.
1680 if (isteacher($course->id
)) {
1681 if ($view_by_student != -1) {
1682 $student_link = '<a href="'.$CFG->wwwroot
.'/user/view.php?id='.$student.'&course='.$course->id
.'">';
1685 $student_link = '<a href="?id='.$course->id
.'&group='.$group.'&action=vcats&user='.$student.'&cview='.$cview.'">';
1687 $student_link .= $grades_by_student[$student]['student_data']['lastname'].', '.$grades_by_student[$student]['student_data']['firstname'].'</a>';
1688 $row .= '<td class="fullname">'.$student_link.'</td>';
1691 foreach($categories as $category => $items) {
1692 if ($category == $cview) {
1693 // make sure that the grades come out in the same order
1694 foreach($item_order as $order=>$assignment) {
1696 $class = $all_categories[$category][$assignment]['modname'];
1698 if ($assignment != 'stats') {
1702 $link_id = grade_get_module_link($course->id
, $all_categories[$category][$assignment]['cminstance'], $all_categories[$category][$assignment]['modid']);
1704 $link = $CFG->wwwroot
.'/mod/'.$all_categories[$category][$assignment]['modname'].'/view.php?id='.$link_id->id
;
1705 $all_categories[$category][$assignment]['link'] = $link;
1706 if ($all_categories[$category][$assignment]['hidden'] == 0) {
1707 $header .= '<th class="'.$class.'" colspan="'.$grade_columns.'"><a href="'.$link.'">'.format_string($assignment,true).'</a>';
1710 $header .= '<th class="'.$class.'" colspan="'.$grade_columns.'"><a class="dimmed" href="'.$link.'">'.format_string($assignment,true).'</a>';
1712 if ($all_categories[$category][$assignment]['extra_credit'] == 1) {
1713 $header .= '<span class="extracredit">('.get_string('extracredit','grades').')</span>';
1716 if ($preferences->show_points
) {
1717 $header1 .= '<th class="'.$class.'">'. $all_categories[$category][$assignment]['maxgrade'];
1718 if ($all_categories[$category][$assignment]['grade_against'] != $all_categories[$category][$assignment]['maxgrade']) {
1719 $header1 .= '('. $all_categories[$category][$assignment]['grade_against'].')';
1721 $header1 .= '</th>';
1724 if($preferences->show_percent
) {
1725 if ($all_categories[$category][$assignment]['grade_against'] != $all_categories[$category][$assignment]['maxgrade']) {
1726 $header1 .= '<th class="'.$class.'">'.get_string('scaledpct','grades').'</th>';
1729 $header1 .= '<th class="'.$class.'">'.get_string('rawpct','grades').'</th>';
1732 if ($preferences->show_weighted
) {
1733 if ($all_categories[$category]['stats']['totalpoints'] != 0) {
1734 $cur_weighted_max = sprintf("%0.2f", $all_categories[$category][$assignment]['grade_against']/$all_categories[$category]['stats']['totalpoints']*$all_categories[$category]['stats']['weight']);
1737 $cur_weighted_max = 0;
1739 $header1 .= '<th>'.$cur_weighted_max.get_string('pctoftotalgrade','grades').'</th>';
1744 if ($preferences->show_points
) {
1745 $class .= ($oddcol) ?
' c0 points' : ' c1 points';
1747 $row .= '<td class="'.$class.'"><a href="'.$all_categories[$category][$assignment]['link'].'">' . $items[$assignment]['grade'] . '</a></td>';
1750 if ($preferences->show_percent
) {
1751 $class .= ($oddcol) ?
' c0 percent' : ' c1 percent';
1753 $row .= '<td class="'.$class.'">'. $items[$assignment]['percent'].'%</td>';
1756 if ($preferences->show_weighted
) {
1757 $class .= ($oddcol) ?
' c0 weighted' : ' c1 weighted';
1759 $row .= '<td class="'.$class.'">'.$items[$assignment]['weighted'].'%</td>';
1769 if (isteacher($course->id
) && $view_by_student == -1) {
1770 $total_sort_link = '<a href="?id='.$course->id
.'&group='.$group.'&action=vcats&cview='.$cview.'&sort=highgrade_category"><img src="'.$CFG->wwwroot
.'/pix/t/down.gif" alt="'.get_string('highgradedescending','grades').'" /></a>';
1771 $total_sort_link .= '<a href="?id='.$course->id
.'&group='.$group.'&action=vcats&cview='.$cview.'&sort=highgrade_category_asc"><img src="'.$CFG->wwwroot
.'/pix/t/up.gif" alt="'.get_string('highgradeascending','grades').'" /></a>';
1774 $total_sort_link = '';
1777 $stats_link = '<a href="javascript:void(0)"onclick="window.open(\'?id='.$course->id
.'&action=stats&group='.$group.'&category='.$cview.'\',\''.get_string('statslink','grades').'\',\'height=200,width=300,scrollbars=no\')">'.get_string('statslink','grades').'</a>';
1778 if ($all_categories[$cview]['stats']['drop'] != 0) {
1779 $header .= '<th class="'.$class.'" colspan="'.$grade_columns.'">'.get_string('total','grades').' (Lowest '. $all_categories[$cview]['stats']['drop']. ' Dropped)'.$total_sort_link.' '.$stats_link.'</th>';
1782 $header .= '<th class="'.$class.'" colspan="'.$grade_columns.'">'.get_string('total','grades').' '.$total_sort_link.' '.$stats_link.'</th>';
1785 if ($preferences->show_points
) {
1786 $header1 .= '<th class="'.$class.'">'.$all_categories[$cview]['stats']['totalpoints'];
1787 if ($all_categories[$cview]['stats']['bonus_points'] != 0) {
1788 $header1 .='(+'.$all_categories[$cview]['stats']['bonus_points'].')';
1792 if ($preferences->show_percent
) {
1793 $header1 .= '<th class="'.$class.'">'.get_string('percent','grades').'</th>';
1797 if ($preferences->show_weighted
) {
1798 $header1 .= '<th class="'.$class.'">'.$all_categories[$cview]['stats']['weight'].get_string('pctoftotalgrade','grades').'</th>';
1801 if (isteacher($course->id
) ) {
1802 $header .= '<th rowspan="2">'.$student_heading_link.'</th></tr>';
1808 //adjust colcount to reflect the actual number of columns output
1809 $colcount++
; // total column
1810 $colcount = $colcount*$grade_columns +
2;
1811 echo '<tr class="title"><th colspan="'.$colcount.'">';
1812 if ($preferences->use_advanced
!= 0) {
1813 echo $cview.' '.get_string('grades','grades');
1816 echo get_string('grades','grades');
1819 if (isteacher($course->id
)) {
1820 helpbutton('teacher', get_string('gradehelp','grades'), 'grade');
1823 helpbutton('student', get_string('gradehelp','grades'), 'grade');
1827 echo $header1.'</tr>';
1831 // total points for category
1832 if ($preferences->show_points
) {
1833 $class .= ($oddcol) ?
' c0 points' : ' c1 points';
1835 $row .= '<td class="'.$class.'">'.$grades_by_student[$student][$cview]['stats']['points'].'</td>';
1838 // total percent for category
1839 if ($preferences->show_percent
) {
1840 $class .= ($oddcol) ?
' c0 percent' : ' c1 percent';
1842 $row .= '<td class="'.$class.'">'.$grades_by_student[$student][$cview]['stats']['percent'].'%</td>';
1846 // total weighted for category
1847 if ($preferences->show_weighted
) {
1848 $class .= ($oddcol) ?
' c0 weighted' : ' c1 weighted';
1850 $row .= '<td class="'.$class.'">'.$grades_by_student[$student][$cview]['stats']['weighted'].'%</td>';
1853 if (isteacher($course->id
) ) {
1854 $row .= '<td class="fullname">'.$student_link.'</td>';
1862 else { // no grades returned
1863 error(get_string('nogradesreturned','grades'), $CFG->wwwroot
.'/course/view.php?id='.$course->id
);
1867 error(get_string('nocategoryview','grades'), $CFG->wwwroot
.'/course/view.php?id='.$course->id
);
1871 function grade_view_all_grades($view_by_student) {
1872 // displays all grades for the course
1875 global $preferences;
1878 if (!isteacher($course->id
)) {
1879 $view_by_student = $USER->id
;
1882 list($grades_by_student, $all_categories) = grade_get_formatted_grades();
1884 if ($grades_by_student != 0 && $all_categories != 0) {
1885 // output a form for the user to download the grades.
1886 grade_download_form();
1888 if ($view_by_student != -1) {
1889 // unset all grades except for this student
1890 foreach ($grades_by_student as $student=>$junk) {
1891 if($student != $view_by_student) {
1892 unset($grades_by_student[$student]);
1896 $grade_columns = $preferences->show_weighted +
$preferences->show_points +
$preferences->show_percent
;
1899 $total_course_points = 0;
1903 echo '<table align="center" class="grades">';
1904 if (isteacher($course->id
) ) {
1905 $student_heading_link = get_string('student','grades');
1906 if ($view_by_student == -1) {
1907 $student_heading_link .='<a href="?id='.$course->id
.'&action=grades&sort=lastname"><br /><font size="-2">'.get_string('sortbylastname','grades').'</font></a>';
1908 $student_heading_link .= '<a href="?id='.$course->id
.'&action=grades&sort=firstname"><br /><font size="-2">'.get_string('sortbyfirstname','grades').'</font></a>';
1911 $student_heading_link .= '<br /><a href="?id='.$course->id
.'&&action=grades"><font size="-2">'.get_string('showallstudents','grades').'</font></a>';
1913 $header = '<tr><th rowspan="2">'.$student_heading_link.'</th>';
1923 foreach($grades_by_student as $student => $categories) {
1926 $total_bonus_points = 0;
1927 if ($preferences->reprint_headers
!= 0 && $reprint >= $preferences->reprint_headers
) {
1928 echo $header.$header1;
1932 // alternate row classes
1933 $row = ($oddrow) ?
'<tr class="r0">' : '<tr class="r1">';
1936 // set the links to student information based on multiview or individual... if individual go to student info... if many go to individual grades view.
1937 if (isteacher($course->id
)) {
1938 if ($view_by_student != -1) {
1939 $studentviewlink = '<a href="'.$CFG->wwwroot
.'/user/view.php?id='.$student.'&course='.$course->id
.'">'.$grades_by_student[$student]['student_data']['lastname'].', '.$grades_by_student[$student]['student_data']['firstname'].'</a>';
1942 $studentviewlink = '<a href="?id='.$course->id
.'&action=view_student_grades&user='.$student.'">'.$grades_by_student[$student]['student_data']['lastname'].', '.$grades_by_student[$student]['student_data']['firstname'].'</a>';
1944 $row .= '<td>'. $studentviewlink .'</td>';
1947 foreach($categories as $category => $items) {
1948 if ($category != 'student_data') {
1951 if ($category == UNCATEGORISED
) {
1952 $categoryname = get_string(UNCATEGORISED
, 'grades');
1954 $categoryname = $category;
1956 // only print the category headers if something is displayed for them
1957 if ($preferences->show_weighted ||
$preferences->show_percent ||
$preferences->show_points
) {
1958 $stats_link = '<a href="javascript:void(0)"onclick="window.open(\'?id='.$course->id
.'&action=stats&category='.$category.'\',\''.get_string('statslink','grades').'\',\'height=200,width=300,scrollbars=no\')"><font size=-2>'.get_string('statslink','grades').'</font></a>';
1959 $header .= '<th colspan="'.$grade_columns.'"><a href="?id='.$course->id
.'&action=vcats&cview='.$category;
1960 if ($view_by_student != -1) {
1961 $header .= '&user='.$view_by_student;
1963 $header .='">'. $categoryname .' '.$stats_link.'</a>';
1965 if ($preferences->display_weighted
!= 0) {
1966 $header .= '('. $all_categories[$category]['stats']['weight'] . '%)';
1969 if ($preferences->show_points
) {
1970 $header1 .= '<th>'.get_string('points','grades').'('.$all_categories[$category]['stats']['totalpoints'].')';
1971 if ($all_categories[$category]['stats']['bonus_points'] != 0) {
1972 $header1 .='(+'.$all_categories[$category]['stats']['bonus_points'].')';
1976 if ($preferences->show_percent
) {
1977 $header1 .= '<th>'.get_string('percent','grades').'</th>';
1979 if ($preferences->show_weighted
) {
1980 $header1 .= '<th>'.get_string('weightedpctcontribution','grades').'</th>';
1982 $maxpercent = $all_categories["$category"]['stats']['weight'] +
$maxpercent;
1983 //$total_course_points = $all_categories[$category]['stats']['totalpoints']+ $total_course_points;
1984 //$total_course_points = $all_categories[$category]['stats']['totalpoints']+ $total_course_points;
1988 if ($preferences->show_points
) {
1989 $row .= '<td align="right">' . $items['stats']['points'] . '</td>';
1991 if ($preferences->show_percent
) {
1992 $row .= '<td align="right">'. $items['stats']['percent'].'%</td>';
1995 if ($preferences->show_weighted
) {
1996 $row .= '<td align="right">'. $items['stats']['weighted'] . '%</td>';
1998 $total_bonus_points = $all_categories[$category]['stats']['bonus_points'];
2002 if ($preferences->show_letters
) {
2003 $total_columns = $grade_columns +
1;
2006 $total_columns = $grade_columns;
2009 if (isteacher($course->id
) && $view_by_student == -1) {
2010 $grade_sort_link = '<a href="?id='.$course->id
.'&action=grades&sort=highgrade"><img src="'.$CFG->wwwroot
.'/pix/t/down.gif" alt="'.get_string('highgradedescending','grades').'" /></a>';
2011 $grade_sort_link .= '<a href="?id='.$course->id
.'&action=grades&sort=highgrade_asc"><img src="'.$CFG->wwwroot
.'/pix/t/up.gif" alt="'.get_string('highgradeascending','grades').'" /></a>';
2012 $points_sort_link = '<a href="?id='.$course->id
.'&action=grades&sort=points"><img src="'.$CFG->wwwroot
.'/pix/t/down.gif" alt="'.get_string('pointsdescending','grades').'" /></a>';
2013 $points_sort_link .= '<a href="?id='.$course->id
.'&action=grades&sort=points_asc"><img src="'.$CFG->wwwroot
.'/pix/t/up.gif" alt="'.get_string('pointsascending','grades').'" /></a>';
2014 $weighted_sort_link = '<a href="?id='.$course->id
.'&action=grades&sort=weighted"><img src="'.$CFG->wwwroot
.'/pix/t/down.gif" alt="'.get_string('weighteddescending','grades').'" /></a>';
2015 $weighted_sort_link .= '<a href="?id='.$course->id
.'&action=grades&sort=weighted_asc"><img src="'.$CFG->wwwroot
.'/pix/t/up.gif" alt="'.get_string('weightedascending','grades').'" /></a>';
2016 $percent_sort_link = '<a href="?id='.$course->id
.'&action=grades&sort=percent"><img src="'.$CFG->wwwroot
.'/pix/t/down.gif" alt="'.get_string('percentdescending','grades').'" /></a>';
2017 $percent_sort_link .= '<a href="?id='.$course->id
.'&action=grades&sort=percent_asc"><img src="'.$CFG->wwwroot
.'/pix/t/up.gif" alt="'.get_string('percentascending','grades').'" /></a>';
2019 $stats_link = '<a href="javascript:void(0)"onclick="window.open(\'?id='.$course->id
.'&action=stats&category=all\',\''.get_string('statslink','grades').'\',\'height=200,width=300,scrollbars=no\')"><font size=-2>'.get_string('statslink','grades').'</font></a>';
2020 $header .= '<th colspan="'.$total_columns.'">'.get_string('total','grades').' '.$stats_link.'</th>';
2021 if (isteacher($course->id
) && $view_by_student == -1) {
2022 if ($preferences->show_points
) {
2023 $header1 .= '<th>'.get_string('points','grades').'('.$all_categories['stats']['totalpoints'].')';
2024 if ($category != 'student_data' && $all_categories[$category]['stats']['bonus_points'] != 0) {
2026 $header1 .='(+'.$total_bonus_points.')';
2028 $header1 .= '<br />'.$points_sort_link.' '.'</th>';
2030 if ($preferences->show_percent
) {
2031 $header1 .= '<th>'.get_string('percentshort','grades').'<br />'.$percent_sort_link.' '.'</th>';
2033 if ($preferences->show_weighted
) {
2034 $header1 .= '<th>'.get_string('weightedpct','grades').'('.$all_categories['stats']['weight'].')'.'<br />'.$weighted_sort_link.' '.'</th>';
2036 if ($preferences->show_letters
) {
2037 $header1 .= '<th>'.get_string('lettergrade','grades').'<br />'.$grade_sort_link.' '.'</th>';
2039 $header1 .= '</tr>';
2042 if ($preferences->show_points
) {
2043 $header1 .= '<th>'.get_string('points','grades').'('.$all_categories['stats']['totalpoints'].')';
2044 if ($category != 'student_data' && $all_categories[$category]['stats']['bonus_points'] != 0) {
2045 $header1 .='(+'.$total_bonus_points.')';
2047 $header1 .= '</th>';
2049 if ($preferences->show_percent
) {
2050 $header1 .= '<th>'.get_string('percentshort','grades').'</th>';
2052 if ($preferences->show_weighted
) {
2053 $header1 .= '<th>'.get_string('weightedpct','grades').'('.$all_categories['stats']['weight'].')</th>';
2055 if ($preferences->show_letters
) {
2056 $header1 .= '<th>'.get_string('lettergrade','grades').'</th>';
2058 $header1 .= '</tr>';
2060 if (isteacher($course->id
)) {
2061 $header .= '<th rowspan="2">'.$student_heading_link.'</th></tr>';
2063 // adjust colcount to reflect actual number of columns output
2064 $colcount = $colcount * $grade_columns +
$total_columns +
2;
2066 echo '<tr><th colspan="'.$colcount.'"><font size="+1">'.get_string('allgrades','grades').'</font>';
2067 if (isteacher($course->id
)) {
2068 helpbutton('teacher', get_string('gradehelp','grades'), 'grade');
2071 helpbutton('student', get_string('gradehelp','grades'), 'grade');
2080 if ($preferences->show_points
) {
2081 $row .= '<td align="right">'.$grades_by_student[$student]['student_data']['points'].'</td>';
2083 if ($preferences->show_percent
) {
2084 $row .= '<td align="right">'.$grades_by_student[$student]['student_data']['percent'].'%</td>';
2086 if ($preferences->show_weighted
) {
2087 $row .= '<td align=right>'.$grades_by_student[$student]['student_data']['weighted'].'%</td>';
2089 if ($preferences->show_letters
) {
2090 if ($preferences->use_weighted_for_letter
== 1) {
2091 $grade = $grades_by_student[$student]['student_data']['weighted'];
2094 $grade = $grades_by_student[$student]['student_data']['percent'];
2096 $letter_grade = grade_get_grade_letter($course->id
, $grade);
2097 if ($letter_grade) {
2098 $row .= '<td align="right">'.$letter_grade->letter
.'</td>';
2101 // there wasn't an appropriate entry to use in the gradebook.
2102 if (grade_letters_set($course->id
)) {
2103 $row .= '<td align="right">'.get_string('nolettergrade','grades').' '.$grade.'</td>';
2106 $row .= '<td align="right">'.get_string('nogradeletters','grades').'</td>';
2110 if (isteacher($course->id
) ) {
2111 $row .= '<td>'. $studentviewlink .'</td></tr>';
2121 else { // no grades returned
2122 error(get_string('nogradesreturned','grades'));
2127 function grade_set_grade_weights() {
2128 // set the grade weights as submitted from the form generated by display_grade_weights
2133 if (!empty($USER->id
)) {
2134 if (!confirm_sesskey()) {
2135 error(get_string('confirmsesskeybad', 'error'));
2139 // get list of all categories
2140 $categories = get_records('grade_category', 'courseid', $course->id
);
2142 foreach ($categories as $category) {
2143 $form_catname = str_replace(' ', '_', $category->name
);
2145 $submitted_category = optional_param($form_catname);
2146 if (is_numeric($submitted_category)) {
2147 // see if there is a weight if so see if it needs to be updated
2148 $weight = grade_get_category_weight($course->id
, $category->name
);
2150 if ($weight->weight
!= $submitted_category)
2152 set_field('grade_category', 'weight', $submitted_category, 'id', $weight->id
);
2155 $cur_drop = optional_param("drop_x_lowest$form_catname");
2156 $cur_bonus_points = optional_param("bonus_points$form_catname");
2157 $cur_hidden = optional_param("hidden$form_catname");
2162 $cur_hidden = false;
2165 if ($weight->drop_x_lowest
!= $cur_drop) {
2166 set_field('grade_category', 'drop_x_lowest', $cur_drop, 'id', $weight->cat_id
);
2168 if ($weight->bonus_points
!= $cur_bonus_points) {
2169 set_field('grade_category', 'bonus_points', $cur_bonus_points, 'id', $weight->cat_id
);
2172 set_field('grade_category', 'hidden', 1, 'id', $weight->cat_id
);
2175 set_field('grade_category', 'hidden', 0, 'id', $weight->cat_id
);
2179 // insert the new record... we shouldn't reach this point anymore
2180 //$new_weight->course = $course->id;
2181 //$new_weight->category = $category->id;
2182 //$new_weight->weight = $submitted_category;
2183 //insert_record('grade_weight', $new_weight);
2187 echo '<center><font color="red">'.get_string('nonumericweight','grades').$category->name
.': "'.$submitted_category.'"</font></center><br />';
2193 function grade_display_grade_weights() {
2194 // get all categories with weights
2195 // then set and display that entry.
2200 $categories = get_records('grade_category', 'courseid', $course->id
);
2202 echo '<table border="0" cellspacing="2" cellpadding="5" align="center" class="generalbox"><tr><th colspan="5" class="header">'.get_string('setweights','grades');
2203 helpbutton('weight', get_string('gradeweighthelp','grades'), 'grade');
2205 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>';
2206 echo '<form name="grade_weights" action="./index.php" method="post">';
2207 echo '<input type="hidden" name="id" value="'.$course->id
.'" />';
2208 echo '<input type="hidden" name="action" value="set_grade_weights" />';
2209 echo '<input type="hidden" name="sesskey" value="'.$USER->sesskey
.'" />';
2213 foreach($categories as $category) {
2214 $val = $category->weight
;
2217 // make names form safe
2218 $form_catname = str_replace(' ', '_', $category->name
);
2219 if ($category->name
== UNCATEGORISED
) {
2220 $category->name
= get_string(UNCATEGORISED
, 'grades');
2222 echo '<tr><td align="center" class="generalboxcontent">'.$category->name
.'</td>';
2223 echo '<td align="center" class="generalboxcontent"><input type="text" size="5" name="'.$form_catname.'" value="'.$val.'" /></td>';
2224 echo '<td align="center" class="generalboxcontent"><input type="text" size="5" name="drop_x_lowest'.$form_catname.'" value="'.$category->drop_x_lowest
.'" /></td>';
2225 echo '<td align="center" class="generalboxcontent"><input type="text" size="5" name="bonus_points'.$form_catname.'" value="'.$category->bonus_points
.'" /></td>';
2226 echo '<td align="center" class="generalboxcontent"><input type="checkbox" name="hidden'.$form_catname.'" ';
2227 if ($category->hidden
== 1) {
2228 echo ' checked="checked"';
2232 echo '<tr><td colspan="5" align="center" class="generalboxcontent"><input type="submit" value="'.get_string('savechanges','grades').'" /></td></tr></form>';
2234 echo '<tr><td colspan="5" align="center" class="generalboxcontent"><font color="red">'.get_string('totalweightnot100','grades').'</font></td></tr>';
2237 echo '<tr><td colspan="5" align="center" class="generalboxcontent"><font color="green">'.get_string('totalweight100','grades').'</font></td></tr>';
2241 /// maybe this should just do the default population of the categories instead?
2242 echo '<font color="red">'.get_string('setcategorieserror','grades').'</font>';
2245 echo '<center>'.get_string('dropxlowestwarning','grades').'</center><br />';
2248 function grade_set_categories() {
2254 /// Collect modules data
2255 get_all_mods($course->id
, $mods, $modnames, $modnamesplural, $modnamesused);
2257 echo '<table border="0" cellspacing="2" cellpadding="5" align="center" class="generalbox"><tr><th colspan="5" class="header">'.get_string('setcategories','grades');
2258 helpbutton('category', get_string('gradecategoryhelp','grades'), 'grade');
2259 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>';
2260 echo '<form name="set_categories" method="post" action="./index.php" >';
2261 echo '<input type="hidden" name="action" value="assign_categories" />';
2262 echo '<input type="hidden" name="id" value="'.$course->id
.'" />';
2263 echo '<input type="hidden" name="sesskey" value="'.$USER->sesskey
.'" />';
2267 /// Search through all the modules, pulling out grade data
2268 $sections = get_all_sections($course->id
); // Sort everything the same as the course
2269 for ($i=0; $i<=$course->numsections
; $i++
) {
2270 if (isset($sections[$i])) { // should always be true
2271 $section = $sections[$i];
2272 if ($section->sequence
) {
2273 $sectionmods = explode(",", $section->sequence
);
2274 foreach ($sectionmods as $sectionmod) {
2275 if (empty($mods[$sectionmod])) {
2278 $mod = $mods[$sectionmod];
2279 $instance = get_record("$mod->modname", "id", "$mod->instance");
2280 $libfile = "$CFG->dirroot/mod/$mod->modname/lib.php";
2281 if (file_exists($libfile)) {
2282 require_once($libfile);
2283 $gradefunction = $mod->modname
."_grades";
2284 if (function_exists($gradefunction)) { // Skip modules without grade function
2285 if ($modgrades = $gradefunction($mod->instance
)) {
2287 if ($modgrades->maxgrade
!= '')
2288 // this block traps out broken modules that don't return a maxgrade according to the moodle API
2291 //modgrades contains student information with associated grade
2292 //echo "<b>modname: $mod->modname id: $mod->id course: $mod->course</b><br />";
2293 echo '<input type="hidden" name="modname'.$itemcount.'" value="'.$mod->modname
.'" />';
2294 echo '<input type="hidden" name="mod'.$itemcount.'" value="'.$mod->instance
.'" />';
2295 echo '<input type="hidden" name="course'.$itemcount.'" value="'.$mod->course
.'" />';
2296 echo '<tr><td align="center" class="generalboxcontent">';
2297 // get instance name from db.
2298 $instance = get_record($mod->modname
, 'id', $mod->instance
);
2299 echo format_string($instance->name
)."</td>";
2300 // see if the item is already in the category table and if it is call category select with the id so it is selected
2301 echo '<td align="center" class="generalboxcontent"><select name="category'.$itemcount.'">';
2302 $item_cat_id = get_record('grade_item', 'modid', $mod->module
, 'courseid', $course->id
, 'cminstance', $mod->instance
);
2303 //print_object($item_cat_id);
2304 if (isset($item_cat_id)) {
2305 grade_category_select($item_cat_id->category
);
2308 grade_category_select(-1);
2310 echo '</select></td><td align="center" class="generalboxcontent">'.$modgrades->maxgrade
.'<input type="hidden" name="maxgrade'.$itemcount.'" value="'.$modgrades->maxgrade
.'" /></td>';
2312 if (isset($item_cat_id)) {
2313 // 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%)
2314 if ($item_cat_id->scale_grade
== '' ||
$item_cat_id->scale_grade
== 0)
2315 $scale_to = $modgrades->maxgrade
;
2317 $scale_to = round($modgrades->maxgrade
/$item_cat_id->scale_grade
);
2318 echo '<td align="center" class="generalboxcontent"><input type="text" size="5" name="scale_grade'.$itemcount.'" value="'.$scale_to.'" /></td>';
2321 echo '<td align="center" class="generalboxcontent"><input type="text" size="5" name="scale_grade'.$itemcount.'" value="'.$modgrades->maxgrade
.'" /></td>';
2324 echo '<td align="center" class="generalboxcontent"><input type="checkbox" name="extra_credit'.$itemcount.'" ';
2325 if ($item_cat_id->extra_credit
== 1) {
2326 echo ' checked="checked"';
2328 echo ' /></td></tr>';
2337 echo '<input type="hidden" name="totalitems" value="'.$itemcount.'" />';
2338 echo '<tr><td colspan="5" align="center" class="generalboxcontent"><input type="submit" value="'.get_string('savechanges','grades').'" /></td></tr>';
2340 echo '<tr><td colspan="5" align="center" class="generalboxcontent">';
2341 grade_add_category_form();
2342 echo '</td></tr><tr><td colspan="5" align="center" class="generalboxcontent">';
2343 grade_delete_category_form();
2344 echo '</td></tr></table>';
2345 echo '<center>'.get_string('extracreditwarning','grades').'<center>';
2348 function grade_delete_category() {
2353 if (!empty($USER->id
)) {
2354 if (!confirm_sesskey()) {
2355 error(get_string('confirmsesskeybad', 'error'));
2359 $cat_id = optional_param('category_id');
2360 if ($cat_id != 'blank') {
2361 // delete the record
2362 delete_records('grade_category', 'id', $cat_id, 'courseid', $course->id
);
2363 // set grade_item category field=0 where it was the deleted category (set uncategorized will clean this up)
2364 set_field('grade_item', 'category', 0, 'category', $cat_id);
2368 function grade_assign_categories() {
2372 $num_categories = optional_param('totalitems');
2374 if (!empty($USER->id
)) {
2375 if (!confirm_sesskey()) {
2376 error(get_string('confirmsesskeybad', 'error'));
2380 for ($i = 1; $i <= $num_categories; $i++
) {
2382 // these next sets of lines are a bit obtuse, but it lets there be a dynamic number of grade items
2383 // in the grade category form (maybe there's a better way?)
2384 $cur_cat_id = '$_REQUEST[\'category'.$i.'\'];';
2385 eval( "\$cur_cat_id = $cur_cat_id;" );
2386 $cur_modname = '$_REQUEST[\'modname'.$i.'\'];';
2387 eval( "\$cur_modname = $cur_modname;" );
2388 $cur_mod = '$_REQUEST[\'mod'.$i.'\'];';
2389 eval( "\$cur_mod = $cur_mod;" );
2390 $cur_maxgrade = '$_REQUEST[\'maxgrade'.$i.'\'];';
2391 eval( "\$cur_maxgrade = $cur_maxgrade;" );
2392 $cur_scale_grade = '$_REQUEST[\'scale_grade'.$i.'\'];';
2393 eval( "\$cur_scale_grade = $cur_scale_grade;" );
2394 $cur_extra_credit = '$_REQUEST[\'extra_credit'.$i.'\'];';
2395 $temp = 'extra_credit'.$i;
2396 $junk = get_record('modules','name',$cur_modname);
2397 $cur_modid = $junk->id
;
2398 if (isset($_REQUEST[$temp])) {
2399 eval( "\$cur_extra_credit = $cur_extra_credit;" );
2402 $cur_extra_credit = false;
2404 if ($cur_extra_credit) {
2405 $cur_extra_credit = 1;
2407 $cur_extra_credit = 0;
2409 if ($cur_scale_grade == 0 ||
$cur_scale_grade == '') {
2410 $cur_scale_grade = 1.0;
2413 $db_cat = get_record('grade_item', 'modid', $cur_modid, 'cminstance', $cur_mod, 'courseid', $course->id
);
2415 if ($db_cat->category
!= $cur_cat_id) {
2416 // item doesn't match in the db so update it to point to the new category
2417 set_field('grade_item', 'category', $cur_cat_id, 'id', $db_cat->id
);
2420 if ($db_cat->scale_grade
!= $cur_maxgrade/$cur_scale_grade) {
2421 // scale_grade doesn't match
2422 set_field('grade_item', 'scale_grade', ($cur_maxgrade/$cur_scale_grade), 'id', $db_cat->id
);
2425 set_field('grade_item', 'extra_credit', $cur_extra_credit, 'id', $db_cat->id
);
2429 $item->courseid
= $course->id
;
2430 $item->category
= $cur_cat_id;
2431 $item->modid
= $cur_modid;
2432 $item->cminstance
= $cur_mod;
2433 $item->scale_grade
= $cur_scale_grade;
2434 $item->extra_credit
= $cur_extra_credit;
2435 insert_record('grade_item', $item);
2440 function grade_add_category_form() {
2441 /// outputs a form to add a category
2442 /// just a simple text box with submit
2445 echo '<form name="new_category">';
2446 echo get_string('addcategory','grades').':<input type="text" name="name" size="20" />';
2447 echo '<input type="hidden" name="id" value="'.$course->id
.'" />';
2448 echo '<input type="hidden" name="action" value="insert_category" />';
2449 echo '<input type="hidden" name="sesskey" value="'.$USER->sesskey
.'" />';
2450 echo '<input type="submit" value="'.get_string('addcategory','grades').'" />';
2454 function grade_delete_category_form() {
2455 // outputs a form to delete a category
2458 echo '<form name="delete_category">';
2459 echo get_string('deletecategory','grades').': <select name="category_id">';
2460 grade_category_select();
2461 echo '</select><input type="hidden" name="id" value="'.$course->id
.'" />';
2462 echo '<input type="hidden" name="sesskey" value="'.$USER->sesskey
.'" />';
2463 echo '<input type="hidden" name="action" value="delete_category" />';
2464 echo '<input type="submit" value="'.get_string('deletecategory','grades').'" /></form>';
2467 function grade_insert_category() {
2472 $category->name
=optional_param('name');
2473 $category->courseid
=$course->id
;
2475 if (!empty($USER->id
)) {
2476 if (!confirm_sesskey()) {
2477 error(get_string('confirmsesskeybad', 'error'));
2481 // make sure the record isn't already there and insert if okay
2482 if (record_exists('grade_category', 'name', $category->name
, 'courseid', $category->course
)) {
2483 // category already exists
2485 elseif ($category->name
!= ''){
2486 if (!insert_record('grade_category', $category) ) {
2487 echo '<font color="red">'.get_string('addcategoryerror','grades').'</font>';
2492 function grade_category_select($id_selected) {
2493 /// prints out a select box containing categories.
2498 echo '<option value="blank">'.get_string('choosecategory','grades').'</option>';
2500 $categories = get_records('grade_category', 'courseid', $course->id
, 'name');
2502 if (!isset($categories)) {
2503 error(get_string("nocategories"));
2506 foreach($categories as $category) {
2507 if ($category->name
== UNCATEGORISED
) {
2508 $category->name
= get_string('uncategorised', 'grades');
2510 if ($category->id
== $id_selected) {
2511 echo '<option value="'.$category->id
.'" selected="selected">'.$category->name
.'</option>';
2514 echo '<option value="'.$category->id
.'">'.$category->name
.'</option>';
2520 function grade_display_grade_preferences($course, $preferences) {
2524 if ($preferences->use_advanced
== 0) {
2526 $buttonlabel = get_string('useadvanced', 'grades');
2529 $buttonlabel = get_String('hideadvanced', 'grades');
2532 $buttonoptions = array('action' => 'set_grade_preferences',
2533 'id' => $course->id
,
2534 'sesskey' => sesskey(),
2535 'use_advanced' => $useadvanced);
2538 print_heading_with_help(get_string('setpreferences','grades'), 'preferences', 'grade');
2541 print_single_button('index.php', $buttonoptions, $buttonlabel, 'post');
2542 echo '<br /></center>';
2544 echo '<form name="set_grade_preferences" method="post" action="./index.php">';
2545 echo '<input type="hidden" name="action" value="set_grade_preferences" />';
2546 echo '<input type="hidden" name="id" value="'.$course->id
.'" />';
2547 echo '<input type="hidden" name="sesskey" value="'.sesskey().'" />';
2548 echo '<table border="0" cellspacing="2" cellpadding="5" align="center" class="gradeprefs generalbox"';
2550 $optionsyesno = NULL;
2551 $optionsyesno[0] = get_string('no');
2552 $optionsyesno[1] = get_string('yes');
2555 if ($preferences->use_advanced
) {
2557 $options[0] = get_string('no');
2558 $options[1] = get_string('toonly', 'moodle', $course->teachers
);
2559 $options[2] = get_string('toeveryone', 'moodle');
2561 // display grade weights
2562 echo '<tr><td class="c0">'.get_string('displayweighted','grades').':</td>';
2563 echo '<td class="c1">';
2564 choose_from_menu($options, 'display_weighted', $preferences->display_weighted
, '');
2568 echo '<tr><td class="c0">'.get_string('displaypoints','grades').':</td>';
2569 echo '<td class="c1">';
2570 choose_from_menu($options, 'display_points', $preferences->display_points
, '');
2574 echo '<tr><td class="c0">'.get_string('displaypercent','grades').':</td>';
2575 echo '<td class="c1">';
2576 choose_from_menu($options, 'display_percent', $preferences->display_percent
, '');
2579 // display letter grade
2580 echo '<tr><td class="c0">'.get_string('displaylettergrade','grades').':</td>';
2581 echo '<td class="c1">';
2582 choose_from_menu($options, 'display_letters', $preferences->display_letters
, '');
2585 // letter grade uses weighted percent
2587 $options[0] = get_string('usepercent','grades');
2588 $options[1] = get_string('useweighted','grades');
2590 echo '<tr><td class="c0">'.get_string('lettergrade','grades').':</td>';
2591 echo '<td class="c1">';
2592 choose_from_menu($options, 'use_weighted_for_letter', $preferences->use_weighted_for_letter
, '');
2596 $headerlist[0] = get_string('none');
2597 for ($i=1; $i<=100; $i++
) {
2598 $headerlist[$i] = $i;
2601 // reprint headers every n lines default n=0
2602 echo '<tr><td class="c0">'.get_string('reprintheaders','grades').':</td>';
2603 echo '<td class="c1">';
2604 choose_from_menu($headerlist, 'reprint_headers', $preferences->reprint_headers
, '');
2607 // show hidden grade items to teacher
2608 echo '<tr><td class="c0">'.get_string('showhiddenitems','grades').'</td>';
2609 echo '<td class="c1">';
2610 choose_from_menu($optionsyesno, 'show_hidden', $preferences->show_hidden
, '');
2613 echo '<tr><td colspan="3" align="center"><input type="submit" value="'.get_string('savepreferences','grades').'" /></td></tr></table></form>';
2618 function grade_display_letter_grades() {
2623 $db_letters = get_records('grade_letter', 'courseid', $course->id
, 'grade_high DESC');
2626 $using_defaults = false;
2627 foreach ($db_letters as $letter) {
2628 $letters[$letter->id
]->letter
= $letter->letter
;
2629 $letters[$letter->id
]->grade_low
= $letter->grade_low
;
2630 $letters[$letter->id
]->grade_high
= $letter->grade_high
;
2631 $letters[$letter->id
]->courseid
= $course->id
;
2635 $using_defaults = true;
2637 $letters[0]->letter
='A';
2638 $letters[0]->grade_low
=93.00;
2639 $letters[0]->grade_high
=100.00;
2640 $letters[0]->courseid
= $course->id
;
2642 $letters[1]->letter
='A-';
2643 $letters[1]->grade_low
=90.00;
2644 $letters[1]->grade_high
=92.99;
2645 $letters[1]->courseid
= $course->id
;
2647 $letters[2]->letter
='B+';
2648 $letters[2]->grade_low
=87.00;
2649 $letters[2]->grade_high
=89.99;
2650 $letters[2]->courseid
= $course->id
;
2652 $letters[3]->letter
='B';
2653 $letters[3]->grade_low
=83.00;
2654 $letters[3]->grade_high
=86.99;
2655 $letters[3]->courseid
= $course->id
;
2657 $letters[4]->letter
='B-';
2658 $letters[4]->grade_low
=80.00;
2659 $letters[4]->grade_high
=82.99;
2660 $letters[4]->courseid
= $course->id
;
2662 $letters[5]->letter
='C+';
2663 $letters[5]->grade_low
=77.00;
2664 $letters[5]->grade_high
=79.99;
2665 $letters[5]->courseid
= $course->id
;
2667 $letters[6]->letter
='C';
2668 $letters[6]->grade_low
=73.00;
2669 $letters[6]->grade_high
=76.99;
2670 $letters[6]->courseid
= $course->id
;
2672 $letters[7]->letter
='C-';
2673 $letters[7]->grade_low
=70.00;
2674 $letters[7]->grade_high
=72.99;
2675 $letters[7]->courseid
= $course->id
;
2677 $letters[8]->letter
='D+';
2678 $letters[8]->grade_low
=67.00;
2679 $letters[8]->grade_high
=69.99;
2680 $letters[8]->courseid
= $course->id
;
2682 $letters[9]->letter
='D';
2683 $letters[9]->grade_low
=60.00;
2684 $letters[9]->grade_high
=66.99;
2685 $letters[9]->courseid
= $course->id
;
2687 $letters[10]->letter
='F';
2688 $letters[10]->grade_low
=0.00;
2689 $letters[10]->grade_high
=59.99;
2690 $letters[10]->courseid
= $course->id
;
2693 echo '<table border="0" cellspacing="2" cellpadding="5" align="center" class="generalbox"><tr><th colspan="3" class="header">'.get_string('setgradeletters','grades');
2694 helpbutton('letter', get_string('gradeletterhelp','grades'), 'grade');
2695 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>';
2696 echo '<form name="grade_letter"><input type="hidden" name="id" value="'.$course->id
.'" />';
2697 echo '<input type="hidden" name="action" value="set_letter_grades" />';
2698 echo '<input type="hidden" name="sesskey" value="'.$USER->sesskey
.'" />';
2700 foreach ($letters as $id=>$items) {
2701 if ($id !='' && !$using_defaults) {
2702 // send the record id so if the user deletes the values we can delete the row.
2703 echo '<input type="hidden" name="id'.$i.'" value="'.$id.'" />';
2705 echo '<tr><td align="center" class="generalboxcontent"><input size="8" type="text" name="letter'.$i.'" value="'.$items->letter
.'" /></td>'."\n";
2706 echo '<td align="center" class="generalboxcontent"><input size="8" type="text" name="grade_low'.$i.'" value="'.$items->grade_low
.'" /></td>'."\n";
2707 echo '<td align="center" class="generalboxcontent"><input size="8" type="text" name="grade_high'.$i.'" value="'.$items->grade_high
.'" /></td></tr>'."\n";
2710 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>';
2711 echo '<tr><td colspan="3" align="center" class="generalboxcontent"><input type="submit" value="'.get_string('savechanges','grades').'" /></td></tr>';
2712 echo '<input type="hidden" name="totalitems" value="'.$i.'" />';
2713 echo '</form><tr><td colspan="3" align="center" class="generalboxcontent">'.get_string('gradeletternote','grades').'</table>';
2716 function grade_set_letter_grades() {
2721 if (!empty($USER->id
)) {
2722 if (!confirm_sesskey()) {
2723 error(get_string('confirmsesskeybad', 'error'));
2727 $totalitems= clean_param($_REQUEST['totalitems'], PARAM_CLEAN
);
2729 for($i=0; $i<=$totalitems; $i++
) {
2730 if (isset($_REQUEST["id$i"])) {
2731 // item submitted was already in database
2732 $letterid = $_REQUEST["id$i"];
2733 $updateletters[$letterid]->letter
= clean_param($_REQUEST["letter$i"], PARAM_CLEAN
);
2734 // grade_low && grade_high don't need cleaning as they are possibly floats (no appropriate clean method) so we check is_numeric
2735 $updateletters[$letterid]->grade_low
= $_REQUEST["grade_low$i"];
2736 $updateletters[$letterid]->grade_high
= $_REQUEST["grade_high$i"];
2737 $updateletters[$letterid]->id
= $letterid;
2741 $newletter->letter
= clean_param($_REQUEST["letter$i"], PARAM_CLEAN
);
2742 $newletter->grade_low
= $_REQUEST["grade_low$i"];
2743 $newletter->grade_high
= $_REQUEST["grade_high$i"];
2744 $newletter->courseid
= $course->id
;
2745 if (is_numeric($newletter->grade_high
) && is_numeric($newletter->grade_low
)) {
2746 insert_record('grade_letter', $newletter);
2749 if ($i < $totalitems) {
2750 if ($newletter->grade_high
!= '' or $newletter->grade_low
!= '') {
2751 echo '<center>'.get_string('lettergradenonnumber','grades').' '.$newletter->letter
.' item number: '.$i.'<br /></center>';
2758 if (isset($updateletters)) {
2759 foreach($updateletters as $id=>$items) {
2760 // see if any of the values are blank... if so delete them
2761 if ($items->letter
== '' ||
$items->grade_low
== '' ||
$items->grade_high
== '') {
2762 delete_records('grade_letter', 'id', $id);
2765 if (is_numeric($items->grade_high
) && is_numeric($items->grade_low
)) {
2766 update_record('grade_letter', $items);
2769 echo '<center><font color="red">'.get_string('errorgradevaluenonnumeric','grades').$letter.'</font></center>';
2776 function grade_download_form($type='both') {
2777 global $course,$USER, $action, $cview;
2778 if ($type != 'both' ||
$type != 'excel' ||
$type != 'text') {
2782 if (isteacher($course->id
)) {
2783 echo '<table align="center"><tr>';
2784 $options['id'] = $course->id
;
2785 $options['sesskey'] = $USER->sesskey
;
2787 if ($type = 'both' ||
$type == 'excel') {
2788 $options['action'] = 'excel';
2789 echo '<td align="center">';
2790 print_single_button("index.php", $options, get_string("downloadexcel"));
2793 if ($type = 'both' ||
$type == 'text') {
2794 $options['action'] = 'text';
2795 echo '<td align="center">';
2796 print_single_button("index.php", $options, get_string("downloadtext"));
2801 $url = 'index.php?id='.$course->id
;
2802 if (!empty($action)) {
2803 $url .= '&action='.$action;
2804 if ($action == 'vcats') {
2805 $url .= '&cview='.$cview;
2808 setup_and_print_groups($course, $course->groupmode
, $url);
2811 echo '</tr></table>';