diff --git a/grade/lib.php b/grade/lib.php
index 1da3b5f2cbc..13254d1746b 100644
--- a/grade/lib.php
+++ b/grade/lib.php
@@ -705,6 +705,11 @@ class grade_seq {
*/
var $items;
+ /**
+ * 1D array of elements
+ */
+ var $elements;
+
/**
* Course context
*/
@@ -727,7 +732,11 @@ class grade_seq {
// get course grade tree
$top_element = grade_category::fetch_course_tree($courseid, true);
- $this->items = grade_seq::flatten($top_element, $category_grade_last, $nooutcomes);
+ $this->elements = grade_seq::flatten($top_element, $category_grade_last, $nooutcomes);
+
+ foreach ($this->elements as $key=>$unused) {
+ $this->items[$key] =& $this->elements[$key]['object'];
+ }
}
/**
@@ -758,10 +767,10 @@ class grade_seq {
$result = array();
foreach ($children as $child) {
if ($child['type'] == 'category') {
- $result = array_merge($result, grade_seq::flatten($child, $category_grade_last, $nooutcomes));
+ $result = $result + grade_seq::flatten($child, $category_grade_last, $nooutcomes);
} else {
$child['eid'] = 'i'.$child['object']->id;
- $result[] = $child;
+ $result[$child['object']->id] = $child;
}
}
@@ -809,7 +818,7 @@ class grade_seq {
}
// it is a category or item
- foreach ($this->items as $element) {
+ foreach ($this->elements as $element) {
if ($element['eid'] == $eid) {
return $element;
}
diff --git a/grade/report/user/lib.php b/grade/report/user/lib.php
index f7ee0e784cd..339ebdc522a 100644
--- a/grade/report/user/lib.php
+++ b/grade/report/user/lib.php
@@ -124,103 +124,104 @@ class grade_report_user extends grade_report {
function fill_table() {
global $CFG;
$numusers = $this->get_numusers(false); // total course users
+ $items =& $this->gseq->items;
+ $grades = array();
- foreach ($this->gseq->items as $element) {
- $grade_item = $element['object'];
- $decimalpoints = $grade_item->get_decimals();
- $data = array();
+ $viewhidden = has_capability('moodle/grade:viewhidden', get_context_instance(CONTEXT_COURSE, $this->courseid));
+ foreach ($items as $key=>$unused) {
+ $grade_item =& $items[$key];
$grade_grade = new grade_grade(array('itemid'=>$grade_item->id, 'userid'=>$this->user->id));
- $grade_grade->grade_item =& $grade_item;
+ $grades[$key] = $grade_grade;
+ $grades[$key]->grade_item =& $grade_item;
+ }
+
+ $hiding_affected = grade_grade::get_hiding_affected($grades, $items);
+
+ foreach ($items as $key=>$unused) {
+ $grade_item =& $items[$key];
+ $grade_grade =& $grades[$key];
+
+ $data = array();
// TODO: indicate items that "needsupdate" - missing final calculation
/// prints grade item name
if ($grade_item->is_course_item() or $grade_item->is_category_item()) {
- $data[] = ''.$grade_item->get_name().'';
+ $data[] = '
'.$grade_item->get_name().'
';
} else {
- $data[] = $this->get_module_link($grade_item->get_name(), $grade_item->itemmodule, $grade_item->iteminstance);;
+ $data[] = ''.$this->get_module_link($grade_item->get_name(), $grade_item->itemmodule, $grade_item->iteminstance).'
';
}
/// prints category
$cat = $grade_item->get_parent_category();
- $data[] = $cat->fullname;
-
+ $data[] = $cat->get_name();
/// prints the grade
- $displaytype = $grade_item->get_displaytype();
-
if ($grade_grade->is_excluded()) {
$excluded = get_string('excluded', 'grades').' ';
} else {
$excluded = '';
}
- if ((int) $grade_grade->finalgrade < 1) {
- $data[] = '-';
- } elseif ($grade_grade->is_hidden() && !has_capability('moodle/grade:viewhidden', get_context_instance(CONTEXT_COURSE, $grade_item->courseid))) {
- $data[] = get_string('gradedon', 'grades', userdate($grade_grade->timemodified));
- } elseif ($grade_item->scaleid) {
- if ($scale = get_record('scale', 'id', $grade_item->scaleid)) {
- $scales = explode(",", $scale->scale);
- // reindex because scale is off 1
- $data[] = $excluded.$scales[$grade_grade->finalgrade-1];
+ if (is_null($grade_grade->finalgrade)) {
+ $data[] = $excluded . '-';
+
+ } else if (($grade_grade->is_hidden() or in_array($grade_item->id, $hiding_affected)) and !$viewhidden) {
+ // TODO: optinally do not show anything for hidden grades
+ // $data[] = '-';
+ if ($grade_grade->is_hidden()) {
+ $data[] = $excluded . ''.get_string('gradedon', 'grades', userdate($grade_grade->timemodified, get_string('strftimedatetimeshort'))).'
';
+ } else {
+ $data[] = $excluded . '-';
}
+
} else {
- $data[] = $excluded . grade_format_gradevalue($grade_grade->finalgrade, $grade_item, true, $displaytype, $decimalpoints);
+ $data[] = $excluded . grade_format_gradevalue($grade_grade->finalgrade, $grade_item, true);
}
/// prints percentage
- if ($grade_grade->is_hidden() && !has_capability('moodle/grade:viewhidden', get_context_instance(CONTEXT_COURSE, $grade_item->courseid))) {
- if ((int) $grade_grade->finalgrade < 1) {
- $data[] = '-';
- } else {
- $data[] = get_string('gradedon', 'grades', userdate($grade_grade->timemodified));
- }
+ if (is_null($grade_grade->finalgrade)) {
+ $data[] = '-';
+
+ } else if (($grade_grade->is_hidden() or in_array($grade_item->id, $hiding_affected)) and !$viewhidden) {
+ $data[] = '-';
+
} else {
- if ($grade_item->gradetype == GRADE_TYPE_VALUE) {
- // processing numeric grade
- if ($grade_grade->finalgrade) {
- $percentage = format_float(($grade_grade->finalgrade / $grade_item->grademax) * 100, $decimalpoints).'%';
- } else {
- $percentage = '-';
- }
-
- } else if ($grade_item->gradetype == GRADE_TYPE_SCALE) {
- // processing scale grade
- $scale = get_record('scale', 'id', $grade_item->scaleid);
- $scalevals = explode(",", $scale->scale);
- $percentage = format_float(($grade_grade->finalgrade) / count($scalevals) * 100, $decimalpoints).'%';
-
- } else {
- // text grade
- $percentage = '-';
- }
-
- $data[] = $percentage;
+ $data[] = grade_format_gradevalue($grade_grade->finalgrade, $grade_item, true, GRADE_DISPLAY_TYPE_PERCENTAGE);
}
+
/// prints rank
- if ($grade_grade->finalgrade) {
+ if (is_null($grade_grade->finalgrade)) {
+ // no grade, no rank
+ $data[] = '-';
+
+ } else if (($grade_grade->is_hidden() or in_array($grade_item->id, $hiding_affected)) and !$viewhidden) {
+ $data[] = '-';
+
+ } else {
/// find the number of users with a higher grade
$sql = "SELECT COUNT(DISTINCT(userid))
- FROM {$CFG->prefix}grade_grades
- WHERE finalgrade > $grade_grade->finalgrade
- AND itemid = $grade_item->id";
+ FROM {$CFG->prefix}grade_grades
+ WHERE finalgrade > {$grade_grade->finalgrade}
+ AND itemid = {$grade_item->id}";
$rank = count_records_sql($sql) + 1;
$data[] = "$rank/$numusers";
- } else {
- // no grade, no rank
- $data[] = "-";
}
/// prints notes
- if (!empty($grade_grade->feedback)) {
- $data[] = format_text($grade_grade->feedback, $grade_grade->feedbackformat);
- } else {
+ if (empty($grade_grade->feedback)) {
$data[] = ' ';
+
+ } else if (($grade_grade->is_hidden() or in_array($grade_item->id, $hiding_affected)) and !$viewhidden) {
+ $data[] = ' ';
+
+ } else {
+ $data[] = format_text($grade_grade->feedback, $grade_grade->feedbackformat);
}
+
$this->table->add_data($data);
}
diff --git a/lib/grade/grade_grade.php b/lib/grade/grade_grade.php
index a97e3c9887e..2d35722aa32 100644
--- a/lib/grade/grade_grade.php
+++ b/lib/grade/grade_grade.php
@@ -471,5 +471,57 @@ class grade_grade extends grade_object {
$standardised_value = $factor * $diff + $target_min;
return $standardised_value;
}
+
+ /**
+ * Return array of grade item ids that are either hidden or indirectly depend
+ * on hidden grades, excluded grades are not returned.
+ * @static
+ * @param array $grades all course grades of one user
+ * @param array $items $grade_items array of grade items, & used for better internal caching
+ * @return array
+ */
+ function get_hiding_affected($grade_grades, &$grade_items) {
+ if (count($grade_grades) !== count($grade_items)) {
+ error("Incorrent size of arrays in params of grade_grade::get_hiding_affected()!");
+ }
+
+ $dependson = array();
+ 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();
+ }
+
+ $todo = array();
+ $hiding = array();
+ 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 {
+ $todo[] = $grade_grade->itemid;
+ }
+ }
+
+ $max = count($grade_items);
+ 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)) {
+ // this item depends on hidden grade indirectly
+ $hiding[] = $do;
+ unset($todo[$key]);
+ $found = true;
+ }
+ }
+ if (!$found) {
+ break;
+ }
+ }
+
+ return $hiding;
+ }
}
?>
diff --git a/theme/standard/styles_fonts.css b/theme/standard/styles_fonts.css
index 4f4f2f79b31..2eb5094e0e3 100644
--- a/theme/standard/styles_fonts.css
+++ b/theme/standard/styles_fonts.css
@@ -509,6 +509,14 @@ body#grade-index .grades .header {
font-weight: bold;
}
+.grade-report-user .gradeddate {
+ font-size: 0.7em;
+}
+
+.grade-report-user .catname {
+ font-weight: bold;
+}
+
/***
*** Login
***/