]> git.mjollnir.org Git - moodle.git/commitdiff
(no commit message)
authorskodak <skodak>
Fri, 19 Oct 2007 08:51:52 +0000 (08:51 +0000)
committerskodak <skodak>
Fri, 19 Oct 2007 08:51:52 +0000 (08:51 +0000)
13 files changed:
admin/settings/grades.php
grade/edit/tree/calculation.php
grade/edit/tree/category_form.php
grade/edit/tree/index.php
grade/lib.php
grade/report/grader/index.php
grade/report/grader/lib.php
grade/report/user/lib.php
lang/en_utf8/grades.php
lib/grade/grade_category.php
lib/grade/grade_grade.php
pix/i/agg_mean.gif [new file with mode: 0644]
pix/i/agg_sum.gif [moved from pix/i/category_grade.gif with 100% similarity]

index 69b013add80cda4d69f650eba25db74445f43831..0d6fbe1be80ab3639953355ace29d2b8e5b664b6 100644 (file)
@@ -10,8 +10,6 @@ $temp = new admin_settingpage('gradessettings', get_string('gradessettings', 'gr
 
 // enable outcomes checkbox
 $temp->add(new admin_setting_configcheckbox('enableoutcomes', get_string('enableoutcomes', 'grades'), get_string('configenableoutcomes', 'grades'), 0, PARAM_INT));
-// enable publishing in exports/imports
-$temp->add(new admin_setting_configcheckbox('gradepublishing', get_string('gradepublishing', 'grades'), get_string('configgradepublishing', 'grades'), 0, PARAM_INT));
 
 $temp->add(new admin_setting_configselect('grade_aggregationposition', get_string('aggregationposition', 'grades'),
                                           get_string('configaggregationposition', 'grades'), GRADE_REPORT_AGGREGATION_POSITION_LAST,
@@ -33,6 +31,11 @@ $temp->add(new admin_setting_configselect('grade_decimalpoints', get_string('dec
                                                  '4' => '4',
                                                  '5' => '5')));
 
+$temp->add(new admin_setting_configcheckbox('grade_hiddenasdate', get_string('hiddenasdate', 'grades'), get_string('confighiddenasdate', 'grades'), 0, PARAM_INT));
+
+// enable publishing in exports/imports
+$temp->add(new admin_setting_configcheckbox('gradepublishing', get_string('gradepublishing', 'grades'), get_string('configgradepublishing', 'grades'), 0, PARAM_INT));
+
 $temp->add(new admin_setting_configselect('grade_export_displaytype', get_string('gradeexportdisplaytype', 'grades'),
                                           get_string('configgradeexportdisplaytype', 'grades'), GRADE_DISPLAY_TYPE_REAL,
                                           array(GRADE_DISPLAY_TYPE_REAL => get_string('real', 'grades'),
@@ -46,20 +49,11 @@ $temp->add(new admin_setting_configselect('grade_export_decimalpoints', get_stri
                                                  '2' => '2',
                                                  '3' => '3',
                                                  '4' => '4',
-                                                 '5' => '5')));                                                 
-                                                 
+                                                 '5' => '5')));
+
 $temp->add(new admin_setting_special_gradeexport());
 $ADMIN->add('grades', $temp);
 
-/// Scales and outcomes
-
-$scales = new admin_externalpage('scales', get_string('scales'), $CFG->wwwroot.'/grade/edit/scale/index.php', 'moodle/grade:manage');
-$ADMIN->add('grades', $scales);
-$outcomes = new admin_externalpage('outcomes', get_string('outcomes', 'grades'), $CFG->wwwroot.'/grade/edit/outcome/index.php', 'moodle/grade:manage');
-$ADMIN->add('grades', $outcomes);
-$letters = new admin_externalpage('letters', get_string('letters', 'grades'), $CFG->wwwroot.'/grade/edit/letter/edit.php', 'moodle/grade:manageletters');
-$ADMIN->add('grades', $letters);
-
 /// Grade category settings
 $temp = new admin_settingpage('gradecategorysettings', get_string('gradecategorysettings', 'grades'));
 
@@ -96,6 +90,15 @@ $temp->add(new admin_setting_configselect('grade_droplow', get_string('droplow',
 
 $ADMIN->add('grades', $temp);
 
+/// Scales and outcomes
+
+$scales = new admin_externalpage('scales', get_string('scales'), $CFG->wwwroot.'/grade/edit/scale/index.php', 'moodle/grade:manage');
+$ADMIN->add('grades', $scales);
+$outcomes = new admin_externalpage('outcomes', get_string('outcomes', 'grades'), $CFG->wwwroot.'/grade/edit/outcome/index.php', 'moodle/grade:manage');
+$ADMIN->add('grades', $outcomes);
+$letters = new admin_externalpage('letters', get_string('letters', 'grades'), $CFG->wwwroot.'/grade/edit/letter/edit.php', 'moodle/grade:manageletters');
+$ADMIN->add('grades', $letters);
+
 // The plugins must implement a settings.php file that adds their admin settings to the $settings object
 
 // Reports
index 39caceadc74bb4947db2b379325895867df941ad..f7fce260d3c6b4a4b4d76d7bd6ca00e2b93e0a72 100644 (file)
@@ -187,35 +187,9 @@ function get_grade_tree(&$gtree, $element, $current_itemid=null, $errors=null) {
         }
     }
 
-    $icon = '<img src="'.$CFG->wwwroot.'/pix/spacer.gif" class="icon" alt=""/>' . "\n";
+    $icon = $gtree->get_element_icon($element);
     $last = '';
-    $catcourseitem = false;
-
-    switch ($type) {
-        case 'item':
-            if ($object->itemtype == 'mod') {
-                $icon = '<img src="'.$CFG->modpixpath.'/'.$object->itemmodule.'/icon.gif" class="icon" alt="'
-                      . get_string('modulename', $object->itemmodule).'"/>' . "\n";
-            } else if ($object->itemtype == 'manual') {
-                //TODO: add manual grading icon
-                if (empty($object->outcomeid)) {
-                    $icon = '<img src="'.$CFG->pixpath.'/t/edit.gif" class="icon" alt="'
-                          . get_string('manualgrade', 'grades').'"/>' . "\n"; // TODO: localize
-                } else {
-                    $icon = '<img src="'.$CFG->pixpath.'/i/outcomes.gif" class="icon" alt="'
-                          . get_string('outcome', 'grades').'"/>' . "\n";
-                }
-            }
-            break;
-        case 'courseitem':
-        case 'categoryitem':
-            $icon = '<img src="'.$CFG->pixpath.'/i/category_grade.gif" class="icon" alt="'.get_string('categorygrade').'"/>' . "\n"; // TODO: localize
-            $catcourseitem = true;
-            break;
-        case 'category':
-            $icon = '<img src="'.$CFG->pixpath.'/f/folder.gif" class="icon" alt="'.get_string('category').'"/>' . "\n";
-            break;
-    }
+    $catcourseitem = ($element['type'] == 'courseitem' or $element['type'] == 'categoryitem');
 
     if ($type != 'category') {
         $return_string .= '<li class="'.$type.'">'.$icon.$name.'</li>' . "\n";
index ec80f54941f1b3e79b9980f892ee4b17da2edd86..59d7ea0bcb883d4c6e10b09c29b6e0f8649f0696 100644 (file)
@@ -42,7 +42,7 @@ class edit_category_form extends moodleform {
                                          GRADE_AGGREGATE_EXTRACREDIT_MEAN=>get_string('aggregateextracreditmean', 'grades'));
 
         // visible elements
-        $mform->addElement('header', 'general', get_string('gradecategory', 'grades'));
+        $mform->addElement('header', 'gradecat', get_string('gradecategory', 'grades'));
         $mform->addElement('text', 'fullname', get_string('categoryname', 'grades'));
 
         if ($CFG->grade_aggregation == -1) {
@@ -62,12 +62,14 @@ class edit_category_form extends moodleform {
             $mform->addElement('static', 'aggregateonlygraded', get_string('aggregateonlygraded', 'grades'));
         }
 
-        if (!empty($CFG->enableoutcomes) && $CFG->grade_aggregateoutcomes == -1) {
-            $mform->addElement('advcheckbox', 'aggregateoutcomes', get_string('aggregateoutcomes', 'grades'));
-            $mform->setHelpButton('aggregateoutcomes', array(false, get_string('aggregateoutcomes', 'grades'),
-                              false, true, false, get_string('aggregateoutcomeshelp', 'grades')));
-        } else {
-            $mform->addElement('static', 'aggregateoutcomes', get_string('aggregateoutcomes', 'grades'));
+        if (!empty($CFG->enableoutcomes)) {
+            if($CFG->grade_aggregateoutcomes == -1) {
+                $mform->addElement('advcheckbox', 'aggregateoutcomes', get_string('aggregateoutcomes', 'grades'));
+                $mform->setHelpButton('aggregateoutcomes', array(false, get_string('aggregateoutcomes', 'grades'),
+                                  false, true, false, get_string('aggregateoutcomeshelp', 'grades')));
+            } else {
+                $mform->addElement('static', 'aggregateoutcomes', get_string('aggregateoutcomes', 'grades'));
+            }
         }
 
         if ($CFG->grade_aggregatesubcats == -1) {
@@ -111,7 +113,7 @@ class edit_category_form extends moodleform {
         }
 
         // user preferences
-        $mform->addElement('header', 'general', get_string('userpreferences', 'grades'));
+        $mform->addElement('header', 'userpref', get_string('myreportpreferences', 'grades'));
         $options = array(GRADE_REPORT_PREFERENCE_DEFAULT => get_string('default', 'grades'),
                          GRADE_REPORT_AGGREGATION_VIEW_FULL => get_string('fullmode', 'grades'),
                          GRADE_REPORT_AGGREGATION_VIEW_AGGREGATES_ONLY => get_string('aggregatesonly', 'grades'),
@@ -158,9 +160,11 @@ class edit_category_form extends moodleform {
             $agg_el->setValue($checkbox_values[$CFG->grade_aggregateonlygraded]);
         }
 
-        if ($CFG->grade_aggregateoutcomes != -1) {
-            $agg_el =& $mform->getElement('aggregateoutcomes');
-            $agg_el->setValue($checkbox_values[$CFG->grade_aggregateoutcomes]);
+        if (!empty($CFG->enableoutcomes)) {
+            if ($CFG->grade_aggregateoutcomes != -1) {
+                $agg_el =& $mform->getElement('aggregateoutcomes');
+                $agg_el->setValue($checkbox_values[$CFG->grade_aggregateoutcomes]);
+            }
         }
 
         if ($CFG->grade_aggregatesubcats != -1) {
index ad217aced3bdc162ecbca56eb2c6ce62bada40db..30092d426d047ffaf13d809da8d14fde8053e851 100644 (file)
@@ -201,35 +201,9 @@ function print_grade_tree(&$gtree, $element, $moving, &$gpr, $switch, $switchedl
     $actions .= $gtree->get_hiding_icon($element, $gpr);
 
 /// prepare icon
-    $icon = '<img src="'.$CFG->wwwroot.'/pix/spacer.gif" class="icon" alt=""/>';
+    $icon = $gtree->get_element_icon($element);
     $last = '';
-    $catcourseitem = false;
-    switch ($element['type']) {
-        case 'item':
-            if ($object->itemtype == 'mod') {
-                $icon = '<img src="'.$CFG->modpixpath.'/'.$object->itemmodule.'/icon.gif" class="icon" alt="'
-                      . get_string('modulename', $object->itemmodule).'"/>';
-            } else if ($object->itemtype == 'manual') {
-                //TODO: add manual grading icon
-                if (empty($object->outcomeid)) {
-                    $icon = '<img src="'.$CFG->pixpath.'/t/edit.gif" class="icon" alt="'
-                          . get_string('manualgrade', 'grades').'"/>'; // TODO: localize
-                } else {
-                    $icon = '<img src="'.$CFG->pixpath.'/i/outcomes.gif" class="icon" alt="'
-                          . get_string('outcome', 'grades').'"/>';
-
-                }
-            }
-            break;
-        case 'courseitem':
-        case 'categoryitem':
-            $icon = '<img src="'.$CFG->pixpath.'/i/category_grade.gif" class="icon" alt="'.get_string('categorygrade').'"/>'; // TODO: localize
-            $catcourseitem = true;
-            break;
-        case 'category':
-            $icon = '<img src="'.$CFG->pixpath.'/f/folder.gif" class="icon" alt="'.get_string('category').'"/>';
-            break;
-    }
+    $catcourseitem = ($element['type'] == 'courseitem' or $element['type'] == 'categoryitem');
 
 /// prepare move target if needed
     $moveto = '';
index d60ef42bd87d14b444b416c4f277e0123385720c..c217ddaf0f3297e1fb44fd56a191f57affb1e2c6 100644 (file)
@@ -839,7 +839,6 @@ class grade_seq {
             return 'g'.$grade_grade->id;
         }
     }
-
 }
 
 /**
@@ -919,6 +918,7 @@ class grade_tree {
         }
 
         grade_tree::fill_levels($this->levels, $this->top_element, 0);
+
     }
 
     /**
@@ -1344,6 +1344,61 @@ class grade_tree {
 
         return $calculation_icon;
     }
+
+    /**
+     * Returns icon of element
+     * @param object $element
+     * @param bool $spacerifnone return spacer if no icon found
+     * @return string icon or spacer
+     */
+    function get_element_icon(&$element, $spacerifnone=true) {
+        global $CFG;
+
+        switch ($element['type']) {
+            case 'item':
+            case 'courseitem':
+            case 'categoryitem':
+                if ($element['object']->is_calculated()) {
+                    return '<img src="'.$CFG->pixpath.'/i/calc.gif" class="icon" alt="'.get_string('calculation', 'grades').'"/>';
+
+                } else if (($element['object']->is_course_item() or $element['object']->is_category_item())
+                  and ($element['object']->gradetype == GRADE_TYPE_SCALE or $element['object']->gradetype == GRADE_TYPE_VALUE)) {
+                    if ($category = $element['object']->get_item_category()) {
+                        switch ($category->aggregation) {
+                            case GRADE_AGGREGATE_MEAN:
+                            case GRADE_AGGREGATE_MEDIAN:
+                            case GRADE_AGGREGATE_WEIGHTED_MEAN:
+                            case GRADE_AGGREGATE_EXTRACREDIT_MEAN:
+                                return '<img src="'.$CFG->pixpath.'/i/agg_mean.gif" class="icon" alt="'.get_string('aggregation', 'grades').'"/>';
+                            //case GRADE_AGGREGATE_SUM:
+                                //return '<img src="'.$CFG->pixpath.'/i/agg_sum.gif" class="icon" alt="'.get_string('aggregation', 'grades').'"/>';
+                        }
+                    }
+
+                } else if ($element['object']->itemtype == 'mod') {
+                    return '<img src="'.$CFG->modpixpath.'/'.$element['object']->itemmodule.'/icon.gif" class="icon" alt="'
+                           .get_string('modulename', $element['object']->itemmodule).'"/>';
+
+                } else if ($element['object']->itemtype == 'manual') {
+                    if ($element['object']->is_outcome_item()) {
+                        return '<img src="'.$CFG->pixpath.'/i/outcomes.gif" class="icon" alt="'.get_string('outcome', 'grades').'"/>';
+                    } else {
+                        //TODO: add better icon
+                        return '<img src="'.$CFG->pixpath.'/t/edit.gif" class="icon" alt="'.get_string('manualitem', 'grades').'"/>';
+                    }
+                }
+                break;
+
+            case 'category':
+                return '<img src="'.$CFG->pixpath.'/f/folder.gif" class="icon" alt="'.get_string('category', 'grades').'"/>';
+        }
+
+        if ($spacerifnone) {
+            return '<img src="'.$CFG->wwwroot.'/pix/spacer.gif" class="icon" alt=""/>';
+        } else {
+            return '';
+        }
+    }
 }
 
 ?>
index 4576e518ea7cb6c79398117dbd67168534f11843..ec0e8a30b2325377e4440ed27676941ad9c64502 100644 (file)
@@ -132,6 +132,8 @@ if ($perpageurl) {
 }
 
 $report->load_users();
+
+
 $numusers = $report->get_numusers();
 $report->load_final_grades();
 
index 20f2ab403c9eb58d5203ddcb0928e2e198827d6e..403fcece53f2f45d36b412d6430f91570452f1e4 100644 (file)
@@ -342,9 +342,10 @@ class grade_report_grader extends grade_report {
 
         $userids = array_keys($this->users);
 
+
         if ($grades = get_records_sql($sql)) {
             foreach ($grades as $graderec) {
-                if (in_array($graderec->userid, $userids)) {
+                if (in_array($graderec->userid, $userids) and array_key_exists($graderec->itemid, $this->gtree->items)) { // some items may not be present!!
                     $this->grades[$graderec->userid][$graderec->itemid] = new grade_grade($graderec, false);
                     $this->grades[$graderec->userid][$graderec->itemid]->grade_item =& $this->gtree->items[$graderec->itemid]; // db caching
                 }
@@ -603,20 +604,23 @@ class grade_report_grader extends grade_report {
      */
     function get_studentshtml() {
         global $CFG, $USER;
+
         $studentshtml = '';
-        $strfeedback = $this->get_lang_string("feedback");
-        $strgrade = $this->get_lang_string('grade');
+        $strfeedback  = $this->get_lang_string("feedback");
+        $strgrade     = $this->get_lang_string('grade');
         $gradetabindex = 1;
         $showuserimage = $this->get_pref('showuserimage');
-        $numusers = count($this->users);
+        $numusers      = count($this->users);
 
         // Preload scale objects for items with a scaleid
         $scales_list = '';
         $tabindices = array();
+
         foreach ($this->gtree->items as $item) {
             if (!empty($item->scaleid)) {
                 $scales_list .= "$item->scaleid,";
             }
+
             $tabindices[$item->id]['grade'] = $gradetabindex;
             $tabindices[$item->id]['feedback'] = $gradetabindex + $numusers;
             $gradetabindex += $numusers * 2;
@@ -633,9 +637,13 @@ class grade_report_grader extends grade_report {
         foreach ($this->users as $userid => $user) {
 
             if ($canviewhidden) {
-                $hiding_affected = array();
+                $altered = array();
+                $unknown = array();
             } else {
                 $hiding_affected = grade_grade::get_hiding_affected($this->grades[$userid], $this->gtree->items);
+                $altered = $hiding_affected['altered'];
+                $unknown = $hiding_affected['unknown'];
+                unset($hiding_affected);
             }
 
             $columncount = 0;
@@ -651,17 +659,24 @@ class grade_report_grader extends grade_report {
 
             foreach ($this->gtree->items as $itemid=>$unused) {
                 $item =& $this->gtree->items[$itemid];
+                $grade = $this->grades[$userid][$item->id];
 
                 // Get the decimal points preference for this item
                 $decimalpoints = $item->get_decimals();
 
-                $grade = $this->grades[$userid][$item->id];
-                $gradeval = $grade->finalgrade;
+                if (in_array($itemid, $unknown)) {
+                    $gradeval = null;
+                } else if (array_key_exists($itemid, $altered)) {
+                    $gradeval = $altered[$itemid];
+                } else {
+                    $gradeval = $grade->finalgrade;
+                }
 
                 // MDL-11274
                 // Hide grades in the grader report if the current grader doesn't have 'moodle/grade:viewhidden'
-                if (!$canviewhidden and ($grade->is_hidden() or in_array($itemid, $hiding_affected))) {
-                    if (!is_null($gradeval) and $grade->is_hidden()) {
+                if (!$canviewhidden and $grade->is_hidden()) {
+                    if (!empty($CFG->grade_hiddenasdate) and !is_null($grade->finalgrade) and !$item->is_category_item() and !$item->is_course_item()) {
+                        // the problem here is that we do not have the time when grade value was modified, 'timemodified' is general modification date for grade_grades records
                         $studentshtml .= '<td class="cell c'.$columncount++.'">'.userdate($grade->timecreated,get_string('strftimedatetimeshort')).'</td>';
                     } else {
                         $studentshtml .= '<td class="cell c'.$columncount++.'">-</td>';
index 4d7933a91680f9add7fd2a3519601f7e735bf20d..da4c6b1afad5b89354ed1503f794b4c2ca3dd7b9 100644 (file)
@@ -137,14 +137,26 @@ class grade_report_user extends grade_report {
         }
 
         if ($canviewhidden) {
-            $hiding_affected = array();
+            $altered = array();
+            $unknown = array();
         } else {
             $hiding_affected = grade_grade::get_hiding_affected($grades, $items);
+            $altered = $hiding_affected['altered'];
+            $unknown = $hiding_affected['unknown'];
+            unset($hiding_affected);
         }
 
-        foreach ($items as $key=>$unused) {
-            $grade_item  =& $items[$key];
-            $grade_grade =& $grades[$key];
+        foreach ($items as $itemid=>$unused) {
+            $grade_item  =& $items[$itemid];
+            $grade_grade =& $grades[$itemid];
+
+            if (in_array($itemid, $unknown)) {
+                $gradeval = null;
+            } else if (array_key_exists($itemid, $altered)) {
+                $gradeval = $altered[$itemid];
+            } else {
+                $gradeval = $grade_grade->finalgrade;
+            }
 
             $data = array();
 
@@ -169,47 +181,31 @@ class grade_report_user extends grade_report {
             if ($grade_item->needsupdate) {
                 $data[] = '<span class="gradingerror">'.get_string('error').'</span>';
 
-            } else if (is_null($grade_grade->finalgrade)) {
-                $data[] = $excluded . '-';
-
-            } else if (!$canviewhidden and ($grade_grade->is_hidden() or in_array($grade_item->id, $hiding_affected))) {
-                // TODO: optinally do not show anything for hidden grades
-                // $data[] = '-';
-                if ($grade_grade->is_hidden()) {
-                    $data[] = $excluded . '<div class="gradeddate">'.get_string('gradedon', 'grades', userdate($grade_grade->timemodified, get_string('strftimedatetimeshort'))).'</div>';
-                } else {
-                    $data[] = $excluded . '-';
-                }
+            } else if (!empty($CFG->grade_hiddenasdate) and !is_null($grade_grade->finalgrade) and !$canviewhidden and $grade_grade->is_hidden()
+                   and !$grade_item->is_category_item() and !$grade_item->is_course_item()) {
+                // the problem here is that we do not have the time when grade value was modified, 'timemodified' is general modification date for grade_grades records
+                $data[] = $excluded . '<div class="gradeddate">'.get_string('gradedon', 'grades', userdate($grade_grade->timemodified, get_string('strftimedatetimeshort'))).'</div>';
 
             } else {
-                $data[] = $excluded . grade_format_gradevalue($grade_grade->finalgrade, $grade_item, true);
+                $data[] = $excluded . grade_format_gradevalue($gradeval, $grade_item, true);
             }
 
             /// prints percentage
             if ($grade_item->needsupdate) {
                 $data[] = '<span class="gradingerror">'.get_string('error').'</span>';
 
-            } else if (is_null($grade_grade->finalgrade)) {
-                $data[] = '-';
-
-            } else if (!$canviewhidden and ($grade_grade->is_hidden() or in_array($grade_item->id, $hiding_affected))) {
-                $data[] = '-';
-
             } else {
-                $data[] = grade_format_gradevalue($grade_grade->finalgrade, $grade_item, true, GRADE_DISPLAY_TYPE_PERCENTAGE);
+                $data[] = grade_format_gradevalue($gradeval, $grade_item, true, GRADE_DISPLAY_TYPE_PERCENTAGE);
             }
 
             /// prints rank
             if ($grade_item->needsupdate) {
                 $data[] = '<span class="gradingerror">'.get_string('error').'</span>';
 
-            } else if (is_null($grade_grade->finalgrade)) {
+            } else if (is_null($gradeval)) {
                 // no grade, no rank
                 $data[] = '-';
 
-            } else if (!$canviewhidden and ($grade_grade->is_hidden() or in_array($grade_item->id, $hiding_affected))) {
-                $data[] = '-';
-
             } else {
                 /// find the number of users with a higher grade
                 $sql = "SELECT COUNT(DISTINCT(userid))
@@ -225,7 +221,7 @@ class grade_report_user extends grade_report {
             if (empty($grade_grade->feedback)) {
                 $data[] = '&nbsp;';
 
-            } else if (!$canviewhidden and ($grade_grade->is_hidden() or in_array($grade_item->id, $hiding_affected))) {
+            } else if (!$canviewhidden and $grade_grade->is_hidden()) {
                 $data[] = '&nbsp;';
 
             } else {
index 0462ad931217bd7245536448eda3645fbfbc1eeb..efa0d1f24e4d6c6f01163b2b7926c2e50f909c9e 100644 (file)
@@ -74,6 +74,7 @@ $string['configexportdecimalpoints'] = 'The number of decimal points to display
 $string['configgradeletter'] = 'A letter or other symbol used to represent a range of grades.';
 $string['configgradeletterdefault'] = 'A letter or other symbol used to represent a range of grades. Leave this field empty to use the site default (currently $a).';
 $string['configgradepublishing'] = 'Enable publishing in exports and imports: Exported grades can be accessed by accessing a URL, without having to log on to a Moodle site. Grades can be imported by accessing such a URL (which means that a moodle site can import grades published by another site). By default only administrators may use this feature, please educate users before adding required capabilities to other roles (dangers of bookmark sharing and download accelerators, IP restrictions, etc.).';
+$string['confighiddenasdate'] = 'If user can not see hidden grades show date instead of \'-\'.';
 $string['configmeanselection'] = 'Select which types of grades will be included in the column averages. Cells with no grade can be ignored, or counted as 0 (default setting).';
 $string['configquickfeedback'] = 'Quick Feedback adds a text input element in each grade cell on the grader report, allowing you to edit many grades at once. You can then click the Update button to perform all these changes at once, instead of one at a time.';
 $string['configquickgrading'] = 'Quick Grading adds a text input element in each grade cell on the grader report, allowing you to edit the feedback for many grades at once. You can then click the Update button to perform all these changes at once, instead of one at a time.';
@@ -163,7 +164,7 @@ $string['gradeboundary'] = 'Letter grade boundary';
 $string['gradecategories'] = 'Grade categories';
 $string['gradecategory'] = 'Grade Category';
 $string['gradecategoryhelp'] = 'Grade Category Help';
-$string['gradecategorysettings'] = 'Grade Category Settings';
+$string['gradecategorysettings'] = 'Grade category settings';
 $string['gradedon'] = 'Graded $a';
 $string['gradedisplay'] = 'Grade display';
 $string['gradedisplaytype'] = 'Grade display type';
@@ -205,6 +206,7 @@ $string['gradeview'] = 'View Grade';
 $string['gradeweighthelp'] = 'Grade Weight Help';
 $string['groupavg'] = 'Group average';
 $string['hidden'] = 'Hidden';
+$string['hiddenasdate'] = 'Show date for hidden grades';
 $string['hiddenuntil'] = 'Hidden until';
 $string['hiddenuntildate'] = 'Hidden until: $a';
 $string['hideadvanced'] = 'Hide Advanced Features';
@@ -256,6 +258,7 @@ $string['locktime'] = 'Lock after';
 $string['locktimedate'] = 'Locked after: $a';
 $string['lowest'] = 'Lowest';
 $string['lowgradeletter'] = 'Low';
+$string['manualitem'] = 'Manual item';
 $string['mapfrom'] = 'Map from';
 $string['mapto'] = 'Map to';
 $string['max'] = 'Highest';
index 7d0d33443ecbede7c8053af25c041aca74bc652b..8e66c5bd4a086b2336c6f1cd40d08f2e02f37b51 100644 (file)
@@ -521,7 +521,38 @@ class grade_category extends grade_object {
             return;
         }
 
-    /// start the aggregation
+        // do the maths
+        $agg_grade = $this->aggregate_values($grade_values, $items);
+
+    /// prepare update of new raw grade
+        $grade->rawgrademin = $this->grade_item->grademin;
+        $grade->rawgrademax = $this->grade_item->grademax;
+        $grade->rawscaleid  = $this->grade_item->scaleid;
+        $grade->rawgrade    = null; // categories do not use raw grades
+
+        // recalculate the rawgrade back to requested range
+        $finalgrade = grade_grade::standardise_score($agg_grade, 0, 1, $this->grade_item->grademin, $this->grade_item->grademax);
+
+        if (!is_null($finalgrade)) {
+            $grade->finalgrade = bounded_number($this->grade_item->grademin, $finalgrade, $this->grade_item->grademax);
+        } else {
+            $grade->finalgrade = $finalgrade;
+        }
+
+        // update in db if changed
+        if (   $grade->finalgrade  !== $oldgrade->finalgrade
+            or $grade->rawgrade    !== $oldgrade->rawgrade
+            or $grade->rawgrademin !== $oldgrade->rawgrademin
+            or $grade->rawgrademax !== $oldgrade->rawgrademax
+            or $grade->rawscaleid  !== $oldgrade->rawscaleid) {
+
+            $grade->update('system');
+        }
+
+        return;
+    }
+
+    function aggregate_values($grade_values, $items) {
         switch ($this->aggregation) {
             case GRADE_AGGREGATE_MEDIAN: // Middle point value in the set: ignores frequencies
                 $num = count($grade_values);
@@ -593,34 +624,8 @@ class grade_category extends grade_object {
                 break;
         }
 
-    /// prepare update of new raw grade
-        $grade->rawgrademin = $this->grade_item->grademin;
-        $grade->rawgrademax = $this->grade_item->grademax;
-        $grade->rawscaleid  = $this->grade_item->scaleid;
-        $grade->rawgrade    = null; // categories do not use raw grades
-
-        // recalculate the rawgrade back to requested range
-        $finalgrade = grade_grade::standardise_score($agg_grade, 0, 1, $this->grade_item->grademin, $this->grade_item->grademax);
-
-        if (!is_null($finalgrade)) {
-            $grade->finalgrade = bounded_number($this->grade_item->grademin, $finalgrade, $this->grade_item->grademax);
-        } else {
-            $grade->finalgrade = $finalgrade;
-        }
-
-        // update in db if changed
-        if (   $grade->finalgrade  !== $oldgrade->finalgrade
-            or $grade->rawgrade    !== $oldgrade->rawgrade
-            or $grade->rawgrademin !== $oldgrade->rawgrademin
-            or $grade->rawgrademax !== $oldgrade->rawgrademax
-            or $grade->rawscaleid  !== $oldgrade->rawscaleid) {
-
-            $grade->update('system');
-        }
-
-        return;
+        return $agg_grade;
     }
-
     /**
      * Given an array of grade values (numerical indices), applies droplow or keephigh
      * rules to limit the final array.
index 3c02bf9f633a96facf904828f7ee5ba2af0c5fec..b1d83d618c14195e876b6328a21f9ae2ac0f637f 100644 (file)
@@ -142,7 +142,7 @@ class grade_grade extends grade_object {
      * Returns array of grades for given grade_item+users.
      * @param object $grade_item
      * @param array $userids
-     * @param bool $include_missing include grades taht do not exist yet
+     * @param bool $include_missing include grades that do not exist yet
      * @return array userid=>grade_grade array
      */
     function fetch_users_grades($grade_item, $userids, $include_missing=true) {
@@ -475,45 +475,136 @@ class grade_grade extends grade_object {
     /**
      * Return array of grade item ids that are either hidden or indirectly depend
      * on hidden grades, excluded grades are not returned.
+     * THIS IS A REALLY BIG HACK! to be replaced by conditional aggregation of hidden grades in 2.0
+     *
      * @static
      * @param array $grades all course grades of one user, & used for better internal caching
      * @param array $items $grade_items array of grade items, & used for better internal caching
      * @return array
      */
     function get_hiding_affected(&$grade_grades, &$grade_items) {
+        global $CFG;
+
         if (count($grade_grades) !== count($grade_items)) {
             error("Incorrent size of arrays in params of grade_grade::get_hiding_affected()!");
         }
 
         $dependson = array();
+        $todo = array();
+        $unknown = array();  // can not find altered
+        $altered = array();  // altered grades
+
         foreach($grade_items as $key=>$unused) {
             $grade_item =& $grade_items[$key]; // reference for improved caching inside grade_item
-            $dependson[$grade_item->id] = $grade_item->depends_on();
+            $dependson[$grade_items[$key]->id] = $grade_items[$key]->depends_on();
         }
 
-        $todo = array();
-        $hiding = array();
+        $hiddenfound = false;
         foreach($grade_grades as $grade_grade) {
-            if ($grade_grade->is_hidden() and !$grade_grade->is_excluded() and !is_null($grade_grade->finalgrade)) {
-                $hiding[] = $grade_grade->itemid;
-            } else {
+            if ($grade_grade->is_excluded()) {
+                //nothing to do, aggregation is ok
+            } else if ($grade_grade->is_hidden()) {
+                $hiddenfound = true;
+                // hidden null grade does not affect the aggregation
+                if (!is_null($grade_grade->finalgrade)) {
+                    $altered[$grade_grade->itemid] = null;
+                }
+            } else if (!empty($dependson[$grade_grade->itemid])) {
                 $todo[] = $grade_grade->itemid;
             }
         }
+        if (!$hiddenfound) {
+            return array('unknown'=>array(), 'altered'=>array());
+        }
 
-        $max = count($grade_items);
+        $max = count($todo);
         for($i=0; $i<$max; $i++) {
             $found = false;
             foreach($todo as $key=>$do) {
-                if (empty($dependson[$do])) {
-                    unset($todo[$key]);
-                    continue;
-
-                } else if (array_intersect($dependson[$do], $hiding)) {
+                if (array_intersect($dependson[$do], $unknown)) {
                     // this item depends on hidden grade indirectly
-                    $hiding[] = $do;
+                    $unknown[$do] = $do;
                     unset($todo[$key]);
                     $found = true;
+                    continue;
+
+                } else if (!array_intersect($dependson[$do], $todo)) {
+                    if (!array_intersect($dependson[$do], array_keys($altered))) {
+                        // hiding does not affect this grade
+                        unset($todo[$key]);
+                        $found = true;
+                        continue;
+
+                    } else {
+                        // depends on altered grades - we should try to recalculate if possible
+                        if ($grade_items[$do]->is_calculated() or (!$grade_items[$do]->is_category_item() and !$grade_items[$do]->is_course_item())) {
+                            $unknown[$do] = $do;
+                            unset($todo[$key]);
+                            $found = true;
+                            continue;
+                        } else {
+                            $grade_category = $grade_items[$do]->load_item_category();
+                            $values = array();
+                            foreach ($dependson[$do] as $itemid) {
+                                if (array_key_exists($itemid, $altered)) {
+                                    $values[$itemid] = $altered[$itemid];
+                                } else {
+                                    $values[$itemid] = $grade_grades[$itemid]->finalgrade;
+                                }
+                            }
+                            if ($CFG->grade_aggregateonlygraded != -1) {
+                                $grade_category->aggregateonlygraded = $CFG->grade_aggregateonlygraded;
+                            }
+                            
+                            if ($grade_category->aggregateonlygraded) {
+                                foreach ($values as $itemid=>$value) {
+                                    if (is_null($value)) {
+                                        unset($values[$itemid]);
+                                    }
+                                }
+                            } else {
+                                foreach ($values as $itemid=>$value) {
+                                    if (is_null($value)) {
+                                        $values[$itemid] = $grade_items[$itemid]->grademin;
+                                    }
+                                }
+                            }
+                            foreach ($values as $itemid=>$value) {
+                                if ($grade_grades[$itemid]->is_excluded()) {
+                                    unset($values[$itemid]);
+                                    continue;
+                                }
+                                $values[$itemid] = grade_grade::standardise_score($value, $grade_items[$itemid]->grademin, $grade_items[$itemid]->grademax, 0, 1);
+                            }
+
+                            // limit and sort
+                            $grade_category->apply_limit_rules($values);
+                            asort($values, SORT_NUMERIC);
+                    
+                            // let's see we have still enough grades to do any statistics
+                            if (count($values) == 0) {
+                                // not enough attempts yet
+                                $altered[$do] = null;
+                                unset($todo[$key]);
+                                $found = true;
+                                continue;
+                            }
+
+                            $agg_grade = $grade_category->aggregate_values($values, $grade_items);
+
+                            // recalculate the rawgrade back to requested range
+                            $finalgrade = grade_grade::standardise_score($agg_grade, 0, 1, $grade_items[$itemid]->grademin, $grade_items[$itemid]->grademax);
+                    
+                            if (!is_null($finalgrade)) {
+                                $finalgrade = bounded_number($grade_items[$itemid]->grademin, $finalgrade, $grade_items[$itemid]->grademax);
+                            }
+
+                            $altered[$do] = $finalgrade;
+                            unset($todo[$key]);
+                            $found = true;
+                            continue;
+                        }
+                    }
                 }
             }
             if (!$found) {
@@ -521,7 +612,7 @@ class grade_grade extends grade_object {
             }
         }
 
-        return $hiding;
+        return array('unknown'=>$unknown, 'altered'=>$altered);
     }
 }
 ?>
diff --git a/pix/i/agg_mean.gif b/pix/i/agg_mean.gif
new file mode 100644 (file)
index 0000000..ed4c0fd
Binary files /dev/null and b/pix/i/agg_mean.gif differ
similarity index 100%
rename from pix/i/category_grade.gif
rename to pix/i/agg_sum.gif