MDL-35984 grade: Recalculate min/max for sum of grades when hidden grades are involved.

This commit is contained in:
Damyon Wiese 2014-08-04 15:03:26 +08:00
parent d2e9fc5845
commit 5232d3f2c9
6 changed files with 154 additions and 29 deletions

View file

@ -412,9 +412,9 @@ abstract class grade_report {
* @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
* @return array[] containing values for 'grade', 'grademax' and 'grademin'
*/
protected function blank_hidden_total($courseid, $course_item, $finalgrade) {
protected function blank_hidden_total_and_adjust_bounds($courseid, $course_item, $finalgrade) {
global $CFG, $DB;
static $hiding_affected = null;//array of items in this course affected by hiding
@ -424,13 +424,16 @@ abstract class grade_report {
// If we're dealing with multiple courses we need to know when we've moved on to a new course.
static $previous_courseid = null;
$grademin = $course_item->grademin;
$grademax = $course_item->grademax;
if (!is_array($this->showtotalsifcontainhidden)) {
debugging('showtotalsifcontainhidden should be an array', DEBUG_DEVELOPER);
$this->showtotalsifcontainhidden = array($courseid => $this->showtotalsifcontainhidden);
}
if ($this->showtotalsifcontainhidden[$courseid] == GRADE_REPORT_SHOW_REAL_TOTAL_IF_CONTAINS_HIDDEN) {
return $finalgrade;
return array('grade' => $finalgrade, 'grademin' => $grademin, 'grademax' => $grademax);
}
// If we've moved on to another course or user, reload the grades.
@ -473,6 +476,12 @@ abstract class grade_report {
} else {
//use reprocessed marks that exclude hidden items
$finalgrade = $hiding_affected['altered'][$course_item->id];
if (!empty($hiding_affected['alteredgrademin'][$course_item->id])) {
$grademin = $hiding_affected['alteredgrademin'][$course_item->id];
}
if (!empty($hiding_affected['alteredgrademax'][$course_item->id])) {
$grademax = $hiding_affected['alteredgrademax'][$course_item->id];
}
}
} else if (!empty($hiding_affected['unknown'][$course_item->id])) {
//not sure whether or not this item depends on a hidden item
@ -482,10 +491,35 @@ abstract class grade_report {
} else {
//use reprocessed marks that exclude hidden items
$finalgrade = $hiding_affected['unknown'][$course_item->id];
if (!empty($hiding_affected['alteredgrademin'][$course_item->id])) {
$grademin = $hiding_affected['alteredgrademin'][$course_item->id];
}
if (!empty($hiding_affected['alteredgrademax'][$course_item->id])) {
$grademax = $hiding_affected['alteredgrademax'][$course_item->id];
}
}
}
return $finalgrade;
return array('grade' => $finalgrade, 'grademin' => $grademin, 'grademax' => $grademax);
}
/**
* Optionally blank out course/category totals if they contain any hidden items
* @deprecated since Moodle 2.8 - Call blank_hidden_total_and_adjust_bounds instead.
* @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) {
// Note it is flawed to call this function directly because
// the aggregated grade does not make sense without the updated min and max information.
debugging('grade_report::blank_hidden_total() is deprecated.
Call grade_report::blank_hidden_total_and_adjust_bounds instead.', DEBUG_DEVELOPER);
$result = $this->blank_hidden_total_and_adjust_bounds($courseid, $course_item, $finalgrade);
return $result['grade'];
}
}

View file

@ -169,7 +169,15 @@ class grade_report_overview extends grade_report {
if ($course_grade->is_hidden()) {
$finalgrade = null;
} else {
$finalgrade = $this->blank_hidden_total($course->id, $course_item, $finalgrade);
$adjustedgrade = $this->blank_hidden_total_and_adjust_bounds($course->id,
$course_item,
$finalgrade);
// We temporarily adjust the view of this grade item - because the min and
// max are affected by the hidden values in the aggregation.
$finalgrade = $adjustedgrade['grade'];
$course_item->grademax = $adjustedgrade['grademax'];
$course_item->grademin = $adjustedgrade['grademin'];
}
}

View file

@ -435,8 +435,17 @@ 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);
$adjustedgrade = $this->blank_hidden_total_and_adjust_bounds($this->courseid,
$grade_grade->grade_item,
$gradeval);
// We temporarily adjust the view of this grade item - because the min and
// max are affected by the hidden values in the aggregation.
$grade_grade->grade_item->grademax = $adjustedgrade['grademax'];
$grade_grade->grade_item->grademin = $adjustedgrade['grademin'];
$data['grade']['content'] = grade_format_gradevalue($adjustedgrade['grade'],
$grade_grade->grade_item,
true);
}
$data['grade']['headers'] = "$header_cat $header_row grade";
}

View file

@ -39,10 +39,10 @@ class grade_report_test extends grade_report {
}
/**
* A wrapper around blank_hidden_total() to allow test code to call it directly
* A wrapper around blank_hidden_total_and_adjust_bounds() to allow test code to call it directly
*/
public function blank_hidden_total($courseid, $courseitem, $finalgrade) {
return parent::blank_hidden_total($courseid, $courseitem, $finalgrade);
public function blank_hidden_total_and_adjust_bounds($courseid, $courseitem, $finalgrade) {
return parent::blank_hidden_total_and_adjust_bounds($courseid, $courseitem, $finalgrade);
}
/**
@ -64,9 +64,9 @@ class grade_report_test extends grade_report {
class core_grade_reportlib_testcase extends advanced_testcase {
/**
* Tests grade_report::blank_hidden_total()
* Tests grade_report::blank_hidden_total_and_adjust_bounds()
*/
public function test_blank_hidden_total() {
public function test_blank_hidden_total_and_adjust_bounds() {
global $DB;
$this->resetAfterTest(true);
@ -121,15 +121,24 @@ class core_grade_reportlib_testcase extends advanced_testcase {
// Should return the supplied student total grade regardless of hiding.
$report->showtotalsifcontainhidden = array($course->id => GRADE_REPORT_SHOW_REAL_TOTAL_IF_CONTAINS_HIDDEN);
$this->assertEquals($datagrade + $forumgrade, $report->blank_hidden_total($course->id, $coursegradeitem, $datagrade + $forumgrade));
$result = $report->blank_hidden_total_and_adjust_bounds($course->id, $coursegradeitem, $datagrade + $forumgrade);
$this->assertEquals(array('grade' => $datagrade + $forumgrade,
'grademax' => $coursegradeitem->grademax,
'grademin' => $coursegradeitem->grademin), $result);
// Should blank the student total as course grade depends on a hidden item.
$report->showtotalsifcontainhidden = array($course->id => GRADE_REPORT_HIDE_TOTAL_IF_CONTAINS_HIDDEN);
$this->assertEquals(null, $report->blank_hidden_total($course->id, $coursegradeitem, $datagrade + $forumgrade));
$result = $report->blank_hidden_total_and_adjust_bounds($course->id, $coursegradeitem, $datagrade + $forumgrade);
$this->assertEquals(array('grade' => null,
'grademax' => $coursegradeitem->grademax,
'grademin' => $coursegradeitem->grademin), $result);
// Should return the course total minus the hidden database activity grade.
$report->showtotalsifcontainhidden = array($course->id => GRADE_REPORT_SHOW_TOTAL_IF_CONTAINS_HIDDEN);
$this->assertEquals($forumgrade, $report->blank_hidden_total($course->id, $coursegradeitem, $datagrade + $forumgrade));
$result = $report->blank_hidden_total_and_adjust_bounds($course->id, $coursegradeitem, $datagrade + $forumgrade);
$this->assertEquals(array('grade' => $forumgrade,
'grademax' => $coursegradeitem->grademax,
'grademin' => $coursegradeitem->grademin), $result);
// Note: we cannot simply hide modules and call $report->blank_hidden_total() again.
// It stores grades in a static variable so $report->blank_hidden_total() will return incorrect totals
@ -183,15 +192,24 @@ class core_grade_reportlib_testcase extends advanced_testcase {
// Should return the supplied student total grade regardless of hiding.
$report->showtotalsifcontainhidden = array($course->id => GRADE_REPORT_SHOW_REAL_TOTAL_IF_CONTAINS_HIDDEN);
$this->assertEquals($datagrade + $forumgrade, $report->blank_hidden_total($course->id, $coursegradeitem, $datagrade + $forumgrade));
$result = $report->blank_hidden_total_and_adjust_bounds($course->id, $coursegradeitem, $datagrade + $forumgrade);
$this->assertEquals(array('grade' => $datagrade + $forumgrade,
'grademax' => $coursegradeitem->grademax,
'grademin' => $coursegradeitem->grademin), $result);
// Should blank the student total as course grade depends on a hidden item.
$report->showtotalsifcontainhidden = array($course->id => GRADE_REPORT_HIDE_TOTAL_IF_CONTAINS_HIDDEN);
$this->assertEquals(null, $report->blank_hidden_total($course->id, $coursegradeitem, $datagrade + $forumgrade));
$result = $report->blank_hidden_total_and_adjust_bounds($course->id, $coursegradeitem, $datagrade + $forumgrade);
$this->assertEquals(array('grade' => null,
'grademax' => $coursegradeitem->grademax,
'grademin' => $coursegradeitem->grademin), $result);
// Should return the course total minus the hidden activity grades.
// They are both hidden so should return null.
$report->showtotalsifcontainhidden = array($course->id => GRADE_REPORT_SHOW_TOTAL_IF_CONTAINS_HIDDEN);
$this->assertEquals(null, $report->blank_hidden_total($course->id, $coursegradeitem, $datagrade + $forumgrade));
$result = $report->blank_hidden_total_and_adjust_bounds($course->id, $coursegradeitem, $datagrade + $forumgrade);
$this->assertEquals(array('grade' => null,
'grademax' => $coursegradeitem->grademax,
'grademin' => $coursegradeitem->grademin), $result);
}
}