diff --git a/grade/report/lib.php b/grade/report/lib.php index 53c4769644d..fb34df37646 100755 --- a/grade/report/lib.php +++ b/grade/report/lib.php @@ -322,5 +322,74 @@ class grade_report { $html = '' . $arrow . ''; return $html; } + + /** + * Optionally blank out course/category totals if they contain any hidden items + * @param string $courseid the course id + * @param string $course_item an instance of grade_item + * @param string $finalgrade the grade for the course_item + * @return string The new final grade + */ + protected function blank_hidden_total($courseid, $course_item, $finalgrade) { + global $CFG; + static $hiding_affected = null;//array of items in this course affected by hiding + + if( $this->showtotalsifcontainhidden==GRADE_REPORT_SHOW_REAL_TOTAL_IF_CONTAINS_HIDDEN ) { + return $finalgrade; + } + + if( !$hiding_affected ) { + $items = grade_item::fetch_all(array('courseid'=>$courseid)); + $grades = array(); + $sql = "SELECT g.* + FROM {$CFG->prefix}grade_grades g + JOIN {$CFG->prefix}grade_items gi ON gi.id = g.itemid + WHERE g.userid = {$this->user->id} AND gi.courseid = {$courseid}"; + if ($gradesrecords = get_records_sql($sql)) { + foreach ($gradesrecords as $grade) { + $grades[$grade->itemid] = new grade_grade($grade, false); + } + unset($gradesrecords); + } + foreach ($items as $itemid=>$unused) { + if (!isset($grades[$itemid])) { + $grade_grade = new grade_grade(); + $grade_grade->userid = $this->user->id; + $grade_grade->itemid = $items[$itemid]->id; + $grades[$itemid] = $grade_grade; + } + $grades[$itemid]->grade_item =& $items[$itemid]; + } + $hiding_affected = grade_grade::get_hiding_affected($grades, $items); + } + + //if the item definitely depends on a hidden item + if (array_key_exists($course_item->id, $hiding_affected['altered'])) { + if( !$this->showtotalsifcontainhidden ) { + //hide the grade + $finalgrade = null; + } + else { + //use reprocessed marks that exclude hidden items + $finalgrade = $hiding_affected['altered'][$course_item->id]; + } + } else if (!empty($hiding_affected['unknown'][$course_item->id])) { + //not sure whether or not this item depends on a hidden item + if( !$this->showtotalsifcontainhidden ) { + //hide the grade + $finalgrade = null; + } + else { + //use reprocessed marks that exclude hidden items + $finalgrade = $hiding_affected['unknown'][$course_item->id]; + } + } + + //unset($hiding_affected); + //unset($grades); + //unset($items); + + return $finalgrade; + } } ?> diff --git a/grade/report/overview/lib.php b/grade/report/overview/lib.php index 82f0294e713..29ac1891624 100644 --- a/grade/report/overview/lib.php +++ b/grade/report/overview/lib.php @@ -47,6 +47,11 @@ class grade_report_overview extends grade_report { */ var $showrank; + /** + * show course/category totals if they contain hidden items + */ + var $showtotalsifcontainhidden; + /** * Constructor. Sets local copies of user preferences and initialises grade_tree. * @param int $userid @@ -59,6 +64,8 @@ class grade_report_overview extends grade_report { $this->showrank = grade_get_setting($this->courseid, 'report_overview_showrank', !empty($CFG->grade_report_overview_showrank)); + $this->showtotalsifcontainhidden = grade_get_setting($this->courseid, 'report_overview_showtotalsifcontainhidden', !empty($CFG->grade_report_overview_showtotalsifcontainhidden)); + // get the user (for full name) $this->user = get_record('user', 'id', $userid); @@ -127,41 +134,8 @@ class grade_report_overview extends grade_report { if (!$canviewhidden and !is_null($finalgrade)) { if ($course_grade->is_hidden()) { $finalgrade = null; - } else { - // This is a really ugly hack, it will be fixed in 2.0 - $items = grade_item::fetch_all(array('courseid'=>$course->id)); - $grades = array(); - $sql = "SELECT g.* - FROM {$CFG->prefix}grade_grades g - JOIN {$CFG->prefix}grade_items gi ON gi.id = g.itemid - WHERE g.userid = {$this->user->id} AND gi.courseid = {$course->id}"; - if ($gradesrecords = get_records_sql($sql)) { - foreach ($gradesrecords as $grade) { - $grades[$grade->itemid] = new grade_grade($grade, false); - } - unset($gradesrecords); - } - foreach ($items as $itemid=>$unused) { - if (!isset($grades[$itemid])) { - $grade_grade = new grade_grade(); - $grade_grade->userid = $this->user->id; - $grade_grade->itemid = $items[$itemid]->id; - $grades[$itemid] = $grade_grade; - } - $grades[$itemid]->grade_item =& $items[$itemid]; - } - $hiding_affected = grade_grade::get_hiding_affected($grades, $items); - if (array_key_exists($course_item->id, $hiding_affected['altered'])) { - $finalgrade = $hiding_affected['altered'][$course_item->id]; - - } else if (!empty($hiding_affected['unknown'][$course_item->id])) { - $finalgrade = null; - } - - unset($hiding_affected); - unset($grades); - unset($items); + $finalgrade = $this->blank_hidden_total($course->id, $course_item, $finalgrade); } } @@ -224,6 +198,7 @@ class grade_report_overview extends grade_report { function grade_report_overview_settings_definition(&$mform) { global $CFG; + //show rank $options = array(-1 => get_string('default', 'grades'), 0 => get_string('hide'), 1 => get_string('show')); @@ -236,6 +211,21 @@ function grade_report_overview_settings_definition(&$mform) { $mform->addElement('select', 'report_overview_showrank', get_string('showrank', 'grades'), $options); $mform->setHelpButton('report_overview_showrank', array('showrank', get_string('showrank', 'grades'), 'grade')); + + //showtotalsifcontainhidden + $options = array(-1 => get_string('default', 'grades'), + GRADE_REPORT_HIDE_TOTAL_IF_CONTAINS_HIDDEN => get_string('hide'), + GRADE_REPORT_SHOW_TOTAL_IF_CONTAINS_HIDDEN => get_string('hidetotalshowexhiddenitems', 'grades'), + GRADE_REPORT_SHOW_REAL_TOTAL_IF_CONTAINS_HIDDEN => get_string('hidetotalshowinchiddenitems', 'grades') ); + + if (empty($CFG->grade_report_overview_showtotalsifcontainhidden)) { + $options[-1] = get_string('defaultprev', 'grades', $options[0]); + } else { + $options[-1] = get_string('defaultprev', 'grades', $options[1]); + } + + $mform->addElement('select', 'report_overview_showtotalsifcontainhidden', get_string('hidetotalifhiddenitems', 'grades'), $options); + $mform->setHelpButton('report_overview_showtotalsifcontainhidden', array('hidetotalifhiddenitems', get_string('hidetotalifhiddenitems', 'grades'), 'grade')); } ?> diff --git a/grade/report/overview/settings.php b/grade/report/overview/settings.php index 3c1fff96d55..2950cbe199e 100644 --- a/grade/report/overview/settings.php +++ b/grade/report/overview/settings.php @@ -19,4 +19,10 @@ $settings->add(new admin_setting_configcheckbox('grade_report_overview_showrank', get_string('showrank', 'grades'), get_string('configshowrank', 'grades'), 0, PARAM_INT)); +$settings->add(new admin_setting_configselect('grade_report_overview_showtotalsifcontainhidden', get_string('hidetotalifhiddenitems', 'grades'), + get_string('hidetotalifhiddenitemsdescription', 'grades'), GRADE_REPORT_HIDE_TOTAL_IF_CONTAINS_HIDDEN, + array(GRADE_REPORT_HIDE_TOTAL_IF_CONTAINS_HIDDEN => get_string('hide'), + GRADE_REPORT_SHOW_TOTAL_IF_CONTAINS_HIDDEN => get_string('hidetotalshowexhiddenitems', 'grades'), + GRADE_REPORT_SHOW_REAL_TOTAL_IF_CONTAINS_HIDDEN => get_string('hidetotalshowinchiddenitems', 'grades') ))); + ?> diff --git a/grade/report/user/lib.php b/grade/report/user/lib.php index 6bebe784c02..82937a2764b 100644 --- a/grade/report/user/lib.php +++ b/grade/report/user/lib.php @@ -99,6 +99,7 @@ class grade_report_user extends grade_report { $this->showrank = grade_get_setting($this->courseid, 'report_user_showrank', $CFG->grade_report_user_showrank); $this->showpercentage = grade_get_setting($this->courseid, 'report_user_showpercentage', $CFG->grade_report_user_showpercentage); $this->showhiddenitems = grade_get_setting($this->courseid, 'report_user_showhiddenitems', $CFG->grade_report_user_showhiddenitems); + $this->showtotalsifcontainhidden = grade_get_setting($this->courseid, 'report_user_showtotalsifcontainhidden', $CFG->grade_report_user_showtotalsifcontainhidden); $this->showrange = true; @@ -274,6 +275,7 @@ class grade_report_user extends grade_report { $data['grade']['content'] = '-'; } else { $data['grade']['class'] = $class; + $gradeval = $this->blank_hidden_total($this->courseid, $grade_grade->grade_item, $gradeval); $data['grade']['content'] = grade_format_gradevalue($gradeval, $grade_grade->grade_item, true); } @@ -461,6 +463,21 @@ function grade_report_user_settings_definition(&$mform) { $mform->addElement('select', 'report_user_showhiddenitems', get_string('showhiddenitems', 'grades'), $options); $mform->setHelpButton('report_user_showhiddenitems', array('showhiddenitems', get_string('showhiddenitems', 'grades'), 'grade')); + + //showtotalsifcontainhidden + $options = array(-1 => get_string('default', 'grades'), + GRADE_REPORT_HIDE_TOTAL_IF_CONTAINS_HIDDEN => get_string('hide'), + GRADE_REPORT_SHOW_TOTAL_IF_CONTAINS_HIDDEN => get_string('hidetotalshowexhiddenitems', 'grades'), + GRADE_REPORT_SHOW_REAL_TOTAL_IF_CONTAINS_HIDDEN => get_string('hidetotalshowinchiddenitems', 'grades') ); + + if (empty($CFG->grade_report_user_showtotalsifcontainhidden)) { + $options[-1] = get_string('defaultprev', 'grades', $options[0]); + } else { + $options[-1] = get_string('defaultprev', 'grades', $options[$CFG->grade_report_user_showtotalsifcontainhidden]); + } + + $mform->addElement('select', 'report_user_showtotalsifcontainhidden', get_string('hidetotalifhiddenitems', 'grades'), $options); + $mform->setHelpButton('report_user_showtotalsifcontainhidden', array('hidetotalifhiddenitems', get_string('hidetotalifhiddenitems', 'grades'), 'grade')); } function grade_report_user_profilereport($course, $user) { diff --git a/grade/report/user/settings.php b/grade/report/user/settings.php index c0adec36747..3b4642dd68e 100644 --- a/grade/report/user/settings.php +++ b/grade/report/user/settings.php @@ -25,4 +25,10 @@ $options = array(0 => get_string('shownohidden', 'grades'), 2 => get_string('showallhidden', 'grades')); $settings->add(new admin_setting_configselect('grade_report_user_showhiddenitems', get_string('showhiddenitems', 'grades'), get_string('configshowhiddenitems', 'grades'), 1, $options)); +$settings->add(new admin_setting_configselect('grade_report_user_showtotalsifcontainhidden', get_string('hidetotalifhiddenitems', 'grades'), + get_string('hidetotalifhiddenitemsdescription', 'grades'), GRADE_REPORT_HIDE_TOTAL_IF_CONTAINS_HIDDEN, + array(GRADE_REPORT_HIDE_TOTAL_IF_CONTAINS_HIDDEN => get_string('hide'), + GRADE_REPORT_SHOW_TOTAL_IF_CONTAINS_HIDDEN => get_string('hidetotalshowexhiddenitems', 'grades'), + GRADE_REPORT_SHOW_REAL_TOTAL_IF_CONTAINS_HIDDEN => get_string('hidetotalshowinchiddenitems', 'grades')))); + ?> diff --git a/lang/en_utf8/grades.php b/lang/en_utf8/grades.php index 3818ea422ec..a0e2de269b7 100644 --- a/lang/en_utf8/grades.php +++ b/lang/en_utf8/grades.php @@ -24,7 +24,7 @@ $string['aggregateonlygradedhelp'] = 'Nonexistent grades are either treated as m $string['aggregateoutcomes'] = 'Include outcomes in aggregation'; $string['aggregateoutcomeshelp'] = 'Including outcomes in aggregation may not lead to the desired overall grade, so you have the option to include or leave them out.'; $string['aggregatesubcats'] = 'Aggregate including subcategories'; -$string['aggregatesubcatshelp'] = 'The aggregation is usually done only with immediate children, it is also possible to aggregate grades in all subcategories excluding other aggregated grades.'; +$string['aggregatesubcatshelp'] = 'The aggregation is usually done only with immediate children, it is also possible to aggregate including individual grades in all subcategories excluding other aggregated grades.'; $string['aggregatesum'] = 'Sum of grades'; $string['aggregatesonly'] = 'Aggregates only'; $string['aggregateweightedmean'] = 'Weighted mean of grades'; @@ -277,6 +277,10 @@ $string['hidelocks'] = 'Hide locks'; $string['hidenooutcomes'] = 'Show outcomes'; $string['hidefeedback'] = 'Hide feedback'; $string['hideranges'] = 'Hide ranges'; +$string['hidetotalifhiddenitems'] = 'Hide totals if contain hidden items?'; +$string['hidetotalifhiddenitemsdescription'] = 'Hide totals if they contain one or more hidden items?'; +$string['hidetotalshowexhiddenitems'] = 'Show totals excluding hidden items'; +$string['hidetotalshowinchiddenitems'] = 'Show totals including hidden items'; $string['hideverbose'] = 'Hide $a->category$a->itemmodule $a->itemname'; $string['highgradeascending'] = 'Sort by high grade ascending'; $string['highgradedescending'] = 'Sort by high grade descending'; diff --git a/lang/en_utf8/help/grade/aggregatesubcats.html b/lang/en_utf8/help/grade/aggregatesubcats.html index 311d7990db2..ca82c21a3de 100644 --- a/lang/en_utf8/help/grade/aggregatesubcats.html +++ b/lang/en_utf8/help/grade/aggregatesubcats.html @@ -1,2 +1,2 @@
The aggregation is usually done only with immediate children, it is also possible to aggregate grades in all subcategories excluding other aggregated grades.
+The aggregation is usually done only with immediate children, it is also possible to aggregate including individual grades in all subcategories excluding other aggregated grades.
diff --git a/lib/grade/constants.php b/lib/grade/constants.php index f048417a1ba..0b299029307 100644 --- a/lib/grade/constants.php +++ b/lib/grade/constants.php @@ -79,6 +79,11 @@ define('GRADE_REPORT_AGGREGATION_VIEW_FULL', 0); define('GRADE_REPORT_AGGREGATION_VIEW_AGGREGATES_ONLY', 1); define('GRADE_REPORT_AGGREGATION_VIEW_GRADES_ONLY', 2); +//What to do if category or course total contains a hidden item +define('GRADE_REPORT_HIDE_TOTAL_IF_CONTAINS_HIDDEN', 0);//hide the total from students +define('GRADE_REPORT_SHOW_TOTAL_IF_CONTAINS_HIDDEN', 1);//show the total to students minus grades from the hidden items +define('GRADE_REPORT_SHOW_REAL_TOTAL_IF_CONTAINS_HIDDEN', 2);//show students the real total including marks from hidden items + define('GRADE_REPORT_PREFERENCE_DEFAULT', 'default'); // means use setting from site preferences define('GRADE_REPORT_PREFERENCE_INHERIT', 'inherit'); // means inherit from parent define('GRADE_REPORT_PREFERENCE_UNUSED', -1); diff --git a/lib/grade/grade_grade.php b/lib/grade/grade_grade.php index 3b81aa76269..4f16538442f 100644 --- a/lib/grade/grade_grade.php +++ b/lib/grade/grade_grade.php @@ -590,10 +590,12 @@ class grade_grade extends grade_object { } $max = count($todo); + $hidden_precursors = null; for($i=0; $i<$max; $i++) { $found = false; foreach($todo as $key=>$do) { - if (array_intersect($dependson[$do], $unknown)) { + $hidden_precursors = array_intersect($dependson[$do], $unknown); + if ($hidden_precursors) { // this item depends on hidden grade indirectly $unknown[$do] = $do; unset($todo[$key]); @@ -601,7 +603,8 @@ class grade_grade extends grade_object { continue; } else if (!array_intersect($dependson[$do], $todo)) { - if (!array_intersect($dependson[$do], array_keys($altered))) { + $hidden_precursors = array_intersect($dependson[$do], array_keys($altered)); + if (!$hidden_precursors) { // hiding does not affect this grade unset($todo[$key]); $found = true; @@ -609,20 +612,22 @@ class grade_grade extends grade_object { } 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())) { + 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)) { + //nulling an altered precursor $values[$itemid] = $altered[$itemid]; - } elseif (!empty($values[$itemid])) { + } elseif (empty($values[$itemid])) { $values[$itemid] = $grade_grades[$itemid]->finalgrade; } }