]> git.mjollnir.org Git - moodle.git/commitdiff
MDL-10438 return tracking in grading forms; new grade plugin selector
authorskodak <skodak>
Mon, 16 Jul 2007 18:58:09 +0000 (18:58 +0000)
committerskodak <skodak>
Mon, 16 Jul 2007 18:58:09 +0000 (18:58 +0000)
14 files changed:
grade/edit/calculation.php
grade/edit/calculation_form.php
grade/edit/category.php
grade/edit/category_form.php
grade/edit/grade.php
grade/edit/grade_form.php
grade/edit/item.php
grade/edit/item_form.php
grade/edit/tree.php
grade/lib.php
grade/report.php
grade/report/grader/index.php
grade/report/grader/lib.php
grade/report/grader/tabs.php

index e8c846d7eb59715194aeb077cf097318014f7182..36e0af573b4ebe1ec8ee3fb6ac35b2a686a2ff04 100644 (file)
@@ -1,5 +1,6 @@
 <?php  //$Id$
 require_once '../../config.php';
+require_once $CFG->dirroot.'/grade/lib.php';
 require_once $CFG->libdir.'/gradelib.php';
 require_once 'calculation_form.php';
 
@@ -16,8 +17,8 @@ $context = get_context_instance(CONTEXT_COURSE, $course->id);
 //require_capability() here!!
 
 // default return url
-//TODO: add proper return support
-$returnurl = $CFG->wwwroot.'/grade/report.php?report=grader&amp;id='.$course->id;
+$gpr = new grade_plugin_return();
+$returnurl = $gpr->get_return_url($CFG->wwwroot.'/grade/report.php?id='.$course->id);
 
 if (!$grade_item = grade_item::fetch(array('id'=>$id, 'courseid'=>$course->id))) {
     error('Incorect item id');
@@ -28,7 +29,7 @@ if ($grade_item->is_normal_item() or ($grade_item->gradetype != GRADE_TYPE_VALUE
     redirect($returnurl, get_string('erornocalculationallowed', 'grades')); //TODO: localize
 }
 
-$mform = new edit_calculation_form();
+$mform = new edit_calculation_form(null, array('gpr'=>$gpr));
 
 if ($mform->is_cancelled()) {
     redirect($returnurl);
index dac6f10eaeb69a0edd5cc036838721bd18eb2159..ae0e7fbe8b69ab39299ae15bd9d2f54351e86b1a 100644 (file)
@@ -21,6 +21,10 @@ class edit_calculation_form extends moodleform {
         $mform->addElement('hidden', 'courseid', 0);
         $mform->setType('courseid', PARAM_INT);
 
+/// add return tracking info
+        $gpr = $this->_customdata['gpr'];
+        $gpr->add_mform_elements($mform);
+
 //-------------------------------------------------------------------------------
         // buttons
         $this->add_action_buttons();
index 6b71532115b7a106ffc1582ab2f5973bb709595f..18b74b2e55aef8fc385197dc45c204c2e4ff202a 100644 (file)
@@ -1,6 +1,7 @@
 <?php  //$Id$
 
 require_once '../../config.php';
+require_once $CFG->dirroot.'/grade/lib.php';
 require_once $CFG->libdir.'/gradelib.php';
 require_once 'category_form.php';
 
@@ -17,10 +18,11 @@ $context = get_context_instance(CONTEXT_COURSE, $course->id);
 //require_capability() here!!
 
 // default return url
-$returnurl = 'tree.php?id='.$course->id;
+$gpr = new grade_plugin_return();
+$returnurl = $gpr->get_return_url('tree.php?id='.$course->id);
 
 
-$mform = new edit_category_form();
+$mform = new edit_category_form(null, array('gpr'=>$gpr));
 if ($category = get_record('grade_categories', 'id', $id, 'courseid', $course->id)) {
     $mform->set_data($category);
 } else {
index 70b5747327dee2aaf6b0c8c536618763b28ad8ce..4244804c194745d73447dc8a064b296e3786b124 100644 (file)
@@ -36,6 +36,10 @@ class edit_category_form extends moodleform {
         $mform->addElement('hidden', 'courseid', 0);
         $mform->setType('courseid', PARAM_INT);
 
+/// add return tracking info
+        $gpr = $this->_customdata['gpr'];
+        $gpr->add_mform_elements($mform);
+
 //-------------------------------------------------------------------------------
         // buttons
         $this->add_action_buttons();
index c9fa645f82c6b86fd878b3b79941d9b6c70aa347..6aabe082bcff96e4031ef4da04c22a3549a66178 100644 (file)
@@ -1,6 +1,7 @@
 <?php  //$Id$
 
 require_once '../../config.php';
+require_once $CFG->dirroot.'/grade/lib.php';
 require_once $CFG->libdir.'/gradelib.php';
 require_once 'grade_form.php';
 
@@ -18,15 +19,15 @@ $context = get_context_instance(CONTEXT_COURSE, $course->id);
 require_capability('gradereport/grader:manage', $context);
 
 // default return url
-//TODO: implement proper return support
-$returnurl = $CFG->wwwroot.'/grade/report.php?report=grader&amp;id='.$course->id;
+$gpr = new grade_plugin_return();
+$returnurl = $gpr->get_return_url($CFG->wwwroot.'/grade/report.php?id='.$course->id);
 
 // TODO: add proper check that grade is editable
 
 $grade_grades = get_record('grade_grades', 'id', $id);
 $gradeitem = get_record('grade_items', 'id', $grade_grades->itemid);
 
-$mform = new edit_grade_form(qualified_me(), array('gradeitem'=>$gradeitem));
+$mform = new edit_grade_form(null, array('gradeitem'=>$gradeitem, 'gpr'=>$gpr));
 if ($grade_grades = get_record('grade_grades', 'id', $id)) {
     if ($grade_text = get_record('grade_grades_text', 'gradeid', $id)) {
         if (can_use_html_editor()) {
@@ -64,7 +65,7 @@ if ($mform->is_cancelled()) {
     // set locktime
     $grade_grades->set_locktime($data->locktime);
 
-    redirect($returnurl, get_string('feedbacksaved', 'grades'), 1);
+    redirect($returnurl);
 }
 
 // Get extra data related to this feedback
index d22883551d8e328246a65d45c083eab76f5aa8cc..e04af01e25b5611a7cb0801be09992bffd152bce 100755 (executable)
@@ -54,6 +54,10 @@ class edit_grade_form extends moodleform {
         $mform->addElement('hidden', 'courseid', 0);
         $mform->setType('courseid', PARAM_INT);
 
+/// add return tracking info
+        $gpr = $this->_customdata['gpr'];
+        $gpr->add_mform_elements($mform);
+
 //-------------------------------------------------------------------------------
         // buttons
         $this->add_action_buttons();
index 1ea75d184b6cfb2a7fb82864295d5f5835f7561c..01230d112ec2aae6a7422616b7f97f094eefde47 100644 (file)
@@ -1,5 +1,6 @@
 <?php  //$Id$
 require_once '../../config.php';
+require_once $CFG->dirroot.'/grade/lib.php';
 require_once $CFG->libdir.'/gradelib.php';
 require_once 'item_form.php';
 
@@ -16,9 +17,10 @@ $context = get_context_instance(CONTEXT_COURSE, $course->id);
 //require_capability() here!!
 
 // default return url
-$returnurl = 'tree.php?id='.$course->id;
+$gpr = new grade_plugin_return();
+$returnurl = $gpr->get_return_url('tree.php?id='.$course->id);
 
-$mform = new edit_item_form();
+$mform = new edit_item_form(null, array('gpr'=>$gpr));
 if ($item = get_record('grade_items', 'id', $id, 'courseid', $course->id)) {
     $item->calculation = grade_item::denormalize_formula($item->calculation, $course->id);
     $mform->set_data($item);
index 4444684ecb7de7a3bf5b74e782635870bf2fc57f..f15faebf8f7445e7a5ffb5b4a63b92e4c8886b2e 100644 (file)
@@ -82,6 +82,10 @@ class edit_item_form extends moodleform {
         $mform->addElement('hidden', 'itemtype', 0);
         $mform->setType('itemtype', PARAM_ALPHA);
 
+/// add return tracking info
+        $gpr = $this->_customdata['gpr'];
+        $gpr->add_mform_elements($mform);
+
 //-------------------------------------------------------------------------------
         // buttons
         $this->add_action_buttons();
index 8ac1b5d99990568943f8f675311930a0a226d403..fdd47f3b5ea30d1ca88487afa97c9a9352653973 100644 (file)
@@ -25,6 +25,7 @@
 ///////////////////////////////////////////////////////////////////////////
 
 require_once '../../config.php';
+require_once $CFG->dirroot.'/grade/lib.php';
 require_once $CFG->libdir.'/gradelib.php';
 
 $courseid = required_param('id', PARAM_INT);
@@ -169,12 +170,11 @@ switch ($action) {
 
 print_header_simple($strgrades . ': ' . $strgraderreport, ': ' . $strcategoriesedit, $navigation, '', '', true, '', navmenu($course));
 
+/// Print the plugin selector at the top
+print_grade_plugin_selector($courseid, 'edit', 'tree');
+
 print_heading(get_string('categoriesedit', 'grades'));
 
-// Add tabs
-// TODO: implement return support - use tabs from the report plugin
-/*$currenttab = 'editcategory';
-include('tabs.php');*/
 
 print_box_start('gradetreebox generalbox');
 echo '<ul id="grade_tree">';
index 319da4d77b823911745b2312dd2f8a8040fa6612..d8b2a7ff637060855c7b3a90622dcf8deb8c9775 100644 (file)
-<?php // $Id$
+<?php //$Id$
 
-if (!defined('MOODLE_INTERNAL')) {
-            die('Direct access to this script is forbidden.');    ///  It must be included from a Moodle page
-}
-
-require_once($CFG->dirroot.'/course/lib.php');
-
-define('UNCATEGORISED', 'uncategorised');
-
-global $GRADEPREFS, $GRADEPREFSDEFAULTS;    // This variables are going to be global... :-/
-
-$GRADEPREFS = array('use_advanced',                // Only add new preferences to the end of this array!
-                    'use_weighted_for_letter',     // as the order counts and will affect backward compatibility
-                    'display_weighted',
-                    'display_points',
-                    'display_percent',
-                    'display_letters',
-                    'reprint_headers',
-                    'show_hidden',
-                    );
-
-
-$GRADEPREFSDEFAULTS = array('use_advanced'                => 0,
-                            'use_weighted_for_letter'     => 0,
-                            'display_weighted'            => 0,
-                            'display_points'              => 2,
-                            'display_percent'             => 1,
-                            'display_letters'             => 0,
-                            'reprint_headers'             => 0,
-                            'show_hidden'                 => 1
-                            );
-
-
-//******************************************************************
-// SQL FUNCTIONS 
-//******************************************************************
-
-function grade_get_category_weight($course, $category) {
-    global $CFG;
-    $sql = "SELECT id, weight, drop_x_lowest, bonus_points, hidden, c.id AS cat_id
-        FROM {$CFG->prefix}grade_category c  
-        WHERE c.courseid=$course  
-            AND c.name='$category'";
-    $temp = get_record_sql($sql);
-    return $temp;
-}
-
-function grade_get_grade_items($course) {
-    global $CFG;
-     $sql = "SELECT i.id, c.name as cname, i.modid, mm.name as modname, i.cminstance, c.hidden, cm.visible, i.sort_order
-            FROM    {$CFG->prefix}grade_item i, 
-                    {$CFG->prefix}grade_category c, 
-                    {$CFG->prefix}course_modules cm, 
-                    {$CFG->prefix}modules mm
-            WHERE c.id=i.category 
-                AND i.courseid=c.courseid 
-                AND c.courseid=$course 
-                AND cm.course=c.courseid 
-                AND cm.module=mm.id
-                AND i.modid=mm.id
-                AND cm.instance=i.cminstance";
-    $temp = get_records_sql($sql);
-    return $temp;
-}
-
-function grade_get_module_link($course, $cminstance, $modid) {
+function print_grade_plugin_selector($courseid, $active_type, $active_plugin, $return=false) {
     global $CFG;
-    $sql = "SELECT cm.id, 1 FROM {$CFG->prefix}course_modules cm, {$CFG->prefix}modules mm, {$CFG->prefix}grade_item i 
-            WHERE i.modid='".$modid."' 
-                AND i.modid=mm.id 
-                AND cm.instance = i.cminstance 
-                AND i.cminstance=".$cminstance."
-                AND i.courseid=cm.course AND cm.module=mm.id AND i.courseid=$course";
-    $temp = get_record_sql($sql);
-    return $temp;
-}
 
-function grade_get_grade_letter($course, $grade) {
-    global $CFG;
-    $sql = "SELECT id, letter FROM {$CFG->prefix}grade_letter WHERE courseid=$course AND grade_high >= $grade AND grade_low <= $grade";
-    $temp = get_record_sql($sql);
-    return $temp;
-}
+    $context = get_context_instance(CONTEXT_COURSE, $courseid);
 
-function grade_get_exceptions($course) {
-    global $CFG;
-    $sql = "SELECT e.id, e.userid, gi.cminstance, gi.modid, c.name as catname, mm.name as modname
-            FROM {$CFG->prefix}grade_exceptions e, 
-                {$CFG->prefix}grade_item gi, 
-                {$CFG->prefix}grade_category c,
-                {$CFG->prefix}course_modules cm, 
-                {$CFG->prefix}modules mm
-            WHERE e.courseid=$course 
-                AND gi.id = e.grade_itemid 
-                AND c.id = gi.category
-                AND cm.course=c.courseid 
-                AND cm.module=mm.id
-                AND gi.modid=mm.id";
-    
-    $temp = get_records_sql($sql);
-    return $temp;
-}
+    $menu = array();
 
-function grade_get_exceptions_user($course, $userid) {
-    global $CFG;
-    $sql = "SELECT e.id, e.userid, gi.cminstance, gi.modid, c.name as catname, mm.name as modname
-            FROM {$CFG->prefix}grade_exceptions e, 
-                {$CFG->prefix}grade_item gi, 
-                {$CFG->prefix}grade_category c,
-                {$CFG->prefix}course_modules cm, 
-                {$CFG->prefix}modules mm
-            WHERE e.courseid=$course
-            AND e.userid=$userid 
-                AND gi.id = e.grade_itemid 
-                AND c.id = gi.category
-                AND cm.course=c.courseid 
-                AND cm.module=mm.id
-                AND gi.modid=mm.id";
-    
-    $temp = get_records_sql($sql);
-    return $temp;
-}
-function grade_letters_set($course) {
-    global $CFG;
-    $sql = "SELECT * FROM {$CFG->prefix}grade_letter WHERE courseid=$course";
-    $letters_set = get_records_sql($sql);
-    if ($letters_set) {
-        return true;
-    }
-    else {
-        return false;
-    }
-}
+    $active = '';
 
-function grade_get_users_by_group($course, $group) {
-    global $CFG;
-    $sql = "SELECT userid FROM {$CFG->prefix}groups_members WHERE courseid=$course AND groupid = $group";
-    $members = get_records_sql($sql);
-    if ($members) {
-        foreach($members as $member) {
-            // FIX ME: there is no $userid defined!!! - from where is this function used anyway??
-            $group->$userid = true;
-        }
-        return $group;
-    }
-    else {
-        return NULL;
-    }
-}
-
-//******************************************************************
-// END SQL FUNCTIONS 
-//******************************************************************
-
-function grade_get_formatted_grades() {
-    global $CFG;
-    global $COURSE;
-    global $preferences;
-    $course = $COURSE;
-    $i = 2; // index to differentiate activities with the same name MDL-6876
-    $grades = grade_get_grades();
-    if (isset($grades)) {
-        // iterate through all students
-        foreach($grades as $cur_category=>$grade_category) {
-            // $cur_category holds the value of the current category name
-            // $grade_category holds an array of all the mod types that are in this category
-            if (isset($grade_category)) {
-                foreach($grade_category as $cur_mod=>$mod_category)  {
-                    // $cur_mod is the id of the current moodle module type
-                    // $mod_category holds the grades for $cur_mod (current mod type)
-                    $module_info = get_record('modules', 'id', $cur_mod);
-                    $cur_modname = $module_info->name;
-                    if (isset($mod_category)) {
-                        foreach($mod_category as $cur_cminstance=>$students_grade) {
-                            // $cur_cminstance is the course module instance for the cur_mod
-                            $instance = get_record($cur_modname, 'id',$cur_cminstance, 'course',$course->id);
-                            // it's necessary to check if the name is blank because some mods don't clean up the grades when the instance is deleted
-                            // this is a bug. as it is plausible that some item could get created and have old data from a previous mod laying around
-                            if ($instance->name != '') {                
-                                // 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
-                                if (isset($all_categories["$cur_category"]["$instance->name"])) {
-                                    $instance->name= $instance->name.' #'.$i++;
-                                }
-
-                                if (isset($students_grade->grades) && $students_grade->grades != '') {
-                                    foreach($students_grade->grades as $student=>$grade) {
-                                        // add an entry for any student that has a grade
-                                        $grades_by_student["$student"]["$cur_category"]["$instance->name"]['grade'] = $grade;
-                                        $grades_by_student["$student"]["$cur_category"]["$instance->name"]['sort_order'] = $students_grade->sort_order;
-                                        
-                                        if (!isset($grades_by_student["$student"]["$cur_category"]['stats'])) {
-                                            $grades_by_student["$student"]["$cur_category"]['stats'] = array();
-                                        }
-                                        
-                                        if (!isset($grades_by_student["$student"]["$cur_category"]['stats']['points'])) {
-                                            $grades_by_student["$student"]["$cur_category"]['stats']['points'] = $grade;
-                                        }
-                                        else {
-                                            $grades_by_student["$student"]["$cur_category"]['stats']['points'] = $grades_by_student["$student"]["$cur_category"]['stats']['points'] + $grade;
-                                        }
-        
-                                        // This next block just creates a comma seperated list of all grades for the category
-                                        if (isset($grades_by_student["$student"]["$cur_category"]['stats']['allgrades'])) {
-                                            $grades_by_student["$student"]["$cur_category"]['stats']['allgrades'] .=  ','.$grade;
-                                        }
-                                        else {
-                                            $grades_by_student["$student"]["$cur_category"]['stats']['allgrades'] = $grade;
-                                        }
-                                    }
-                                }
-
-                            
-                        
-                                // set up a list of all categories and assignments (adjusting things for extra credit where necessary)
-                                $all_categories["$cur_category"]["$instance->name"]['hidden'] = $students_grade->hidden;
-                                $all_categories["$cur_category"]["$instance->name"]['sort_order'] = $students_grade->sort_order;
-                                
-                                $all_categories["$cur_category"]["$instance->name"]['extra_credit'] = $students_grade->extra_credit;
-                                
-                                if ($all_categories["$cur_category"]["$instance->name"]['extra_credit'] != 1) {
-                                    $all_categories["$cur_category"]["$instance->name"]['maxgrade'] = $students_grade->maxgrade;
-                                }
-                                else {
-                                    $all_categories["$cur_category"]["$instance->name"]['maxgrade'] = 0; 
-                                }                                
-                                $all_categories["$cur_category"]["$instance->name"]['scale_grade'] = $students_grade->scale_grade;
-                                if ($students_grade->scale_grade != 0) {
-                                    $all_categories["$cur_category"]["$instance->name"]['scaled_max'] = round($all_categories["$cur_category"]["$instance->name"]['maxgrade']/$students_grade->scale_grade);
-                                }
-                                else {
-                                    // avoids divide by zero... scale_grade shouldn't be set to 0 anyway
-                                    $all_categories["$cur_category"]["$instance->name"]['scaled_max'] = $all_categories["$cur_category"]["$instance->name"]['maxgrade'];
-                                    $all_categories["$cur_category"]["$instance->name"]['scale_grade'] = 1.0;
-                                }
-                                if (! isset($all_categories["$cur_category"]['stats']) ) {
-                                    $all_categories["$cur_category"]['stats'] = array();
-                                }
-                                $all_categories["$cur_category"]["$instance->name"]['grade_against'] = $all_categories["$cur_category"]["$instance->name"]['scaled_max'];
-                                if (!isset($all_categories["$cur_category"]['stats']['weight'])) {
-                                    $weight = grade_get_category_weight($course->id, $cur_category);        
-                                    $all_categories["$cur_category"]['stats']['weight'] = $weight->weight;
-                                }
-        
-                                $all_categories["$cur_category"]["$instance->name"]['cminstance'] = $cur_cminstance;
-                                $all_categories["$cur_category"]["$instance->name"]['modid'] = $cur_mod;
-                                $modname = get_record('modules','id',$cur_mod);
-                                $all_categories["$cur_category"]["$instance->name"]['modname'] = $modname->name;
-        
-                                // get bonus points and drop the x lowest                            
-                                $drop = get_record('grade_category', 'courseid', $course->id, 'name', $cur_category);
-                                $all_categories["$cur_category"]['stats']['drop'] = $drop->drop_x_lowest;
-                                $all_categories["$cur_category"]['stats']['bonus_points'] = $drop->bonus_points;
-                            }
-                        }
-                    }
-                } 
-            }
-        }
-        if (!$students = grade_get_course_students($course->id)) {
-            return false;  
-        }
-
-                              
-        if (isset($students) && $students) {
-            foreach ($students as $userid => $student) {  
-                $grades_by_student["$userid"]['student_data']['firstname'] = $student->firstname;
-                $grades_by_student["$userid"]['student_data']['lastname'] = $student->lastname;
-                $grades_by_student["$userid"]['student_data']['email'] = $student->email;
-                if (isset($student->location)) {
-                    $grades_by_student["$userid"]['student_data']['location'] = $student->location;
-                }
-                $grades_by_student["$userid"]['student_data']['department'] = $student->department;
-                $grades_by_student["$userid"]['student_data']['idnumber'] = $student->idnumber;
-            }
-        }
-        
-        // unset any item that has a "" for a name at this point this inludes instructors who have grades or any student formerly enrolled.
-        if (isset($grades_by_student)) {
-            foreach ($grades_by_student as $student => $assignments) {
-                if (!isset($grades_by_student["$student"]['student_data']['firstname']) && !isset($grades_by_student["$student"]['student_data']['lastname'])) {
-                    unset($grades_by_student["$student"]);
-                }
-            }
-        }
-        
-        
-        // set the totalpoints for each category taking into account drop_x_lowest
-        // also set the number of grade items for the category to make calculating grades for students who have not taken anything easier        
-        foreach($all_categories as $category => $assignments) {
-            $dropcount = 0;    
-            $all_categories["$category"]['stats']['totalpoints'] = 0;
-            $all_categories["$category"]['stats']['grade_items'] = 0;
-            if (isset($assignments)) {
-                foreach($assignments as $assignment=>$grade) {
-                    if ($assignment != 'stats') {
-                        if ($dropcount < $all_categories["$category"]['stats']['drop']) {
-                            // skip a grade in the total
-                            $dropcount++;
-                        }
-                        else {
-                            // make sure the current assignment is not extra credit and then add it to the totalpoints
-                            if ($all_categories["$category"][$assignment]['extra_credit'] != 1) {
-                                $all_categories["$category"]['stats']['totalpoints'] = $all_categories["$category"]['stats']['totalpoints'] + $assignments["$assignment"]['grade_against'];
-                                $all_categories["$category"]['stats']['grade_items'] = $all_categories["$category"]['stats']['grade_items'] + 1;
-                            }
-                        }
-                    }
-                }
-            }
-        }
-    
-
-        // if the user has selected a group to view by get the group members
-        if ($currentgroup = get_current_group($course->id)) {
-            $groupmembers = get_group_users($currentgroup);
-        }
-
-        // this next block catches any students who do not have a grade for any item in a particular category
-        foreach($all_categories as $category => $main_category) {
-            // make sure each student has an entry for each category
-            if (isset($grades_by_student)) {
-                foreach($grades_by_student as $student=>$categories) {
-                    if ( (isset($groupmembers) && isset($groupmembers[$student])) || !isset($groupmembers)) {
-                
-                        $grades_by_student["$student"]["$category"]['stats']['totalpoints'] = $main_category['stats']['totalpoints'];
-                        $grades_by_student["$student"]["$category"]['stats']['weight'] = $main_category['stats']['weight'];
-                        $grades_by_student["$student"]["$category"]['stats']['grade_items'] = $main_category['stats']['grade_items'];
-
-                        foreach($main_category as $assignment => $items) {
-                            if ($assignment != 'stats') {
-                                if(!isset($grades_by_student["$student"]["$category"]["$assignment"]['grade'])) {
-                                    if (isset($grades_by_student["$student"]["$category"]['stats']['allgrades'])) {
-                                        $grades_by_student["$student"]["$category"]['stats']['allgrades'] .=  ',0';
-                                    } else {
-                                        $grades_by_student["$student"]["$category"]['stats']['allgrades'] = '0';
-                                    }
-                                }
-                            }            
-                        }
-            
-                        if (!isset($grades_by_student["$student"]["$category"]['stats']['points'])) {
-                           $grades_by_student["$student"]["$category"]['stats']['points'] = '-';
-               
-                        }
-        
-                        else {
-                            // points are set... see if the current category is using drop the x lowest and do so
-                            // also drop exceptions first, so then this grades(s) won't be recoqnized as the x lowest
-                // Get exception scores and assign them in the array
-                            if ($main_category['stats']['drop'] != 0) {
-                                $exceptions = grade_get_exceptions_user($course->id, $student);
-                                if (isset($exceptions) && $exceptions) {
-                                    foreach($exceptions as $exception) {
-                                        if (isset($grades_by_student["$exception->userid"])) {
-                                            if ($grades_by_student["$exception->userid"]["$exception->catname"]) {
-                                                $assgn = get_record($exception->modname, 'id', $exception->cminstance, 'course', $course->id);
-                                                $grade = $grades_by_student["$exception->userid"]["$exception->catname"]["$assgn->name"]['grade'];
-                        if (isset($grade)) {
-                            if (!isset($grades_by_student["$exception->userid"]["$exception->catname"]['stats']['exceptions'])) {
-                                                             $grades_by_student["$exception->userid"]["$exception->catname"]['stats']['exceptions'] = $grade;
-                                                    }
-                                                    elseif (isset($grades_by_student["$exception->userid"]["$exception->catname"]['stats']['exceptions'])) {
-                                                             $grades_by_student["$exception->userid"]["$exception->catname"]['stats']['exceptions'] .= ','. $grade;
-                            }
-                        }
-                                            }
-                                        }
-                                    }
-                }
-                                if (isset($grades_by_student["$student"]["$category"]['stats']['exceptions'])) {
-                                    $grades_by_student["$student"]["$category"]['stats']['allgrades'] = grade_drop_exceptions($grades_by_student["$student"]["$category"]['stats']['allgrades'], $grades_by_student["$student"]["$category"]['stats']['exceptions']);
-                                }
-                
-                                $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']);
-                                if ($grades_by_student["$student"]["$category"]['stats']['points'] != '-') {
-                                    $cat_points = 0;
-                                    $count_grades = explode(',',$grades_by_student["$student"]["$category"]['stats']['allgrades']);
-                                    foreach($count_grades as $grade) {
-                                        $cat_points = $cat_points + $grade;
-                                    }
-                                    $grades_by_student["$student"]["$category"]['stats']['points'] = $cat_points;
-                                }
-                            }
-                        }
-       
-                        // add any bonus points for the category
-                        if ($all_categories["$category"]['stats']['bonus_points'] != 0) {
-                            $grades_by_student["$student"]["$category"]['stats']['points'] = $grades_by_student["$student"]["$category"]['stats']['points'] + $all_categories["$category"]['stats']['bonus_points'];
-                        }
-        
-                        foreach($main_category as $assignment => $items) {
-                            if ($assignment != 'stats') {
-                                if(!isset($grades_by_student["$student"]["$category"]["$assignment"]['maxgrade'])) {
-                                    $grades_by_student["$student"]["$category"]["$assignment"]['maxgrade'] = $all_categories["$category"]["$assignment"]['grade_against'];
-                                }
-                                if(!isset($grades_by_student["$student"]["$category"]["$assignment"]['grade'])) {
-                                    $grades_by_student["$student"]["$category"]["$assignment"]['grade'] = '-';
-                                    $grades_by_student["$student"]["$category"]["$assignment"]['sort_order'] = $all_categories["$category"]["$assignment"]['sort_order'];
-                                }
-                            }            
-                        }
-                    } // end groupmember if
-                    else {
-                        // unset grade since they are not in the selected group.
-                        unset($grades_by_student["$student"]);
-                    }
-                }
-            }
-        }
-        // set the total coursepoints
-        $all_categories['stats']['weight'] = 0;
-        $all_categories['stats']['totalpoints'] = 0;
-        foreach($all_categories as $category => $info) {
-            if ($category != 'stats') {
-                $all_categories['stats']['weight'] = $all_categories['stats']['weight'] + $all_categories["$category"]['stats']['weight'];
-                $all_categories['stats']['totalpoints'] = $all_categories['stats']['totalpoints'] + $all_categories["$category"]['stats']['totalpoints'];
-            }
-        }
-        
-        // set each individuals total points by category so we can then exclude some grades if set to use exceptions
-        if (isset($grades_by_student)) {
-            foreach($grades_by_student as $student => $categories) {
-                foreach($all_categories as $category => $assignments) {
-                    if ($category != 'stats') {
-                        $grades_by_student["$student"]["$category"]['stats']['totalpoints'] = $all_categories["$category"]['stats']['totalpoints'];
-                    }
-                }
-                $grades_by_student["$student"]['student_data']['totalpoints'] = $all_categories['stats']['totalpoints'];
-            }
-        }
-        
-        // take into account any excluded grade_items
-        $strexcluded = get_string('excluded', 'grades');
-        $exceptions = grade_get_exceptions($course->id);
-        if (isset($exceptions) && $exceptions) {
-            foreach($exceptions as $exception) {
-                if (isset($grades_by_student["$exception->userid"])) {
-                    if ($grades_by_student["$exception->userid"]["$exception->catname"]) {
-                        $assgn = get_record($exception->modname, 'id', $exception->cminstance, 'course', $course->id);
-                        $grades_by_student["$exception->userid"]['student_data']['totalpoints'] = $grades_by_student["$exception->userid"]['student_data']['totalpoints'] - $all_categories["$exception->catname"]["$assgn->name"]['maxgrade'];
-            //total point should not be smaller than grade against
-            if ($grades_by_student["$exception->userid"]["$exception->catname"]['stats']['totalpoints'] - $all_categories["$exception->catname"]["$assgn->name"]['grade_against'] != 0 ) {
-                            $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'];
-            }
-                        $grades_by_student["$exception->userid"]["$exception->catname"]['stats']['grade_items'] = $grades_by_student["$exception->userid"]["$exception->catname"]['stats']['grade_items'] - 1;
-                        if ($grades_by_student["$exception->userid"]["$exception->catname"]['stats']['grade_items'] < 0) {
-                            $grades_by_student["$exception->userid"]["$exception->catname"]['stats']['grade_items'] = 0;
-            }
-                        if ($all_categories["$exception->catname"]['stats']['drop'] == 0) {
-                            $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'];
-                        }
-                        $grades_by_student["$exception->userid"]["$exception->catname"]["$assgn->name"]['maxgrade'] = $strexcluded;
-                        $grades_by_student["$exception->userid"]["$exception->catname"]["$assgn->name"]['grade'] = $strexcluded;
-                        // see if they are excluded entirely from a category
-                        if ($grades_by_student["$exception->userid"]["$exception->catname"]['stats']['totalpoints'] == 0) {
-                            $grades_by_student["$exception->userid"]["$exception->catname"]['stats']['totalpoints'] = $strexcluded;
-                            $grades_by_student["$exception->userid"]["$exception->catname"]['stats']['percent'] = $strexcluded;
-                            $grades_by_student["$exception->userid"]["$exception->catname"]['stats']['points'] = $strexcluded;
-                            $grades_by_student["$exception->userid"]["$exception->catname"]['stats']['weight'] = $strexcluded;
-                            $grades_by_student["$exception->userid"]["$exception->catname"]['stats']['weighted'] = $strexcluded;
-                        }
-                    }
-                }
-                else {
-                    // 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
-                }
-            }
-        }
-                        
-        if (isset($grades_by_student)) {
-            foreach($grades_by_student as $student => $categories) {
-                $grades_by_student["$student"]['student_data']['points'] = '-';
-                $grades_by_student["$student"]['student_data']['totalpoints'] = 0;
-                $grades_by_student["$student"]['student_data']['weight'] = 0;
-                $grades_by_student["$student"]['student_data']['weighted'] = 0;
-                foreach($categories as $category => $assignments) {
-                    if ($category != 'student_data') {
-                        // set the student's total points earned 
-                        if ($grades_by_student["$student"]["$category"]['stats']['points'] != $strexcluded) {
-                            if ($grades_by_student["$student"]["$category"]['stats']['points'] != '-') {
-                                $grades_by_student["$student"]['student_data']['points'] = $grades_by_student["$student"]['student_data']['points'] + $grades_by_student["$student"]["$category"]['stats']['points'];
-                            }
-                        $grades_by_student["$student"]['student_data']['totalpoints'] = $grades_by_student["$student"]['student_data']['totalpoints'] + $grades_by_student["$student"]["$category"]['stats']['totalpoints'];
-                        }
-                
-                        // set percents and weights for each assignment
-                        foreach($assignments as $assignment => $info) {
-                            if ($assignment != 'stats') {
-                                if ($grades_by_student["$student"]["$category"]["$assignment"]['grade'] != $strexcluded) {    
-                                    if ($grades_by_student["$student"]["$category"]["$assignment"]['maxgrade'] != 0) {
-                                        $grades_by_student["$student"]["$category"]["$assignment"]['percent'] = round($grades_by_student["$student"]["$category"]["$assignment"]['grade']/$grades_by_student["$student"]["$category"]["$assignment"]['maxgrade']*100,2);
-                                    }
-                                    else {
-                                        $grades_by_student["$student"]["$category"]["$assignment"]['percent'] = 0;
-                                    }
-                                    if ($grades_by_student["$student"]["$category"]['stats']['totalpoints'] != 0) {
-                                        $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);
-                                    }
-                                    else {
-                                        $grades_by_student["$student"]["$category"]["$assignment"]['weight'] = 0.00;
-                                    }
-                                    if ($grades_by_student["$student"]["$category"]["$assignment"]['weight'] != 0) {
-                                        $grades_by_student["$student"]["$category"]["$assignment"]['weighted'] = round($grades_by_student["$student"]["$category"]["$assignment"]['percent']*$grades_by_student["$student"]["$category"]["$assignment"]['weight']/100,2);
-                                    }
-                                    else {
-                                        // should only be here if this is extra credit
-                                        $grades_by_student["$student"]["$category"]["$assignment"]['weighted'] = 0.00;
-                                    }
-                                }
-                                else {
-                                    $grades_by_student["$student"]["$category"]["$assignment"]['percent'] = $strexcluded;
-                                    $grades_by_student["$student"]["$category"]["$assignment"]['weight'] = $strexcluded;
-                                    $grades_by_student["$student"]["$category"]["$assignment"]['weighted'] = $strexcluded;
-                                }
-                            }
-                        }
-                        // set the percent and weight per category
-                        if ($grades_by_student["$student"]["$category"]['stats']['totalpoints'] != 0 ) {
-                            $grades_by_student["$student"]["$category"]['stats']['percent']  = round($grades_by_student["$student"]["$category"]['stats']['points']/$grades_by_student["$student"]["$category"]['stats']['totalpoints']*100,2);
-                            $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);
-                        }
-                        else {
-                            if ($grades_by_student["$student"]["$category"]['stats']['totalpoints'] != $strexcluded) {
-                                $grades_by_student["$student"]["$category"]['stats']['percent'] = 0.00;
-                                $grades_by_student["$student"]["$category"]['stats']['weighted'] = 0.00;
-                            }
-                        }
-                                
-                        // set students overall weight (this is what percent they will be graded against)
-                        if ($grades_by_student["$student"]["$category"]['stats']['weight'] != $strexcluded) {
-                            $grades_by_student["$student"]['student_data']['weight'] = $grades_by_student["$student"]['student_data']['weight'] + $grades_by_student["$student"]["$category"]['stats']['weight'];
-                        }
-                        
-                        // 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
-                        // be excluded from a whole category.
-                        if ($all_categories["$category"]['stats']['totalpoints'] != 0)  {
-                            $grades_by_student["$student"]['student_data']['weighted'] = $grades_by_student["$student"]['student_data']['weighted'] + $grades_by_student["$student"]["$category"]['stats']['weighted'];
-                        }
-                    }
-                    
-    
-                }
-                
-                // set the percent and weight overall
-                if ($grades_by_student["$student"]['student_data']['totalpoints'] != 0 && $grades_by_student["$student"]['student_data']['totalpoints'] != $strexcluded) {
-                    $grades_by_student["$student"]['student_data']['percent'] = round($grades_by_student["$student"]['student_data']['points']/$grades_by_student["$student"]['student_data']['totalpoints']*100,2);
-                    if ($grades_by_student["$student"]['student_data']['weight'] != 0) {
-                        $grades_by_student["$student"]['student_data']['weighted'] = round($grades_by_student["$student"]['student_data']['weighted']/$grades_by_student["$student"]['student_data']['weight']*100,2);
-                    }
-                    else {
-                        $grades_by_student["$student"]['student_data']['weighted'] = 0.00;
-                    }
-                }
-                else if ($grades_by_student["$student"]['student_data']['totalpoints'] == 0) {
-                    $grades_by_student["$student"]['student_data']['percent'] = 0.00;
-                }
-                
-            }
-        }
-        
-        if (isset($grades_by_student)) {
-            $sort = optional_param('sort','default');
-            
-            switch ($sort) {
-                case 'highgrade_category':
-                    uasort($grades_by_student, 'grade_sort_by_highgrade_category');
-                    break;
-                case 'highgrade_category_asc':
-                    uasort($grades_by_student, 'grade_sort_by_highgrade_category_asc');
-                    break;
-                case 'highgrade':
-                {
-                    if ($preferences->use_weighted_for_letter == 1) {
-                        uasort($grades_by_student, 'grade_sort_by_weighted');
-                    }
-                    else {
-                        uasort($grades_by_student, 'grade_sort_by_percent');
-                    }
-                    break;
-                }
-                case 'points':
-                    uasort($grades_by_student, 'grade_sort_by_points');
-                    break;
-                case 'points_asc':
-                    uasort($grades_by_student, 'grade_sort_by_points_asc');
-                    break;
-                case 'weighted':
-                    uasort($grades_by_student, 'grade_sort_by_weighted');
-                    break;
-                case 'weighted_asc':
-                    uasort($grades_by_student, 'grade_sort_by_weighted_asc');
-                    break;
-                case 'percent':
-                    uasort($grades_by_student, 'grade_sort_by_percent');
-                    break;
-                case 'percent_asc':
-                    uasort($grades_by_student, 'grade_sort_by_percent_asc');
-                    break;
-                case 'highgrade_asc':
-                {
-                    if ($preferences->use_weighted_for_letter == 1) {
-                        uasort($grades_by_student, 'grade_sort_by_weighted_asc');
-                    }
-                    else {
-                        uasort($grades_by_student, 'grade_sort_by_percent_asc');
-                    }
-                    break;
-                }
-                case 'firstname':
-                    uasort($grades_by_student, 'grade_sort_by_firstname');
-                    break;
-                default:
-                    uasort($grades_by_student, 'grade_sort_by_lastname');
+/// report plugins with its special structure
+    if ($reports = get_list_of_plugins('grade/report', 'CVS')) {         // Get all installed reports
+        foreach ($reports as $key => $plugin) {                      // Remove ones we can't see
+            if (!has_capability('gradereport/'.$plugin.':view', $context)) {
+                unset($reports[$key]);
             }
         }
-        else {
-            $grades_by_student = 0;
-        }        
-        $retval = array($grades_by_student, $all_categories);
-    }
-    else {
-        $retval = array(0,0);
-        // echo "<center><font color=red>Could not find any graded items for this course.</font></center>";
-    }
-    return $retval;
-}
-
-function grade_drop_exceptions($grades, $grades_exceptions) {
-    $grade_array = explode(',',$grades);
-    $grade_exception_array = explode(',',$grades_exceptions);
-    $ret_grades = Array(); 
-    foreach ($grade_array as $key => $val) {
-        $posb = array_search($val,$grade_exception_array);
-        if (is_integer($posb)) {
-            unset($grade_exception_array[$posb]);
-        } else {
-        
-            $ret_grades[] = $val;
-        }
-    }
-    $grades = implode(',', $ret_grades);
-    return $grades;
-}
-
-function grade_drop_lowest($grades, $drop, $total) {
-    // drops the lowest $drop numbers from the comma seperated $grades making sure that if $grades has 
-    // fewer items than $total that we don't drop too many
-    $grade_array = explode(',',$grades);
-    if (count($grade_array) == 1) {
-    $grades = implode('', $grade_array);
-    }
-    else if ($drop > 0 AND (count($grade_array) > $drop)) {
-        rsort($grade_array);
-
-        for($i=0; $i < (count($grade_array) - $drop); $i++) {
-            $ret_grades["$i"] = $grade_array["$i"];
-        }
-        if (isset($ret_grades)) {
-            $grades = implode(',',$ret_grades);
-        }
     }
-    else {
-        $grades = 0;
-    }
-    return $grades;    
-}
-
-function grade_get_grades() {
-    global $CFG;
-    global $course;
-    $mods = grade_get_grade_items($course->id);
-    $preferences = grade_get_preferences($course->id);
-    
-    if ($mods) {
-        foreach ($mods as $mod)    {
-            // hidden is a gradebook setting for an assignment and visible is a course_module setting 
-            if (($mod->hidden != 1 && $mod->visible==1) or (has_capability('moodle/course:viewhiddenactivities', get_context_instance(CONTEXT_MODULE, $mod->id)) && $preferences->show_hidden==1)) {
-                $libfile = "$CFG->dirroot/mod/$mod->modname/lib.php";
-                if (file_exists($libfile)) {
-                    require_once($libfile);
-                    $gradefunction = $mod->modname."_grades";
-                    if ($grades["$mod->cname"]["$mod->modid"]["$mod->cminstance"] = $gradefunction($mod->cminstance)) {
-                        // added grades for particular mod
-                        // now get the grade_item modifiers ie. scale_grade and extra credit
-                        $scale_grade = get_record('grade_item', 'courseid', $course->id, 'cminstance', $mod->cminstance, 'modid', $mod->modid);
-
-                        if (isset($scale_grade)) {
-                            $grades["$mod->cname"]["$mod->modid"]["$mod->cminstance"]->scale_grade = $scale_grade->scale_grade;
-                            $grades["$mod->cname"]["$mod->modid"]["$mod->cminstance"]->extra_credit = $scale_grade->extra_credit;
-                        }
-                        else {
-                            $grades["$mod->cname"]["$mod->modid"]["$mod->cminstance"]->scale_grade = 1.00;
-                            $grades["$mod->cname"]["$mod->modid"]["$mod->cminstance"]->extra_credit = 0;
-                        }
-                        
-                        if ($mod->hidden != 1 && $mod->visible==1) {
-                            $grades["$mod->cname"]["$mod->modid"]["$mod->cminstance"]->hidden = 0;
-                        }
-                        else {
-                            $grades["$mod->cname"]["$mod->modid"]["$mod->cminstance"]->hidden = 1;
-                        }
-                        
-                        $grades["$mod->cname"]["$mod->modid"]["$mod->cminstance"]->sort_order = $scale_grade->sort_order;
-                        
-                        // 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 
-                        // 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.
-                        // this happens when grading is set to a non-numeric for a forum ie. uses "seperate and connected ways of knowing"
-                        if ($grades["$mod->cname"]["$mod->modid"]["$mod->cminstance"]->maxgrade == '')
-                        {
-                            $grades["$mod->cname"]["$mod->modid"]["$mod->cminstance"]->maxgrade = 100;
-                            //unset($grades["$mod->cname"]["$mod->modid"]["$mod->cminstance"]);
-                        }
-                    }
-                    else {
-                        // delete this item from the grade_item table since it was deleted through the mod interface
-                        delete_records('grade_item', 'modid', $mods->modid, 'courseid', $course->id);
-                        delete_records('grade_exceptions', 'grade_itemid', $mod->id, 'courseid', $course->id);
-                    }                
-                }
-                else {
-                    //echo "<center><font color=red>Could not find lib file for $mod->modid</font></center>";
-                }
+    $reportnames = array();
+    if (!empty($reports)) {
+        foreach ($reports as $plugin) {
+            $url = 'report.php?id='.$courseid.'&amp;report='.$plugin;
+            if ($active_type == 'report' and $active_plugin == $plugin ) {
+                $active = $url;
             }
+            $reportnames[$url] = get_string('modulename', 'gradereport_'.$plugin);
         }
+        asort($reportnames);
     }
-    else {
-        // Do something here for no grades
-        //echo "<center><font color=red>No grades returned. It appears that there are no items with grades for this course.</font></center>";
-    }
-    if (isset($grades)) {
-        return $grades;
+    if (!empty($reportnames)) {
+        $menu['reportgroup']='--'.get_string('reportplugins', 'grades');
+        $menu = $menu+$reportnames;
     }
-    else {
-        return NULL;
-    }    
-}
-
-function grade_set_uncategorized() {
-    // this function checks to see if any mods have not been assigned a category and sets them to uncategorized.
-    global $CFG;
-    global $course;
-    $uncat = UNCATEGORISED;
 
-    $uncat_id = get_record('grade_category', 'courseid', $course->id, 'name', $uncat);
-    
-    if (!$uncat_id) {
-        // insert the uncategorized category 
-        $temp->name=$uncat;
-        $temp->courseid=$course->id;
-        $temp->drop_x_lowest = 0;
-        $temp->bonus_points = 0;
-        $temp->hidden = 0;
-        $temp->weight = 100.00;
-        
-        insert_record('grade_category', $temp);
-        $uncat_id = get_record('grade_category', 'courseid', $course->id, 'name', $uncat);
-        if (!$uncat_id) {
-            error(get_string('errornocategorizedid','grades'));
-            exit(0);
-        }
-    }
-    
-
-    /// Collect modules data
-    get_all_mods($course->id, $mods, $modnames, $modnamesplural, $modnamesused);
-    $itemcount = 0;
-    
-    // this will let us establish the order for gradebook item display
-    $sort = 0;
-    
-    /// Search through all the modules, pulling out grade data
-    $sections = get_all_sections($course->id); // Sort everything the same as the course
-    for ($i=0; $i<=$course->numsections; $i++) {
-        if (isset($sections["$i"])) {   // should always be true
-            $section = $sections["$i"];
-            if ($section->sequence) {
-                $sectionmods = explode(",", $section->sequence);
-                foreach ($sectionmods as $sectionmod) {
-                    if (isset($mods["$sectionmod"])) {
-                        $mod = $mods["$sectionmod"];
-                        $instance = get_record("$mod->modname", "id", "$mod->instance");
-                        $libfile = "$CFG->dirroot/mod/$mod->modname/lib.php";
-                        if (file_exists($libfile)) {
-                            require_once($libfile);
-                            $gradefunction = $mod->modname."_grades";
-                            if (function_exists($gradefunction)) {   // Skip modules without grade function
-                                if ($modgrades = $gradefunction($mod->instance)) {
-                                    $itemcount++;
-                                    //modgrades contains student information with associated grade
-                                    //echo "<b>modname: $mod->modname id: $mod->id course: $mod->course</b><br/>";
-                                    // get instance name from db.
-                                    $instance = get_record($mod->modname, 'id', $mod->instance);
-                                    // see if the item is already in the category table and if it is call category select with the id so it is selected
-                                    get_record('modules', 'name', $mod->modname);
-                                    $item = get_record('grade_item', 'courseid', $course->id, 'modid', $mod->module, 'cminstance', $mod->instance);
-                                    if (!$item) {
-                                        // set the item to uncategorized in grade_item
-                                        $item->courseid = $course->id;
-                                        $item->category = $uncat_id->id;
-                                        $item->modid = $mod->module;
-                                        $item->cminstance = $mod->instance;
-                                        $item->id = insert_record('grade_item', $item);
-                                    }
-                                    else if ($item->category == 0) {
-                                        // this catches any errors where they may have some wierd category set
-                                        set_field('grade_item', 'category', $uncat_id->id, 'id', $item->id);
-                                    }
-                                    set_field('grade_item', 'sort_order', $sort, 'id', $item->id);
-                                    $sort++;
-                                }
-                            }
-                        }
-                    }
-                }
+/// standard import plugins
+    if ($imports = get_list_of_plugins('grade/import', 'CVS')) {         // Get all installed reports
+        foreach ($imports as $key => $plugin) {                      // Remove ones we can't see
+            if (!has_capability('gradeimport/'.$plugin.':view', $context)) {
+                unset($imports[$key]);
             }
         }
     }
-}
-
-// sorting functions for grades
-function grade_sort_by_lastname($x,$y)
-{
-    //$grades_by_student["$student->userid"]['student_data']['firstname'] = $student->firstname;
-    //$grades_by_student["$student->userid"]['student_data']['lastname'] = $student->lastname;
-    if (strnatcasecmp($x['student_data']['lastname'],$y['student_data']['lastname']) == 0) {
-        return strnatcasecmp($x['student_data']['firstname'],$y['student_data']['firstname']);
-    }
-    else {
-        return strnatcasecmp($x['student_data']['lastname'],$y['student_data']['lastname']);
-    }
-}
-
-function grade_sort_by_firstname($x,$y)
-{
-    //$grades_by_student["$student->userid"]['student_data']['firstname'] = $student->firstname;
-    //$grades_by_student["$student->userid"]['student_data']['lastname'] = $student->lastname;
-    if (strnatcasecmp($x['student_data']['firstname'],$y['student_data']['firstname']) == 0) {
-        return strnatcasecmp($x['student_data']['lastname'],$y['student_data']['lastname']);
-    }
-    else {
-        return strnatcasecmp($x['student_data']['firstname'],$y['student_data']['firstname']);
-    }
-}
-
-function grade_sort_by_points($x,$y) {
-    if ($x['student_data']['points'] == $y['student_data']['points']) {
-        return grade_sort_by_lastname($x,$y);
-    }
-    else {
-        if ($x['student_data']['points'] > $y['student_data']['points'])
-            return -1;
-        else 
-            return 1;
-    }
-}
-
-function grade_sort_by_points_asc($x,$y) {
-    if ($x['student_data']['points'] == $y['student_data']['points']) {
-        return grade_sort_by_lastname($x,$y);
-    }
-    else {
-        if ($x['student_data']['points'] < $y['student_data']['points'])
-            return -1;
-        else 
-            return 1;
-    }
-}
-
-function grade_sort_by_weighted($x,$y) {
-    if ($x['student_data']['weighted'] == $y['student_data']['weighted']) {
-        return grade_sort_by_lastname($x,$y);
-    }
-    else {
-        if ($x['student_data']['weighted'] > $y['student_data']['weighted'])
-            return -1;
-        else 
-            return 1;
-    }
-}
-
-function grade_sort_by_percent($x,$y) {
-    if ($x['student_data']['percent'] == $y['student_data']['percent']) {
-        return grade_sort_by_lastname($x,$y);
-    }
-    else {
-        if ($x['student_data']['percent'] > $y['student_data']['percent'])
-            return -1;
-        else 
-            return 1;
-    }
-}
-
-function grade_sort_by_percent_asc($x,$y) {
-    if ($x['student_data']['percent'] == $y['student_data']['percent']) {
-        return grade_sort_by_lastname($x,$y);
-    }
-    else {
-        if ($x['student_data']['percent'] < $y['student_data']['percent'])
-            return -1;
-        else 
-            return 1;
-    }
-}
-
-function grade_sort_by_weighted_asc($x,$y) {
-    if ($x['student_data']['weighted'] == $y['student_data']['weighted']) {
-        return grade_sort_by_lastname($x,$y);
-    }
-    else {
-        if ($x['student_data']['weighted'] < $y['student_data']['weighted'])
-            return -1;
-        else 
-            return 1;
-    }
-}
-    
-function grade_sort_by_highgrade_category($x,$y) {
-    global $cview;
-    
-    if(!$cview) {
-        $cview = optional_param('cview');
-    }
-    
-    if ($x["$cview"]['stats']['points'] == $y["$cview"]['stats']['points']) {
-        return grade_sort_by_lastname($x,$y);
-    }
-    else {
-        return ($y["$cview"]['stats']['points'] - $x["$cview"]['stats']['points']);
-    }
-}
-
-function grade_sort_by_highgrade_category_asc($x,$y) {
-    global $cview;
-    
-    if(!$cview)
-        $cview = optional_param('cview');
-    
-    if ($x["$cview"]['stats']['points'] == $y["$cview"]['stats']['points']) {
-        return grade_sort_by_lastname($x,$y);
-    }
-    else {
-        return ($x["$cview"]['stats']['points'] - $y["$cview"]['stats']['points']);
-    }
-}
-
-
-function grade_set_preference($courseid, $name, $value) {
-    global $GRADEPREFS;
-
-    if (false !== ($key = array_search($name, $GRADEPREFS))) {
-        if ($record = get_record('grade_preferences', 'courseid', $courseid, 'preference', $key)) {
-            $record->value = $value;
-            update_record('grade_preferences', $record);
-        } else {   // Make a new one
-            $record->preference = $key;
-            $record->courseid = $courseid;
-            $record->value = $value;
-            insert_record('grade_preferences', $record);
+    $importnames = array();
+    if (!empty($imports)) {
+        foreach ($imports as $plugin) {
+            $url = 'import/'.$plugin.'/index.php?id='.$courseid;
+            if ($active_type == 'impot' and $active_plugin == $plugin ) {
+                $active = $url;
+            }
+            $importnames[$url] = get_string('modulename', 'gradeimport_'.$plugin);
         }
+        asort($importnames);
     }
-}
-
-function grade_get_preference($courseid, $name) {
-    global $GRADEPREFS, $GRADEPREFSDEFAULTS;
-
-    if (false !== ($key = array_search($name, $GRADEPREFS))) {
-        if (!($record = get_record('grade_preferences', 'courseid', $courseid, 'preference', $key))) {
-            // Make a new one
-            $record->preference = $key;
-            $record->courseid = $courseid;
-            $record->value = $GRADEPREFSDEFAULTS[$name];
-            insert_record('grade_preferences', $record);
-        }
-        return $record->value;
+    if (!empty($importnames)) {
+        $menu['importgroup']='--'.get_string('importplugins', 'grades');
+        $menu = $menu+$importnames;
     }
-    return NULL;
-}
-
-function grade_get_preferences($courseid) {
-    global $CFG;
-    global $GRADEPREFS, $GRADEPREFSDEFAULTS;
 
-    $preferences = NULL;
-
-    // Get the preferences for the course.
-    if ($rawprefs = get_records('grade_preferences', 'courseid', $courseid)) {
-        foreach ($rawprefs as $pref) {
-            if (isset($GRADEPREFS[$pref->preference])) {  // Valid pref
-                $name = $GRADEPREFS[$pref->preference];
-                $preferences->$name = $pref->value;
+/// standard export plugins
+    if ($exports = get_list_of_plugins('grade/export', 'CVS')) {         // Get all installed reports
+        foreach ($exports as $key => $plugin) {                      // Remove ones we can't see
+            if (!has_capability('gradeexport/'.$plugin.':view', $context)) {
+                unset($exports[$key]);
             }
         }
     }
-
-    // Check for any missing ones and create them from defaults
-    // We don't save them in the database so we save space
-    foreach ($GRADEPREFS as $number => $name) {
-        if (!isset($preferences->$name)) {
-            $preferences->$name = $GRADEPREFSDEFAULTS[$name];
+    $exportnames = array();
+    if (!empty($exports)) {
+        foreach ($exports as $plugin) {
+            $url = 'export/'.$plugin.'/index.php?id='.$courseid;
+            if ($active_type == 'impot' and $active_plugin == $plugin ) {
+                $active = $url;
+            }
+            $exportnames[$url] = get_string('modulename', 'gradeexport_'.$plugin);
         }
+        asort($exportnames);
     }
-
-    // Construct some other ones about which fields are shown
-
-    $isteacher = has_capability('moodle/course:managegrades', get_context_instance(CONTEXT_COURSE, $courseid));
-
-    $preferences->show_weighted = (($preferences->display_weighted > 0  && $isteacher) || 
-                                   ($preferences->display_weighted > 1 && !$isteacher));
-    
-    $preferences->show_points   = (($preferences->display_points > 0  && $isteacher) || 
-                                   ($preferences->display_points > 1 && !$isteacher));
-    
-    $preferences->show_percent  = (($preferences->display_percent > 0  && $isteacher) || 
-                                   ($preferences->display_percent > 1 && !$isteacher));
-
-    $preferences->show_letters  = (($preferences->display_letters > 0  && $isteacher) || 
-                                   ($preferences->display_letters > 1 && !$isteacher));
-
-    return $preferences;
-}
-
-
-function grade_set_preferences($course, $newprefs) {
-    
-    if (!isset($newprefs->use_advanced) or ($newprefs->use_advanced == 1)) {
-        foreach ($newprefs as $name => $value) {        /// Just save them all
-            grade_set_preference($course->id, $name, $value);
-        }
-        return true;
+    if (!empty($exportnames)) {
+        $menu['exportgroup']='--'.get_string('exportplugins', 'grades');
+        $menu = $menu+$exportnames;
     }
 
-/// We don't need advanced features, and we need to unset all extra features
-/// So they don't affect grades    (This approach should be revisited because it resets everything!!)
-    
-    grade_set_preference($course->id, 'use_advanced', 0);
-    grade_set_preference($course->id, 'use_weighted_for_letter', 0);
-    grade_set_preference($course->id, 'display_weighted', 0);
-    grade_set_preference($course->id, 'display_points', 2);
-    grade_set_preference($course->id, 'display_percent', 0);
-    grade_set_preference($course->id, 'display_letters', 0);
-    
-/// Lose all exceptions
-    delete_records('grade_exceptions', 'courseid', $course->id);
-        
-    if (!$uncat = get_record('grade_category', 'courseid', $course->id, 'name', UNCATEGORISED)) {
-        /// Make a category for uncategorised stuff
-        $uncat->name=UNCATEGORISED;
-        $uncat->courseid=$course->id;
-        if (!$uncat->id = insert_record('grade_category', $uncat)) {
-            error(get_string('errornocategorizedid','grades'));
+/// editing scripts - not real plugins
+    if (true) { //TODO: add proper capability here
+        $menu['edit']='--'.get_string('edit');
+        $url = 'edit/tree.php?id='.$courseid;
+        if ($active_type == 'edit' and $active_plugin == 'tree' ) {
+            $active = $url;
         }
-    }
-    
-    set_field('grade_item', 'category', $uncat->id, 'courseid', $course->id);
-    set_field('grade_item', 'scale_grade', 1.00, 'courseid', $course->id);
-    set_field('grade_item', 'extra_credit', 0, 'courseid', $course->id);
-
-    set_field('grade_category', 'weight', 100.0, 'courseid', $course->id, 'id', $uncat->id);
-    set_field('grade_category', 'bonus_points', '0', 'courseid', $course->id);
-}
-
-
-function grade_preferences_menu($action, $course) {
-
-    if (!has_capability('moodle/course:managegrades', get_context_instance(CONTEXT_COURSE, $course->id))) {
-        return;
-    }
-
-    // remap some actions to simplify later code        
-    switch ($action) {
-        case 'prefs':
-        case 'set_grade_preferences':
-            $curraction = 'prefs';
-            break;
-        case 'cats':
-        case 'vcats':
-            $curraction = '';
-            break;
-        case 'insert_category':
-        case 'assign_categories':
-        case 'delete_category':
-            $curraction = 'cats';
-            break;
-        case 'set_grade_weights':
-        case 'weights':
-            $curraction = 'weights';
-            break;
-        case 'letters':
-        case 'set_letter_grades':
-            $curraction = 'letters';
-            break;
-        case 'view_student_grades':
-        case 'view_student_category_grades':
-        case 'grades':
-            $curraction = 'grades';
-            break;
-        case 'excepts':
-            $curraction = 'excepts';
-            break;
-
-        default:
-            $curraction = 'grades';
+        $menu[$url] = get_string('edittree', 'grades');
     }
 
-    $tabs = $row = array();
-    $row[] = new tabobject('grades', 'index.php?id='.$course->id,
-                           get_string('viewgrades', 'grades'));
-    $row[] = new tabobject('prefs', 'index.php?id='.$course->id.'&amp;action=prefs',
-                           get_string('setpreferences', 'grades'));
-    // only show the extra options if advanced is turned on, they don't do anything otherwise
-    if (grade_get_preference($course->id, 'use_advanced') == 1) {
-        $row[] = new tabobject('cats', 'index.php?id='.$course->id.'&amp;action=cats',
-                               get_string('setcategories', 'grades'));
-        $row[] = new tabobject('weights', 'index.php?id='.$course->id.'&amp;action=weights',
-                               get_string('setweights', 'grades'));
-        $row[] = new tabobject('letters', 'index.php?id='.$course->id.'&amp;action=letters',
-                               get_string('setgradeletters', 'grades'));
-        $row[] = new tabobject('excepts', 'exceptions.php?id='.$course->id.'&amp;action=excepts',
-                               get_string('gradeexceptions', 'grades'));
-    }
-    $tabs[] = $row;
-
-    print_tabs($tabs, $curraction);
+/// finally print/return the popup form
+    return popup_form($CFG->wwwroot.'/grade/', $menu, 'choosepluginreport', $active, 'choose', '', '', $return, 'self', get_string('selectplugin', 'grades'));
 }
 
+class grade_plugin_return {
+    var $type;
+    var $plugin;
+    var $courseid;
+    var $userid;
+    var $page;
 
-function grade_nav($course, $action='grades') {
-    global $CFG;
-    global $USER;
-    global $cview;
-
-    $strgrades = get_string('grades', 'grades');
-    $gradenav = "<a href=\"$CFG->wwwroot/course/view.php?id=$course->id\">$course->shortname</a>";
+    function grade_plugin_return ($params=null) {
+        if (empty($params)) {
+            $this->type     = optional_param('gpr_type', null, PARAM_SAFEDIR);
+            $this->plugin   = optional_param('gpr_plugin', null, PARAM_SAFEDIR);
+            $this->courseid = optional_param('gpr_courseid', null, PARAM_INT);
+            $this->userid   = optional_param('gpr_userid', null, PARAM_INT);
+            $this->page     = optional_param('gpr_page', null, PARAM_INT);
 
-    if (has_capability('moodle/course:managegrades', get_context_instance(CONTEXT_COURSE, $course->id))) {
-        switch ($action) {
-            case 'prefs':
-            case 'set_grade_preferences':
-                $strcurpage = get_string('setpreferences','grades');
-                break;
-            case 'cats':
-            case 'delete_category':
-            case 'cats':
-            case 'insert_category':
-            case 'assign_categories':
-                $strcurpage = get_string('setcategories','grades');
-                break;
-            case 'weights':
-            case 'set_grade_weights':
-                $strcurpage = get_string('setweights','grades');
-                break;
-            case 'set_letter_grades':
-            case 'letters':
-                $strcurpage = get_string('setgradeletters','grades');
-                break;
-            case 'excepts':
-                $strcurpage = get_string('gradeexceptions', 'grades');
-                break;
-            case 'exporttxt':
-            case 'exportxml':
-            case 'exportods':
-            case 'exportxls':
-            case 'importcsv':
-            case 'importxml':
-                $strcurpage = get_string($action, 'grades');
-                break;
-            default:
-                unset($strcurpage);
-                break;
-        }
-    
-        if ($action=='grades') {
-            $gradenav .= " -> $strgrades";
         } else {
-            $gradenav .= " -> <a href=\"index.php?id=$course->id&amp;action=grades\">$strgrades</a>";
-        }
-        
-        // if we are on a grades sub-page provide a link back (including grade preferences and grade items
-        
-        if (isset($strcurpage)) {
-            $gradenav .= " -> $strcurpage";
-        } else if($action =='vcats') {
-            // show sub category
-            if (isset($cview)) {
-                $gradenav .= " -> $cview";
+            foreach ($params as $key=>$value) {
+                if (array_key_exists($key, $this)) {
+                    $this->$key = $value;
+                }
             }
         }
-
-    } else {
-        $gradenav .= " -> $strgrades";
-    }
-    
-    return $gradenav;    
-}
-
-function grade_download($download, $id) {
-    global $CFG;
-
-    require_login();
-
-    if (! $course = get_record("course", "id", $id)) {
-        error("Course ID was incorrect");
-    }
-
-    require_capability('moodle/course:viewcoursegrades', get_context_instance(CONTEXT_COURSE, $id));
-
-    $strgrades = get_string("grades");
-    $strgrade = get_string("grade");
-    $strmax = get_string("maximumshort");
-    $stractivityreport = get_string("activityreport");
-
-/// Check to see if groups are being used in this course
-    $currentgroup = get_current_group($course->id);
-
-    if ($currentgroup) {
-        $students = get_group_students($currentgroup, "u.lastname ASC");
-    } else {
-        $students = grade_get_course_students($course->id);
     }
 
-    if (!empty($students)) {
-        foreach ($students as $student) {
-            $grades[$student->id] = array();    // Collect all grades in this array
-            $gradeshtml[$student->id] = array(); // Collect all grades html formatted in this array
-            $totals[$student->id] = array();    // Collect all totals in this array
+    function get_options() {
+        if (empty($this->type) or empty($this->plugin)) {
+            return array();
         }
-    }
-    $columns = array();     // Accumulate column names in this array.
-    $columnhtml = array();  // Accumulate column html in this array.
-
 
-/// Collect modules data
-    get_all_mods($course->id, $mods, $modnames, $modnamesplural, $modnamesused);
+        $params = array();
 
-/// Search through all the modules, pulling out grade data
-    $sections = get_all_sections($course->id); // Sort everything the same as the course
-    for ($i=0; $i<=$course->numsections; $i++) {
-        if (isset($sections[$i])) {   // should always be true
-            $section = $sections[$i];
-            if ($section->sequence) {
-                $sectionmods = explode(",", $section->sequence);
-                foreach ($sectionmods as $sectionmod) {
-                    $mod = $mods[$sectionmod];
-                    $instance = get_record("$mod->modname", "id", "$mod->instance");
-                    $libfile = "$CFG->dirroot/mod/$mod->modname/lib.php";    
-                    
-                    if (file_exists($libfile)) {
-                        require_once($libfile);
-                        $gradefunction = $mod->modname."_grades";
-                        if (function_exists($gradefunction)) {   // Skip modules without grade function
-                            if ($modgrades = $gradefunction($mod->instance)) {
-                                if (!empty($modgrades->maxgrade)) {
-                                    if ($mod->visible) {
-                                        $maxgrade = "$strmax: $modgrades->maxgrade";
-                                    } else {
-                                        $maxgrade = "$strmax: $modgrades->maxgrade";
-                                    }
-                                } else {
-                                    $maxgrade = "";
-                                }
+        $params['plugin'] = $this->plugin;
 
-                                $columns[] = "$mod->modfullname: ".format_string($instance->name,true)." - $maxgrade";
-
-                                if (!empty($students)) {
-                                    foreach ($students as $student) {
-                                        if (!empty($modgrades->grades[$student->id])) {
-                                            $grades[$student->id][] = $currentstudentgrade = $modgrades->grades[$student->id];
-                                        } else {
-                                            $grades[$student->id][] = $currentstudentgrade = "";
-                                            $gradeshtml[$student->id][] = "";
-                                        }
-                                        if (!empty($modgrades->maxgrade)) {
-                                            $totals[$student->id] = (float)($totals[$student->id]) + (float)($currentstudentgrade);
-                                        } else {
-                                            $totals[$student->id] = (float)($totals[$student->id]) + 0;
-                                        }
-                                    }
-                                }
-                            }
-                        }
-                    }
-                }
-            }
+        if (!empty($this->courseid)) {
+            $params['id'] = $this->courseid;
         }
-    } // a new Moodle nesting record? ;-)
-
-/// OK, we have all the data, now present it to the user
-/// OK, we have all the data, now present it to the user
-    if ($download == "ods" and confirm_sesskey()) {
-        require_once("../lib/odslib.class.php");
 
-    /// Calculate file name
-        $downloadfilename = clean_filename("$course->shortname $strgrades.ods");
-    /// Creating a workbook
-        $workbook = new MoodleODSWorkbook("-");
-    /// Sending HTTP headers
-        $workbook->send($downloadfilename);
-    /// Adding the worksheet
-        $myxls =& $workbook->add_worksheet($strgrades);
-    
-    /// Print names of all the fields
-        $myxls->write_string(0,0,get_string("firstname"));
-        $myxls->write_string(0,1,get_string("lastname"));
-        $myxls->write_string(0,2,get_string("idnumber"));
-        $myxls->write_string(0,3,get_string("institution"));
-        $myxls->write_string(0,4,get_string("department"));
-        $myxls->write_string(0,5,get_string("email"));
-        $pos=6;
-        foreach ($columns as $column) {
-            $myxls->write_string(0,$pos++,strip_tags($column));
+        if (!empty($this->userid)) {
+            $params['userid'] = $this->userid;
         }
-        $myxls->write_string(0,$pos,get_string("total"));
-    
-    /// Print all the lines of data.
-        $i = 0;
-        if (!empty($grades)) {
-            foreach ($grades as $studentid => $studentgrades) {
-                $i++;
-                $student = $students[$studentid];
-                if (empty($totals[$student->id])) {
-                    $totals[$student->id] = '';
-                }
-        
-                $myxls->write_string($i,0,$student->firstname);
-                $myxls->write_string($i,1,$student->lastname);
-                $myxls->write_string($i,2,$student->idnumber);
-                $myxls->write_string($i,3,$student->institution);
-                $myxls->write_string($i,4,$student->department);
-                $myxls->write_string($i,5,$student->email);
-                $j=6;
-                foreach ($studentgrades as $grade) {
-                    if (is_numeric($grade)) {
-                        $myxls->write_number($i,$j++,strip_tags($grade));
-                    }
-                    else {
-                        $myxls->write_string($i,$j++,strip_tags($grade));
-                    }
-                }
-                $myxls->write_number($i,$j,$totals[$student->id]);
-            }
-        }
-
-    /// Close the workbook
-        $workbook->close();
-    
-        exit;
 
-    } else if ($download == "xls" and confirm_sesskey()) {
-        require_once("../lib/excellib.class.php");
-
-    /// Calculate file name
-        $downloadfilename = clean_filename("$course->shortname $strgrades.xls");
-    /// Creating a workbook
-        $workbook = new MoodleExcelWorkbook("-");
-    /// Sending HTTP headers
-        $workbook->send($downloadfilename);
-    /// Adding the worksheet
-        $myxls =& $workbook->add_worksheet($strgrades);
-    
-    /// Print names of all the fields
-        $myxls->write_string(0,0,get_string("firstname"));
-        $myxls->write_string(0,1,get_string("lastname"));
-        $myxls->write_string(0,2,get_string("idnumber"));
-        $myxls->write_string(0,3,get_string("institution"));
-        $myxls->write_string(0,4,get_string("department"));
-        $myxls->write_string(0,5,get_string("email"));
-        $pos=6;
-        foreach ($columns as $column) {
-            $myxls->write_string(0,$pos++,strip_tags($column));
-        }
-        $myxls->write_string(0,$pos,get_string("total"));
-    
-    /// Print all the lines of data.
-        $i = 0;
-        if (!empty($grades)) {
-            foreach ($grades as $studentid => $studentgrades) {
-                $i++;
-                $student = $students[$studentid];
-                if (empty($totals[$student->id])) {
-                    $totals[$student->id] = '';
-                }
-        
-                $myxls->write_string($i,0,$student->firstname);
-                $myxls->write_string($i,1,$student->lastname);
-                $myxls->write_string($i,2,$student->idnumber);
-                $myxls->write_string($i,3,$student->institution);
-                $myxls->write_string($i,4,$student->department);
-                $myxls->write_string($i,5,$student->email);
-                $j=6;
-                foreach ($studentgrades as $grade) {
-                    if (is_numeric($grade)) {
-                        $myxls->write_number($i,$j++,strip_tags($grade));
-                    }
-                    else {
-                        $myxls->write_string($i,$j++,strip_tags($grade));
-                    }
-                }
-                $myxls->write_number($i,$j,$totals[$student->id]);
-            }
+        if (!empty($this->page)) {
+            $params['page'] = $this->page;
         }
 
-    /// Close the workbook
-        $workbook->close();
-    
-        exit;
-
-    } else if ($download == "txt" and confirm_sesskey()) {
-
-/// Print header to force download
-
-        header("Content-Type: application/download\n"); 
-        $downloadfilename = clean_filename("$course->shortname $strgrades");
-        header("Content-Disposition: attachment; filename=\"$downloadfilename.txt\"");
-
-/// Print names of all the fields
-
-        echo get_string("firstname")."\t".
-             get_string("lastname")."\t".
-             get_string("idnumber")."\t".
-             get_string("institution")."\t".
-             get_string("department")."\t".
-             get_string("email");
-        foreach ($columns as $column) {
-            $column = strip_tags($column);
-            echo "\t$column";
-        }
-        echo "\t".get_string("total")."\n";
-    
-/// Print all the lines of data.
-        foreach ($grades as $studentid => $studentgrades) {
-            $student = $students[$studentid];
-            if (empty($totals[$student->id])) {
-                $totals[$student->id] = '';
-            }
-            echo "$student->firstname\t$student->lastname\t$student->idnumber\t$student->institution\t$student->department\t$student->email";
-            foreach ($studentgrades as $grade) {
-                $grade = strip_tags($grade);
-                echo "\t$grade";
-            }
-            echo "\t".$totals[$student->id];
-            echo "\n";
-        }
-    
-        exit;
-    
-    }else if ($download == '' and confirm_sesskey()) {
-        error("No file type specified");
-        exit;
+        return $params;
     }
-}
 
-function grade_get_stats($category='all') {
-    list($grades_by_student, $all_categories) = grade_get_formatted_grades();
+    function get_return_url($default) {
+        global $CFG;
 
-    if ($grades_by_student != 0 && $all_categories != 0) {
-        switch($category) {
-            case 'all':
-            {
-                //populate the sum of student points, # items and totalpoints for each category
-                foreach($grades_by_student as $student=>$categories) {
-                    foreach($categories as $cur_category=>$assignments) {
-                        if($category != 'student_data') {
-                            if (isset($assignments['stats'])) {
-                                if (isset($stats[$cur_category]['sum'])) {
-                                    $stats[$cur_category]['sum'] = $stats[$cur_category]['sum'] + $assignments['stats']['points'];
-                                }
-                                else {
-                                    $stats[$cur_category]['sum'] = $assignments['stats']['points'];
-                                }
-                                $stats[$cur_category]['items'] = $assignments['stats']['grade_items'];
-                                $stats[$cur_category]['totalpoints'] = $assignments['stats']['totalpoints'];
-                                $stats[$cur_category]['weight'] = $all_categories[$cur_category]['stats']['weight'];
-                            }
-                        }
-                    }
-                }
-                // populate the overall sum,items and totalpoints 
-                foreach($stats as $cur_category=>$info) {
-                    if($cur_category != 'all' && $cur_category != 'student_data') {
-                        
-                        if ($stats[$cur_category]['totalpoints'] == get_string('excluded', 'grades')) {
-                            $stats[$cur_category]['totalpoints'] = 1;
-                            $stats['all']['sum'] = $stats['all']['sum'] + $stats[$cur_category]['sum'];
-                            $stats['all']['items']  = $stats['all']['items'] + $stats[$cur_category]['items'];
-                            $stats['all']['totalpoints'] = $stats['all']['totalpoints'] + $stats[$cur_category]['totalpoints'];
-                            $stats['all']['weighted_sum'] = $stats['all']['weighted_sum'] + ($stats[$cur_category]['sum']/($stats[$cur_category]['totalpoints']))*$stats[$cur_category]['weight'];
-                        }
-                        
-                        else if (isset($stats['all'])) {
-                            $stats['all']['sum'] = $stats['all']['sum'] + $stats[$cur_category]['sum'];
-                            $stats['all']['items']  = $stats['all']['items'] + $stats[$cur_category]['items'];
-                            $stats['all']['totalpoints'] = $stats['all']['totalpoints'] + $stats[$cur_category]['totalpoints'];
-                            $stats['all']['weighted_sum'] = $stats['all']['weighted_sum'] + ($stats[$cur_category]['sum']/($stats[$cur_category]['totalpoints']))*$stats[$cur_category]['weight'];
-                        }
-                        else {
-                            $stats['all']['sum'] = $stats[$cur_category]['sum'];
-                            $stats['all']['items']  = $stats[$cur_category]['items'];
-                            $stats['all']['totalpoints'] = $stats[$cur_category]['totalpoints'];
-                            $stats['all']['weighted_sum'] = ($stats[$cur_category]['sum']/($stats[$cur_category]['totalpoints']))*$stats[$cur_category]['weight'];
-
-                        }
-                    } 
-                }
-                $stats['all']['students'] = count($grades_by_student);
-                $stats['all']['average'] = $stats['all']['sum'] / $stats['all']['students'];
-                $stats['all']['average_weighted'] = $stats['all']['weighted_sum']/$stats['all']['students'];
-                
-                // calculate the average squared deviation and populate a list of all scores while we're at it
-                $stats['all']['avgsqddev'] = 0;
-                $stats['all']['avgsqddev_weighted'] = 0;
-                foreach($grades_by_student as $student=>$categories) {
-                    foreach($categories as $cur_category=>$assignments) {
-                        if ($cur_category != 'student_data') {
-                            $stats['all']['avgsqddev'] = $stats['all']['avgsqddev'] + pow(($grades_by_student[$student]['student_data']['points']-$stats['all']['average']),2);
-                            $stats['all']['avgsqddev_weighted'] = $stats['all']['avgsqddev_weighted'] + pow(($grades_by_student[$student]['student_data']['weighted']-$stats['all']['average_weighted']),2);
-                        }
-                    }
-                    if (isset($stats['all']['all_scores'])) {
-                        $stats['all']['all_scores'] .= ','.$grades_by_student[$student]['student_data']['points'];
-                        $stats['all']['all_scores_weighted'] .= ','.$grades_by_student[$student]['student_data']['weighted'];
-                    }
-                    else {
-                        $stats['all']['all_scores'] = $grades_by_student[$student]['student_data']['points'];
-                        $stats['all']['all_scores_weighted'] = $grades_by_student[$student]['student_data']['weighted'];
-                    }
-                }
-                $stats['all']['avgsqddev']=$stats['all']['avgsqddev']/$stats['all']['students'];
-                $stats['all']['avgsqddev_weighted']=$stats['all']['avgsqddev_weighted']/$stats['all']['students'];
-                $stats['all']['stddev'] = sqrt($stats['all']['avgsqddev']);
-                $stats['all']['stddev_weighted'] = sqrt($stats['all']['avgsqddev_weighted']);
-                $stats['all']['mode'] = grade_mode($stats['all']['all_scores']);
-                $stats['all']['mode_weighted'] = grade_mode($stats['all']['all_scores_weighted']);
-                
-                // make sure the mode is not set to every score
-                if(count($stats['all']['mode']) == count($grades_by_student)) {
-                    $stats['all']['mode'] = get_string('nomode','grade');
-                }
-                if(count($stats['all']['mode_weighted']) == count($grades_by_student)) {
-                    $stats['all']['mode_weighted'] = get_string('nomode','grade');
-                }
-                break;
-            }
-            default:
-            {
-                // get the stats for category
-                //populate the sum of student points, # items and totalpoints for each category
-                foreach($grades_by_student as $student=>$categories) {
-                        if(isset($grades_by_student[$student][$category]['stats'])) {
-                            if (isset($stats[$category]['sum'])) {
-                                $stats[$category]['sum'] = $stats[$category]['sum'] + $grades_by_student[$student][$category]['stats']['points'];
-                            }
-                            else {
-                                $stats[$category]['sum'] = $grades_by_student[$student][$category]['stats']['points'];
-                            }
-                            $stats[$category]['items'] = $grades_by_student[$student][$category]['stats']['grade_items'];
-                            $stats[$category]['totalpoints'] = $grades_by_student[$student][$category]['stats']['totalpoints'];
-                        }
-                }
-                $stats[$category]['students'] = count($grades_by_student);
-                $stats[$category]['average'] = $stats[$category]['sum']/$stats[$category]['students'];
-                
-                // calculate the average squared deviation and populate a list of all scores too
-                $stats[$category]['avgsqddev'] = 0;
-                foreach($grades_by_student as $student=>$categories) {
-                    foreach($categories as $cur_category=>$assignment) {
-                        if ($cur_category != 'student_data') {
-                            if ($grades_by_student[$student][$category]['stats']['points'] == '-' || $grades_by_student[$student][$category]['stats']['points'] == get_string('grades','excluded')) {
-                                // count grade as a zero
-                                $stats[$category]['avgsqddev'] = $stats[$category]['avgsqddev'] + pow(($stats[$category]['average']),2);
-                            }
-                            else {
-                                $stats[$category]['avgsqddev'] = $stats[$category]['avgsqddev'] + pow(($grades_by_student[$student][$category]['stats']['points']-$stats[$category]['average']),2);
-                            }
-                        }
-                    }
-
-                    if (isset($stats[$category]['all_scores'])) {
-                        $stats[$category]['all_scores'] .= ','.$grades_by_student[$student][$category]['stats']['points'];
-                    }
-                    else {
-                        $stats[$category]['all_scores'] = $grades_by_student[$student][$category]['stats']['points'];
-                    }
-                }
-                $stats[$category]['avgsqddev'] = $stats[$category]['avgsqddev']/$stats[$category]['students'];
-                $stats[$category]['stddev'] = sqrt($stats[$category]['avgsqddev']);
-                $stats[$category]['mode'] = grade_mode($stats[$category]['all_scores']);
-                break;
-            }
-        } // end switch
-        // do a little cleanup 
-        $stats[$category]['stddev'] = sprintf("%0.2f", $stats[$category]['stddev']);
-        $stats[$category]['average'] = sprintf("%0.2f", $stats[$category]['average']);
-        $stats[$category]['max'] = max(explode(',',$stats[$category]['all_scores'])); 
-        $stats[$category]['min'] = min(explode(',',$stats[$category]['all_scores']));
-        $stats[$category]['median'] = explode(',',$stats[$category]['all_scores']);
-        
-        if (isset($stats[$category]['stddev_weighted'])) {
-            $stats[$category]['stddev_weighted'] = sprintf("%0.2f", $stats[$category]['stddev_weighted']);
-        }
-        if (isset($stats[$category]['average_weighted'])) {
-            $stats[$category]['average_weighted'] = sprintf("%0.2f", $stats[$category]['average_weighted']);
-        }
-        if (isset($stats[$category]['max_weighted'])) {
-            $stats[$category]['max_weighted'] = max(explode(',',$stats[$category]['all_scores_weighted'])); 
-        }
-        if (isset($stats[$category]['min_weighted'])) {
-            $stats[$category]['min_weighted'] = min(explode(',',$stats[$category]['all_scores_weighted']));
-        }
-        
-        if (isset($stats[$category]['all_scores_weighted'])) {
-            $stats[$category]['median_weighted'] = explode(',',$stats[$category]['all_scores_weighted']);
-        }
-        else {
-        
+        if (empty($this->type) or empty($this->plugin)) {
+            return $default;
         }
 
-        
-        sort($stats[$category]['median']);
-
-        if (count($stats[$category]['median'])/2 == floor(count($stats[$category]['median'])/2) ) {
-            // even number of scores
-            $temp = $stats[$category]['median'][count($stats[$category]['median'])/2-1] + $stats[$category]['median'][count($stats[$category]['median'])/2];
-            $temp = $temp/2;
-        }
-        else {
-            // odd number of scores
-            $temp = $stats[$category]['median'][floor(count($stats[$category]['median'])/2)];
-        }        
-        unset($stats[$category]['median']);
-        $stats[$category]['median'] = $temp;
-        
-        if (isset($stats[$category]['median_weighted'])) {
-            if (count($stats[$category]['median_weighted'])/2 == floor(count($stats[$category]['median_weighted'])/2)) {
-                // even number of scores
-                $temp = $stats[$category]['median_weighted'][count($stats[$category]['median_weighted'])/2-1] + $stats[$category]['median_weighted'][count($stats[$category]['median_weighted'])/2+1];
-                $temp = $temp/2;
-            }
-            else {
-                // odd number of scores
-                $temp = $stats[$category]['median_weighted'][floor(count($stats[$category]['median_weighted'])/2)];
-            }         
-            unset($stats[$category]['median_weighted']);
-            $stats[$category]['median_weighted'] = $temp;
-        }
-    }
-    return $stats;
-}
+        if ($this->type == 'report') {
+            $url = $CFG->wwwroot.'/grade/report.php?report='.$this->plugin;
+            $glue = '&amp;';
 
-// returns a comma seperated list of the most common values in $items, $items is expected to be a comma sperated list of numbers
-function grade_mode($items) {
-    $all_scores = explode(',',$items);
-    foreach($all_scores as $value) {
-        if (isset($frequency[$value])) {
-            $frequency[$value]++;
-        }
-        else {
-            $frequency[$value] = 1;
-        }
-    }
-    $max = max($frequency);
-    foreach($frequency as $key=>$value) {
-        if ($value == $max) {
-            if (isset($retval)) {
-                $retval .= ', '.$key;
-            }
-            else {
-                $retval = $key;
-            }
+        } else {
+            $url = $CFG->wwwroot.'/grade/'.$this->type.'/'.$this->plugin.'/index.php';
+            $glue = '?';
         }
-    }
-    return $retval;
-}
-
-
-function grade_stats() {
-    global $CFG;
-    global $course;
-    global $USER;
-    global $preferences;
-
-    if (!isset($category)) {
-        $category = clean_param($_REQUEST['category'], PARAM_CLEAN);
-    }
-    
-    $stats = grade_get_stats($category);
-
-    // output our data    
-    print_header();
-    echo  '<table align="center"><tr><th colspan="3" scope="col">'.$category.' '.get_string('stats','grades').'</th></tr>';
-    if ($preferences->show_weighted == 1 && $preferences->use_weighted_for_letter == 1 && $category== 'all') {
-        echo  '<tr><th scope="col">&nbsp;</th><th scope="col">'.get_string('points','grades').'<th scope="col">'.get_string('weight','grades').'</th></tr>';            
-    }
-
-    echo  '<tr><td align="right">'.get_string('max','grades').':</td><td align="right">'.$stats[$category]['max'].'</td>';
-    if ($preferences->show_weighted == 1 && $preferences->use_weighted_for_letter == 1 && $category== 'all') {
-        echo  '<td align="right">'.$stats[$category]['max_weighted'].'</td>';            
-    }
-    echo  '</tr>';
-    
-    echo  '<tr><td align="right">'.get_string('min','grades').':</td><td align="right">'.$stats[$category]['min'].'</td>';
-    if ($preferences->show_weighted == 1 && $preferences->use_weighted_for_letter == 1 && $category== 'all') {
-        echo  '<td align="right">'.$stats[$category]['min_weighted'].'</td>';            
-    }
-    echo  '</tr>';
-    
-    echo  '<tr><td align="right">'.get_string('average','grades').':</td><td align="right">'.$stats[$category]['average'].'</td>';
-    if ($preferences->show_weighted == 1 && $preferences->use_weighted_for_letter == 1 && $category== 'all') {
-        echo  '<td align="right">'.$stats[$category]['average_weighted'].'</td>';            
-    }
-    echo  '</tr>';
-    
-    echo  '<tr><td align="right">'.get_string('median','grades').':</td><td align="right">'.$stats[$category]['median'].'</td>';
-    if ($preferences->show_weighted == 1 && $preferences->use_weighted_for_letter == 1 && $category== 'all') {
-        echo  '<td align="right">'.$stats[$category]['median_weighted'].'</td>';            
-    }
-    echo  '</tr>';
-    
-    echo  '<tr><td align="right">'.get_string('mode','grades').':</td><td align="right">'.$stats[$category]['mode'].'</td>';
-    if ($preferences->show_weighted == 1 && $preferences->use_weighted_for_letter == 1 && $category== 'all') {
-        echo  '<td align="right">'.$stats[$category]['mode_weighted'].'</td>';            
-    }
-    echo  '</tr>';
-    
-    echo  '<tr><td align="right">'.get_string('standarddeviation','grades').':</td><td align="right">'.$stats[$category]['stddev'].'</td>';
-    if ($preferences->show_weighted == 1 && $preferences->use_weighted_for_letter == 1 && $category== 'all') {
-        echo  '<td align="right">'.$stats[$category]['stddev_weighted'].'</td>';            
-    }
-    echo  '</tr>';
-    echo  '</table>';
-    print_footer();
-}
-
-function grade_view_category_grades($view_by_student) {
-    global $CFG;
-    global $course;
-    global $USER;
-    global $preferences;
-
-    $context = get_context_instance(CONTEXT_COURSE, $course->id);
-    
-    // if can't see course grades, print single grade view
-    if (!has_capability('moodle/course:viewcoursegrades', $context)) {
-        $view_by_student = $USER->id;
-    }
-
-    if ($preferences->use_advanced == 0) {
-        $cview = UNCATEGORISED;
-    }
-    else {
-        $cview=clean_param($_REQUEST['cview'], PARAM_CLEAN);
-    }
-    
-    if ($cview) {
-        list($grades_by_student, $all_categories) = grade_get_formatted_grades();
-
-        if ($grades_by_student != 0 && $all_categories != 0) {
-            // output a form for the user to download the grades.
-            grade_download_form();
-
-            if ($view_by_student != -1) {
-                // unset all grades except for this student
-                foreach ($grades_by_student as $student=>$junk) {
-                    if($student != $view_by_student) {
-                        unset($grades_by_student[$student]);
-                    }
-                }
-            }
-
-            $grade_columns = $preferences->show_weighted + $preferences->show_points + $preferences->show_percent;
-
-            $first = 0;
-            //$maxpoints = 0;
-            $maxpercent = 0;
-            $reprint = 0;
-            if (has_capability('moodle/course:viewcoursegrades', $context)) {
-                $student_heading_link = get_string('student','grades');
-                //only set sorting links if more than one student displayed.
-                if ($view_by_student == -1) {
-                    $student_heading_link .='<br /><a href="?id='.$course->id.'&amp;action=vcats&amp;cview='.$cview.'&amp;sort=lastname">'.get_string('sortbylastname','grades').'</a>';
-                    $student_heading_link .= '<br /><a href="?id='.$course->id.'&amp;action=vcats&amp;cview='.$cview.'&amp;sort=firstname">'.get_string('sortbyfirstname','grades').'</a>';
-                }
-                else {
-                    $student_heading_link .= '<br /><a href="?id='.$course->id.'&amp;action=vcats&amp;cview='.$cview.'">'.get_string('showallstudents','grades').'</a>';
-                }
-            }
-            echo '<table align="center" class="grades">';
-            if (has_capability('moodle/course:viewcoursegrades', $context)) {
-                $header = '<tr class="header"><th rowspan="2" scope="col">'.$student_heading_link.'</th>';
-            }
-            else {
-                $header = '<tr class="header">';
-            }
-            $header1 = '<tr class="header">';
-            
-            // to keep track of what we've output
-            $colcount = 0;
-            $oddrow = true;
-            $reprint = 0;
-            
-            // this next section is to display the items in the course order
-            foreach($grades_by_student as $student => $categories) {
-                if (isset($item_order)) {
-                    // we already have the sort order let's jump out
-                    break;
-                }
-                $item_order = array();
-                foreach($categories as $category => $items) {
-                    if ($category == $cview) {
-                        foreach ($items as $assignment=>$points) {
-                            if ($assignment != 'stats') {
-                                $temp = $points['sort_order'];
-                                $item_order[$temp] = $assignment;
-                            }
-                        }
-                    }
-                }
-            }
-            /// Make sure $item_order is initialised (bug 3424)
-            if (empty($item_order)) $item_order = array();
-            
-            ksort($item_order);
-            
-            foreach($grades_by_student as $student => $categories) {
-                
-                if ($preferences->reprint_headers != 0 && $reprint >= $preferences->reprint_headers) {
-                    echo  $header.$header1.'</tr>';
-                    $reprint=0;
-                }
-                
-                // alternate row classes
-                $row = ($oddrow) ? '<tr class="r0">' : '<tr class="r1">';
-                $oddrow = !$oddrow;
-
-                // reset the col classes
-                $oddcol = true;
-
-                    
-                // set the links to student information based on multiview or individual... if individual go to student info... if many go to individual grades view.
-                if (has_capability('moodle/course:viewcoursegrades', $context)) {
-                    if ($view_by_student != -1) {
-                        $student_link = '<a href="'.$CFG->wwwroot.'/user/view.php?id='.$student.'&amp;course='.$course->id.'">';
-                    }
-                    else {
-                        $student_link = '<a href="?id='.$course->id.'&amp;action=vcats&amp;user='.$student.'&amp;cview='.$cview.'">';
-                    }
-                    $student_link .= $grades_by_student[$student]['student_data']['lastname'].', '.$grades_by_student[$student]['student_data']['firstname'].'</a>';
-                    $row .= '<th class="fullname" scope="row">'.$student_link.'</th>';
-                }
-                
-                foreach($categories as $category => $items) {
-                    if ($category == $cview) {
-                        // make sure that the grades come out in the same order
-                        foreach($item_order as $order=>$assignment) {
-                            
-                            $class = $all_categories[$category][$assignment]['modname'];
-
-                            if ($assignment != 'stats') {
-                                    
-                                if ($first == 0) {
-                                    $colcount++;
-                                    $link_id = grade_get_module_link($course->id, $all_categories[$category][$assignment]['cminstance'], $all_categories[$category][$assignment]['modid']);
-
-                                    $link = $CFG->wwwroot.'/mod/'.$all_categories[$category][$assignment]['modname'].'/view.php?id='.$link_id->id;
-                                    $all_categories[$category][$assignment]['link'] = $link;
-                                    if ($all_categories[$category][$assignment]['hidden'] == 0) {
-                                        $header .= '<th class="'.$class.'" colspan="'.$grade_columns.'" scope="col"><a href="'.$link.'">'.format_string($assignment,true).'</a>';
-                                    }
-                                    else {
-                                        $header .= '<th class="'.$class.'" colspan="'.$grade_columns.'" scope="col"><a class="dimmed" href="'.$link.'">'.format_string($assignment,true).'</a>';
-                                    }
-                                    if ($all_categories[$category][$assignment]['extra_credit'] == 1) {
-                                        $header .= '<span class="extracredit">('.get_string('extracredit','grades').')</span>'; 
-                                    }
-                                    $header .='</th>';
-                                    if ($preferences->show_points) {
-                                        $header1 .= '<th class="'.$class.'" scope="col">'. $all_categories[$category][$assignment]['maxgrade'];
-                                        if ($all_categories[$category][$assignment]['grade_against'] != $all_categories[$category][$assignment]['maxgrade']) {
-                                            $header1 .= '('. $all_categories[$category][$assignment]['grade_against'].')';
-                                        }
-                                        $header1 .= '</th>';
-                                    }
-                                                                        
-                                    if($preferences->show_percent)    {
-                                        if ($all_categories[$category][$assignment]['grade_against'] != $all_categories[$category][$assignment]['maxgrade']) {
-                                            $header1 .= '<th class="'.$class.'" scope="col">'.get_string('scaledpct','grades').'</th>';
-                                        }
-                                        else {
-                                            $header1 .= '<th class="'.$class.'" scope="col">'.get_string('rawpct','grades').'</th>';
-                                        }
-                                    }
-                                    if ($preferences->show_weighted) {
-                                        if ($all_categories[$category]['stats']['totalpoints'] != 0) {
-                                            $cur_weighted_max = sprintf("%0.2f", $all_categories[$category][$assignment]['grade_against']/$all_categories[$category]['stats']['totalpoints']*$all_categories[$category]['stats']['weight']);
-                                        }
-                                        else {
-                                            $cur_weighted_max = 0;
-                                        }
-                                        $header1 .= '<th scope="col">'.$cur_weighted_max.get_string('pctoftotalgrade','grades').'</th>';
-                                    }
-                                }
-
-                                // display points 
-                                if ($preferences->show_points) { 
-                                    $class .= ($oddcol) ? ' c0 points' : ' c1 points';
-                                    $oddcol = !$oddcol;
-                                    $row .= '<td class="'.$class.'"><a href="'.$all_categories[$category][$assignment]['link'].'">' . $items[$assignment]['grade'] . '</a></td>';
-                                }
 
-                                if ($preferences->show_percent) {
-                                    $class .= ($oddcol) ? ' c0 percent' : ' c1 percent';
-                                    $oddcol = !$oddcol;
-                                    $row .= '<td class="'.$class.'">'. $items[$assignment]['percent'].'%</td>';
-                                }
-                                
-                                if ($preferences->show_weighted) {
-                                    $class .= ($oddcol) ? ' c0 weighted' : ' c1 weighted';
-                                    $oddcol = !$oddcol;
-                                    $row .= '<td class="'.$class.'">'.$items[$assignment]['weighted'].'%</td>';
-                                }
-                            }
-                        }
-                    } else {
-                        $class = '';
-                    }
-                }
-                
-                if ($first == 0) {
-                    if (has_capability('moodle/course:viewcoursegrades', $context) && $view_by_student == -1) {
-                        $total_sort_link = '<a href="?id='.$course->id.'&amp;action=vcats&amp;cview='.$cview.'&amp;sort=highgrade_category"><img src="'.$CFG->wwwroot.'/pix/t/down.gif" alt="'.get_string('highgradedescending','grades').'" /></a>';
-                        $total_sort_link .= '<a href="?id='.$course->id.'&amp;action=vcats&amp;cview='.$cview.'&amp;sort=highgrade_category_asc"><img src="'.$CFG->wwwroot.'/pix/t/up.gif" alt="'.get_string('highgradeascending','grades').'" /></a>';
-                    }
-                    else {
-                        $total_sort_link = '';
-                    }
-                    
-                    $stats_link = '<a href="javascript:void(0)" onclick="window.open(\'?id='.$course->id.'&amp;action=stats&amp;category='.$cview.'\',\''.get_string('statslink','grades').'\',\'height=200,width=300,scrollbars=no\')">'.get_string('statslink','grades').'</a>';
-                    if ($all_categories[$cview]['stats']['drop'] != 0) {
-                        $header .= '<th class="'.$class.'" colspan="'.$grade_columns.'" scope="col">'.get_string('total','grades').'&nbsp; (Lowest '. $all_categories[$cview]['stats']['drop']. ' Dropped)'.$total_sort_link.' '.$stats_link.'</th>';
-                    }
-                    else {
-                        $header .= '<th class="'.$class.'" colspan="'.$grade_columns.'" scope="col">'.get_string('total','grades').'&nbsp;'.$total_sort_link.' '.$stats_link.'</th>';
-                    }
-                    
-                    if ($preferences->show_points) {
-                        $header1 .= '<th class="'.$class.'" scope="col">'.$all_categories[$cview]['stats']['totalpoints'];
-                        if ($all_categories[$cview]['stats']['bonus_points'] != 0) {
-                            $header1 .='(+'.$all_categories[$cview]['stats']['bonus_points'].')';
-                        }
-                        $header1 .='</th>';
-                    }
-                    if ($preferences->show_percent) {
-                        $header1 .= '<th class="'.$class.'" scope="col">'.get_string('percent','grades').'</th>';
-                    }
-                    
-                    
-                    if ($preferences->show_weighted) {
-                        $header1 .= '<th class="'.$class.'" scope="col">'.$all_categories[$cview]['stats']['weight'].get_string('pctoftotalgrade','grades').'</th>';
-                    }
-                    
-                    if (has_capability('moodle/course:viewcoursegrades', $context)) {
-                        $header .= '<th rowspan="2" scope="col">'.$student_heading_link.'</th></tr>';
-                    }
-                    else {
-                        $header .= '</tr>';
-                    }
-                    
-                    //adjust colcount to reflect the actual number of columns output
-                    $colcount++; // total column
-                    $colcount = $colcount*$grade_columns + 2;
-                    echo  '<tr class="title"><th colspan="'.$colcount.'" scope="col">';
-                    if ($preferences->use_advanced != 0) {
-                        echo  $cview.' '.get_string('grades','grades');
-                    }
-                    else {
-                        echo  get_string('grades','grades');
-                    }
-
-                    if (has_capability('moodle/course:viewcoursegrades', $context)) {
-                        helpbutton('teacher', get_string('gradehelp','grades'), 'grade');
-                    }
-                    else {
-                        helpbutton('student', get_string('gradehelp','grades'), 'grade');
-                    }
-                    echo  '</th></tr>';
-                    echo  $header;
-                    echo  $header1.'</tr>';
-                    $first = 1;
-                }
-
-                // total points for category
-                if ($preferences->show_points) {
-                    $class .= ($oddcol) ? ' c0 points' : ' c1 points';
-                    $oddcol = !$oddcol;
-                    $row .= '<td class="'.$class.'">'.$grades_by_student[$student][$cview]['stats']['points'].'</td>';
-                }
-                
-                // total percent for category
-                if ($preferences->show_percent) {
-                    $class .= ($oddcol) ? ' c0 percent' : ' c1 percent';
-                    $oddcol = !$oddcol;
-                    $row .= '<td class="'.$class.'">'.$grades_by_student[$student][$cview]['stats']['percent'].'%</td>';
-                }
-                
-
-                // total weighted for category
-                if ($preferences->show_weighted) {
-                    $class .= ($oddcol) ? ' c0 weighted' : ' c1 weighted';
-                    $oddcol = !$oddcol;
-                    $row .= '<td class="'.$class.'">'.$grades_by_student[$student][$cview]['stats']['weighted'].'%</td>';
-                }
-
-                if (has_capability('moodle/course:viewcoursegrades', $context)) {
-                    $row .= '<td class="fullname">'.$student_link.'</td>';
-                }
-                $row .= '</tr>';
-                echo  $row;
-                $reprint++;
-            }
-            echo  '</table>';
-        }
-        else { // no grades returned
-            error(get_string('nogradesreturned','grades'), $CFG->wwwroot.'/course/view.php?id='.$course->id);
+        if (!empty($this->courseid)) {
+            $url .= $glue.'id='.$this->courseid;
+            $glue = '&amp;';
         }
-    }
-    else {
-        error(get_string('nocategoryview','grades'), $CFG->wwwroot.'/course/view.php?id='.$course->id);
-    }
-}
 
-function grade_view_all_grades($view_by_student) { // if mode=='grade' then we are in user view
-// displays all grades for the course
-    global $CFG;
-    global $course;
-    global $USER;
-    global $preferences;
-    
-    if (!$context = get_context_instance(CONTEXT_COURSE, $course->id)) {
-        return false;
-    }
-
-    // if can't see course grades, print single grade view
-    if (!has_capability('moodle/course:viewcoursegrades', $context)) {
-        $view_by_student = $USER->id;
-    }
-    
-    list($grades_by_student, $all_categories) = grade_get_formatted_grades();
-
-    if ($grades_by_student != 0 && $all_categories != 0) {
-      
-        // output a form for the user to download the grades.  
-        grade_download_form();
-        
-        if ($view_by_student != -1) {
-            // unset all grades except for this student
-            foreach ($grades_by_student as $student=>$junk) {
-                if($student != $view_by_student) {
-                    unset($grades_by_student[$student]);
-                }
-            }
+        if (!empty($this->userid)) {
+            $url .= $glue.'userid='.$this->userid;
+            $glue = '&amp;';
         }
-        
-        $grade_columns = $preferences->show_weighted + $preferences->show_points + $preferences->show_percent;
-        
-        $first = 0;
-        $total_course_points = 0;
-        $maxpercent = 0;
-        $reprint=0;
-        
-        echo  '<table align="center" class="grades">';
-        if (has_capability('moodle/course:viewcoursegrades', $context)) {
-            $student_heading_link = get_string('student','grades');
-            if ($view_by_student == -1) {
-                $student_heading_link .='<a href="?id='.$course->id.'&amp;action=grades&amp;sort=lastname"><br /><font size="-2">'.get_string('sortbylastname','grades').'</font></a>';
-                $student_heading_link .= '<a href="?id='.$course->id.'&amp;action=grades&amp;sort=firstname"><br /><font size="-2">'.get_string('sortbyfirstname','grades').'</font></a>';
-            }
-            else {
-                $student_heading_link .= '<br /><a href="?id='.$course->id.'&amp;&amp;action=grades"><font size="-2">'.get_string('showallstudents','grades').'</font></a>';
-            }
-            $header = '<tr><th rowspan="2" scope="col">'.$student_heading_link.'</th>';
-        }
-        else {
-            $header = '</tr>';
-        }
-        $header1 = '<tr>';
-        
-        $rowcount = 0;
-        $oddrow = true;
-        $colcount = 0;
-  
-        foreach($grades_by_student as $student => $categories) {
-            $totalpoints = 0;
-            $totalgrade = 0;
-            $total_bonus_points = 0;
-            if ($preferences->reprint_headers != 0 && $reprint >= $preferences->reprint_headers) {
-                echo  $header.$header1;
-                $reprint=0;
-            }
-            
-            // alternate row classes
-            $row = ($oddrow) ? '<tr class="r0">' : '<tr class="r1">';
-            $oddrow = !$oddrow;
-            
-            // set the links to student information based on multiview or individual... if individual go to student info... if many go to individual grades view.
-            if (has_capability('moodle/course:viewcoursegrades', $context)) {
-                if ($view_by_student != -1) {
-                    $studentviewlink = '<a href="'.$CFG->wwwroot.'/user/view.php?id='.$student.'&amp;course='.$course->id.'">'.$grades_by_student[$student]['student_data']['lastname'].', '.$grades_by_student[$student]['student_data']['firstname'].'</a>';
-                }
-                else {
-                    $studentviewlink = '<a href="?id='.$course->id.'&amp;action=view_student_grades&amp;user='.$student.'">'.$grades_by_student[$student]['student_data']['lastname'].', '.$grades_by_student[$student]['student_data']['firstname'].'</a>';
-                }
-                $row .= '<th scope="row">'. $studentviewlink .'</th>';
-            }
-            ksort($categories);
 
-            foreach($categories as $category => $items) {
-                if ($category != 'student_data') {
-                   
-                    if ($first == 0) {
-                        $colcount++;
-                        if ($category == UNCATEGORISED) {
-                            $categoryname = get_string(UNCATEGORISED, 'grades');
-                        } else {
-                            $categoryname = $category;
-                        }
-                        // only print the category headers if something is displayed for them
-                        if ($preferences->show_weighted || $preferences->show_percent || $preferences->show_points) {
-                            $stats_link = '<a href="javascript:void(0)" onclick="window.open(\'?id='.$course->id.'&amp;action=stats&amp;category='.$category.'\',\''.get_string('statslink','grades').'\',\'height=200,width=300,scrollbars=no\')"><font size="-2">'.get_string('statslink','grades').'</font></a>';
-                            $header .= '<th colspan="'.$grade_columns.'" scope="col"><a href="?id='.$course->id.'&amp;action=vcats&amp;cview='.$category;
-                            if ($view_by_student != -1) {
-                                $header .= '&amp;user='.$view_by_student;
-                            }
-                            $header .='">'. $categoryname .' '.$stats_link.'</a>';
-                        }
-                        if ($preferences->display_weighted != 0) {
-                            $header .= '('. $all_categories[$category]['stats']['weight'] . '%)';
-                        }
-                        $header .= '</th>';
-                        if ($preferences->show_points) {
-                            $header1 .= '<th scope="col">'.get_string('points','grades').'('.$all_categories[$category]['stats']['totalpoints'].')';
-                            if ($all_categories[$category]['stats']['bonus_points'] != 0) {
-                                $header1 .='(+'.$all_categories[$category]['stats']['bonus_points'].')';
-                            }
-                            $header1 .='</th>';
-                        }
-                        if ($preferences->show_percent) {
-                            $header1 .= '<th scope="col">'.get_string('percent','grades').'</th>';
-                        }
-                        if ($preferences->show_weighted) {
-                            $header1 .= '<th scope="col">'.get_string('weightedpctcontribution','grades').'</th>';
-                        }
-                        $maxpercent = $all_categories["$category"]['stats']['weight'] + $maxpercent;
-                        //$total_course_points = $all_categories[$category]['stats']['totalpoints']+ $total_course_points;
-                        //$total_course_points = $all_categories[$category]['stats']['totalpoints']+ $total_course_points;
-                    }
-                    
-                    if ($preferences->show_points) {
-                        $row .= '<td align="right">' . $items['stats']['points'] . '</td>';
-                    }
-                    if ($preferences->show_percent) {
-                        $row .= '<td align="right">'. $items['stats']['percent'].'%</td>';
-                    }
-
-                    if ($preferences->show_weighted) {
-                        $row .= '<td align="right">'. $items['stats']['weighted'] . '%</td>';
-                    }
-                    $total_bonus_points = $all_categories[$category]['stats']['bonus_points'];
-                } 
-            }
-            if ($first == 0) {
-                if ($preferences->show_letters) {
-                    $total_columns = $grade_columns + 1;
-                }
-                else {
-                    $total_columns = $grade_columns;
-                }
-                
-                if (has_capability('moodle/course:viewcoursegrades', $context) && $view_by_student == -1) {
-                    $grade_sort_link = '<a href="?id='.$course->id.'&amp;action=grades&amp;sort=highgrade"><img src="'.$CFG->wwwroot.'/pix/t/down.gif" alt="'.get_string('highgradedescending','grades').'" /></a>';
-                    $grade_sort_link .= '<a href="?id='.$course->id.'&amp;action=grades&amp;sort=highgrade_asc"><img src="'.$CFG->wwwroot.'/pix/t/up.gif" alt="'.get_string('highgradeascending','grades').'" /></a>';
-                    $points_sort_link = '<a href="?id='.$course->id.'&amp;action=grades&amp;sort=points"><img src="'.$CFG->wwwroot.'/pix/t/down.gif" alt="'.get_string('pointsdescending','grades').'" /></a>';
-                    $points_sort_link .= '<a href="?id='.$course->id.'&amp;action=grades&amp;sort=points_asc"><img src="'.$CFG->wwwroot.'/pix/t/up.gif" alt="'.get_string('pointsascending','grades').'" /></a>';
-                    $weighted_sort_link = '<a href="?id='.$course->id.'&amp;action=grades&amp;sort=weighted"><img src="'.$CFG->wwwroot.'/pix/t/down.gif" alt="'.get_string('weighteddescending','grades').'" /></a>';
-                    $weighted_sort_link .= '<a href="?id='.$course->id.'&amp;action=grades&amp;sort=weighted_asc"><img src="'.$CFG->wwwroot.'/pix/t/up.gif" alt="'.get_string('weightedascending','grades').'" /></a>';
-                    $percent_sort_link = '<a href="?id='.$course->id.'&amp;action=grades&amp;sort=percent"><img src="'.$CFG->wwwroot.'/pix/t/down.gif" alt="'.get_string('percentdescending','grades').'" /></a>';
-                    $percent_sort_link .= '<a href="?id='.$course->id.'&amp;action=grades&amp;sort=percent_asc"><img src="'.$CFG->wwwroot.'/pix/t/up.gif" alt="'.get_string('percentascending','grades').'" /></a>';
-                }
-                $stats_link = '<a href="javascript:void(0)" onclick="window.open(\'?id='.$course->id.'&amp;action=stats&amp;category=all\',\''.get_string('statslink','grades').'\',\'height=200,width=300,scrollbars=no\')"><font size="-2">'.get_string('statslink','grades').'</font></a>';
-                $header .= '<th colspan="'.$total_columns.'" scope="col">'.get_string('total','grades').'&nbsp;'.$stats_link.'</th>';
-                if (has_capability('moodle/course:viewcoursegrades', $context) && $view_by_student == -1) {
-                    if ($preferences->show_points) {
-                        $header1 .= '<th scope="col">'.get_string('points','grades').'('.$all_categories['stats']['totalpoints'].')';
-                        if ($category != 'student_data' && $all_categories[$category]['stats']['bonus_points'] != 0) {
-
-                            $header1 .='(+'.$total_bonus_points.')';
-                        }
-                        $header1 .= '<br />'.$points_sort_link.' '.'</th>';
-                    }
-                    if ($preferences->show_percent) {
-                        $header1 .= '<th scope="col">'.get_string('percentshort','grades').'<br />'.$percent_sort_link.' '.'</th>';
-                    }
-                    if ($preferences->show_weighted) {
-                        $header1 .= '<th scope="col">'.get_string('weightedpct','grades').'('.$all_categories['stats']['weight'].')'.'<br />'.$weighted_sort_link.' '.'</th>';
-                    }
-                    if ($preferences->show_letters) {
-                        $header1 .= '<th scope="col">'.get_string('lettergrade','grades').'<br />'.$grade_sort_link.' '.'</th>';
-                    }
-                    $header1 .= '</tr>';
-                }
-                else {
-                    if ($preferences->show_points) {
-                        $header1 .= '<th scope="col">'.get_string('points','grades').'('.$all_categories['stats']['totalpoints'].')';
-                        if ($category != 'student_data' && $all_categories[$category]['stats']['bonus_points'] != 0) {
-                            $header1 .='(+'.$total_bonus_points.')';
-                        }
-                        $header1 .= '</th>';
-                    }
-                    if ($preferences->show_percent) {
-                        $header1 .= '<th scope="col">'.get_string('percentshort','grades').'</th>';
-                    }
-                    if ($preferences->show_weighted) {
-                        $header1 .= '<th scope="col">'.get_string('weightedpct','grades').'('.$all_categories['stats']['weight'].')</th>';
-                    }
-                    if ($preferences->show_letters) {
-                        $header1 .= '<th scope="col">'.get_string('lettergrade','grades').'</th>';
-                    }
-                    $header1 .= '</tr>';
-                }
-                if (has_capability('moodle/course:viewcoursegrades', $context)) {
-                    $header .= '<th rowspan="2" scope="col">'.$student_heading_link.'</th></tr>';
-                }
-                // adjust colcount to reflect actual number of columns output
-                $colcount = $colcount * $grade_columns + $total_columns + 2;
-  
-                echo  '<tr><th colspan="'.$colcount.'" scope="col"><font size="+1">'.get_string('allgrades','grades').'</font>';
-                if (has_capability('moodle/course:viewcoursegrades', $context)) {
-                    helpbutton('teacher', get_string('gradehelp','grades'), 'grade');
-                }
-                else {
-                    helpbutton('student', get_string('gradehelp','grades'), 'grade');
-                }
-                echo  '</th></tr>';
-                
-                                
-                echo  $header;
-                echo  $header1;
-                $first = 1;
-            }
-            if ($preferences->show_points) {
-                $row .= '<td align="right">'.$grades_by_student[$student]['student_data']['points'].'</td>';
-            }
-            if ($preferences->show_percent) {
-                $row .= '<td align="right">'.$grades_by_student[$student]['student_data']['percent'].'%</td>';
-            }
-            if ($preferences->show_weighted) {
-                $row .= '<td align=right>'.$grades_by_student[$student]['student_data']['weighted'].'%</td>';
-            }
-            if ($preferences->show_letters) {
-                if ($preferences->use_weighted_for_letter == 1) {
-                    $grade = $grades_by_student[$student]['student_data']['weighted'];
-                }
-                else {
-                    $grade = $grades_by_student[$student]['student_data']['percent'];
-                }
-                $letter_grade = grade_get_grade_letter($course->id, $grade);
-                if ($letter_grade) {
-                    $row .= '<td align="right">'.$letter_grade->letter.'</td>';
-                }
-                else {
-                    // there wasn't an appropriate entry to use in the gradebook.
-                    if (grade_letters_set($course->id)) {
-                        $row .= '<td align="right">'.get_string('nolettergrade','grades').' '.$grade.'</td>';
-                    }
-                    else {
-                        $row .= '<td align="right">'.get_string('nogradeletters','grades').'</td>';
-                    }
-                }
-            }
-            if (has_capability('moodle/course:viewcoursegrades', $context)) {
-                $row .= '<td>'. $studentviewlink .'</td></tr>';
-            }
-            else {
-                $row .= '</tr>';
-            }
-
-            echo $row;           
-            $reprint++;
+        if (!empty($this->page)) {
+            $url .= $glue.'page='.$this->page;
         }
-        echo  '</table>';
-    }
-    else { // no grades returned
-        error(get_string('nogradesreturned','grades'));
-    }
-}
 
-
-function grade_set_grade_weights() {
-// set the grade weights as submitted from the form generated by display_grade_weights    
-    global $CFG;
-    global $course;
-    global $USER;
-    
-    if (!empty($USER->id)) {
-        if (!confirm_sesskey()) {
-            error(get_string('confirmsesskeybad', 'error'));
-        }
+        return $url;
     }
-    
-    // get list of all categories
-    $categories = get_records('grade_category', 'courseid', $course->id);
-    if ($categories) {
-        foreach ($categories as $category) {
-            $form_catname = preg_replace('/[.| ]/', '_', $category->name);
 
-            $submitted_category = optional_param($form_catname);    
-            if (is_numeric($submitted_category)) {
-                // see if there is a weight if so see if it needs to be updated
-                $weight = grade_get_category_weight($course->id, $category->name);
-                if ($weight) {
-                    if ($weight->weight != $submitted_category)
-                    {                        
-                        set_field('grade_category', 'weight', $submitted_category, 'id', $weight->id);
-                    }
-                    
-                    $cur_drop = optional_param("drop_x_lowest$form_catname");
-                    $cur_bonus_points = optional_param("bonus_points$form_catname");
-                    $cur_hidden = optional_param("hidden$form_catname");
-                    if ($cur_hidden) {
-                        $cur_hidden = true;
-                    }
-                    else {
-                        $cur_hidden = false;
-                    }
-                    
-                    if ($weight->drop_x_lowest != $cur_drop) {
-                        set_field('grade_category', 'drop_x_lowest', $cur_drop, 'id', $weight->cat_id);
-                    }
-                    if ($weight->bonus_points != $cur_bonus_points) {
-                        set_field('grade_category', 'bonus_points', $cur_bonus_points, 'id', $weight->cat_id);
-                    }
-                    if ($cur_hidden) {
-                        set_field('grade_category', 'hidden', 1, 'id', $weight->cat_id);
-                    }
-                    else {
-                        set_field('grade_category', 'hidden', 0, 'id', $weight->cat_id);
-                    }
-                }
-                else {
-                    // insert the new record... we shouldn't reach this point anymore
-                    //$new_weight->course = $course->id;
-                    //$new_weight->category = $category->id;
-                    //$new_weight->weight = $submitted_category;
-                    //insert_record('grade_weight', $new_weight);
-                }
-            }
-            else {
-                echo  '<center><font color="red">'.get_string('nonumericweight','grades').
-                        format_string($category->name) .': "'.$submitted_category.'"</font></center><br />';
-            }
+    function get_form_fields() {
+        if (empty($this->type) or empty($this->plugin)) {
+            return '';
         }
-    }
-}
 
-function grade_display_grade_weights() {
-// get all categories with weights
-// then set and display that entry.
-    global $CFG;
-    global $course;
-    global $USER;
-    
-    $categories = get_records('grade_category', 'courseid', $course->id);
-    if ($categories) {
-        echo  '<form id="grade_weights" action="./index.php" method="post">';
-        echo  '<table border="0" cellspacing="2" cellpadding="5" align="center" class="generalbox">';
-        echo  '<tr><th colspan="5" class="header" scope="col">'.get_string('setweights','grades');
-        helpbutton('weight', get_string('gradeweighthelp','grades'), 'grade');
-        echo  '</th></tr>';
-        echo  '<tr><td align="center" class="generaltableheader">'.get_string('category','grades').'</td>';
-        echo  '<td align="center" class="generaltableheader">'.get_string('weight','grades').'</td>';
-        echo  '<td align="center" class="generaltableheader">'.get_string('dropxlowest','grades').'</td>';
-        echo  '<td align="center" class="generaltableheader">'.get_string('bonuspoints','grades').'</td>';
-        echo  '<td align="center" class="generaltableheader">'.get_string('hidecategory','grades').'</td>';
-        echo  '</tr>';
-        echo  '<input type="hidden" name="id" value="'.$course->id.'" />';
-        echo  '<input type="hidden" name="action" value="set_grade_weights" />';
-        echo  '<input type="hidden" name="sesskey" value="'.$USER->sesskey.'" />';
+        $result  = '<input type="hidden" name="gpr_type" value="'.$this->type.'" />';
+        $result .= '<input type="hidden" name="gpr_plugin" value="'.$this->plugin.'" />';
 
-        $sum = 0;
-        
-        foreach($categories as $category) {
-            $val = $category->weight;
-            $sum = $sum + $val;
-                        
-            // make names form safe
-            $form_catname = str_replace(' ', '_', $category->name);
-            if ($category->name == UNCATEGORISED) {
-                $category->name = get_string(UNCATEGORISED, 'grades');
-            }
-            echo  '<tr><td align="center" class="generalboxcontent">'. format_string($category->name) .'</td>';
-            echo  '<td align="center" class="generalboxcontent"><input type="text" size="5" name="'.$form_catname.'" value="'.$val.'" /></td>';
-            echo  '<td align="center" class="generalboxcontent"><input type="text" size="5" name="drop_x_lowest'.$form_catname.'" value="'.$category->drop_x_lowest.'" /></td>';
-            echo  '<td align="center" class="generalboxcontent"><input type="text" size="5" name="bonus_points'.$form_catname.'" value="'.$category->bonus_points.'" /></td>';
-            echo  '<td align="center" class="generalboxcontent"><input type="checkbox" name="hidden'.$form_catname.'" ';
-            if ($category->hidden == 1) {
-                echo  ' checked="checked"';
-            }
-            echo  ' /></td></tr>';
-        }
-        echo  '<tr><td colspan="5" align="center" class="generalboxcontent">';
-        echo  '<input type="submit" value="'.get_string('savechanges','grades').'" />';
-        echo  '</td></tr>';
-        if ($sum != 100) {
-            echo  '<tr><td colspan="5" align="center" class="generalboxcontent"><font color="red">'.get_string('totalweightnot100','grades').'</font></td></tr>';
+        if (!empty($this->courseid)) {
+            $result .= '<input type="hidden" name="gpr_courseid" value="'.$this->courseid.'" />';
         }
-        else {
-            echo  '<tr><td colspan="5" align="center" class="generalboxcontent"><font color="green">'.get_string('totalweight100','grades').'</font></td></tr>';
-        }
-    }
-    else {
-        /// maybe this should just do the default population of the categories instead?
-        echo  '<font color="red">'.get_string('setcategorieserror','grades').'</font>';
-    }
-    echo  '</table>';
-    echo  '</form>';
-    echo  '<center>'.get_string('dropxlowestwarning','grades').'</center><br />';
-}
-
-function grade_set_categories() {
-    global $CFG;
-    global $course;
-    global $USER;
-    
 
-    /// Collect modules data
-    get_all_mods($course->id, $mods, $modnames, $modnamesplural, $modnamesused);
-    
-    echo  '<table border="0" cellspacing="2" cellpadding="5" align="center" class="generalbox">';
-    echo  '<tr><th colspan="5" class="header" scope="col">'.get_string('setcategories','grades');
-    helpbutton('category', get_string('gradecategoryhelp','grades'), 'grade');
-    echo  '</th></tr>';
-    echo  '<tr><td align="center" class="generaltableheader">'.get_string('gradeitem','grades').'</td>';
-    echo  '<td align="center" class="generaltableheader">'.get_string('category','grades').'</td>';
-    echo  '<td align="center" class="generaltableheader">'.get_string('maxgrade','grades').'</td>';
-    echo  '<td align="center" class="generaltableheader">'.get_string('curveto','grades').'</td>';
-    echo  '<td align="center" class="generaltableheader">'.get_string('extracredit','grades').'</td></tr>';
-    echo  '<form id="set_categories" method="post" action="./index.php" >';
-    echo  '<input type="hidden" name="action" value="assign_categories" />';
-    echo  '<input type="hidden" name="id" value="'.$course->id.'" />';
-    echo  '<input type="hidden" name="sesskey" value="'.$USER->sesskey.'" />';
-    
-    $itemcount = 0;
-    
-    /// Search through all the modules, pulling out grade data
-    $sections = get_all_sections($course->id); // Sort everything the same as the course
-    for ($i=0; $i<=$course->numsections; $i++) {
-        if (isset($sections[$i])) {   // should always be true
-            $section = $sections[$i];
-            if ($section->sequence) {
-                $sectionmods = explode(",", $section->sequence);
-                foreach ($sectionmods as $sectionmod) {
-                    if (empty($mods[$sectionmod])) {
-                        continue;
-                    }
-                    $mod = $mods[$sectionmod];
-                    $instance = get_record("$mod->modname", "id", "$mod->instance");
-                    $libfile = "$CFG->dirroot/mod/$mod->modname/lib.php";
-                    if (file_exists($libfile)) {
-                        require_once($libfile);
-                        $gradefunction = $mod->modname."_grades";
-                        if (function_exists($gradefunction)) {   // Skip modules without grade function
-                            if ($modgrades = $gradefunction($mod->instance)) {
-                                
-                                if ($modgrades->maxgrade != '')
-                                // this block traps out broken modules that don't return a maxgrade according to the moodle API
-                                {
-                                    $itemcount++;
-                                    //modgrades contains student information with associated grade
-                                    //echo  "<b>modname: $mod->modname id: $mod->id course: $mod->course</b><br />";
-                                    echo  '<input type="hidden" name="modname'.$itemcount.'" value="'.$mod->modname.'" />';
-                                    echo  '<input type="hidden" name="mod'.$itemcount.'" value="'.$mod->instance.'" />';
-                                    echo  '<input type="hidden" name="course'.$itemcount.'" value="'.$mod->course.'" />';
-                                    echo  '<tr><td align="center" class="generalboxcontent">';
-                                    // get instance name from db.
-                                    $instance = get_record($mod->modname, 'id', $mod->instance);
-                                    echo  format_string($instance->name)."</td>";
-                                    // see if the item is already in the category table and if it is call category select with the id so it is selected
-                                    echo  '<td align="center" class="generalboxcontent"><select name="category'.$itemcount.'">';
-                                    $item_cat_id = get_record('grade_item', 'modid', $mod->module, 'courseid', $course->id, 'cminstance', $mod->instance);
-                                    //print_object($item_cat_id);
-                                    if (isset($item_cat_id)) {
-                                        grade_category_select($item_cat_id->category);
-                                    }
-                                    else {
-                                        grade_category_select(-1);
-                                    }
-                                    echo  '</select></td><td align="center" class="generalboxcontent">'.$modgrades->maxgrade.'<input type="hidden" name="maxgrade'.$itemcount.'" value="'.$modgrades->maxgrade.'" /></td>';
-                                        
-                                    if (isset($item_cat_id)) {
-                                        // 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%)
-                                        if ($item_cat_id->scale_grade == '' || $item_cat_id->scale_grade == 0)
-                                            $scale_to = $modgrades->maxgrade;
-                                        else
-                                            $scale_to = round($modgrades->maxgrade/$item_cat_id->scale_grade);
-                                        echo  '<td align="center" class="generalboxcontent"><input type="text" size="5" name="scale_grade'.$itemcount.'" value="'.$scale_to.'" /></td>';
-                                    }
-                                    else {
-                                        echo  '<td align="center" class="generalboxcontent"><input type="text" size="5" name="scale_grade'.$itemcount.'" value="'.$modgrades->maxgrade.'" /></td>';
-                                    }
-                                    
-                                    echo  '<td align="center" class="generalboxcontent"><input type="checkbox" name="extra_credit'.$itemcount.'" ';
-                                    if ($item_cat_id->extra_credit == 1) {
-                                        echo  ' checked="checked"';
-                                    }
-                                    echo  ' /></td></tr>';
-                                }
-                            }
-                        }
-                    }
-                }
-            }
+        if (!empty($this->userid)) {
+            $result .= '<input type="hidden" name="gpr_userid" value="'.$this->userid.'" />';
         }
-    }
-    echo  '<input type="hidden" name="totalitems" value="'.$itemcount.'" />';
-    echo  '<tr><td colspan="5" align="center" class="generalboxcontent"><input type="submit" value="'.get_string('savechanges','grades').'" /></td></tr>';
-    echo  '</form>';
-    echo  '<tr><td colspan="5" align="center" class="generalboxcontent">';
-    grade_add_category_form();
-    echo  '</td></tr><tr><td colspan="5" align="center" class="generalboxcontent">';
-    grade_delete_category_form();
-    echo  '</td></tr></table>';
-    echo '<center>'.get_string('extracreditwarning','grades').'</center>';
-}
 
-function grade_delete_category() {
-    global $CFG;
-    global $course;
-    global $USER;
-    
-    if (!empty($USER->id)) {
-        if (!confirm_sesskey()) {
-            error(get_string('confirmsesskeybad', 'error'));
+        if (!empty($this->page)) {
+            $result .= '<input type="hidden" name="gpr_page" value="'.$this->page.'" />';
         }
     }
-    
-    $cat_id = optional_param('category_id');
-    if ($cat_id != 'blank') {
-        // delete the record
-        delete_records('grade_category', 'id', $cat_id, 'courseid', $course->id);
-        // set grade_item category field=0 where it was the deleted category (set uncategorized will clean this up)
-        set_field('grade_item', 'category', 0, 'category', $cat_id);
-    }
-}
 
-function grade_assign_categories() {
-    global $CFG;
-    global $course;
-    global $USER;
-    $num_categories = optional_param('totalitems');
-
-    if (!empty($USER->id)) {
-        if (!confirm_sesskey()) {
-            error(get_string('confirmsesskeybad', 'error'));
+    function add_mform_elements(&$mform) {
+        if (empty($this->type) or empty($this->plugin)) {
+            return;
         }
-    }
 
-    for ($i = 1; $i <= $num_categories; $i++) {
+        $mform->addElement('hidden', 'gpr_type', $this->type);
+        $mform->setType('gpr_type', PARAM_SAFEDIR);
 
-        // these next sets of lines are a bit obtuse, but it lets there be a dynamic number of grade items
-        // in the grade category form (maybe there's a better way?)
-        $cur_cat_id = '$_REQUEST[\'category'.$i.'\'];';
-        eval( "\$cur_cat_id = $cur_cat_id;" ); 
-        $cur_modname = '$_REQUEST[\'modname'.$i.'\'];';
-        eval( "\$cur_modname = $cur_modname;" ); 
-        $cur_mod = '$_REQUEST[\'mod'.$i.'\'];';
-        eval( "\$cur_mod = $cur_mod;" );
-        $cur_maxgrade = '$_REQUEST[\'maxgrade'.$i.'\'];';
-        eval( "\$cur_maxgrade = $cur_maxgrade;" );
-        $cur_scale_grade = '$_REQUEST[\'scale_grade'.$i.'\'];';
-        eval( "\$cur_scale_grade = $cur_scale_grade;" );
-        $cur_extra_credit = '$_REQUEST[\'extra_credit'.$i.'\'];';
-        $temp = 'extra_credit'.$i;
-        $junk = get_record('modules','name',$cur_modname);
-        $cur_modid = $junk->id;
-        if (isset($_REQUEST[$temp])) {
-            eval( "\$cur_extra_credit = $cur_extra_credit;" );
-        }
-        else {
-            $cur_extra_credit = false;
-        }
-        if ($cur_extra_credit) {
-        $cur_extra_credit = 1;
-        } else {
-            $cur_extra_credit = 0;
-        }
-        if ($cur_scale_grade == 0 || $cur_scale_grade == '') {
-            $cur_scale_grade = 1.0;
-        }
-        
-        $db_cat = get_record('grade_item', 'modid', $cur_modid, 'cminstance', $cur_mod, 'courseid', $course->id);
-        if ( $db_cat ) {
-            if ($db_cat->category != $cur_cat_id) {
-                // item doesn't match in the db so update it to point to the new category
-                set_field('grade_item', 'category', $cur_cat_id, 'id', $db_cat->id);
-            }
-
-            if ($db_cat->scale_grade != $cur_maxgrade/$cur_scale_grade) {
-                // scale_grade doesn't match
-                set_field('grade_item', 'scale_grade', ($cur_maxgrade/$cur_scale_grade), 'id', $db_cat->id);
-            }
+        $mform->addElement('hidden', 'gpr_plugin', $this->plugin);
+        $mform->setType('gpr_plugin', PARAM_SAFEDIR);
 
-            set_field('grade_item', 'extra_credit', $cur_extra_credit, 'id', $db_cat->id);
+        if (!empty($this->courseid)) {
+            $mform->addElement('hidden', 'gpr_courseid', $this->courseid);
+            $mform->setType('gpr_courseid', PARAM_INT);
         }
-        else {
-            // add a new record
-            $item->courseid = $course->id;
-            $item->category = $cur_cat_id;
-            $item->modid = $cur_modid;
-            $item->cminstance = $cur_mod;
-            $item->scale_grade = $cur_scale_grade;
-            $item->extra_credit = $cur_extra_credit;
-            insert_record('grade_item', $item);
-        }
-    }
-}
 
-function grade_add_category_form() {
-    /// outputs a form to add a category
-    /// just a simple text box with submit
-    global $course;
-    global $USER;
-    echo  '<form id="new_category">';
-    echo  get_string('addcategory','grades').':<input type="text" name="name" size="20" />';
-    echo  '<input type="hidden" name="id" value="'.$course->id.'" />';
-    echo  '<input type="hidden" name="action" value="insert_category" />';
-    echo  '<input type="hidden" name="sesskey" value="'.$USER->sesskey.'" />';
-    echo  '<input type="submit" value="'.get_string('addcategory','grades').'" />';
-    echo  '</form>';
-}
-
-function grade_delete_category_form() {
-    // outputs a form to delete a category
-    global $course;
-    global $USER;
-    echo  '<form id="delete_category">';
-    echo  get_string('deletecategory','grades').': <select name="category_id">';
-    grade_category_select();
-    echo  '</select><input type="hidden" name="id" value="'.$course->id.'" />';
-    echo  '<input type="hidden" name="sesskey" value="'.$USER->sesskey.'" />';
-    echo  '<input type="hidden" name="action" value="delete_category" />';
-    echo  '<input type="submit" value="'.get_string('deletecategory','grades').'" /></form>';
-}
-
-function grade_insert_category() {
-    global $CFG;
-    global $course;
-    global $USER;
-    
-    $category->name=optional_param('name');
-    $category->courseid=$course->id;
-    
-    if (!empty($USER->id)) {
-        if (!confirm_sesskey()) {
-            error(get_string('confirmsesskeybad', 'error'));
-        }
-    }
-    
-    // make sure the record isn't already there and insert if okay
-    if (record_exists('grade_category', 'name', $category->name, 'courseid', $category->courseid)) {
-            // category already exists
-    }
-    elseif ($category->name != ''){
-        if (!insert_record('grade_category', $category) ) {
-            echo  '<font color="red">'.get_string('addcategoryerror','grades').'</font>';
+        if (!empty($this->userid)) {
+            $mform->addElement('hidden', 'gpr_userid', $this->userid);
+            $mform->setType('gpr_userid', PARAM_INT);
         }
-    }
-}
-
-function grade_category_select($id_selected = 0) {
-    /// prints out a select box containing categories.
-    global $CFG;
-    global $course;
 
-    
-    echo  '<option value="blank">'.get_string('choosecategory','grades').'</option>';
-    
-    $categories = get_records('grade_category', 'courseid', $course->id, 'name');
-    
-    if (!isset($categories)) {
-        error(get_string("nocategories"));
-    }
-    else {
-        foreach($categories as $category) {
-            if ($category->name == UNCATEGORISED) {
-                $category->name = get_string('uncategorised', 'grades');
-            }
-            if ($category->id == $id_selected) {
-                echo  '<option value="'.$category->id.'" selected="selected">'. format_string($category->name) .'</option>';
-            }
-            else {
-                echo  '<option value="'.$category->id.'">'. format_string($category->name) .'</option>';
-            }
+        if (!empty($this->page)) {
+            $mform->addElement('hidden', 'gpr_page', $this->page);
+            $mform->setType('gpr_page', PARAM_INT);
         }
     }
-}
-
-function grade_display_grade_preferences($course, $preferences) {
-    global $CFG;
-    global $USER;
-
-    if ($preferences->use_advanced == 0) {
-        $useadvanced = 1;
-        $buttonlabel = get_string('useadvanced', 'grades');
-    } else {
-        $useadvanced = 0;
-        $buttonlabel = get_String('hideadvanced', 'grades');
-    }
-
-    $buttonoptions = array('action'  => 'set_grade_preferences',
-                           'id'      => $course->id,
-                           'sesskey' => sesskey(),
-                           'use_advanced' => $useadvanced);
-                           
-
-    print_heading_with_help(get_string('setpreferences','grades'), 'preferences', 'grade');
-    
-    echo '<center>';
-    print_single_button('index.php', $buttonoptions, $buttonlabel, 'post');
-    echo '<br /></center>';
-
-    echo  '<form id="set_grade_preferences" method="post" action="./index.php">';
-    echo  '<input type="hidden" name="action" value="set_grade_preferences" />';
-    echo  '<input type="hidden" name="id" value="'.$course->id.'" />';
-    echo  '<input type="hidden" name="sesskey" value="'.sesskey().'" />';
-    echo  '<table border="0" cellspacing="2" cellpadding="5" align="center" class="gradeprefs generalbox">';
-    
-    $optionsyesno = NULL;
-    $optionsyesno[0] = get_string('no');
-    $optionsyesno[1] = get_string('yes');
-
-    
-    if ($preferences->use_advanced) {
-        $options = NULL;
-        $options[0] = get_string('no');
-        $options[1] = get_string('toonly', 'moodle', $course->teachers);
-        $options[2] = get_string('toeveryone', 'moodle');
-
-        // display grade weights
-        echo  '<tr><td class="c0">'.get_string('displayweighted','grades').':</td>';
-        echo  '<td class="c1">';
-        choose_from_menu($options, 'display_weighted', $preferences->display_weighted, '');
-        echo  '</td></tr>';
-        
-        // display points    
-        echo  '<tr><td class="c0">'.get_string('displaypoints','grades').':</td>';
-        echo  '<td class="c1">';
-        choose_from_menu($options, 'display_points', $preferences->display_points, '');
-        echo  '</td></tr>';
-
-        // display percent
-        echo  '<tr><td class="c0">'.get_string('displaypercent','grades').':</td>';
-        echo  '<td class="c1">';
-        choose_from_menu($options, 'display_percent', $preferences->display_percent, '');
-        echo  '</td></tr>';
-        
-        // display letter grade
-        echo  '<tr><td class="c0">'.get_string('displaylettergrade','grades').':</td>';
-        echo  '<td class="c1">';
-        choose_from_menu($options, 'display_letters', $preferences->display_letters, '');
-        echo  '</td></tr>';
-
-        // letter grade uses weighted percent
-        $options = NULL;
-        $options[0] = get_string('usepercent','grades');
-        $options[1] = get_string('useweighted','grades');
-
-        echo  '<tr><td class="c0">'.get_string('lettergrade','grades').':</td>';
-        echo  '<td class="c1">';
-        choose_from_menu($options, 'use_weighted_for_letter', $preferences->use_weighted_for_letter, '');
-        echo  '</td></tr>';
-    }
 
-    $headerlist[0] = get_string('none');
-    for ($i=1; $i<=100; $i++) {
-        $headerlist[$i] = $i;
-    }
-    
-    // reprint headers every n lines default n=0
-    echo '<tr><td class="c0">'.get_string('reprintheaders','grades').':</td>';
-    echo '<td class="c1">';
-    choose_from_menu($headerlist, 'reprint_headers', $preferences->reprint_headers, '');
-    echo '</td></tr>';
-    
-    // show hidden grade items to teacher
-    echo  '<tr><td class="c0">'.get_string('showhiddenitems','grades').'</td>';
-    echo  '<td class="c1">';
-    choose_from_menu($optionsyesno, 'show_hidden', $preferences->show_hidden, '');
-    echo  '</td></tr>';
-    
-    echo  '<tr><td colspan="3" align="center"><input type="submit" value="'.get_string('savepreferences','grades').'" /></td></tr></table></form>';
-}
-
-
-
-function grade_display_letter_grades() {
-    global $CFG;
-    global $course;
-    global $USER;
-    
-    $db_letters = get_records('grade_letter', 'courseid', $course->id, 'grade_high DESC');
-    
-    if ($db_letters) {
-        $using_defaults = false;
-        foreach ($db_letters as $letter) {
-            $letters[$letter->id]->letter = $letter->letter;
-            $letters[$letter->id]->grade_low = $letter->grade_low;
-            $letters[$letter->id]->grade_high = $letter->grade_high;
-            $letters[$letter->id]->courseid = $course->id;
+    function add_url_params($url) {
+        if (empty($this->type) or empty($this->plugin)) {
+            return $url;
         }
-    }
-    else {
-        $using_defaults = true;
-        // default A
-        $letters[0]->letter='A';
-        $letters[0]->grade_low=93.00;
-        $letters[0]->grade_high=100.00;
-        $letters[0]->courseid = $course->id;
-        // default A-
-        $letters[1]->letter='A-';
-        $letters[1]->grade_low=90.00;
-        $letters[1]->grade_high=92.99;
-        $letters[1]->courseid = $course->id;
-        // default B+
-        $letters[2]->letter='B+';
-        $letters[2]->grade_low=87.00;
-        $letters[2]->grade_high=89.99;
-        $letters[2]->courseid = $course->id;
-        // default B
-        $letters[3]->letter='B';
-        $letters[3]->grade_low=83.00;
-        $letters[3]->grade_high=86.99;
-        $letters[3]->courseid = $course->id;
-        // default B-
-        $letters[4]->letter='B-';
-        $letters[4]->grade_low=80.00;
-        $letters[4]->grade_high=82.99;
-        $letters[4]->courseid = $course->id;
-        // default C+
-        $letters[5]->letter='C+';
-        $letters[5]->grade_low=77.00;
-        $letters[5]->grade_high=79.99;
-        $letters[5]->courseid = $course->id;
-        // default C
-        $letters[6]->letter='C';
-        $letters[6]->grade_low=73.00;
-        $letters[6]->grade_high=76.99;
-        $letters[6]->courseid = $course->id;
-        // default C-
-        $letters[7]->letter='C-';
-        $letters[7]->grade_low=70.00;
-        $letters[7]->grade_high=72.99;
-        $letters[7]->courseid = $course->id;
-        // default D+
-        $letters[8]->letter='D+';
-        $letters[8]->grade_low=67.00;
-        $letters[8]->grade_high=69.99;
-        $letters[8]->courseid = $course->id;
-        // default D
-        $letters[9]->letter='D';
-        $letters[9]->grade_low=60.00;
-        $letters[9]->grade_high=66.99;
-        $letters[9]->courseid = $course->id;
-        // default F
-        $letters[10]->letter='F';
-        $letters[10]->grade_low=0.00;
-        $letters[10]->grade_high=59.99;
-        $letters[10]->courseid = $course->id;
-    }
 
-    echo '<form id="grade_letter"><input type="hidden" name="id" value="'.$course->id.'" />';
-    echo '<table border="0" cellspacing="2" cellpadding="5" align="center" class="generalbox"><tr>';
-    echo '<th colspan="3" class="header" scope="col">'.get_string('setgradeletters','grades');
-    helpbutton('letter', get_string('gradeletterhelp','grades'), 'grade');
-    echo '</th></tr>';
-    echo '<tr><td align="center" class="generaltableheader">'.get_string('gradeletter','grades').'</td>';
-    echo '<td align="center" class="generaltableheader">'.get_string('lowgradeletter','grades').'</td>';
-    echo '<td align="center" class="generaltableheader">'.get_string('highgradeletter','grades').'</td></tr>';
-    echo '<input type="hidden" name="action" value="set_letter_grades" />';
-    echo '<input type="hidden" name="sesskey" value="'.$USER->sesskey.'" />';
-    $i=0;
-    foreach ($letters as $id=>$items) {
-        if ($id !='' && !$using_defaults) {
-            // send the record id so if the user deletes the values we can delete the row.
-            echo '<input type="hidden" name="id'.$i.'" value="'.$id.'" />';
+        if (strpos($url, '?') === false) {
+            $url .= '?gpr_type='.$this->type;
+        } else {
+            $url .= '&amp;gpr_type='.$this->type;
         }
-        echo '<tr><td align="center" class="generalboxcontent"><input size="8" type="text" name="letter'.$i.'" value="'.$items->letter.'" /></td>'."\n";
-        echo '<td align="center" class="generalboxcontent"><input size="8" type="text" name="grade_low'.$i.'" value="'.$items->grade_low.'" /></td>'."\n";
-        echo '<td align="center" class="generalboxcontent"><input size="8" type="text" name="grade_high'.$i.'" value="'.$items->grade_high.'" /></td></tr>'."\n";
-        $i++;
-    }
-    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>';
-    echo '<tr><td colspan="3" align="center" class="generalboxcontent"><input type="submit" value="'.get_string('savechanges','grades').'" /></td></tr>';
-    echo '<input type="hidden" name="totalitems" value="'.$i.'" />';
-    echo '<tr><td colspan="3" align="center" class="generalboxcontent">'.get_string('gradeletternote','grades').'</td></tr></table>';
-    echo '</form>';
-}
 
-function grade_set_letter_grades() {
-    global $CFG;
-    global $course;
-    global $USER;
-    
-    if (!empty($USER->id)) {
-        if (!confirm_sesskey()) {
-            error(get_string('confirmsesskeybad', 'error'));
-        }
-    }
-    
-    $totalitems= clean_param($_REQUEST['totalitems'], PARAM_CLEAN);
-    
-    for($i=0; $i<=$totalitems; $i++) {
-        if (isset($_REQUEST["id$i"])) {
-            // item submitted was already in database
-            $letterid = $_REQUEST["id$i"];
-            $updateletters[$letterid]->letter = clean_param($_REQUEST["letter$i"], PARAM_CLEAN);
-            // grade_low && grade_high don't need cleaning as they are possibly floats (no appropriate clean method) so we check is_numeric
-            $updateletters[$letterid]->grade_low = $_REQUEST["grade_low$i"];
-            $updateletters[$letterid]->grade_high = $_REQUEST["grade_high$i"];
-            $updateletters[$letterid]->id = $letterid;
-        }
-        else {
-            // its a new item
-            $newletter->letter = clean_param($_REQUEST["letter$i"], PARAM_CLEAN);
-            $newletter->grade_low = $_REQUEST["grade_low$i"];
-            $newletter->grade_high = $_REQUEST["grade_high$i"];
-            $newletter->courseid = $course->id;
-            if (is_numeric($newletter->grade_high) && is_numeric($newletter->grade_low)) {
-                insert_record('grade_letter', $newletter);
-            }
-            else {
-                if ($i < $totalitems) {
-                    if ($newletter->grade_high != '' or $newletter->grade_low != '') {
-                        echo '<center>'.get_string('lettergradenonnumber','grades').' '.$newletter->letter.' item number: '.$i.'<br /></center>';
-                    }
-                }
-            }
-        }
-    }
+        $url .= '&amp;gpr_plugin='.$this->plugin;
 
-    if (isset($updateletters)) {
-        foreach($updateletters as $id=>$items) {
-            // see if any of the values are blank... if so delete them
-            if ($items->letter == '' || $items->grade_low == '' || $items->grade_high == '') {
-                delete_records('grade_letter', 'id', $id);
-            }
-            else {
-                if (is_numeric($items->grade_high) && is_numeric($items->grade_low)) {
-                    update_record('grade_letter', $items);
-                }
-                else {
-                    echo '<center><font color="red">'.get_string('errorgradevaluenonnumeric','grades').$letter.'</font></center>';
-                }
-            }
+        if (!empty($this->courseid)) {
+            $url .= '&amp;gpr_courseid='.$this->courseid;
         }
-    }
-}
 
-function grade_download_form($type='both') {
-    global $course,$USER, $action, $cview;
-    if ($type != 'both' and $type != 'ods' and $type != 'excel' and $type != 'text') {
-        $type = 'both';
-    }
-    
-    if (has_capability('moodle/course:viewcoursegrades', get_context_instance(CONTEXT_COURSE, $course->id))) {
-        echo '<table align="center"><tr>';
-        $options['id'] = $course->id;
-        $options['sesskey'] = $USER->sesskey;
-        
-        if ($type == 'both' || $type == 'ods') {
-            $options['action'] = 'ods';
-            echo '<td align="center">';
-            print_single_button("index.php", $options, get_string("downloadods"));
-            echo '</td>';
-        }
-        if ($type == 'both' || $type == 'excel') {
-            $options['action'] = 'excel';
-            echo '<td align="center">';
-            print_single_button("index.php", $options, get_string("downloadexcel"));
-            echo '</td>';
+        if (!empty($this->userid)) {
+            $url .= '&amp;gpr_userid='.$this->userid;
         }
-        if ($type == 'both' || $type == 'text') {
-            $options['action'] = 'text';
-            echo '<td align="center">';
-            print_single_button("index.php", $options, get_string("downloadtext"));
-            echo '</td>';
-        }
-        echo '<td>';
-        
-        $url = 'index.php?id='.$course->id;
-        if (!empty($action)) {
-            $url .= '&amp;action='.$action;
-            if ($action == 'vcats') {
-               $url .= '&amp;cview='.$cview;
-            }
-        }
-        echo '</td>';
-
-        echo '</tr></table>';
-    }
-}
-
-
-
 
-
-/** 
- * Simply prints all grade of one student from all modules from a given course
- * used in the grade book for student view, and grade button under user profile
- * @param int $userid;
- * @param int $courseid;
- */
-function print_student_grade($user, $course) {
-    
-    global $CFG;
-  
-    if (!empty($user)) {
-        $grades[$user->id] = array();    // Collect all grades in this array
-        $gradeshtml[$user->id] = array(); // Collect all grades html formatted in this array
-        $totals[$user->id] = array();    // Collect all totals in this array
-    }
-  
-    $strmax = get_string("maximumshort");
-  /// Collect modules data
-    get_all_mods($course->id, $mods, $modnames, $modnamesplural, $modnamesused);
-
-/// Search through all the modules, pulling out grade data
-    $sections = get_all_sections($course->id); // Sort everything the same as the course
-    
-    // prints table
-
-    // flag for detecting whether to print table header or not
-    $nograde = 0;
-    
-    for ($i=0; $i<=$course->numsections; $i++) {
-        if (isset($sections[$i])) {   // should always be true
-            $section = $sections[$i];
-            if ($section->sequence) {
-                $sectionmods = explode(",", $section->sequence);
-                foreach ($sectionmods as $sectionmod) {
-                 
-                    $mod = $mods[$sectionmod];
-                    if (empty($mod->modname)) {
-                        continue;  // Just in case, see MDL-7150
-                    }
-                    $instance = get_record($mod->modname, 'id', $mod->instance);
-                    $libfile = "$CFG->dirroot/mod/$mod->modname/lib.php";    
-                    
-                    if (file_exists($libfile)) {
-                        require_once($libfile);
-                        $gradefunction = $mod->modname.'_grades';
-                        if (function_exists($gradefunction)) {   // Skip modules without grade function
-                            if ($modgrades = $gradefunction($mod->instance)) {
-                                if (!empty($modgrades->maxgrade)) {
-                                    if ($mod->visible) {
-                                        $maxgrade = $modgrades->maxgrade;
-                                    } else {
-                                        $maxgrade = $modgrades->maxgrade;
-                                    }
-                                } else {
-                                    $maxgrade = '';
-                                }
-                                
-                                if ($maxgrade) { 
-                                    if (!$nograde) {
-                                         echo ('<table align="center" class="grades"><tr><th scope="col">'.get_string('activity').'</th><th scope="col">'.get_string('yourgrade','grades').'</th><th scope="col">'.get_string('maxgrade','grades').'</th></tr>');
-                                    }
-                                    $nograde++;                               
-                                  
-                                    $link_id = grade_get_module_link($course->id, $mod->instance, $mod->module);
-                                    $link = $CFG->wwwroot.'/mod/'.$mod->modname.'/view.php?id='.$link_id->id;
-
-                                    echo '<tr>';
-                                    if (!empty($modgrades->grades[$user->id])) {
-                                        $currentgrade = $modgrades->grades[$user->id];
-                                        echo "<td><a href='$link'>$mod->modfullname: ".format_string($instance->name,true)."</a></td><td>$currentgrade</td><td>$maxgrade</td>";            
-                                    } else {
-                                        echo "<td><a href='$link'>$mod->modfullname: ".format_string($instance->name,true)."</a></td><td>".get_string('nograde')."</td><td>$maxgrade</td>";                                        
-                                    }
-                                    echo '</tr>';                       
-                                }
-                            }
-                        }
-                    }
-                }
-            }
+        if (!empty($this->page)) {
+            $url .= '&amp;gpr_page='.$this->page;
         }
-    } // a new Moodle nesting record? ;-)
-    
-    if ($nograde) {
-        echo '</table>';
-    }
-}
 
-function grade_get_course_students($courseid) {
-    global $CFG;
-    // The list of roles to display is stored in CFG->gradebookroles
-    if (!$context = get_context_instance(CONTEXT_COURSE, $courseid)) {
-        return false;  
-    } 
-        
-    $configvar = get_config('', 'gradebookroles');
-    if (empty($configvar)) {
-        notify ('no roles defined in admin->appearance->graderoles');
-        return false; // no roles to displayreturn false;  
-    }
-         
-    if ($rolestoget = explode(',', $configvar)) {
-        foreach ($rolestoget as $crole) {
-            if ($tempstudents = get_role_users($crole, $context, true)) {
-                foreach ($tempstudents as $tempuserid=>$tempstudent) {
-                    $students[$tempuserid] = $tempstudent;  
-                }            
-            }
-        }
-    } else {
-        notify ('no roles defined in admin->appearance->graderoles');
-        return false; // no roles to displayreturn false;  
+        return $url;
     }
-    return isset($students)?$students:'';
 }
-?>
+?>
\ No newline at end of file
index bacc06f07dd34d7387c3072f59d7311c4dd323d8..690a2964eb52b59411ddf9a9ba701bb5de89b4f9 100644 (file)
 ///////////////////////////////////////////////////////////////////////////
 
 
-    require_once("../config.php");
-    require_once("../lib/gradelib.php");
+    require_once '../config.php';
+    require_once $CFG->libdir.'/gradelib.php';
+    require_once $CFG->dirroot.'/grade/lib.php';
 
     $courseid = required_param('id');                   // course id
-    $report   = optional_param('report', get_user_preferences('grade_defaultreport', 'user'), PARAM_FILE); 
+    $report   = optional_param('report', get_user_preferences('grade_defaultreport', 'user'), PARAM_SAFEDIR);
+    $userid   = optional_param('userid', 0, PARAM_INT); // user detail
+    $page     = optional_param('page', 0, PARAM_INT);   // active page
     $edit     = optional_param('edit', -1, PARAM_BOOL); // sticky editting mode
 
 /// Make sure they can even access this course
         set_user_preference('grade_defaultreport', $report);
     }
 
-
-/// Create menu of reports
-
-    $reportnames = array();
-
-    if (count($reports) > 1) {
-        foreach ($reports as $plugin) {
-            $reportnames[$plugin] = get_string('modulename', 'gradereport_'.$plugin);
-        }
-    }
-
-    asort($reportnames);    // Alphabetical sort
-
+/// return tracking object
+    $gpr = new grade_plugin_return(array('type'=>'report', 'plugin'=>$report, 'courseid'=>$courseid,
+                                         'userid'=>$userid, 'page'=>$page));
 
 /// Build navigation
 
     $strgrades = get_string('grades');
+    $reportname = get_string('modulename', 'gradereport_'.$report);
     $navlinks = array();
     $navlinks[] = array('name' => $strgrades, 'link' => $CFG->wwwroot . '/grade/index.php?id='.$courseid, 'type' => 'misc');
-    $navlinks[] = array('name' => $reportnames[$report], 'link' => '', 'type' => 'misc');
+    $navlinks[] = array('name' => $reportname, 'link' => '', 'type' => 'misc');
 
     $navigation = build_navigation($navlinks);
 
     }
 
     // params for the turn editting on
-    $options = array();
-    $options['id'] = $courseid;
-    $options['report'] = $report;
+    $options = $gpr->get_options();
 
     if ($USER->gradeediting) {
         $options['edit'] = 0;
 
 /// Print header
 
-    print_header_simple($strgrades.':'.$reportnames[$report], ':'.$strgrades, $navigation,
+    print_header_simple($strgrades.':'.$reportname, ':'.$strgrades, $navigation,
                         '', '', true, $buttons, navmenu($course));
 
-/// Print the report selector at the top if there is more than one report
-
-    if ($reportnames) {
-        popup_form($CFG->wwwroot.'/grade/report.php?id='.$course->id.'&amp;report=', $reportnames,
-                   'choosegradereport', $report, '', '', '', false, 'self', get_string('gradereports', 'grades').':');
-    }
+/// Print the plugin selector at the top
+    print_grade_plugin_selector($courseid, 'report', $report);
 
 
 /// Now simply include the report here and we're done
index dd4f3a28bfc7cb1eb4e14b3c15394f323869a35a..3de8b30daeb882e5e43c9136ec57d2af093335c9 100644 (file)
@@ -7,7 +7,6 @@ require_once($CFG->dirroot.'/grade/report/grader/lib.php');
 $gradeserror = array();
 
 // get the params ($report, $courseid and $context are already set in grade/report.php)
-$page          = optional_param('page', 0, PARAM_INT);
 $sortitemid    = optional_param('sortitemid', 0, PARAM_ALPHANUM); // sort by which grade item
 $action        = optional_param('action', 0, PARAM_ALPHA);
 $move          = optional_param('move', 0, PARAM_INT);
@@ -65,11 +64,11 @@ echo $report->get_toggles_html();
 print_paging_bar($numusers, $report->page, $report->get_pref('studentsperpage'), $report->pbarurl);
 
 $reporthtml = '<table class="gradestable">';
-$reporthtml .= $report->get_headerhtml();
-$reporthtml .= $report->get_scalehtml();
-$reporthtml .= $report->get_studentshtml();
-$reporthtml .= $report->get_groupavghtml();
-$reporthtml .= $report->get_gradeavghtml($numusers);
+$reporthtml .= $report->get_headerhtml($gpr);
+$reporthtml .= $report->get_scalehtml($gpr);
+$reporthtml .= $report->get_studentshtml($gpr);
+$reporthtml .= $report->get_groupavghtml($gpr);
+$reporthtml .= $report->get_gradeavghtml($gpr, $numusers); //TODO: numusers not in function definition??
 $reporthtml .= "</table>";
 // print submit button
 if ($USER->gradeediting) {
index 5f56c1fb90cf5a8297e25b886614c1f89a4799b7..b486a25d5a8e83c18c63a43206fd31001a6e9014 100644 (file)
@@ -441,7 +441,7 @@ class grade_report_grader extends grade_report {
      * Builds and returns the HTML code for the headers.
      * @return string $headerhtml
      */
-    function get_headerhtml() {
+    function get_headerhtml($gpr) {
         global $CFG, $USER;
 
         $strsortasc  = $this->get_lang_string('sortasc', 'grades');
@@ -510,7 +510,7 @@ class grade_report_grader extends grade_report {
 
                     // Print icons
                     if ($USER->gradeediting) {
-                        $headerhtml .= $this->get_icons($element);
+                        $headerhtml .= $this->get_icons($element, $gpr);
                     }
 
                     $headerhtml .= '</th>';
@@ -544,7 +544,7 @@ class grade_report_grader extends grade_report {
                               . $element['object']->id .'">'. $element['object']->get_name()
                               . '</a>' . $arrow;
 
-                    $headerhtml .= $this->get_icons($element) . '</th>';
+                    $headerhtml .= $this->get_icons($element, $gpr) . '</th>';
 
                     $this->items[$element['object']->sortorder] =& $element['object'];
                 }
@@ -560,7 +560,7 @@ class grade_report_grader extends grade_report {
      * Builds and return the HTML rows of the table (grades headed by student).
      * @return string HTML
      */
-    function get_studentshtml() {
+    function get_studentshtml($gpr) {
         global $CFG, $USER;
         $studentshtml = '';
         $strfeedback = $this->get_lang_string("feedback");
@@ -616,7 +616,7 @@ class grade_report_grader extends grade_report {
                     $states = array('is_hidden' => $item->hidden,
                                     'is_locked' => $item->locked,
                                     'is_editable' => $item->gradetype != GRADE_TYPE_NONE && !$grade->locked && !$item->locked);
-                    $studentshtml .= $this->get_icons($element, null, true, $states);
+                    $studentshtml .= $this->get_icons($element, $gpr, null, true, $states);
                 }
 
                 // if in editting mode, we need to print either a text box
@@ -724,7 +724,7 @@ class grade_report_grader extends grade_report {
      * Builds and return the HTML rows of the table (grades headed by student).
      * @return string HTML
      */
-    function get_groupavghtml() {
+    function get_groupavghtml($gpr) {
         global $CFG;
 
         $groupavghtml = '';
@@ -759,7 +759,7 @@ class grade_report_grader extends grade_report {
                     $groupavghtml .= '<td>-</td>';
                 } else {
                     $sum = $groupsum[$item->id];
-                    
+
                     if ($item->scaleid) {
                         $gradeitemsum = $groupsum[$item->id];
                         $gradeitemavg = $gradeitemsum/$groupscount[$item->id];
@@ -769,12 +769,12 @@ class grade_report_grader extends grade_report {
                         $scales_array = get_records_list('scale', 'id', $item->scaleid);
                         $scale = $scales_array[$item->scaleid];
                         $scales = explode(",", $scale->scale);
-                        
+
                         // this could be a 0 when summed and rounded, e.g, 1, no grade, no grade, no grade
                         if ($scaleval < 1) {
-                            $scaleval = 1;  
+                            $scaleval = 1;
                         }
-                        
+
                         $gradehtml = $scales[$scaleval-1];
                     } else {
                         $gradeval = $this->get_grade_clean($sum/$groupscount[$item->id]);
@@ -792,7 +792,7 @@ class grade_report_grader extends grade_report {
      * Builds and return the HTML row of column totals.
      * @return string HTML
      */
-    function get_gradeavghtml() {
+    function get_gradeavghtml($gpr) {
         global $CFG;
 
         $gradeavghtml = '';
@@ -830,17 +830,17 @@ class grade_report_grader extends grade_report {
                         $scales_array = get_records_list('scale', 'id', $item->scaleid);
                         $scale = $scales_array[$item->scaleid];
                         $scales = explode(",", $scale->scale);
-                        
+
                         // this could be a 0 when summed and rounded, e.g, 1, no grade, no grade, no grade
                         if ($scaleval < 1) {
-                            $scaleval = 1;  
+                            $scaleval = 1;
                         }
-                        
+
                         $gradehtml = $scales[$scaleval-1];
-                    } else {                    
+                    } else {
                         $gradeval = $this->get_grade_clean($sum/$classcount[$itemid]);
                         $gradehtml = $gradeval;
-                    }                    
+                    }
                     $gradeavghtml .= '<td>'.$gradehtml.'</td>';
                 }
             }
@@ -853,7 +853,7 @@ class grade_report_grader extends grade_report {
      * Builds and return the HTML row of scales for each column (i.e. range).
      * @return string HTML
      */
-    function get_scalehtml() {
+    function get_scalehtml($gpr) {
         $scalehtml = '';
         if ($this->get_pref('showranges')) {
             $scalehtml = '<tr><th class="range">'.$this->get_lang_string('range','grades').'</th>';
@@ -876,7 +876,7 @@ class grade_report_grader extends grade_report {
      * @param object $states An optional array of states (hidden, locked, editable), shortcuts to increase performance.
      * @return string HTML
      */
-    function get_icons($element, $icons=null, $limit=true, $states=array()) {
+    function get_icons($element, $gpr, $icons=null, $limit=true, $states=array()) {
         global $CFG;
         global $USER;
 
@@ -931,18 +931,21 @@ class grade_report_grader extends grade_report {
         $edit_icon = '';
         if ($states['is_editable']) {
             if ($type == 'category') {
-                $edit_icon = '<a href="'. GRADE_EDIT_URL . '/category.php?courseid='.$object->courseid.'&amp;id='.$object->id.'">'
-                           . '<img src="'.$CFG->pixpath.'/t/edit.gif" class="iconsmall" alt="'
+                $url = GRADE_EDIT_URL . '/category.php?courseid='.$object->courseid.'&amp;id='.$object->id;
+                $url = $gpr->add_url_params($url);
+                $edit_icon = '<a href="'.$url.'"><img src="'.$CFG->pixpath.'/t/edit.gif" class="iconsmall" alt="'
                            . $stredit.'" title="'.$stredit.'" /></a>'. "\n";
             } else if ($type == 'item' or $type == 'categoryitem' or $type == 'courseitem'){
-                $edit_icon = '<a href="'. GRADE_EDIT_URL . '/item.php?courseid='.$object->courseid.'&amp;id='.$object->id.'">'
-                           . '<img src="'.$CFG->pixpath.'/t/edit.gif" class="iconsmall" alt="'
+                $url = GRADE_EDIT_URL . '/item.php?courseid='.$object->courseid.'&amp;id='.$object->id;
+                $url = $gpr->add_url_params($url);
+                $edit_icon = '<a href="'.$url.'"><img src="'.$CFG->pixpath.'/t/edit.gif" class="iconsmall" alt="'
                            . $stredit.'" title="'.$stredit.'" /></a>'. "\n";
             } else if ($type == 'grade' and ($states['is_editable'] or empty($object->id))) {
             // TODO: change link to use itemid and userid to allow creating of new grade objects
-                $edit_icon = '<a href="'. GRADE_EDIT_URL . '/grade.php?courseid='.$object->courseid.'&amp;id='.$object->id.'">'
-                                 . '<img ' . $overlib . ' src="'.$CFG->pixpath.'/t/edit.gif"'
-                                 . 'class="iconsmall" alt="' . $stredit.'" title="'.$stredit.'" /></a>'. "\n";
+                $url = GRADE_EDIT_URL . '/grade.php?courseid='.$object->courseid.'&amp;id='.$object->id;
+                $url = $gpr->add_url_params($url);
+                $edit_icon = '<a href="'.$url.'"><img ' . $overlib . ' src="'.$CFG->pixpath.'/t/edit.gif"'
+                           . 'class="iconsmall" alt="' . $stredit.'" title="'.$stredit.'" /></a>'. "\n";
             }
         }
 
@@ -950,8 +953,9 @@ class grade_report_grader extends grade_report {
         if ($type == 'item' or $type == 'courseitem' or $type == 'categoryitem') {
             // show calculation icon only when calculation possible
             if (!$object->is_normal_item() and ($object->gradetype == GRADE_TYPE_SCALE or $object->gradetype == GRADE_TYPE_VALUE)) {
-                $edit_calculation_icon = '<a href="'. GRADE_EDIT_URL . '/calculation.php?courseid='.$object->courseid.'&amp;id='.$object->id.'">'
-                                       . '<img src="'.$CFG->pixpath.'/t/calc.gif" class="iconsmall" alt="'
+                $url = GRADE_EDIT_URL . '/calculation.php?courseid='.$object->courseid.'&amp;id='.$object->id;
+                $url = $gpr->add_url_params($url);
+                $edit_calculation_icon = '<a href="'. $url.'"><img src="'.$CFG->pixpath.'/t/calc.gif" class="iconsmall" alt="'
                                        . $streditcalculation.'" title="'.$streditcalculation.'" /></a>'. "\n";
             }
         }
index 5366c07a83ae005df7bf52f748048c6c5649500f..9ee698299949b74868bbd328bf8ecd07882d6878 100644 (file)
@@ -4,10 +4,6 @@
                            $CFG->wwwroot.'/grade/report.php?id='.$courseid.'&amp;report=grader',
                            get_string('graderreport', 'grades'));
 
-    $row[] = new tabobject('editcategory',
-                           $CFG->wwwroot.'/grade/edit/tree.php?id='.$courseid,
-                           get_string('categoriesedit', 'grades'));
-
     $row[] = new tabobject('preferences',
                            $CFG->wwwroot.'/grade/report/grader/preferences.php?id='.$courseid,
                            get_string('preferences'));