3 if (!defined('MOODLE_INTERNAL')) {
4 die('Direct access to this script is forbidden.'); /// It must be included from a Moodle page
7 require_once($CFG->dirroot
.'/course/lib.php');
9 define('UNCATEGORISED', 'uncategorised');
11 global $GRADEPREFS, $GRADEPREFSDEFAULTS; // This variables are going to be global... :-/
13 $GRADEPREFS = array('use_advanced', // Only add new preferences to the end of this array!
14 'use_weighted_for_letter', // as the order counts and will affect backward compatibility
24 $GRADEPREFSDEFAULTS = array('use_advanced' => 0,
25 'use_weighted_for_letter' => 0,
26 'display_weighted' => 0,
27 'display_points' => 2,
28 'display_percent' => 1,
29 'display_letters' => 0,
30 'reprint_headers' => 0,
35 //******************************************************************
37 //******************************************************************
39 function grade_get_category_weight($course, $category) {
41 $sql = "SELECT id, weight, drop_x_lowest, bonus_points, hidden, c.id AS cat_id
42 FROM {$CFG->prefix}grade_category c
43 WHERE c.courseid=$course
44 AND c.name='$category'";
45 $temp = get_record_sql($sql);
49 function grade_get_grade_items($course) {
51 $sql = "SELECT i.id, c.name as cname, i.modid, mm.name as modname, i.cminstance, c.hidden, cm.visible, i.sort_order
52 FROM {$CFG->prefix}grade_item i,
53 {$CFG->prefix}grade_category c,
54 {$CFG->prefix}course_modules cm,
55 {$CFG->prefix}modules mm
57 AND i.courseid=c.courseid
58 AND c.courseid=$course
59 AND cm.course=c.courseid
62 AND cm.instance=i.cminstance";
63 $temp = get_records_sql($sql);
67 function grade_get_module_link($course, $cminstance, $modid) {
69 $sql = "SELECT cm.id, 1 FROM {$CFG->prefix}course_modules cm, {$CFG->prefix}modules mm, {$CFG->prefix}grade_item i
70 WHERE i.modid='".$modid."'
72 AND cm.instance = i.cminstance
73 AND i.cminstance=".$cminstance."
74 AND i.courseid=cm.course AND cm.module=mm.id AND i.courseid=$course";
75 $temp = get_record_sql($sql);
79 function grade_get_grade_letter($course, $grade) {
81 $sql = "SELECT id, letter FROM {$CFG->prefix}grade_letter WHERE courseid=$course AND grade_high >= $grade AND grade_low <= $grade";
82 $temp = get_record_sql($sql);
86 function grade_get_exceptions($course) {
88 $sql = "SELECT e.id, e.userid, gi.cminstance, gi.modid, c.name as catname, mm.name as modname
89 FROM {$CFG->prefix}grade_exceptions e,
90 {$CFG->prefix}grade_item gi,
91 {$CFG->prefix}grade_category c,
92 {$CFG->prefix}course_modules cm,
93 {$CFG->prefix}modules mm
94 WHERE e.courseid=$course
95 AND gi.id = e.grade_itemid
96 AND c.id = gi.category
97 AND cm.course=c.courseid
101 $temp = get_records_sql($sql);
105 function grade_get_exceptions_user($course, $userid) {
107 $sql = "SELECT e.id, e.userid, gi.cminstance, gi.modid, c.name as catname, mm.name as modname
108 FROM {$CFG->prefix}grade_exceptions e,
109 {$CFG->prefix}grade_item gi,
110 {$CFG->prefix}grade_category c,
111 {$CFG->prefix}course_modules cm,
112 {$CFG->prefix}modules mm
113 WHERE e.courseid=$course
115 AND gi.id = e.grade_itemid
116 AND c.id = gi.category
117 AND cm.course=c.courseid
121 $temp = get_records_sql($sql);
124 function grade_letters_set($course) {
126 $sql = "SELECT * FROM {$CFG->prefix}grade_letter WHERE courseid=$course";
127 $letters_set = get_records_sql($sql);
136 function grade_get_users_by_group($course, $group) {
138 $sql = "SELECT userid FROM {$CFG->prefix}groups_members WHERE courseid=$course AND groupid = $group";
139 $members = get_records_sql($sql);
141 foreach($members as $member) {
142 // FIX ME: there is no $userid defined!!! - from where is this function used anyway??
143 $group->$userid = true;
152 //******************************************************************
154 //******************************************************************
156 function grade_get_formatted_grades() {
160 $i = 2; // index to differentiate activities with the same name MDL-6876
161 $grades = grade_get_grades();
162 if (isset($grades)) {
163 // iterate through all students
164 foreach($grades as $cur_category=>$grade_category) {
165 // $cur_category holds the value of the current category name
166 // $grade_category holds an array of all the mod types that are in this category
167 if (isset($grade_category)) {
168 foreach($grade_category as $cur_mod=>$mod_category) {
169 // $cur_mod is the id of the current moodle module type
170 // $mod_category holds the grades for $cur_mod (current mod type)
171 $module_info = get_record('modules', 'id', $cur_mod);
172 $cur_modname = $module_info->name
;
173 if (isset($mod_category)) {
174 foreach($mod_category as $cur_cminstance=>$students_grade) {
175 // $cur_cminstance is the course module instance for the cur_mod
176 $instance = get_record($cur_modname, 'id',$cur_cminstance, 'course',$course->id
);
177 // it's necessary to check if the name is blank because some mods don't clean up the grades when the instance is deleted
178 // this is a bug. as it is plausible that some item could get created and have old data from a previous mod laying around
179 if ($instance->name
!= '') {
180 // 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
181 if (isset($all_categories["$cur_category"]["$instance->name"])) {
182 $instance->name
= $instance->name
.' #'.$i++
;
185 if (isset($students_grade->grades
) && $students_grade->grades
!= '') {
186 foreach($students_grade->grades
as $student=>$grade) {
187 // add an entry for any student that has a grade
188 $grades_by_student["$student"]["$cur_category"]["$instance->name"]['grade'] = $grade;
189 $grades_by_student["$student"]["$cur_category"]["$instance->name"]['sort_order'] = $students_grade->sort_order
;
191 if (!isset($grades_by_student["$student"]["$cur_category"]['stats'])) {
192 $grades_by_student["$student"]["$cur_category"]['stats'] = array();
195 if (!isset($grades_by_student["$student"]["$cur_category"]['stats']['points'])) {
196 $grades_by_student["$student"]["$cur_category"]['stats']['points'] = $grade;
199 $grades_by_student["$student"]["$cur_category"]['stats']['points'] = $grades_by_student["$student"]["$cur_category"]['stats']['points'] +
$grade;
202 // This next block just creates a comma seperated list of all grades for the category
203 if (isset($grades_by_student["$student"]["$cur_category"]['stats']['allgrades'])) {
204 $grades_by_student["$student"]["$cur_category"]['stats']['allgrades'] .= ','.$grade;
207 $grades_by_student["$student"]["$cur_category"]['stats']['allgrades'] = $grade;
214 // set up a list of all categories and assignments (adjusting things for extra credit where necessary)
215 $all_categories["$cur_category"]["$instance->name"]['hidden'] = $students_grade->hidden
;
216 $all_categories["$cur_category"]["$instance->name"]['sort_order'] = $students_grade->sort_order
;
218 $all_categories["$cur_category"]["$instance->name"]['extra_credit'] = $students_grade->extra_credit
;
220 if ($all_categories["$cur_category"]["$instance->name"]['extra_credit'] != 1) {
221 $all_categories["$cur_category"]["$instance->name"]['maxgrade'] = $students_grade->maxgrade
;
224 $all_categories["$cur_category"]["$instance->name"]['maxgrade'] = 0;
226 $all_categories["$cur_category"]["$instance->name"]['scale_grade'] = $students_grade->scale_grade
;
227 if ($students_grade->scale_grade
!= 0) {
228 $all_categories["$cur_category"]["$instance->name"]['scaled_max'] = round($all_categories["$cur_category"]["$instance->name"]['maxgrade']/$students_grade->scale_grade
);
231 // avoids divide by zero... scale_grade shouldn't be set to 0 anyway
232 $all_categories["$cur_category"]["$instance->name"]['scaled_max'] = $all_categories["$cur_category"]["$instance->name"]['maxgrade'];
233 $all_categories["$cur_category"]["$instance->name"]['scale_grade'] = 1.0;
235 if (! isset($all_categories["$cur_category"]['stats']) ) {
236 $all_categories["$cur_category"]['stats'] = array();
238 $all_categories["$cur_category"]["$instance->name"]['grade_against'] = $all_categories["$cur_category"]["$instance->name"]['scaled_max'];
239 if (!isset($all_categories["$cur_category"]['stats']['weight'])) {
240 $weight = grade_get_category_weight($course->id
, $cur_category);
241 $all_categories["$cur_category"]['stats']['weight'] = $weight->weight
;
244 $all_categories["$cur_category"]["$instance->name"]['cminstance'] = $cur_cminstance;
245 $all_categories["$cur_category"]["$instance->name"]['modid'] = $cur_mod;
246 $modname = get_record('modules','id',$cur_mod);
247 $all_categories["$cur_category"]["$instance->name"]['modname'] = $modname->name
;
249 // get bonus points and drop the x lowest
250 $drop = get_record('grade_category', 'courseid', $course->id
, 'name', $cur_category);
251 $all_categories["$cur_category"]['stats']['drop'] = $drop->drop_x_lowest
;
252 $all_categories["$cur_category"]['stats']['bonus_points'] = $drop->bonus_points
;
260 // set the students name under student_data (this has the added bonus of creating an entry for students who do not have any grades)
261 $students = get_course_students($course->id
);
262 if (isset($students) && $students) {
263 foreach ($students as $userid => $student) {
264 $grades_by_student["$userid"]['student_data']['firstname'] = $student->firstname
;
265 $grades_by_student["$userid"]['student_data']['lastname'] = $student->lastname
;
266 $grades_by_student["$userid"]['student_data']['email'] = $student->email
;
267 if (isset($student->location
)) {
268 $grades_by_student["$userid"]['student_data']['location'] = $student->location
;
270 $grades_by_student["$userid"]['student_data']['department'] = $student->department
;
271 $grades_by_student["$userid"]['student_data']['idnumber'] = $student->idnumber
;
275 // unset any item that has a "" for a name at this point this inludes instructors who have grades or any student formerly enrolled.
276 if (isset($grades_by_student)) {
277 foreach ($grades_by_student as $student => $assignments) {
278 if (!isset($grades_by_student["$student"]['student_data']['firstname']) && !isset($grades_by_student["$student"]['student_data']['lastname'])) {
279 unset($grades_by_student["$student"]);
285 // set the totalpoints for each category taking into account drop_x_lowest
286 // also set the number of grade items for the category to make calculating grades for students who have not taken anything easier
287 foreach($all_categories as $category => $assignments) {
289 $all_categories["$category"]['stats']['totalpoints'] = 0;
290 $all_categories["$category"]['stats']['grade_items'] = 0;
291 if (isset($assignments)) {
292 foreach($assignments as $assignment=>$grade) {
293 if ($assignment != 'stats') {
294 if ($dropcount < $all_categories["$category"]['stats']['drop']) {
295 // skip a grade in the total
299 // make sure the current assignment is not extra credit and then add it to the totalpoints
300 if ($all_categories["$category"][$assignment]['extra_credit'] != 1) {
301 $all_categories["$category"]['stats']['totalpoints'] = $all_categories["$category"]['stats']['totalpoints'] +
$assignments["$assignment"]['grade_against'];
302 $all_categories["$category"]['stats']['grade_items'] = $all_categories["$category"]['stats']['grade_items'] +
1;
311 if (isset($_REQUEST['group'])) {
312 $group = clean_param($_REQUEST['group'], PARAM_INT
);
314 // if the user has selected a group to view by get the group members
315 if (isset($group) && $group != 0) {
316 $groupmembers = get_group_users($group);
319 // this next block catches any students who do not have a grade for any item in a particular category
320 foreach($all_categories as $category => $main_category) {
321 // make sure each student has an entry for each category
322 if (isset($grades_by_student)) {
323 foreach($grades_by_student as $student=>$categories) {
324 if ( (isset($groupmembers) && isset($groupmembers[$student])) ||
!isset($groupmembers)) {
326 $grades_by_student["$student"]["$category"]['stats']['totalpoints'] = $main_category['stats']['totalpoints'];
327 $grades_by_student["$student"]["$category"]['stats']['weight'] = $main_category['stats']['weight'];
328 $grades_by_student["$student"]["$category"]['stats']['grade_items'] = $main_category['stats']['grade_items'];
330 foreach($main_category as $assignment => $items) {
331 if ($assignment != 'stats') {
332 if(!isset($grades_by_student["$student"]["$category"]["$assignment"]['grade'])) {
333 if (isset($grades_by_student["$student"]["$category"]['stats']['allgrades'])) {
334 $grades_by_student["$student"]["$category"]['stats']['allgrades'] .= ',0';
336 $grades_by_student["$student"]["$category"]['stats']['allgrades'] = '0';
342 if (!isset($grades_by_student["$student"]["$category"]['stats']['points'])) {
343 $grades_by_student["$student"]["$category"]['stats']['points'] = '-';
348 // points are set... see if the current category is using drop the x lowest and do so
349 // also drop exceptions first, so then this grades(s) won't be recoqnized as the x lowest
350 // Get exception scores and assign them in the array
351 if ($main_category['stats']['drop'] != 0) {
352 $exceptions = grade_get_exceptions_user($course->id
, $student);
353 if (isset($exceptions) && $exceptions) {
354 foreach($exceptions as $exception) {
355 if (isset($grades_by_student["$exception->userid"])) {
356 if ($grades_by_student["$exception->userid"]["$exception->catname"]) {
357 $assgn = get_record($exception->modname
, 'id', $exception->cminstance
, 'course', $course->id
);
358 $grade = $grades_by_student["$exception->userid"]["$exception->catname"]["$assgn->name"]['grade'];
360 if (!isset($grades_by_student["$exception->userid"]["$exception->catname"]['stats']['exceptions'])) {
361 $grades_by_student["$exception->userid"]["$exception->catname"]['stats']['exceptions'] = $grade;
363 elseif (isset($grades_by_student["$exception->userid"]["$exception->catname"]['stats']['exceptions'])) {
364 $grades_by_student["$exception->userid"]["$exception->catname"]['stats']['exceptions'] .= ','. $grade;
371 if (isset($grades_by_student["$student"]["$category"]['stats']['exceptions'])) {
372 $grades_by_student["$student"]["$category"]['stats']['allgrades'] = grade_drop_exceptions($grades_by_student["$student"]["$category"]['stats']['allgrades'], $grades_by_student["$student"]["$category"]['stats']['exceptions']);
375 $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']);
376 if ($grades_by_student["$student"]["$category"]['stats']['points'] != '-') {
378 $count_grades = explode(',',$grades_by_student["$student"]["$category"]['stats']['allgrades']);
379 foreach($count_grades as $grade) {
380 $cat_points = $cat_points +
$grade;
382 $grades_by_student["$student"]["$category"]['stats']['points'] = $cat_points;
387 // add any bonus points for the category
388 if ($all_categories["$category"]['stats']['bonus_points'] != 0) {
389 $grades_by_student["$student"]["$category"]['stats']['points'] = $grades_by_student["$student"]["$category"]['stats']['points'] +
$all_categories["$category"]['stats']['bonus_points'];
392 foreach($main_category as $assignment => $items) {
393 if ($assignment != 'stats') {
394 if(!isset($grades_by_student["$student"]["$category"]["$assignment"]['maxgrade'])) {
395 $grades_by_student["$student"]["$category"]["$assignment"]['maxgrade'] = $all_categories["$category"]["$assignment"]['grade_against'];
397 if(!isset($grades_by_student["$student"]["$category"]["$assignment"]['grade'])) {
398 $grades_by_student["$student"]["$category"]["$assignment"]['grade'] = '-';
399 $grades_by_student["$student"]["$category"]["$assignment"]['sort_order'] = $all_categories["$category"]["$assignment"]['sort_order'];
403 } // end groupmember if
405 // unset grade since they are not in the selected group.
406 unset($grades_by_student["$student"]);
411 // set the total coursepoints
412 $all_categories['stats']['weight'] = 0;
413 $all_categories['stats']['totalpoints'] = 0;
414 foreach($all_categories as $category => $info) {
415 if ($category != 'stats') {
416 $all_categories['stats']['weight'] = $all_categories['stats']['weight'] +
$all_categories["$category"]['stats']['weight'];
417 $all_categories['stats']['totalpoints'] = $all_categories['stats']['totalpoints'] +
$all_categories["$category"]['stats']['totalpoints'];
421 // set each individuals total points by category so we can then exclude some grades if set to use exceptions
422 if (isset($grades_by_student)) {
423 foreach($grades_by_student as $student => $categories) {
424 foreach($all_categories as $category => $assignments) {
425 if ($category != 'stats') {
426 $grades_by_student["$student"]["$category"]['stats']['totalpoints'] = $all_categories["$category"]['stats']['totalpoints'];
429 $grades_by_student["$student"]['student_data']['totalpoints'] = $all_categories['stats']['totalpoints'];
433 // take into account any excluded grade_items
434 $strexcluded = get_string('excluded', 'grades');
435 $exceptions = grade_get_exceptions($course->id
);
436 if (isset($exceptions) && $exceptions) {
437 foreach($exceptions as $exception) {
438 if (isset($grades_by_student["$exception->userid"])) {
439 if ($grades_by_student["$exception->userid"]["$exception->catname"]) {
440 $assgn = get_record($exception->modname
, 'id', $exception->cminstance
, 'course', $course->id
);
441 $grades_by_student["$exception->userid"]['student_data']['totalpoints'] = $grades_by_student["$exception->userid"]['student_data']['totalpoints'] - $all_categories["$exception->catname"]["$assgn->name"]['maxgrade'];
442 //total point should not be smaller than grade against
443 if ($grades_by_student["$exception->userid"]["$exception->catname"]['stats']['totalpoints'] - $all_categories["$exception->catname"]["$assgn->name"]['grade_against'] != 0 ) {
444 $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'];
446 $grades_by_student["$exception->userid"]["$exception->catname"]['stats']['grade_items'] = $grades_by_student["$exception->userid"]["$exception->catname"]['stats']['grade_items'] - 1;
447 if ($grades_by_student["$exception->userid"]["$exception->catname"]['stats']['grade_items'] < 0) {
448 $grades_by_student["$exception->userid"]["$exception->catname"]['stats']['grade_items'] = 0;
450 if ($all_categories["$exception->catname"]['stats']['drop'] == 0) {
451 $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'];
453 $grades_by_student["$exception->userid"]["$exception->catname"]["$assgn->name"]['maxgrade'] = $strexcluded;
454 $grades_by_student["$exception->userid"]["$exception->catname"]["$assgn->name"]['grade'] = $strexcluded;
455 // see if they are excluded entirely from a category
456 if ($grades_by_student["$exception->userid"]["$exception->catname"]['stats']['totalpoints'] == 0) {
457 $grades_by_student["$exception->userid"]["$exception->catname"]['stats']['totalpoints'] = $strexcluded;
458 $grades_by_student["$exception->userid"]["$exception->catname"]['stats']['percent'] = $strexcluded;
459 $grades_by_student["$exception->userid"]["$exception->catname"]['stats']['points'] = $strexcluded;
460 $grades_by_student["$exception->userid"]["$exception->catname"]['stats']['weight'] = $strexcluded;
461 $grades_by_student["$exception->userid"]["$exception->catname"]['stats']['weighted'] = $strexcluded;
466 // 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
471 if (isset($grades_by_student)) {
472 foreach($grades_by_student as $student => $categories) {
473 $grades_by_student["$student"]['student_data']['points'] = '-';
474 $grades_by_student["$student"]['student_data']['totalpoints'] = 0;
475 $grades_by_student["$student"]['student_data']['weight'] = 0;
476 $grades_by_student["$student"]['student_data']['weighted'] = 0;
477 foreach($categories as $category => $assignments) {
478 if ($category != 'student_data') {
479 // set the student's total points earned
480 if ($grades_by_student["$student"]["$category"]['stats']['points'] != $strexcluded) {
481 if ($grades_by_student["$student"]["$category"]['stats']['points'] != '-') {
482 $grades_by_student["$student"]['student_data']['points'] = $grades_by_student["$student"]['student_data']['points'] +
$grades_by_student["$student"]["$category"]['stats']['points'];
484 $grades_by_student["$student"]['student_data']['totalpoints'] = $grades_by_student["$student"]['student_data']['totalpoints'] +
$grades_by_student["$student"]["$category"]['stats']['totalpoints'];
487 // set percents and weights for each assignment
488 foreach($assignments as $assignment => $info) {
489 if ($assignment != 'stats') {
490 if ($grades_by_student["$student"]["$category"]["$assignment"]['grade'] != $strexcluded) {
491 if ($grades_by_student["$student"]["$category"]["$assignment"]['maxgrade'] != 0) {
492 $grades_by_student["$student"]["$category"]["$assignment"]['percent'] = round($grades_by_student["$student"]["$category"]["$assignment"]['grade']/$grades_by_student["$student"]["$category"]["$assignment"]['maxgrade']*100,2);
495 $grades_by_student["$student"]["$category"]["$assignment"]['percent'] = 0;
497 if ($grades_by_student["$student"]["$category"]['stats']['totalpoints'] != 0) {
498 $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);
501 $grades_by_student["$student"]["$category"]["$assignment"]['weight'] = 0.00;
503 if ($grades_by_student["$student"]["$category"]["$assignment"]['weight'] != 0) {
504 $grades_by_student["$student"]["$category"]["$assignment"]['weighted'] = round($grades_by_student["$student"]["$category"]["$assignment"]['percent']*$grades_by_student["$student"]["$category"]["$assignment"]['weight']/100,2);
507 // should only be here if this is extra credit
508 $grades_by_student["$student"]["$category"]["$assignment"]['weighted'] = 0.00;
512 $grades_by_student["$student"]["$category"]["$assignment"]['percent'] = $strexcluded;
513 $grades_by_student["$student"]["$category"]["$assignment"]['weight'] = $strexcluded;
514 $grades_by_student["$student"]["$category"]["$assignment"]['weighted'] = $strexcluded;
518 // set the percent and weight per category
519 if ($grades_by_student["$student"]["$category"]['stats']['totalpoints'] != 0 ) {
520 $grades_by_student["$student"]["$category"]['stats']['percent'] = round($grades_by_student["$student"]["$category"]['stats']['points']/$grades_by_student["$student"]["$category"]['stats']['totalpoints']*100,2);
521 $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);
524 if ($grades_by_student["$student"]["$category"]['stats']['totalpoints'] != $strexcluded) {
525 $grades_by_student["$student"]["$category"]['stats']['percent'] = 0.00;
526 $grades_by_student["$student"]["$category"]['stats']['weighted'] = 0.00;
530 // set students overall weight (this is what percent they will be graded against)
531 if ($grades_by_student["$student"]["$category"]['stats']['weight'] != $strexcluded) {
532 $grades_by_student["$student"]['student_data']['weight'] = $grades_by_student["$student"]['student_data']['weight'] +
$grades_by_student["$student"]["$category"]['stats']['weight'];
535 // 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
536 // be excluded from a whole category.
537 if ($all_categories["$category"]['stats']['totalpoints'] != 0) {
538 $grades_by_student["$student"]['student_data']['weighted'] = $grades_by_student["$student"]['student_data']['weighted'] +
$grades_by_student["$student"]["$category"]['stats']['weighted'];
545 // set the percent and weight overall
546 if ($grades_by_student["$student"]['student_data']['totalpoints'] != 0 && $grades_by_student["$student"]['student_data']['totalpoints'] != $strexcluded) {
547 $grades_by_student["$student"]['student_data']['percent'] = round($grades_by_student["$student"]['student_data']['points']/$grades_by_student["$student"]['student_data']['totalpoints']*100,2);
548 if ($grades_by_student["$student"]['student_data']['weight'] != 0) {
549 $grades_by_student["$student"]['student_data']['weighted'] = round($grades_by_student["$student"]['student_data']['weighted']/$grades_by_student["$student"]['student_data']['weight']*100,2);
552 $grades_by_student["$student"]['student_data']['weighted'] = 0.00;
555 else if ($grades_by_student["$student"]['student_data']['totalpoints'] == 0) {
556 $grades_by_student["$student"]['student_data']['percent'] = 0.00;
562 if (isset($grades_by_student)) {
563 $sort = optional_param('sort','default');
566 case 'highgrade_category':
567 uasort($grades_by_student, 'grade_sort_by_highgrade_category');
569 case 'highgrade_category_asc':
570 uasort($grades_by_student, 'grade_sort_by_highgrade_category_asc');
574 if ($preferences->use_weighted_for_letter
== 1) {
575 uasort($grades_by_student, 'grade_sort_by_weighted');
578 uasort($grades_by_student, 'grade_sort_by_percent');
583 uasort($grades_by_student, 'grade_sort_by_points');
586 uasort($grades_by_student, 'grade_sort_by_points_asc');
589 uasort($grades_by_student, 'grade_sort_by_weighted');
592 uasort($grades_by_student, 'grade_sort_by_weighted_asc');
595 uasort($grades_by_student, 'grade_sort_by_percent');
598 uasort($grades_by_student, 'grade_sort_by_percent_asc');
600 case 'highgrade_asc':
602 if ($preferences->use_weighted_for_letter
== 1) {
603 uasort($grades_by_student, 'grade_sort_by_weighted_asc');
606 uasort($grades_by_student, 'grade_sort_by_percent_asc');
611 uasort($grades_by_student, 'grade_sort_by_firstname');
614 uasort($grades_by_student, 'grade_sort_by_lastname');
618 $grades_by_student = 0;
620 $retval = array($grades_by_student, $all_categories);
623 $retval = array(0,0);
624 // echo "<center><font color=red>Could not find any graded items for this course.</font></center>";
629 function grade_drop_exceptions($grades, $grades_exceptions) {
630 $grade_array = explode(',',$grades);
631 $grade_exception_array = explode(',',$grades_exceptions);
632 $ret_grades = Array();
633 foreach ($grade_array as $key => $val) {
634 $posb = array_search($val,$grade_exception_array);
635 if (is_integer($posb)) {
636 unset($grade_exception_array[$posb]);
639 $ret_grades[] = $val;
642 $grades = implode(',', $ret_grades);
646 function grade_drop_lowest($grades, $drop, $total) {
647 // drops the lowest $drop numbers from the comma seperated $grades making sure that if $grades has
648 // fewer items than $total that we don't drop too many
649 $grade_array = explode(',',$grades);
650 if (count($grade_array) == 1) {
651 $grades = implode('', $grade_array);
653 else if ($drop > 0 AND (count($grade_array) > $drop)) {
656 for($i=0; $i < (count($grade_array) - $drop); $i++
) {
657 $ret_grades["$i"] = $grade_array["$i"];
659 if (isset($ret_grades)) {
660 $grades = implode(',',$ret_grades);
669 function grade_get_grades() {
672 $mods = grade_get_grade_items($course->id
);
673 $preferences = grade_get_preferences($course->id
);
676 foreach ($mods as $mod) {
677 // hidden is a gradebook setting for an assignment and visible is a course_module setting
678 if (($mod->hidden
!= 1 && $mod->visible
==1) or (isteacher($course->id
) && $preferences->show_hidden
==1)) {
679 $libfile = "$CFG->dirroot/mod/$mod->modname/lib.php";
680 if (file_exists($libfile)) {
681 require_once($libfile);
682 $gradefunction = $mod->modname
."_grades";
683 if ($grades["$mod->cname"]["$mod->modid"]["$mod->cminstance"] = $gradefunction($mod->cminstance
)) {
684 // added grades for particular mod
685 // now get the grade_item modifiers ie. scale_grade and extra credit
686 $scale_grade = get_record('grade_item', 'courseid', $course->id
, 'cminstance', $mod->cminstance
, 'modid', $mod->modid
);
688 if (isset($scale_grade)) {
689 $grades["$mod->cname"]["$mod->modid"]["$mod->cminstance"]->scale_grade
= $scale_grade->scale_grade
;
690 $grades["$mod->cname"]["$mod->modid"]["$mod->cminstance"]->extra_credit
= $scale_grade->extra_credit
;
693 $grades["$mod->cname"]["$mod->modid"]["$mod->cminstance"]->scale_grade
= 1.00;
694 $grades["$mod->cname"]["$mod->modid"]["$mod->cminstance"]->extra_credit
= 0;
697 if ($mod->hidden
!= 1 && $mod->visible
==1) {
698 $grades["$mod->cname"]["$mod->modid"]["$mod->cminstance"]->hidden
= 0;
701 $grades["$mod->cname"]["$mod->modid"]["$mod->cminstance"]->hidden
= 1;
704 $grades["$mod->cname"]["$mod->modid"]["$mod->cminstance"]->sort_order
= $scale_grade->sort_order
;
706 // 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
707 // 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.
708 // this happens when grading is set to a non-numeric for a forum ie. uses "seperate and connected ways of knowing"
709 if ($grades["$mod->cname"]["$mod->modid"]["$mod->cminstance"]->maxgrade
== '')
711 $grades["$mod->cname"]["$mod->modid"]["$mod->cminstance"]->maxgrade
= 100;
712 //unset($grades["$mod->cname"]["$mod->modid"]["$mod->cminstance"]);
716 // delete this item from the grade_item table since it was deleted through the mod interface
717 delete_records('grade_item', 'modid', $mods->modid
, 'courseid', $course->id
);
718 delete_records('grade_exceptions', 'grade_itemid', $mod->id
, 'courseid', $course->id
);
722 //echo "<center><font color=red>Could not find lib file for $mod->modid</font></center>";
728 // Do something here for no grades
729 //echo "<center><font color=red>No grades returned. It appears that there are no items with grades for this course.</font></center>";
731 if (isset($grades)) {
739 function grade_set_uncategorized() {
740 // this function checks to see if any mods have not been assigned a category and sets them to uncategorized.
743 $uncat = UNCATEGORISED
;
745 $uncat_id = get_record('grade_category', 'courseid', $course->id
, 'name', $uncat);
748 // insert the uncategorized category
750 $temp->courseid
=$course->id
;
751 $temp->drop_x_lowest
= 0;
752 $temp->bonus_points
= 0;
754 $temp->weight
= 100.00;
756 insert_record('grade_category', $temp);
757 $uncat_id = get_record('grade_category', 'courseid', $course->id
, 'name', $uncat);
759 error(get_string('errornocategorizedid','grades'));
765 /// Collect modules data
766 get_all_mods($course->id
, $mods, $modnames, $modnamesplural, $modnamesused);
769 // this will let us establish the order for gradebook item display
772 /// Search through all the modules, pulling out grade data
773 $sections = get_all_sections($course->id
); // Sort everything the same as the course
774 for ($i=0; $i<=$course->numsections
; $i++
) {
775 if (isset($sections["$i"])) { // should always be true
776 $section = $sections["$i"];
777 if ($section->sequence
) {
778 $sectionmods = explode(",", $section->sequence
);
779 foreach ($sectionmods as $sectionmod) {
780 if (isset($mods["$sectionmod"])) {
781 $mod = $mods["$sectionmod"];
782 $instance = get_record("$mod->modname", "id", "$mod->instance");
783 $libfile = "$CFG->dirroot/mod/$mod->modname/lib.php";
784 if (file_exists($libfile)) {
785 require_once($libfile);
786 $gradefunction = $mod->modname
."_grades";
787 if (function_exists($gradefunction)) { // Skip modules without grade function
788 if ($modgrades = $gradefunction($mod->instance
)) {
790 //modgrades contains student information with associated grade
791 //echo "<b>modname: $mod->modname id: $mod->id course: $mod->course</b><br>";
792 // get instance name from db.
793 $instance = get_record($mod->modname
, 'id', $mod->instance
);
794 // see if the item is already in the category table and if it is call category select with the id so it is selected
795 get_record('modules', 'name', $mod->modname
);
796 $item = get_record('grade_item', 'courseid', $course->id
, 'modid', $mod->module
, 'cminstance', $mod->instance
);
798 // set the item to uncategorized in grade_item
799 $item->courseid
= $course->id
;
800 $item->category
= $uncat_id->id
;
801 $item->modid
= $mod->module
;
802 $item->cminstance
= $mod->instance
;
803 $item->id
= insert_record('grade_item', $item);
805 else if ($item->category
== 0) {
806 // this catches any errors where they may have some wierd category set
807 set_field('grade_item', 'category', $uncat_id->id
, 'id', $item->id
);
809 set_field('grade_item', 'sort_order', $sort, 'id', $item->id
);
821 // sorting functions for grades
822 function grade_sort_by_lastname($x,$y)
824 //$grades_by_student["$student->userid"]['student_data']['firstname'] = $student->firstname;
825 //$grades_by_student["$student->userid"]['student_data']['lastname'] = $student->lastname;
826 if (strnatcasecmp($x['student_data']['lastname'],$y['student_data']['lastname']) == 0) {
827 return strnatcasecmp($x['student_data']['firstname'],$y['student_data']['firstname']);
830 return strnatcasecmp($x['student_data']['lastname'],$y['student_data']['lastname']);
834 function grade_sort_by_firstname($x,$y)
836 //$grades_by_student["$student->userid"]['student_data']['firstname'] = $student->firstname;
837 //$grades_by_student["$student->userid"]['student_data']['lastname'] = $student->lastname;
838 if (strnatcasecmp($x['student_data']['firstname'],$y['student_data']['firstname']) == 0) {
839 return strnatcasecmp($x['student_data']['lastname'],$y['student_data']['lastname']);
842 return strnatcasecmp($x['student_data']['firstname'],$y['student_data']['firstname']);
846 function grade_sort_by_points($x,$y) {
847 if ($x['student_data']['points'] == $y['student_data']['points']) {
848 return grade_sort_by_lastname($x,$y);
851 if ($x['student_data']['points'] > $y['student_data']['points'])
858 function grade_sort_by_points_asc($x,$y) {
859 if ($x['student_data']['points'] == $y['student_data']['points']) {
860 return grade_sort_by_lastname($x,$y);
863 if ($x['student_data']['points'] < $y['student_data']['points'])
870 function grade_sort_by_weighted($x,$y) {
871 if ($x['student_data']['weighted'] == $y['student_data']['weighted']) {
872 return grade_sort_by_lastname($x,$y);
875 if ($x['student_data']['weighted'] > $y['student_data']['weighted'])
882 function grade_sort_by_percent($x,$y) {
883 if ($x['student_data']['percent'] == $y['student_data']['percent']) {
884 return grade_sort_by_lastname($x,$y);
887 if ($x['student_data']['percent'] > $y['student_data']['percent'])
894 function grade_sort_by_percent_asc($x,$y) {
895 if ($x['student_data']['percent'] == $y['student_data']['percent']) {
896 return grade_sort_by_lastname($x,$y);
899 if ($x['student_data']['percent'] < $y['student_data']['percent'])
906 function grade_sort_by_weighted_asc($x,$y) {
907 if ($x['student_data']['weighted'] == $y['student_data']['weighted']) {
908 return grade_sort_by_lastname($x,$y);
911 if ($x['student_data']['weighted'] < $y['student_data']['weighted'])
918 function grade_sort_by_highgrade_category($x,$y) {
922 $cview = optional_param('cview');
925 if ($x["$cview"]['stats']['points'] == $y["$cview"]['stats']['points']) {
926 return grade_sort_by_lastname($x,$y);
929 return ($y["$cview"]['stats']['points'] - $x["$cview"]['stats']['points']);
933 function grade_sort_by_highgrade_category_asc($x,$y) {
937 $cview = optional_param('cview');
939 if ($x["$cview"]['stats']['points'] == $y["$cview"]['stats']['points']) {
940 return grade_sort_by_lastname($x,$y);
943 return ($x["$cview"]['stats']['points'] - $y["$cview"]['stats']['points']);
948 function grade_set_preference($courseid, $name, $value) {
951 if (false !== ($key = array_search($name, $GRADEPREFS))) {
952 if ($record = get_record('grade_preferences', 'courseid', $courseid, 'preference', $key)) {
953 $record->value
= $value;
954 update_record('grade_preferences', $record);
955 } else { // Make a new one
956 $record->preference
= $key;
957 $record->courseid
= $courseid;
958 $record->value
= $value;
959 insert_record('grade_preferences', $record);
964 function grade_get_preference($courseid, $name) {
965 global $GRADEPREFS, $GRADEPREFSDEFAULTS;
967 if (false !== ($key = array_search($name, $GRADEPREFS))) {
968 if (!($record = get_record('grade_preferences', 'courseid', $courseid, 'preference', $key))) {
970 $record->preference
= $key;
971 $record->courseid
= $courseid;
972 $record->value
= $GRADEPREFSDEFAULTS[$name];
973 insert_record('grade_preferences', $record);
975 return $record->value
;
980 function grade_get_preferences($courseid) {
982 global $GRADEPREFS, $GRADEPREFSDEFAULTS;
986 // Get the preferences for the course.
987 if ($rawprefs = get_records('grade_preferences', 'courseid', $courseid)) {
988 foreach ($rawprefs as $pref) {
989 if (isset($GRADEPREFS[$pref->preference
])) { // Valid pref
990 $name = $GRADEPREFS[$pref->preference
];
991 $preferences->$name = $pref->value
;
996 // Check for any missing ones and create them from defaults
997 // We don't save them in the database so we save space
998 foreach ($GRADEPREFS as $number => $name) {
999 if (!isset($preferences->$name)) {
1000 $preferences->$name = $GRADEPREFSDEFAULTS[$name];
1004 // Construct some other ones about which fields are shown
1006 $isteacher = isteacher($courseid);
1008 $preferences->show_weighted
= (($preferences->display_weighted
> 0 && $isteacher) ||
1009 ($preferences->display_weighted
> 1 && !$isteacher));
1011 $preferences->show_points
= (($preferences->display_points
> 0 && $isteacher) ||
1012 ($preferences->display_points
> 1 && !$isteacher));
1014 $preferences->show_percent
= (($preferences->display_percent
> 0 && $isteacher) ||
1015 ($preferences->display_percent
> 1 && !$isteacher));
1017 $preferences->show_letters
= (($preferences->display_letters
> 0 && $isteacher) ||
1018 ($preferences->display_letters
> 1 && !$isteacher));
1020 return $preferences;
1024 function grade_set_preferences($course, $newprefs) {
1026 if (!isset($newprefs->use_advanced
) or ($newprefs->use_advanced
== 1)) {
1027 foreach ($newprefs as $name => $value) { /// Just save them all
1028 grade_set_preference($course->id
, $name, $value);
1033 /// We don't need advanced features, and we need to unset all extra features
1034 /// So they don't affect grades (This approach should be revisited because it resets everything!!)
1036 grade_set_preference($course->id
, 'use_advanced', 0);
1037 grade_set_preference($course->id
, 'use_weighted_for_letter', 0);
1038 grade_set_preference($course->id
, 'display_weighted', 0);
1039 grade_set_preference($course->id
, 'display_points', 2);
1040 grade_set_preference($course->id
, 'display_percent', 0);
1041 grade_set_preference($course->id
, 'display_letters', 0);
1043 /// Lose all exceptions
1044 delete_records('grade_exceptions', 'courseid', $course->id
);
1046 if (!$uncat = get_record('grade_category', 'courseid', $course->id
, 'name', UNCATEGORISED
)) {
1047 /// Make a category for uncategorised stuff
1048 $uncat->name
=UNCATEGORISED
;
1049 $uncat->courseid
=$course->id
;
1050 if (!$uncat->id
= insert_record('grade_category', $uncat)) {
1051 error(get_string('errornocategorizedid','grades'));
1055 set_field('grade_item', 'category', $uncat->id
, 'courseid', $course->id
);
1056 set_field('grade_item', 'scale_grade', 1.00, 'courseid', $course->id
);
1057 set_field('grade_item', 'extra_credit', 0, 'courseid', $course->id
);
1059 set_field('grade_category', 'weight', 100.0, 'courseid', $course->id
, 'id', $uncat->id
);
1060 set_field('grade_category', 'bonus_points', '0', 'courseid', $course->id
);
1064 function grade_preferences_menu($action, $course, $group=0) {
1066 if (!isteacher($course->id
)) {
1070 // remap some actions to simplify later code
1073 case 'set_grade_preferences':
1074 $curraction = 'prefs';
1080 case 'insert_category':
1081 case 'assign_categories':
1082 case 'delete_category':
1083 $curraction = 'cats';
1085 case 'set_grade_weights':
1087 $curraction = 'weights';
1090 case 'set_letter_grades':
1091 $curraction = 'letters';
1093 case 'view_student_grades':
1094 case 'view_student_category_grades':
1096 $curraction = 'grades';
1099 $curraction = 'excepts';
1103 $curraction = 'grades';
1106 $tabs = $row = array();
1107 $row[] = new tabobject('grades', 'index.php?id='.$course->id
,
1108 get_string('viewgrades', 'grades'));
1109 $row[] = new tabobject('prefs', 'index.php?id='.$course->id
.'&action=prefs',
1110 get_string('setpreferences', 'grades'));
1111 // only show the extra options if advanced is turned on, they don't do anything otherwise
1112 if (grade_get_preference($course->id
, 'use_advanced') == 1) {
1113 $row[] = new tabobject('cats', 'index.php?id='.$course->id
.'&action=cats',
1114 get_string('setcategories', 'grades'));
1115 $row[] = new tabobject('weights', 'index.php?id='.$course->id
.'&action=weights',
1116 get_string('setweights', 'grades'));
1117 $row[] = new tabobject('letters', 'index.php?id='.$course->id
.'&action=letters',
1118 get_string('setgradeletters', 'grades'));
1119 $row[] = new tabobject('excepts', 'exceptions.php?id='.$course->id
.'&action=excepts',
1120 get_string('gradeexceptions', 'grades'));
1124 print_tabs($tabs, $curraction);
1128 function grade_nav($course, $action='grades') {
1133 $strgrades = get_string('grades', 'grades');
1134 $gradenav = "<a href=\"$CFG->wwwroot/course/view.php?id=$course->id\">$course->shortname</a>";
1136 if (isteacher($course->id
)) {
1139 case 'set_grade_preferences':
1140 $strcurpage = get_string('setpreferences','grades');
1143 case 'delete_category':
1145 case 'insert_category':
1146 case 'assign_categories':
1147 $strcurpage = get_string('setcategories','grades');
1150 case 'set_grade_weights':
1151 $strcurpage = get_string('setweights','grades');
1153 case 'set_letter_grades':
1155 $strcurpage = get_string('setgradeletters','grades');
1158 $strcurpage = get_string('gradeexceptions', 'grades');
1165 if ($action=='grades') {
1166 $gradenav .= " -> $strgrades";
1168 $gradenav .= " -> <a href=\"index.php?id=$course->id&action=grades\">$strgrades</a>";
1171 // if we are on a grades sub-page provide a link back (including grade preferences and grade items
1173 if (isset($strcurpage)) {
1174 $gradenav .= " -> $strcurpage";
1175 } else if($action =='vcats') {
1176 // show sub category
1177 if (isset($cview)) {
1178 $gradenav .= " -> $cview";
1183 $gradenav .= " -> $strgrades";
1189 function grade_download($download, $id) {
1194 if (! $course = get_record("course", "id", $id)) {
1195 error("Course ID was incorrect");
1198 if (!isteacher($course->id
)) {
1199 error("Only teachers can use this page!");
1202 $strgrades = get_string("grades");
1203 $strgrade = get_string("grade");
1204 $strmax = get_string("maximumshort");
1205 $stractivityreport = get_string("activityreport");
1207 /// Check to see if groups are being used in this course
1208 if ($groupmode = groupmode($course)) { // Groups are being used
1209 if (isset($_GET['group'])) {
1210 $changegroup = $_GET['group']; /// 0 or higher
1212 $changegroup = -1; /// This means no group change was specified
1215 $currentgroup = get_and_set_current_group($course, $groupmode, $changegroup);
1217 $currentgroup = false;
1220 if ($currentgroup) {
1221 $students = get_group_students($currentgroup, "u.lastname ASC");
1223 $students = get_course_students($course->id
, "u.lastname ASC");
1226 if (!empty($students)) {
1227 foreach ($students as $student) {
1228 $grades[$student->id
] = array(); // Collect all grades in this array
1229 $gradeshtml[$student->id
] = array(); // Collect all grades html formatted in this array
1230 $totals[$student->id
] = array(); // Collect all totals in this array
1233 $columns = array(); // Accumulate column names in this array.
1234 $columnhtml = array(); // Accumulate column html in this array.
1237 /// Collect modules data
1238 get_all_mods($course->id
, $mods, $modnames, $modnamesplural, $modnamesused);
1240 /// Search through all the modules, pulling out grade data
1241 $sections = get_all_sections($course->id
); // Sort everything the same as the course
1242 for ($i=0; $i<=$course->numsections
; $i++
) {
1243 if (isset($sections[$i])) { // should always be true
1244 $section = $sections[$i];
1245 if ($section->sequence
) {
1246 $sectionmods = explode(",", $section->sequence
);
1247 foreach ($sectionmods as $sectionmod) {
1248 $mod = $mods[$sectionmod];
1249 $instance = get_record("$mod->modname", "id", "$mod->instance");
1250 $libfile = "$CFG->dirroot/mod/$mod->modname/lib.php";
1252 if (file_exists($libfile)) {
1253 require_once($libfile);
1254 $gradefunction = $mod->modname
."_grades";
1255 if (function_exists($gradefunction)) { // Skip modules without grade function
1256 if ($modgrades = $gradefunction($mod->instance
)) {
1257 if (!empty($modgrades->maxgrade
)) {
1258 if ($mod->visible
) {
1259 $maxgrade = "$strmax: $modgrades->maxgrade";
1261 $maxgrade = "$strmax: $modgrades->maxgrade";
1267 $columns[] = "$mod->modfullname: ".format_string($instance->name
,true)." - $maxgrade";
1269 if (!empty($students)) {
1270 foreach ($students as $student) {
1271 if (!empty($modgrades->grades
[$student->id
])) {
1272 $grades[$student->id
][] = $currentstudentgrade = $modgrades->grades
[$student->id
];
1274 $grades[$student->id
][] = $currentstudentgrade = "";
1275 $gradeshtml[$student->id
][] = "";
1277 if (!empty($modgrades->maxgrade
)) {
1278 $totals[$student->id
] = (float)($totals[$student->id
]) +
(float)($currentstudentgrade);
1280 $totals[$student->id
] = (float)($totals[$student->id
]) +
0;
1290 } // a new Moodle nesting record? ;-)
1292 /// OK, we have all the data, now present it to the user
1293 if ($download == "xls" and confirm_sesskey()) {
1294 require_once("../lib/excellib.class.php");
1296 /// Calculate file name
1297 $downloadfilename = clean_filename("$course->shortname $strgrades.xls");
1298 /// Creating a workbook
1299 $workbook = new MoodleExcelWorkbook("-");
1300 /// Sending HTTP headers
1301 $workbook->send($downloadfilename);
1302 /// Adding the worksheet
1303 $myxls =& $workbook->add_worksheet($strgrades);
1305 /// Print names of all the fields
1306 $myxls->write_string(0,0,get_string("firstname"));
1307 $myxls->write_string(0,1,get_string("lastname"));
1308 $myxls->write_string(0,2,get_string("idnumber"));
1309 $myxls->write_string(0,3,get_string("institution"));
1310 $myxls->write_string(0,4,get_string("department"));
1311 $myxls->write_string(0,5,get_string("email"));
1313 foreach ($columns as $column) {
1314 $myxls->write_string(0,$pos++
,strip_tags($column));
1316 $myxls->write_string(0,$pos,get_string("total"));
1318 /// Print all the lines of data.
1320 if (!empty($grades)) {
1321 foreach ($grades as $studentid => $studentgrades) {
1323 $student = $students[$studentid];
1324 if (empty($totals[$student->id
])) {
1325 $totals[$student->id
] = '';
1328 $myxls->write_string($i,0,$student->firstname
);
1329 $myxls->write_string($i,1,$student->lastname
);
1330 $myxls->write_string($i,2,$student->idnumber
);
1331 $myxls->write_string($i,3,$student->institution
);
1332 $myxls->write_string($i,4,$student->department
);
1333 $myxls->write_string($i,5,$student->email
);
1335 foreach ($studentgrades as $grade) {
1336 if (is_numeric($grade)) {
1337 $myxls->write_number($i,$j++
,strip_tags($grade));
1340 $myxls->write_string($i,$j++
,strip_tags($grade));
1343 $myxls->write_number($i,$j,$totals[$student->id
]);
1347 /// Close the workbook
1352 } else if ($download == "txt" and confirm_sesskey()) {
1354 /// Print header to force download
1356 header("Content-Type: application/download\n");
1357 $downloadfilename = clean_filename("$course->shortname $strgrades");
1358 header("Content-Disposition: attachment; filename=\"$downloadfilename.txt\"");
1360 /// Print names of all the fields
1362 echo get_string("firstname")."\t".
1363 get_string("lastname")."\t".
1364 get_string("idnumber")."\t".
1365 get_string("institution")."\t".
1366 get_string("department")."\t".
1367 get_string("email");
1368 foreach ($columns as $column) {
1369 $column = strip_tags($column);
1372 echo "\t".get_string("total")."\n";
1374 /// Print all the lines of data.
1375 foreach ($grades as $studentid => $studentgrades) {
1376 $student = $students[$studentid];
1377 if (empty($totals[$student->id
])) {
1378 $totals[$student->id
] = '';
1380 echo "$student->firstname\t$student->lastname\t$student->idnumber\t$student->institution\t$student->department\t$student->email";
1381 foreach ($studentgrades as $grade) {
1382 $grade = strip_tags($grade);
1385 echo "\t".$totals[$student->id
];
1391 }else if ($download == '' and confirm_sesskey()) {
1392 error("No file type specified");
1397 function grade_get_stats($category='all') {
1398 list($grades_by_student, $all_categories) = grade_get_formatted_grades();
1400 if ($grades_by_student != 0 && $all_categories != 0) {
1404 //populate the sum of student points, # items and totalpoints for each category
1405 foreach($grades_by_student as $student=>$categories) {
1406 foreach($categories as $cur_category=>$assignments) {
1407 if($category != 'student_data') {
1408 if (isset($assignments['stats'])) {
1409 if (isset($stats[$cur_category]['sum'])) {
1410 $stats[$cur_category]['sum'] = $stats[$cur_category]['sum'] +
$assignments['stats']['points'];
1413 $stats[$cur_category]['sum'] = $assignments['stats']['points'];
1415 $stats[$cur_category]['items'] = $assignments['stats']['grade_items'];
1416 $stats[$cur_category]['totalpoints'] = $assignments['stats']['totalpoints'];
1417 $stats[$cur_category]['weight'] = $all_categories[$cur_category]['stats']['weight'];
1422 // populate the overall sum,items and totalpoints
1423 foreach($stats as $cur_category=>$info) {
1424 if($cur_category != 'all' && $cur_category != 'student_data') {
1426 if ($stats[$cur_category]['totalpoints'] == get_string('excluded', 'grades')) {
1427 $stats[$cur_category]['totalpoints'] = 1;
1428 $stats['all']['sum'] = $stats['all']['sum'] +
$stats[$cur_category]['sum'];
1429 $stats['all']['items'] = $stats['all']['items'] +
$stats[$cur_category]['items'];
1430 $stats['all']['totalpoints'] = $stats['all']['totalpoints'] +
$stats[$cur_category]['totalpoints'];
1431 $stats['all']['weighted_sum'] = $stats['all']['weighted_sum'] +
($stats[$cur_category]['sum']/($stats[$cur_category]['totalpoints']))*$stats[$cur_category]['weight'];
1434 else if (isset($stats['all'])) {
1435 $stats['all']['sum'] = $stats['all']['sum'] +
$stats[$cur_category]['sum'];
1436 $stats['all']['items'] = $stats['all']['items'] +
$stats[$cur_category]['items'];
1437 $stats['all']['totalpoints'] = $stats['all']['totalpoints'] +
$stats[$cur_category]['totalpoints'];
1438 $stats['all']['weighted_sum'] = $stats['all']['weighted_sum'] +
($stats[$cur_category]['sum']/($stats[$cur_category]['totalpoints']))*$stats[$cur_category]['weight'];
1441 $stats['all']['sum'] = $stats[$cur_category]['sum'];
1442 $stats['all']['items'] = $stats[$cur_category]['items'];
1443 $stats['all']['totalpoints'] = $stats[$cur_category]['totalpoints'];
1444 $stats['all']['weighted_sum'] = ($stats[$cur_category]['sum']/($stats[$cur_category]['totalpoints']))*$stats[$cur_category]['weight'];
1449 $stats['all']['students'] = count($grades_by_student);
1450 $stats['all']['average'] = $stats['all']['sum'] / $stats['all']['students'];
1451 $stats['all']['average_weighted'] = $stats['all']['weighted_sum']/$stats['all']['students'];
1453 // calculate the average squared deviation and populate a list of all scores while we're at it
1454 $stats['all']['avgsqddev'] = 0;
1455 $stats['all']['avgsqddev_weighted'] = 0;
1456 foreach($grades_by_student as $student=>$categories) {
1457 foreach($categories as $cur_category=>$assignments) {
1458 if ($cur_category != 'student_data') {
1459 $stats['all']['avgsqddev'] = $stats['all']['avgsqddev'] +
pow(($grades_by_student[$student]['student_data']['points']-$stats['all']['average']),2);
1460 $stats['all']['avgsqddev_weighted'] = $stats['all']['avgsqddev_weighted'] +
pow(($grades_by_student[$student]['student_data']['weighted']-$stats['all']['average_weighted']),2);
1463 if (isset($stats['all']['all_scores'])) {
1464 $stats['all']['all_scores'] .= ','.$grades_by_student[$student]['student_data']['points'];
1465 $stats['all']['all_scores_weighted'] .= ','.$grades_by_student[$student]['student_data']['weighted'];
1468 $stats['all']['all_scores'] = $grades_by_student[$student]['student_data']['points'];
1469 $stats['all']['all_scores_weighted'] = $grades_by_student[$student]['student_data']['weighted'];
1472 $stats['all']['avgsqddev']=$stats['all']['avgsqddev']/$stats['all']['students'];
1473 $stats['all']['avgsqddev_weighted']=$stats['all']['avgsqddev_weighted']/$stats['all']['students'];
1474 $stats['all']['stddev'] = sqrt($stats['all']['avgsqddev']);
1475 $stats['all']['stddev_weighted'] = sqrt($stats['all']['avgsqddev_weighted']);
1476 $stats['all']['mode'] = grade_mode($stats['all']['all_scores']);
1477 $stats['all']['mode_weighted'] = grade_mode($stats['all']['all_scores_weighted']);
1479 // make sure the mode is not set to every score
1480 if(count($stats['all']['mode']) == count($grades_by_student)) {
1481 $stats['all']['mode'] = get_string('nomode','grade');
1483 if(count($stats['all']['mode_weighted']) == count($grades_by_student)) {
1484 $stats['all']['mode_weighted'] = get_string('nomode','grade');
1490 // get the stats for category
1491 //populate the sum of student points, # items and totalpoints for each category
1492 foreach($grades_by_student as $student=>$categories) {
1493 if(isset($grades_by_student[$student][$category]['stats'])) {
1494 if (isset($stats[$category]['sum'])) {
1495 $stats[$category]['sum'] = $stats[$category]['sum'] +
$grades_by_student[$student][$category]['stats']['points'];
1498 $stats[$category]['sum'] = $grades_by_student[$student][$category]['stats']['points'];
1500 $stats[$category]['items'] = $grades_by_student[$student][$category]['stats']['grade_items'];
1501 $stats[$category]['totalpoints'] = $grades_by_student[$student][$category]['stats']['totalpoints'];
1504 $stats[$category]['students'] = count($grades_by_student);
1505 $stats[$category]['average'] = $stats[$category]['sum']/$stats[$category]['students'];
1507 // calculate the average squared deviation and populate a list of all scores too
1508 $stats[$category]['avgsqddev'] = 0;
1509 foreach($grades_by_student as $student=>$categories) {
1510 foreach($categories as $cur_category=>$assignment) {
1511 if ($cur_category != 'student_data') {
1512 if ($grades_by_student[$student][$category]['stats']['points'] == '-' ||
$grades_by_student[$student][$category]['stats']['points'] == get_string('grades','excluded')) {
1513 // count grade as a zero
1514 $stats[$category]['avgsqddev'] = $stats[$category]['avgsqddev'] +
pow(($stats[$category]['average']),2);
1517 $stats[$category]['avgsqddev'] = $stats[$category]['avgsqddev'] +
pow(($grades_by_student[$student][$category]['stats']['points']-$stats[$category]['average']),2);
1522 if (isset($stats[$category]['all_scores'])) {
1523 $stats[$category]['all_scores'] .= ','.$grades_by_student[$student][$category]['stats']['points'];
1526 $stats[$category]['all_scores'] = $grades_by_student[$student][$category]['stats']['points'];
1529 $stats[$category]['avgsqddev'] = $stats[$category]['avgsqddev']/$stats[$category]['students'];
1530 $stats[$category]['stddev'] = sqrt($stats[$category]['avgsqddev']);
1531 $stats[$category]['mode'] = grade_mode($stats[$category]['all_scores']);
1535 // do a little cleanup
1536 $stats[$category]['stddev'] = sprintf("%0.2f", $stats[$category]['stddev']);
1537 $stats[$category]['average'] = sprintf("%0.2f", $stats[$category]['average']);
1538 $stats[$category]['max'] = max(explode(',',$stats[$category]['all_scores']));
1539 $stats[$category]['min'] = min(explode(',',$stats[$category]['all_scores']));
1540 $stats[$category]['median'] = explode(',',$stats[$category]['all_scores']);
1542 if (isset($stats[$category]['stddev_weighted'])) {
1543 $stats[$category]['stddev_weighted'] = sprintf("%0.2f", $stats[$category]['stddev_weighted']);
1545 if (isset($stats[$category]['average_weighted'])) {
1546 $stats[$category]['average_weighted'] = sprintf("%0.2f", $stats[$category]['average_weighted']);
1548 if (isset($stats[$category]['max_weighted'])) {
1549 $stats[$category]['max_weighted'] = max(explode(',',$stats[$category]['all_scores_weighted']));
1551 if (isset($stats[$category]['min_weighted'])) {
1552 $stats[$category]['min_weighted'] = min(explode(',',$stats[$category]['all_scores_weighted']));
1555 if (isset($stats[$category]['all_scores_weighted'])) {
1556 $stats[$category]['median_weighted'] = explode(',',$stats[$category]['all_scores_weighted']);
1563 sort($stats[$category]['median']);
1565 if (count($stats[$category]['median'])/2 == floor(count($stats[$category]['median'])/2) ) {
1566 // even number of scores
1567 $temp = $stats[$category]['median'][count($stats[$category]['median'])/2-1] +
$stats[$category]['median'][count($stats[$category]['median'])/2];
1571 // odd number of scores
1572 $temp = $stats[$category]['median'][floor(count($stats[$category]['median'])/2)];
1574 unset($stats[$category]['median']);
1575 $stats[$category]['median'] = $temp;
1577 if (isset($stats[$category]['median_weighted'])) {
1578 if (count($stats[$category]['median_weighted'])/2 == floor(count($stats[$category]['median_weighted'])/2)) {
1579 // even number of scores
1580 $temp = $stats[$category]['median_weighted'][count($stats[$category]['median_weighted'])/2-1] +
$stats[$category]['median_weighted'][count($stats[$category]['median_weighted'])/2+
1];
1584 // odd number of scores
1585 $temp = $stats[$category]['median_weighted'][floor(count($stats[$category]['median_weighted'])/2)];
1587 unset($stats[$category]['median_weighted']);
1588 $stats[$category]['median_weighted'] = $temp;
1594 // returns a comma seperated list of the most common values in $items, $items is expected to be a comma sperated list of numbers
1595 function grade_mode($items) {
1596 $all_scores = explode(',',$items);
1597 foreach($all_scores as $value) {
1598 if (isset($frequency[$value])) {
1599 $frequency[$value]++
;
1602 $frequency[$value] = 1;
1605 $max = max($frequency);
1606 foreach($frequency as $key=>$value) {
1607 if ($value == $max) {
1608 if (isset($retval)) {
1609 $retval .= ', '.$key;
1620 function grade_stats() {
1624 global $preferences;
1626 if (!isset($category)) {
1627 $category = clean_param($_REQUEST['category'], PARAM_CLEAN
);
1630 $stats = grade_get_stats($category);
1634 echo '<table align="center"><tr><th colspan="3">'.$category.' '.get_string('stats','grades').'</th></tr>';
1635 if ($preferences->show_weighted
== 1 && $preferences->use_weighted_for_letter
== 1 && $category== 'all') {
1636 echo '<tr><th> </th><th>'.get_string('points','grades').'<th>'.get_string('weight','grades').'</th></tr>';
1639 echo '<tr><td align="right">'.get_string('max','grades').':</td><td align="right">'.$stats[$category]['max'].'</td>';
1640 if ($preferences->show_weighted
== 1 && $preferences->use_weighted_for_letter
== 1 && $category== 'all') {
1641 echo '<td align="right">'.$stats[$category]['max_weighted'].'</td>';
1645 echo '<tr><td align="right">'.get_string('min','grades').':</td><td align="right">'.$stats[$category]['min'].'</td>';
1646 if ($preferences->show_weighted
== 1 && $preferences->use_weighted_for_letter
== 1 && $category== 'all') {
1647 echo '<td align="right">'.$stats[$category]['min_weighted'].'</td>';
1651 echo '<tr><td align="right">'.get_string('average','grades').':</td><td align="right">'.$stats[$category]['average'].'</td>';
1652 if ($preferences->show_weighted
== 1 && $preferences->use_weighted_for_letter
== 1 && $category== 'all') {
1653 echo '<td align="right">'.$stats[$category]['average_weighted'].'</td>';
1657 echo '<tr><td align="right">'.get_string('median','grades').':</td><td align="right">'.$stats[$category]['median'].'</td>';
1658 if ($preferences->show_weighted
== 1 && $preferences->use_weighted_for_letter
== 1 && $category== 'all') {
1659 echo '<td align="right">'.$stats[$category]['median_weighted'].'</td>';
1663 echo '<tr><td align="right">'.get_string('mode','grades').':</td><td align="right">'.$stats[$category]['mode'].'</td>';
1664 if ($preferences->show_weighted
== 1 && $preferences->use_weighted_for_letter
== 1 && $category== 'all') {
1665 echo '<td align="right">'.$stats[$category]['mode_weighted'].'</td>';
1669 echo '<tr><td align="right">'.get_string('standarddeviation','grades').':</td><td align="right">'.$stats[$category]['stddev'].'</td>';
1670 if ($preferences->show_weighted
== 1 && $preferences->use_weighted_for_letter
== 1 && $category== 'all') {
1671 echo '<td align="right">'.$stats[$category]['stddev_weighted'].'</td>';
1678 function grade_view_category_grades($view_by_student) {
1682 global $preferences;
1684 if (!isteacher($course->id
)) {
1685 $view_by_student = $USER->id
;
1688 if ($preferences->use_advanced
== 0) {
1689 $cview = UNCATEGORISED
;
1692 $cview=clean_param($_REQUEST['cview'], PARAM_CLEAN
);
1696 list($grades_by_student, $all_categories) = grade_get_formatted_grades();
1698 if ($grades_by_student != 0 && $all_categories != 0) {
1699 // output a form for the user to download the grades.
1700 grade_download_form();
1702 if ($view_by_student != -1) {
1703 // unset all grades except for this student
1704 foreach ($grades_by_student as $student=>$junk) {
1705 if($student != $view_by_student) {
1706 unset($grades_by_student[$student]);
1711 $grade_columns = $preferences->show_weighted +
$preferences->show_points +
$preferences->show_percent
;
1717 if (isteacher($course->id
)) {
1718 $student_heading_link = get_string('student','grades');
1719 //only set sorting links if more than one student displayed.
1720 if ($view_by_student == -1) {
1721 $student_heading_link .='<br /><a href="?id='.$course->id
.'&group='.$group.'&action=vcats&cview='.$cview.'&sort=lastname">'.get_string('sortbylastname','grades').'</a>';
1722 $student_heading_link .= '<br /><a href="?id='.$course->id
.'&group='.$group.'&action=vcats&cview='.$cview.'&sort=firstname">'.get_string('sortbyfirstname','grades').'</a>';
1725 $student_heading_link .= '<br /><a href="?id='.$course->id
.'&group='.$group.'&action=vcats&cview='.$cview.'">'.get_string('showallstudents','grades').'</a>';
1728 echo '<table align="center" class="grades">';
1729 if (isteacher($course->id
)) {
1730 $header = '<tr class="header"><th rowspan="2">'.$student_heading_link.'</th>';
1733 $header = '<tr class="header">';
1735 $header1 = '<tr class="header">';
1737 // to keep track of what we've output
1742 // this next section is to display the items in the course order
1743 foreach($grades_by_student as $student => $categories) {
1744 if (isset($item_order)) {
1745 // we already have the sort order let's jump out
1748 $item_order = array();
1749 foreach($categories as $category => $items) {
1750 if ($category == $cview) {
1751 foreach ($items as $assignment=>$points) {
1752 if ($assignment != 'stats') {
1753 $temp = $points['sort_order'];
1754 $item_order[$temp] = $assignment;
1760 /// Make sure $item_order is initialised (bug 3424)
1761 if (empty($item_order)) $item_order = array();
1765 foreach($grades_by_student as $student => $categories) {
1767 if ($preferences->reprint_headers
!= 0 && $reprint >= $preferences->reprint_headers
) {
1768 echo $header.$header1.'</tr>';
1772 // alternate row classes
1773 $row = ($oddrow) ?
'<tr class="r0">' : '<tr class="r1">';
1776 // reset the col classes
1780 // set the links to student information based on multiview or individual... if individual go to student info... if many go to individual grades view.
1781 if (isteacher($course->id
)) {
1782 if ($view_by_student != -1) {
1783 $student_link = '<a href="'.$CFG->wwwroot
.'/user/view.php?id='.$student.'&course='.$course->id
.'">';
1786 $student_link = '<a href="?id='.$course->id
.'&group='.$group.'&action=vcats&user='.$student.'&cview='.$cview.'">';
1788 $student_link .= $grades_by_student[$student]['student_data']['lastname'].', '.$grades_by_student[$student]['student_data']['firstname'].'</a>';
1789 $row .= '<td class="fullname">'.$student_link.'</td>';
1792 foreach($categories as $category => $items) {
1793 if ($category == $cview) {
1794 // make sure that the grades come out in the same order
1795 foreach($item_order as $order=>$assignment) {
1797 $class = $all_categories[$category][$assignment]['modname'];
1799 if ($assignment != 'stats') {
1803 $link_id = grade_get_module_link($course->id
, $all_categories[$category][$assignment]['cminstance'], $all_categories[$category][$assignment]['modid']);
1805 $link = $CFG->wwwroot
.'/mod/'.$all_categories[$category][$assignment]['modname'].'/view.php?id='.$link_id->id
;
1806 $all_categories[$category][$assignment]['link'] = $link;
1807 if ($all_categories[$category][$assignment]['hidden'] == 0) {
1808 $header .= '<th class="'.$class.'" colspan="'.$grade_columns.'"><a href="'.$link.'">'.format_string($assignment,true).'</a>';
1811 $header .= '<th class="'.$class.'" colspan="'.$grade_columns.'"><a class="dimmed" href="'.$link.'">'.format_string($assignment,true).'</a>';
1813 if ($all_categories[$category][$assignment]['extra_credit'] == 1) {
1814 $header .= '<span class="extracredit">('.get_string('extracredit','grades').')</span>';
1817 if ($preferences->show_points
) {
1818 $header1 .= '<th class="'.$class.'">'. $all_categories[$category][$assignment]['maxgrade'];
1819 if ($all_categories[$category][$assignment]['grade_against'] != $all_categories[$category][$assignment]['maxgrade']) {
1820 $header1 .= '('. $all_categories[$category][$assignment]['grade_against'].')';
1822 $header1 .= '</th>';
1825 if($preferences->show_percent
) {
1826 if ($all_categories[$category][$assignment]['grade_against'] != $all_categories[$category][$assignment]['maxgrade']) {
1827 $header1 .= '<th class="'.$class.'">'.get_string('scaledpct','grades').'</th>';
1830 $header1 .= '<th class="'.$class.'">'.get_string('rawpct','grades').'</th>';
1833 if ($preferences->show_weighted
) {
1834 if ($all_categories[$category]['stats']['totalpoints'] != 0) {
1835 $cur_weighted_max = sprintf("%0.2f", $all_categories[$category][$assignment]['grade_against']/$all_categories[$category]['stats']['totalpoints']*$all_categories[$category]['stats']['weight']);
1838 $cur_weighted_max = 0;
1840 $header1 .= '<th>'.$cur_weighted_max.get_string('pctoftotalgrade','grades').'</th>';
1845 if ($preferences->show_points
) {
1846 $class .= ($oddcol) ?
' c0 points' : ' c1 points';
1848 $row .= '<td class="'.$class.'"><a href="'.$all_categories[$category][$assignment]['link'].'">' . $items[$assignment]['grade'] . '</a></td>';
1851 if ($preferences->show_percent
) {
1852 $class .= ($oddcol) ?
' c0 percent' : ' c1 percent';
1854 $row .= '<td class="'.$class.'">'. $items[$assignment]['percent'].'%</td>';
1857 if ($preferences->show_weighted
) {
1858 $class .= ($oddcol) ?
' c0 weighted' : ' c1 weighted';
1860 $row .= '<td class="'.$class.'">'.$items[$assignment]['weighted'].'%</td>';
1870 if (isteacher($course->id
) && $view_by_student == -1) {
1871 $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>';
1872 $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>';
1875 $total_sort_link = '';
1878 $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>';
1879 if ($all_categories[$cview]['stats']['drop'] != 0) {
1880 $header .= '<th class="'.$class.'" colspan="'.$grade_columns.'">'.get_string('total','grades').' (Lowest '. $all_categories[$cview]['stats']['drop']. ' Dropped)'.$total_sort_link.' '.$stats_link.'</th>';
1883 $header .= '<th class="'.$class.'" colspan="'.$grade_columns.'">'.get_string('total','grades').' '.$total_sort_link.' '.$stats_link.'</th>';
1886 if ($preferences->show_points
) {
1887 $header1 .= '<th class="'.$class.'">'.$all_categories[$cview]['stats']['totalpoints'];
1888 if ($all_categories[$cview]['stats']['bonus_points'] != 0) {
1889 $header1 .='(+'.$all_categories[$cview]['stats']['bonus_points'].')';
1893 if ($preferences->show_percent
) {
1894 $header1 .= '<th class="'.$class.'">'.get_string('percent','grades').'</th>';
1898 if ($preferences->show_weighted
) {
1899 $header1 .= '<th class="'.$class.'">'.$all_categories[$cview]['stats']['weight'].get_string('pctoftotalgrade','grades').'</th>';
1902 if (isteacher($course->id
) ) {
1903 $header .= '<th rowspan="2">'.$student_heading_link.'</th></tr>';
1909 //adjust colcount to reflect the actual number of columns output
1910 $colcount++
; // total column
1911 $colcount = $colcount*$grade_columns +
2;
1912 echo '<tr class="title"><th colspan="'.$colcount.'">';
1913 if ($preferences->use_advanced
!= 0) {
1914 echo $cview.' '.get_string('grades','grades');
1917 echo get_string('grades','grades');
1920 if (isteacher($course->id
)) {
1921 helpbutton('teacher', get_string('gradehelp','grades'), 'grade');
1924 helpbutton('student', get_string('gradehelp','grades'), 'grade');
1928 echo $header1.'</tr>';
1932 // total points for category
1933 if ($preferences->show_points
) {
1934 $class .= ($oddcol) ?
' c0 points' : ' c1 points';
1936 $row .= '<td class="'.$class.'">'.$grades_by_student[$student][$cview]['stats']['points'].'</td>';
1939 // total percent for category
1940 if ($preferences->show_percent
) {
1941 $class .= ($oddcol) ?
' c0 percent' : ' c1 percent';
1943 $row .= '<td class="'.$class.'">'.$grades_by_student[$student][$cview]['stats']['percent'].'%</td>';
1947 // total weighted for category
1948 if ($preferences->show_weighted
) {
1949 $class .= ($oddcol) ?
' c0 weighted' : ' c1 weighted';
1951 $row .= '<td class="'.$class.'">'.$grades_by_student[$student][$cview]['stats']['weighted'].'%</td>';
1954 if (isteacher($course->id
) ) {
1955 $row .= '<td class="fullname">'.$student_link.'</td>';
1963 else { // no grades returned
1964 error(get_string('nogradesreturned','grades'), $CFG->wwwroot
.'/course/view.php?id='.$course->id
);
1968 error(get_string('nocategoryview','grades'), $CFG->wwwroot
.'/course/view.php?id='.$course->id
);
1972 function grade_view_all_grades($view_by_student) {
1973 // displays all grades for the course
1976 global $preferences;
1978 global $group; // yu: fix for 5814
1980 if (!isteacher($course->id
)) {
1981 $view_by_student = $USER->id
;
1984 list($grades_by_student, $all_categories) = grade_get_formatted_grades();
1986 if ($grades_by_student != 0 && $all_categories != 0) {
1987 // output a form for the user to download the grades.
1988 grade_download_form();
1990 if ($view_by_student != -1) {
1991 // unset all grades except for this student
1992 foreach ($grades_by_student as $student=>$junk) {
1993 if($student != $view_by_student) {
1994 unset($grades_by_student[$student]);
1998 $grade_columns = $preferences->show_weighted +
$preferences->show_points +
$preferences->show_percent
;
2001 $total_course_points = 0;
2005 echo '<table align="center" class="grades">';
2006 if (isteacher($course->id
) ) {
2007 $student_heading_link = get_string('student','grades');
2008 if ($view_by_student == -1) {
2009 $student_heading_link .='<a href="?id='.$course->id
.'&action=grades&sort=lastname&group='.$group.'"><br /><font size="-2">'.get_string('sortbylastname','grades').'</font></a>';
2010 $student_heading_link .= '<a href="?id='.$course->id
.'&action=grades&sort=firstname&group='.$group.'"><br /><font size="-2">'.get_string('sortbyfirstname','grades').'</font></a>';
2013 $student_heading_link .= '<br /><a href="?id='.$course->id
.'&&action=grades"><font size="-2">'.get_string('showallstudents','grades').'</font></a>';
2015 $header = '<tr><th rowspan="2">'.$student_heading_link.'</th>';
2025 foreach($grades_by_student as $student => $categories) {
2028 $total_bonus_points = 0;
2029 if ($preferences->reprint_headers
!= 0 && $reprint >= $preferences->reprint_headers
) {
2030 echo $header.$header1;
2034 // alternate row classes
2035 $row = ($oddrow) ?
'<tr class="r0">' : '<tr class="r1">';
2038 // set the links to student information based on multiview or individual... if individual go to student info... if many go to individual grades view.
2039 if (isteacher($course->id
)) {
2040 if ($view_by_student != -1) {
2041 $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>';
2044 $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>';
2046 $row .= '<td>'. $studentviewlink .'</td>';
2049 foreach($categories as $category => $items) {
2050 if ($category != 'student_data') {
2053 if ($category == UNCATEGORISED
) {
2054 $categoryname = get_string(UNCATEGORISED
, 'grades');
2056 $categoryname = $category;
2058 // only print the category headers if something is displayed for them
2059 if ($preferences->show_weighted ||
$preferences->show_percent ||
$preferences->show_points
) {
2060 $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>';
2061 $header .= '<th colspan="'.$grade_columns.'"><a href="?id='.$course->id
.'&action=vcats&cview='.$category;
2062 if ($view_by_student != -1) {
2063 $header .= '&user='.$view_by_student;
2065 $header .='">'. $categoryname .' '.$stats_link.'</a>';
2067 if ($preferences->display_weighted
!= 0) {
2068 $header .= '('. $all_categories[$category]['stats']['weight'] . '%)';
2071 if ($preferences->show_points
) {
2072 $header1 .= '<th>'.get_string('points','grades').'('.$all_categories[$category]['stats']['totalpoints'].')';
2073 if ($all_categories[$category]['stats']['bonus_points'] != 0) {
2074 $header1 .='(+'.$all_categories[$category]['stats']['bonus_points'].')';
2078 if ($preferences->show_percent
) {
2079 $header1 .= '<th>'.get_string('percent','grades').'</th>';
2081 if ($preferences->show_weighted
) {
2082 $header1 .= '<th>'.get_string('weightedpctcontribution','grades').'</th>';
2084 $maxpercent = $all_categories["$category"]['stats']['weight'] +
$maxpercent;
2085 //$total_course_points = $all_categories[$category]['stats']['totalpoints']+ $total_course_points;
2086 //$total_course_points = $all_categories[$category]['stats']['totalpoints']+ $total_course_points;
2090 if ($preferences->show_points
) {
2091 $row .= '<td align="right">' . $items['stats']['points'] . '</td>';
2093 if ($preferences->show_percent
) {
2094 $row .= '<td align="right">'. $items['stats']['percent'].'%</td>';
2097 if ($preferences->show_weighted
) {
2098 $row .= '<td align="right">'. $items['stats']['weighted'] . '%</td>';
2100 $total_bonus_points = $all_categories[$category]['stats']['bonus_points'];
2104 if ($preferences->show_letters
) {
2105 $total_columns = $grade_columns +
1;
2108 $total_columns = $grade_columns;
2111 if (isteacher($course->id
) && $view_by_student == -1) {
2112 $grade_sort_link = '<a href="?id='.$course->id
.'&action=grades&sort=highgrade&group='.$group.'"><img src="'.$CFG->wwwroot
.'/pix/t/down.gif" alt="'.get_string('highgradedescending','grades').'" /></a>';
2113 $grade_sort_link .= '<a href="?id='.$course->id
.'&action=grades&sort=highgrade_asc&group='.$group.'"><img src="'.$CFG->wwwroot
.'/pix/t/up.gif" alt="'.get_string('highgradeascending','grades').'" /></a>';
2114 $points_sort_link = '<a href="?id='.$course->id
.'&action=grades&sort=points&group='.$group.'"><img src="'.$CFG->wwwroot
.'/pix/t/down.gif" alt="'.get_string('pointsdescending','grades').'" /></a>';
2115 $points_sort_link .= '<a href="?id='.$course->id
.'&action=grades&sort=points_asc&group='.$group.'"><img src="'.$CFG->wwwroot
.'/pix/t/up.gif" alt="'.get_string('pointsascending','grades').'" /></a>';
2116 $weighted_sort_link = '<a href="?id='.$course->id
.'&action=grades&sort=weighted&group='.$group.'"><img src="'.$CFG->wwwroot
.'/pix/t/down.gif" alt="'.get_string('weighteddescending','grades').'" /></a>';
2117 $weighted_sort_link .= '<a href="?id='.$course->id
.'&action=grades&sort=weighted_asc&group='.$group.'"><img src="'.$CFG->wwwroot
.'/pix/t/up.gif" alt="'.get_string('weightedascending','grades').'" /></a>';
2118 $percent_sort_link = '<a href="?id='.$course->id
.'&action=grades&sort=percent&group='.$group.'"><img src="'.$CFG->wwwroot
.'/pix/t/down.gif" alt="'.get_string('percentdescending','grades').'" /></a>';
2119 $percent_sort_link .= '<a href="?id='.$course->id
.'&action=grades&sort=percent_asc&group='.$group.'"><img src="'.$CFG->wwwroot
.'/pix/t/up.gif" alt="'.get_string('percentascending','grades').'" /></a>';
2121 $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>';
2122 $header .= '<th colspan="'.$total_columns.'">'.get_string('total','grades').' '.$stats_link.'</th>';
2123 if (isteacher($course->id
) && $view_by_student == -1) {
2124 if ($preferences->show_points
) {
2125 $header1 .= '<th>'.get_string('points','grades').'('.$all_categories['stats']['totalpoints'].')';
2126 if ($category != 'student_data' && $all_categories[$category]['stats']['bonus_points'] != 0) {
2128 $header1 .='(+'.$total_bonus_points.')';
2130 $header1 .= '<br />'.$points_sort_link.' '.'</th>';
2132 if ($preferences->show_percent
) {
2133 $header1 .= '<th>'.get_string('percentshort','grades').'<br />'.$percent_sort_link.' '.'</th>';
2135 if ($preferences->show_weighted
) {
2136 $header1 .= '<th>'.get_string('weightedpct','grades').'('.$all_categories['stats']['weight'].')'.'<br />'.$weighted_sort_link.' '.'</th>';
2138 if ($preferences->show_letters
) {
2139 $header1 .= '<th>'.get_string('lettergrade','grades').'<br />'.$grade_sort_link.' '.'</th>';
2141 $header1 .= '</tr>';
2144 if ($preferences->show_points
) {
2145 $header1 .= '<th>'.get_string('points','grades').'('.$all_categories['stats']['totalpoints'].')';
2146 if ($category != 'student_data' && $all_categories[$category]['stats']['bonus_points'] != 0) {
2147 $header1 .='(+'.$total_bonus_points.')';
2149 $header1 .= '</th>';
2151 if ($preferences->show_percent
) {
2152 $header1 .= '<th>'.get_string('percentshort','grades').'</th>';
2154 if ($preferences->show_weighted
) {
2155 $header1 .= '<th>'.get_string('weightedpct','grades').'('.$all_categories['stats']['weight'].')</th>';
2157 if ($preferences->show_letters
) {
2158 $header1 .= '<th>'.get_string('lettergrade','grades').'</th>';
2160 $header1 .= '</tr>';
2162 if (isteacher($course->id
)) {
2163 $header .= '<th rowspan="2">'.$student_heading_link.'</th></tr>';
2165 // adjust colcount to reflect actual number of columns output
2166 $colcount = $colcount * $grade_columns +
$total_columns +
2;
2168 echo '<tr><th colspan="'.$colcount.'"><font size="+1">'.get_string('allgrades','grades').'</font>';
2169 if (isteacher($course->id
)) {
2170 helpbutton('teacher', get_string('gradehelp','grades'), 'grade');
2173 helpbutton('student', get_string('gradehelp','grades'), 'grade');
2182 if ($preferences->show_points
) {
2183 $row .= '<td align="right">'.$grades_by_student[$student]['student_data']['points'].'</td>';
2185 if ($preferences->show_percent
) {
2186 $row .= '<td align="right">'.$grades_by_student[$student]['student_data']['percent'].'%</td>';
2188 if ($preferences->show_weighted
) {
2189 $row .= '<td align=right>'.$grades_by_student[$student]['student_data']['weighted'].'%</td>';
2191 if ($preferences->show_letters
) {
2192 if ($preferences->use_weighted_for_letter
== 1) {
2193 $grade = $grades_by_student[$student]['student_data']['weighted'];
2196 $grade = $grades_by_student[$student]['student_data']['percent'];
2198 $letter_grade = grade_get_grade_letter($course->id
, $grade);
2199 if ($letter_grade) {
2200 $row .= '<td align="right">'.$letter_grade->letter
.'</td>';
2203 // there wasn't an appropriate entry to use in the gradebook.
2204 if (grade_letters_set($course->id
)) {
2205 $row .= '<td align="right">'.get_string('nolettergrade','grades').' '.$grade.'</td>';
2208 $row .= '<td align="right">'.get_string('nogradeletters','grades').'</td>';
2212 if (isteacher($course->id
) ) {
2213 $row .= '<td>'. $studentviewlink .'</td></tr>';
2223 else { // no grades returned
2224 error(get_string('nogradesreturned','grades'));
2229 function grade_set_grade_weights() {
2230 // set the grade weights as submitted from the form generated by display_grade_weights
2235 if (!empty($USER->id
)) {
2236 if (!confirm_sesskey()) {
2237 error(get_string('confirmsesskeybad', 'error'));
2241 // get list of all categories
2242 $categories = get_records('grade_category', 'courseid', $course->id
);
2244 foreach ($categories as $category) {
2245 $form_catname = preg_replace('/[.| ]/', '_', $category->name
);
2247 $submitted_category = optional_param($form_catname);
2248 if (is_numeric($submitted_category)) {
2249 // see if there is a weight if so see if it needs to be updated
2250 $weight = grade_get_category_weight($course->id
, $category->name
);
2252 if ($weight->weight
!= $submitted_category)
2254 set_field('grade_category', 'weight', $submitted_category, 'id', $weight->id
);
2257 $cur_drop = optional_param("drop_x_lowest$form_catname");
2258 $cur_bonus_points = optional_param("bonus_points$form_catname");
2259 $cur_hidden = optional_param("hidden$form_catname");
2264 $cur_hidden = false;
2267 if ($weight->drop_x_lowest
!= $cur_drop) {
2268 set_field('grade_category', 'drop_x_lowest', $cur_drop, 'id', $weight->cat_id
);
2270 if ($weight->bonus_points
!= $cur_bonus_points) {
2271 set_field('grade_category', 'bonus_points', $cur_bonus_points, 'id', $weight->cat_id
);
2274 set_field('grade_category', 'hidden', 1, 'id', $weight->cat_id
);
2277 set_field('grade_category', 'hidden', 0, 'id', $weight->cat_id
);
2281 // insert the new record... we shouldn't reach this point anymore
2282 //$new_weight->course = $course->id;
2283 //$new_weight->category = $category->id;
2284 //$new_weight->weight = $submitted_category;
2285 //insert_record('grade_weight', $new_weight);
2289 echo '<center><font color="red">'.get_string('nonumericweight','grades').$category->name
.': "'.$submitted_category.'"</font></center><br />';
2295 function grade_display_grade_weights() {
2296 // get all categories with weights
2297 // then set and display that entry.
2302 $categories = get_records('grade_category', 'courseid', $course->id
);
2304 echo '<table border="0" cellspacing="2" cellpadding="5" align="center" class="generalbox"><tr><th colspan="5" class="header">'.get_string('setweights','grades');
2305 helpbutton('weight', get_string('gradeweighthelp','grades'), 'grade');
2307 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>';
2308 echo '<form name="grade_weights" action="./index.php" method="post">';
2309 echo '<input type="hidden" name="id" value="'.$course->id
.'" />';
2310 echo '<input type="hidden" name="action" value="set_grade_weights" />';
2311 echo '<input type="hidden" name="sesskey" value="'.$USER->sesskey
.'" />';
2315 foreach($categories as $category) {
2316 $val = $category->weight
;
2319 // make names form safe
2320 $form_catname = str_replace(' ', '_', $category->name
);
2321 if ($category->name
== UNCATEGORISED
) {
2322 $category->name
= get_string(UNCATEGORISED
, 'grades');
2324 echo '<tr><td align="center" class="generalboxcontent">'.$category->name
.'</td>';
2325 echo '<td align="center" class="generalboxcontent"><input type="text" size="5" name="'.$form_catname.'" value="'.$val.'" /></td>';
2326 echo '<td align="center" class="generalboxcontent"><input type="text" size="5" name="drop_x_lowest'.$form_catname.'" value="'.$category->drop_x_lowest
.'" /></td>';
2327 echo '<td align="center" class="generalboxcontent"><input type="text" size="5" name="bonus_points'.$form_catname.'" value="'.$category->bonus_points
.'" /></td>';
2328 echo '<td align="center" class="generalboxcontent"><input type="checkbox" name="hidden'.$form_catname.'" ';
2329 if ($category->hidden
== 1) {
2330 echo ' checked="checked"';
2334 echo '<tr><td colspan="5" align="center" class="generalboxcontent"><input type="submit" value="'.get_string('savechanges','grades').'" /></td></tr></form>';
2336 echo '<tr><td colspan="5" align="center" class="generalboxcontent"><font color="red">'.get_string('totalweightnot100','grades').'</font></td></tr>';
2339 echo '<tr><td colspan="5" align="center" class="generalboxcontent"><font color="green">'.get_string('totalweight100','grades').'</font></td></tr>';
2343 /// maybe this should just do the default population of the categories instead?
2344 echo '<font color="red">'.get_string('setcategorieserror','grades').'</font>';
2347 echo '<center>'.get_string('dropxlowestwarning','grades').'</center><br />';
2350 function grade_set_categories() {
2356 /// Collect modules data
2357 get_all_mods($course->id
, $mods, $modnames, $modnamesplural, $modnamesused);
2359 echo '<table border="0" cellspacing="2" cellpadding="5" align="center" class="generalbox"><tr><th colspan="5" class="header">'.get_string('setcategories','grades');
2360 helpbutton('category', get_string('gradecategoryhelp','grades'), 'grade');
2361 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>';
2362 echo '<form name="set_categories" method="post" action="./index.php" >';
2363 echo '<input type="hidden" name="action" value="assign_categories" />';
2364 echo '<input type="hidden" name="id" value="'.$course->id
.'" />';
2365 echo '<input type="hidden" name="sesskey" value="'.$USER->sesskey
.'" />';
2369 /// Search through all the modules, pulling out grade data
2370 $sections = get_all_sections($course->id
); // Sort everything the same as the course
2371 for ($i=0; $i<=$course->numsections
; $i++
) {
2372 if (isset($sections[$i])) { // should always be true
2373 $section = $sections[$i];
2374 if ($section->sequence
) {
2375 $sectionmods = explode(",", $section->sequence
);
2376 foreach ($sectionmods as $sectionmod) {
2377 if (empty($mods[$sectionmod])) {
2380 $mod = $mods[$sectionmod];
2381 $instance = get_record("$mod->modname", "id", "$mod->instance");
2382 $libfile = "$CFG->dirroot/mod/$mod->modname/lib.php";
2383 if (file_exists($libfile)) {
2384 require_once($libfile);
2385 $gradefunction = $mod->modname
."_grades";
2386 if (function_exists($gradefunction)) { // Skip modules without grade function
2387 if ($modgrades = $gradefunction($mod->instance
)) {
2389 if ($modgrades->maxgrade
!= '')
2390 // this block traps out broken modules that don't return a maxgrade according to the moodle API
2393 //modgrades contains student information with associated grade
2394 //echo "<b>modname: $mod->modname id: $mod->id course: $mod->course</b><br />";
2395 echo '<input type="hidden" name="modname'.$itemcount.'" value="'.$mod->modname
.'" />';
2396 echo '<input type="hidden" name="mod'.$itemcount.'" value="'.$mod->instance
.'" />';
2397 echo '<input type="hidden" name="course'.$itemcount.'" value="'.$mod->course
.'" />';
2398 echo '<tr><td align="center" class="generalboxcontent">';
2399 // get instance name from db.
2400 $instance = get_record($mod->modname
, 'id', $mod->instance
);
2401 echo format_string($instance->name
)."</td>";
2402 // see if the item is already in the category table and if it is call category select with the id so it is selected
2403 echo '<td align="center" class="generalboxcontent"><select name="category'.$itemcount.'">';
2404 $item_cat_id = get_record('grade_item', 'modid', $mod->module
, 'courseid', $course->id
, 'cminstance', $mod->instance
);
2405 //print_object($item_cat_id);
2406 if (isset($item_cat_id)) {
2407 grade_category_select($item_cat_id->category
);
2410 grade_category_select(-1);
2412 echo '</select></td><td align="center" class="generalboxcontent">'.$modgrades->maxgrade
.'<input type="hidden" name="maxgrade'.$itemcount.'" value="'.$modgrades->maxgrade
.'" /></td>';
2414 if (isset($item_cat_id)) {
2415 // 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%)
2416 if ($item_cat_id->scale_grade
== '' ||
$item_cat_id->scale_grade
== 0)
2417 $scale_to = $modgrades->maxgrade
;
2419 $scale_to = round($modgrades->maxgrade
/$item_cat_id->scale_grade
);
2420 echo '<td align="center" class="generalboxcontent"><input type="text" size="5" name="scale_grade'.$itemcount.'" value="'.$scale_to.'" /></td>';
2423 echo '<td align="center" class="generalboxcontent"><input type="text" size="5" name="scale_grade'.$itemcount.'" value="'.$modgrades->maxgrade
.'" /></td>';
2426 echo '<td align="center" class="generalboxcontent"><input type="checkbox" name="extra_credit'.$itemcount.'" ';
2427 if ($item_cat_id->extra_credit
== 1) {
2428 echo ' checked="checked"';
2430 echo ' /></td></tr>';
2439 echo '<input type="hidden" name="totalitems" value="'.$itemcount.'" />';
2440 echo '<tr><td colspan="5" align="center" class="generalboxcontent"><input type="submit" value="'.get_string('savechanges','grades').'" /></td></tr>';
2442 echo '<tr><td colspan="5" align="center" class="generalboxcontent">';
2443 grade_add_category_form();
2444 echo '</td></tr><tr><td colspan="5" align="center" class="generalboxcontent">';
2445 grade_delete_category_form();
2446 echo '</td></tr></table>';
2447 echo '<center>'.get_string('extracreditwarning','grades').'<center>';
2450 function grade_delete_category() {
2455 if (!empty($USER->id
)) {
2456 if (!confirm_sesskey()) {
2457 error(get_string('confirmsesskeybad', 'error'));
2461 $cat_id = optional_param('category_id');
2462 if ($cat_id != 'blank') {
2463 // delete the record
2464 delete_records('grade_category', 'id', $cat_id, 'courseid', $course->id
);
2465 // set grade_item category field=0 where it was the deleted category (set uncategorized will clean this up)
2466 set_field('grade_item', 'category', 0, 'category', $cat_id);
2470 function grade_assign_categories() {
2474 $num_categories = optional_param('totalitems');
2476 if (!empty($USER->id
)) {
2477 if (!confirm_sesskey()) {
2478 error(get_string('confirmsesskeybad', 'error'));
2482 for ($i = 1; $i <= $num_categories; $i++
) {
2484 // these next sets of lines are a bit obtuse, but it lets there be a dynamic number of grade items
2485 // in the grade category form (maybe there's a better way?)
2486 $cur_cat_id = '$_REQUEST[\'category'.$i.'\'];';
2487 eval( "\$cur_cat_id = $cur_cat_id;" );
2488 $cur_modname = '$_REQUEST[\'modname'.$i.'\'];';
2489 eval( "\$cur_modname = $cur_modname;" );
2490 $cur_mod = '$_REQUEST[\'mod'.$i.'\'];';
2491 eval( "\$cur_mod = $cur_mod;" );
2492 $cur_maxgrade = '$_REQUEST[\'maxgrade'.$i.'\'];';
2493 eval( "\$cur_maxgrade = $cur_maxgrade;" );
2494 $cur_scale_grade = '$_REQUEST[\'scale_grade'.$i.'\'];';
2495 eval( "\$cur_scale_grade = $cur_scale_grade;" );
2496 $cur_extra_credit = '$_REQUEST[\'extra_credit'.$i.'\'];';
2497 $temp = 'extra_credit'.$i;
2498 $junk = get_record('modules','name',$cur_modname);
2499 $cur_modid = $junk->id
;
2500 if (isset($_REQUEST[$temp])) {
2501 eval( "\$cur_extra_credit = $cur_extra_credit;" );
2504 $cur_extra_credit = false;
2506 if ($cur_extra_credit) {
2507 $cur_extra_credit = 1;
2509 $cur_extra_credit = 0;
2511 if ($cur_scale_grade == 0 ||
$cur_scale_grade == '') {
2512 $cur_scale_grade = 1.0;
2515 $db_cat = get_record('grade_item', 'modid', $cur_modid, 'cminstance', $cur_mod, 'courseid', $course->id
);
2517 if ($db_cat->category
!= $cur_cat_id) {
2518 // item doesn't match in the db so update it to point to the new category
2519 set_field('grade_item', 'category', $cur_cat_id, 'id', $db_cat->id
);
2522 if ($db_cat->scale_grade
!= $cur_maxgrade/$cur_scale_grade) {
2523 // scale_grade doesn't match
2524 set_field('grade_item', 'scale_grade', ($cur_maxgrade/$cur_scale_grade), 'id', $db_cat->id
);
2527 set_field('grade_item', 'extra_credit', $cur_extra_credit, 'id', $db_cat->id
);
2531 $item->courseid
= $course->id
;
2532 $item->category
= $cur_cat_id;
2533 $item->modid
= $cur_modid;
2534 $item->cminstance
= $cur_mod;
2535 $item->scale_grade
= $cur_scale_grade;
2536 $item->extra_credit
= $cur_extra_credit;
2537 insert_record('grade_item', $item);
2542 function grade_add_category_form() {
2543 /// outputs a form to add a category
2544 /// just a simple text box with submit
2547 echo '<form name="new_category">';
2548 echo get_string('addcategory','grades').':<input type="text" name="name" size="20" />';
2549 echo '<input type="hidden" name="id" value="'.$course->id
.'" />';
2550 echo '<input type="hidden" name="action" value="insert_category" />';
2551 echo '<input type="hidden" name="sesskey" value="'.$USER->sesskey
.'" />';
2552 echo '<input type="submit" value="'.get_string('addcategory','grades').'" />';
2556 function grade_delete_category_form() {
2557 // outputs a form to delete a category
2560 echo '<form name="delete_category">';
2561 echo get_string('deletecategory','grades').': <select name="category_id">';
2562 grade_category_select();
2563 echo '</select><input type="hidden" name="id" value="'.$course->id
.'" />';
2564 echo '<input type="hidden" name="sesskey" value="'.$USER->sesskey
.'" />';
2565 echo '<input type="hidden" name="action" value="delete_category" />';
2566 echo '<input type="submit" value="'.get_string('deletecategory','grades').'" /></form>';
2569 function grade_insert_category() {
2574 $category->name
=optional_param('name');
2575 $category->courseid
=$course->id
;
2577 if (!empty($USER->id
)) {
2578 if (!confirm_sesskey()) {
2579 error(get_string('confirmsesskeybad', 'error'));
2583 // make sure the record isn't already there and insert if okay
2584 if (record_exists('grade_category', 'name', $category->name
, 'courseid', $category->courseid
)) {
2585 // category already exists
2587 elseif ($category->name
!= ''){
2588 if (!insert_record('grade_category', $category) ) {
2589 echo '<font color="red">'.get_string('addcategoryerror','grades').'</font>';
2594 function grade_category_select($id_selected = 0) {
2595 /// prints out a select box containing categories.
2600 echo '<option value="blank">'.get_string('choosecategory','grades').'</option>';
2602 $categories = get_records('grade_category', 'courseid', $course->id
, 'name');
2604 if (!isset($categories)) {
2605 error(get_string("nocategories"));
2608 foreach($categories as $category) {
2609 if ($category->name
== UNCATEGORISED
) {
2610 $category->name
= get_string('uncategorised', 'grades');
2612 if ($category->id
== $id_selected) {
2613 echo '<option value="'.$category->id
.'" selected="selected">'.$category->name
.'</option>';
2616 echo '<option value="'.$category->id
.'">'.$category->name
.'</option>';
2622 function grade_display_grade_preferences($course, $preferences) {
2626 if ($preferences->use_advanced
== 0) {
2628 $buttonlabel = get_string('useadvanced', 'grades');
2631 $buttonlabel = get_String('hideadvanced', 'grades');
2634 $buttonoptions = array('action' => 'set_grade_preferences',
2635 'id' => $course->id
,
2636 'sesskey' => sesskey(),
2637 'use_advanced' => $useadvanced);
2640 print_heading_with_help(get_string('setpreferences','grades'), 'preferences', 'grade');
2643 print_single_button('index.php', $buttonoptions, $buttonlabel, 'post');
2644 echo '<br /></center>';
2646 echo '<form name="set_grade_preferences" method="post" action="./index.php">';
2647 echo '<input type="hidden" name="action" value="set_grade_preferences" />';
2648 echo '<input type="hidden" name="id" value="'.$course->id
.'" />';
2649 echo '<input type="hidden" name="sesskey" value="'.sesskey().'" />';
2650 echo '<table border="0" cellspacing="2" cellpadding="5" align="center" class="gradeprefs generalbox"';
2652 $optionsyesno = NULL;
2653 $optionsyesno[0] = get_string('no');
2654 $optionsyesno[1] = get_string('yes');
2657 if ($preferences->use_advanced
) {
2659 $options[0] = get_string('no');
2660 $options[1] = get_string('toonly', 'moodle', $course->teachers
);
2661 $options[2] = get_string('toeveryone', 'moodle');
2663 // display grade weights
2664 echo '<tr><td class="c0">'.get_string('displayweighted','grades').':</td>';
2665 echo '<td class="c1">';
2666 choose_from_menu($options, 'display_weighted', $preferences->display_weighted
, '');
2670 echo '<tr><td class="c0">'.get_string('displaypoints','grades').':</td>';
2671 echo '<td class="c1">';
2672 choose_from_menu($options, 'display_points', $preferences->display_points
, '');
2676 echo '<tr><td class="c0">'.get_string('displaypercent','grades').':</td>';
2677 echo '<td class="c1">';
2678 choose_from_menu($options, 'display_percent', $preferences->display_percent
, '');
2681 // display letter grade
2682 echo '<tr><td class="c0">'.get_string('displaylettergrade','grades').':</td>';
2683 echo '<td class="c1">';
2684 choose_from_menu($options, 'display_letters', $preferences->display_letters
, '');
2687 // letter grade uses weighted percent
2689 $options[0] = get_string('usepercent','grades');
2690 $options[1] = get_string('useweighted','grades');
2692 echo '<tr><td class="c0">'.get_string('lettergrade','grades').':</td>';
2693 echo '<td class="c1">';
2694 choose_from_menu($options, 'use_weighted_for_letter', $preferences->use_weighted_for_letter
, '');
2698 $headerlist[0] = get_string('none');
2699 for ($i=1; $i<=100; $i++
) {
2700 $headerlist[$i] = $i;
2703 // reprint headers every n lines default n=0
2704 echo '<tr><td class="c0">'.get_string('reprintheaders','grades').':</td>';
2705 echo '<td class="c1">';
2706 choose_from_menu($headerlist, 'reprint_headers', $preferences->reprint_headers
, '');
2709 // show hidden grade items to teacher
2710 echo '<tr><td class="c0">'.get_string('showhiddenitems','grades').'</td>';
2711 echo '<td class="c1">';
2712 choose_from_menu($optionsyesno, 'show_hidden', $preferences->show_hidden
, '');
2715 echo '<tr><td colspan="3" align="center"><input type="submit" value="'.get_string('savepreferences','grades').'" /></td></tr></table></form>';
2720 function grade_display_letter_grades() {
2725 $db_letters = get_records('grade_letter', 'courseid', $course->id
, 'grade_high DESC');
2728 $using_defaults = false;
2729 foreach ($db_letters as $letter) {
2730 $letters[$letter->id
]->letter
= $letter->letter
;
2731 $letters[$letter->id
]->grade_low
= $letter->grade_low
;
2732 $letters[$letter->id
]->grade_high
= $letter->grade_high
;
2733 $letters[$letter->id
]->courseid
= $course->id
;
2737 $using_defaults = true;
2739 $letters[0]->letter
='A';
2740 $letters[0]->grade_low
=93.00;
2741 $letters[0]->grade_high
=100.00;
2742 $letters[0]->courseid
= $course->id
;
2744 $letters[1]->letter
='A-';
2745 $letters[1]->grade_low
=90.00;
2746 $letters[1]->grade_high
=92.99;
2747 $letters[1]->courseid
= $course->id
;
2749 $letters[2]->letter
='B+';
2750 $letters[2]->grade_low
=87.00;
2751 $letters[2]->grade_high
=89.99;
2752 $letters[2]->courseid
= $course->id
;
2754 $letters[3]->letter
='B';
2755 $letters[3]->grade_low
=83.00;
2756 $letters[3]->grade_high
=86.99;
2757 $letters[3]->courseid
= $course->id
;
2759 $letters[4]->letter
='B-';
2760 $letters[4]->grade_low
=80.00;
2761 $letters[4]->grade_high
=82.99;
2762 $letters[4]->courseid
= $course->id
;
2764 $letters[5]->letter
='C+';
2765 $letters[5]->grade_low
=77.00;
2766 $letters[5]->grade_high
=79.99;
2767 $letters[5]->courseid
= $course->id
;
2769 $letters[6]->letter
='C';
2770 $letters[6]->grade_low
=73.00;
2771 $letters[6]->grade_high
=76.99;
2772 $letters[6]->courseid
= $course->id
;
2774 $letters[7]->letter
='C-';
2775 $letters[7]->grade_low
=70.00;
2776 $letters[7]->grade_high
=72.99;
2777 $letters[7]->courseid
= $course->id
;
2779 $letters[8]->letter
='D+';
2780 $letters[8]->grade_low
=67.00;
2781 $letters[8]->grade_high
=69.99;
2782 $letters[8]->courseid
= $course->id
;
2784 $letters[9]->letter
='D';
2785 $letters[9]->grade_low
=60.00;
2786 $letters[9]->grade_high
=66.99;
2787 $letters[9]->courseid
= $course->id
;
2789 $letters[10]->letter
='F';
2790 $letters[10]->grade_low
=0.00;
2791 $letters[10]->grade_high
=59.99;
2792 $letters[10]->courseid
= $course->id
;
2795 echo '<table border="0" cellspacing="2" cellpadding="5" align="center" class="generalbox"><tr><th colspan="3" class="header">'.get_string('setgradeletters','grades');
2796 helpbutton('letter', get_string('gradeletterhelp','grades'), 'grade');
2797 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>';
2798 echo '<form name="grade_letter"><input type="hidden" name="id" value="'.$course->id
.'" />';
2799 echo '<input type="hidden" name="action" value="set_letter_grades" />';
2800 echo '<input type="hidden" name="sesskey" value="'.$USER->sesskey
.'" />';
2802 foreach ($letters as $id=>$items) {
2803 if ($id !='' && !$using_defaults) {
2804 // send the record id so if the user deletes the values we can delete the row.
2805 echo '<input type="hidden" name="id'.$i.'" value="'.$id.'" />';
2807 echo '<tr><td align="center" class="generalboxcontent"><input size="8" type="text" name="letter'.$i.'" value="'.$items->letter
.'" /></td>'."\n";
2808 echo '<td align="center" class="generalboxcontent"><input size="8" type="text" name="grade_low'.$i.'" value="'.$items->grade_low
.'" /></td>'."\n";
2809 echo '<td align="center" class="generalboxcontent"><input size="8" type="text" name="grade_high'.$i.'" value="'.$items->grade_high
.'" /></td></tr>'."\n";
2812 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>';
2813 echo '<tr><td colspan="3" align="center" class="generalboxcontent"><input type="submit" value="'.get_string('savechanges','grades').'" /></td></tr>';
2814 echo '<input type="hidden" name="totalitems" value="'.$i.'" />';
2815 echo '</form><tr><td colspan="3" align="center" class="generalboxcontent">'.get_string('gradeletternote','grades').'</table>';
2818 function grade_set_letter_grades() {
2823 if (!empty($USER->id
)) {
2824 if (!confirm_sesskey()) {
2825 error(get_string('confirmsesskeybad', 'error'));
2829 $totalitems= clean_param($_REQUEST['totalitems'], PARAM_CLEAN
);
2831 for($i=0; $i<=$totalitems; $i++
) {
2832 if (isset($_REQUEST["id$i"])) {
2833 // item submitted was already in database
2834 $letterid = $_REQUEST["id$i"];
2835 $updateletters[$letterid]->letter
= clean_param($_REQUEST["letter$i"], PARAM_CLEAN
);
2836 // grade_low && grade_high don't need cleaning as they are possibly floats (no appropriate clean method) so we check is_numeric
2837 $updateletters[$letterid]->grade_low
= $_REQUEST["grade_low$i"];
2838 $updateletters[$letterid]->grade_high
= $_REQUEST["grade_high$i"];
2839 $updateletters[$letterid]->id
= $letterid;
2843 $newletter->letter
= clean_param($_REQUEST["letter$i"], PARAM_CLEAN
);
2844 $newletter->grade_low
= $_REQUEST["grade_low$i"];
2845 $newletter->grade_high
= $_REQUEST["grade_high$i"];
2846 $newletter->courseid
= $course->id
;
2847 if (is_numeric($newletter->grade_high
) && is_numeric($newletter->grade_low
)) {
2848 insert_record('grade_letter', $newletter);
2851 if ($i < $totalitems) {
2852 if ($newletter->grade_high
!= '' or $newletter->grade_low
!= '') {
2853 echo '<center>'.get_string('lettergradenonnumber','grades').' '.$newletter->letter
.' item number: '.$i.'<br /></center>';
2860 if (isset($updateletters)) {
2861 foreach($updateletters as $id=>$items) {
2862 // see if any of the values are blank... if so delete them
2863 if ($items->letter
== '' ||
$items->grade_low
== '' ||
$items->grade_high
== '') {
2864 delete_records('grade_letter', 'id', $id);
2867 if (is_numeric($items->grade_high
) && is_numeric($items->grade_low
)) {
2868 update_record('grade_letter', $items);
2871 echo '<center><font color="red">'.get_string('errorgradevaluenonnumeric','grades').$letter.'</font></center>';
2878 function grade_download_form($type='both') {
2879 global $course,$USER, $action, $cview;
2880 if ($type != 'both' and $type != 'excel' and $type != 'text') {
2884 if (isteacher($course->id
)) {
2885 echo '<table align="center"><tr>';
2886 $options['id'] = $course->id
;
2887 $options['sesskey'] = $USER->sesskey
;
2889 if ($type == 'both' ||
$type == 'excel') {
2890 $options['action'] = 'excel';
2891 echo '<td align="center">';
2892 print_single_button("index.php", $options, get_string("downloadexcel"));
2895 if ($type == 'both' ||
$type == 'text') {
2896 $options['action'] = 'text';
2897 echo '<td align="center">';
2898 print_single_button("index.php", $options, get_string("downloadtext"));
2903 $url = 'index.php?id='.$course->id
;
2904 if (!empty($action)) {
2905 $url .= '&action='.$action;
2906 if ($action == 'vcats') {
2907 $url .= '&cview='.$cview;
2910 setup_and_print_groups($course, $course->groupmode
, $url);
2913 echo '</tr></table>';