David Mudrak ff268dcb28 MDL-21695 Replaced grade/showpercentage.html
AMOS BEGIN
 MOV [configshowpercentage,core_grades],[showpercentage_help,core_grades]
 HLP grade/showpercentage.html,[showpercentage_help,core_grades]
AMOS END
2010-06-21 08:39:27 +00:00

510 lines
20 KiB
PHP

<?php
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
/**
* File in which the user_report class is defined.
* @package gradebook
*/
require_once($CFG->dirroot . '/grade/report/lib.php');
require_once($CFG->libdir.'/tablelib.php');
//showhiddenitems values
define("GRADE_REPORT_USER_HIDE_HIDDEN", 0);
define("GRADE_REPORT_USER_HIDE_UNTIL", 1);
define("GRADE_REPORT_USER_SHOW_HIDDEN", 2);
/**
* Class providing an API for the user report building and displaying.
* @uses grade_report
* @package gradebook
*/
class grade_report_user extends grade_report {
/**
* The user.
* @var object $user
*/
public $user;
/**
* A flexitable to hold the data.
* @var object $table
*/
public $table;
var $gtree;
/**
* Flat structure similar to grade tree
*/
public $gseq;
/**
* show student ranks
*/
public $showrank;
/**
* show grade percentages
*/
public $showpercentage;
/**
* Show range
*/
var $showrange;
var $tableheaders;
var $tablecolumns;
var $maxdepth;
var $evenodd;
var $tabledata;
var $canviewhidden;
var $switch;
/**
* Show hidden items even when user does not have required cap
*/
public $showhiddenitems;
/**
* Constructor. Sets local copies of user preferences and initialises grade_tree.
* @param int $courseid
* @param object $gpr grade plugin return tracking object
* @param string $context
* @param int $userid The id of the user
*/
public function __construct($courseid, $gpr, $context, $userid) {
global $CFG, $DB;
parent::__construct($courseid, $gpr, $context);
$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;
$this->switch = grade_get_setting($this->courseid, 'aggregationposition', $CFG->grade_aggregationposition);
// Grab the grade_tree for this course
$this->gtree = new grade_tree($this->courseid, false, $this->switch, false, !$CFG->enableoutcomes);
// Determine the number of rows and indentation
$this->maxdepth = 1;
$this->inject_rowspans($this->gtree->top_element);
$this->maxdepth++; // Need to account for the lead column that spans all children
for ($i = 1; $i <= $this->maxdepth; $i++) {
$this->evenodd[$i] = 0;
}
$this->tabledata = array();
$this->canviewhidden = has_capability('moodle/grade:viewhidden', get_context_instance(CONTEXT_COURSE, $this->courseid));
// get the user (for full name)
$this->user = $DB->get_record('user', array('id' => $userid));
// base url for sorting by first/last name
$this->baseurl = $CFG->wwwroot.'/grade/report?id='.$courseid.'&amp;userid='.$userid;
$this->pbarurl = $this->baseurl;
// no groups on this report - rank is from all course users
$this->setup_table();
}
function inject_rowspans(&$element) {
if ($element['depth'] > $this->maxdepth) {
$this->maxdepth = $element['depth'];
}
if (empty($element['children'])) {
return 1;
}
$count = 1;
foreach ($element['children'] as $key=>$child) {
$count += $this->inject_rowspans($element['children'][$key]);
}
$element['rowspan'] = $count;
return $count;
}
/**
* Prepares the headers and attributes of the flexitable.
*/
public function setup_table() {
global $CFG;
/*
* Table has 5-6 columns
*| itemname/description | final grade | percentage final grade | rank (optional) | feedback |
*/
// setting up table headers
$this->tablecolumns = array('itemname', 'grade');
$this->tableheaders = array($this->get_lang_string('gradeitem', 'grades'),
$this->get_lang_string('grade'));
if ($this->showrange) {
$this->tablecolumns[] = 'range';
$this->tableheaders[] = $this->get_lang_string('range', 'grades');
}
if ($this->showpercentage) {
$this->tablecolumns[] = 'percentage';
$this->tableheaders[] = $this->get_lang_string('percentage', 'grades');
}
if ($this->showrank) {
// TODO: this is broken if hidden grades present!!
$this->tablecolumns[] = 'rank';
$this->tableheaders[] = $this->get_lang_string('rank', 'grades');
}
$this->tablecolumns[] = 'feedback';
$this->tableheaders[] = $this->get_lang_string('feedback', 'grades');
}
function fill_table() {
//print "<pre>";
//print_r($this->gtree->top_element);
$this->fill_table_recursive($this->gtree->top_element);
//print_r($this->tabledata);
//print "</pre>";
return true;
}
private function fill_table_recursive(&$element) {
global $CFG, $DB;
$type = $element['type'];
$depth = $element['depth'];
$grade_object = $element['object'];
$eid = $grade_object->id;
$fullname = $this->gtree->get_element_header($element, true, true, true);
$data = array();
$hidden = '';
$excluded = '';
$class = '';
// If this is a hidden grade category, hide it completely from the user
if ($type == 'category' && $grade_object->is_hidden() && !$this->canviewhidden && (
$this->showhiddenitems == GRADE_REPORT_USER_HIDE_HIDDEN ||
($this->showhiddenitems == GRADE_REPORT_USER_HIDE_UNTIL && !$grade_object->is_hiddenuntil()))) {
return false;
}
if ($type == 'category') {
$this->evenodd[$depth] = (($this->evenodd[$depth] + 1) % 2);
}
$alter = ($this->evenodd[$depth] == 0) ? 'even' : 'odd';
/// Process those items that have scores associated
if ($type == 'item' or $type == 'categoryitem' or $type == 'courseitem') {
if (! $grade_grade = grade_grade::fetch(array('itemid'=>$grade_object->id,'userid'=>$this->user->id))) {
$grade_grade = new grade_grade();
$grade_grade->userid = $this->user->id;
$grade_grade->itemid = $grade_object->id;
}
$grade_grade->load_grade_item();
/// Hidden Items
if ($grade_grade->grade_item->is_hidden()) {
$hidden = ' hidden';
}
// If this is a hidden grade item, hide it completely from the user.
if ($grade_grade->is_hidden() && !$this->canviewhidden && (
$this->showhiddenitems == GRADE_REPORT_USER_HIDE_HIDDEN ||
($this->showhiddenitems == GRADE_REPORT_USER_HIDE_UNTIL && !$grade_grade->is_hiddenuntil()))) {
// return false;
} else {
/// Excluded Item
if ($grade_grade->is_excluded()) {
$fullname .= ' ['.get_string('excluded', 'grades').']';
$excluded = ' excluded';
}
/// Other class information
$class = "$hidden $excluded";
if ($this->switch) { // alter style based on whether aggregation is first or last
$class .= ($type == 'categoryitem' or $type == 'courseitem') ? " ".$alter."d$depth baggt b2b" : " item b1b";
} else {
$class .= ($type == 'categoryitem' or $type == 'courseitem') ? " ".$alter."d$depth baggb" : " item b1b";
}
/// Name
$data['itemname']['content'] = $fullname;
$data['itemname']['class'] = $class;
$data['itemname']['colspan'] = ($this->maxdepth - $depth);
/// Actual Grade
$gradeval = $grade_grade->finalgrade;
if ($grade_grade->grade_item->needsupdate) {
$data['grade']['class'] = $class.' gradingerror';
$data['grade']['content'] = get_string('error');
} else if (!empty($CFG->grade_hiddenasdate) and $grade_grade->get_datesubmitted() and !$this->canviewhidden and $grade_grade->is_hidden()
and !$grade_grade->grade_item->is_category_item() and !$grade_grade->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
$class .= ' datesubmitted';
$data['grade']['class'] = $class;
$data['grade']['content'] = get_string('submittedon', 'grades', userdate($grade_grade->get_datesubmitted(), get_string('strftimedatetimeshort')));
} elseif ($grade_grade->is_hidden()) {
$data['grade']['class'] = $class.' hidden';
$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);
}
/// Percentage
if ($this->showpercentage) {
if ($grade_grade->grade_item->needsupdate) {
$data['percentage']['class'] = $class.' gradingerror';
$data['percentage']['content'] = get_string('error');
} elseif ($grade_grade->is_hidden()) {
$data['percentage']['class'] = $class.' hidden';
$data['percentage']['content'] = '-';
} else {
$data['percentage']['class'] = $class;
$data['percentage']['content'] = grade_format_gradevalue($gradeval, $grade_grade->grade_item, true, GRADE_DISPLAY_TYPE_PERCENTAGE);
}
}
/// Rank
if ($this->showrank) {
// TODO: this is broken if hidden grades present!!
if ($grade_grade->grade_item->needsupdate) {
$data['rank']['class'] = $class.' gradingerror';
$data['rank']['content'] = get_string('error');
} elseif ($grade_grade->is_hidden()) {
$data['rank']['class'] = $class.' hidden';
$data['rank']['content'] = '-';
} else if (is_null($gradeval)) {
// no grade, no rank
$data['rank']['class'] = $class;
$data['rank']['content'] = '-';
} else {
/// find the number of users with a higher grade
$sql = "SELECT COUNT(DISTINCT(userid))
FROM {grade_grades}
WHERE finalgrade > ?
AND itemid = ?";
$rank = $DB->count_records_sql($sql, array($grade_grade->finalgrade, $grade_grade->grade_item->id)) + 1;
$data['rank']['class'] = $class;
$data['rank']['content'] = "$rank/".$this->get_numusers(false); // total course users
}
}
/// Feedback
if (empty($grade_grade->feedback) or (!$this->canviewhidden and $grade_grade->is_hidden())) {
$data['feedback']['class'] = $class.' feedbacktext';
$data['feedback']['content'] = '&nbsp;';
} else {
$data['feedback']['class'] = $class.' feedbacktext';
$data['feedback']['content'] = format_text($grade_grade->feedback, $grade_grade->feedbackformat);
}
/// Range
if ($this->showrange) {
$data['range']['class'] = $class;
$data['range']['content'] = $grade_grade->grade_item->get_formatted_range();
}
}
}
/// Category
if ($type == 'category') {
$data['leader']['class'] = $class.' '.$alter."d$depth b1t b2b b1l";
$data['leader']['rowspan'] = $element['rowspan'];
if ($this->switch) { // alter style based on whether aggregation is first or last
$data['itemname']['class'] = $class.' '.$alter."d$depth b1b b1t";
} else {
$data['itemname']['class'] = $class.' '.$alter."d$depth b2t";
}
$data['itemname']['colspan'] = ($this->maxdepth - $depth + count($this->tablecolumns) - 1);
$data['itemname']['content'] = $fullname;
}
/// Add this row to the overall system
$this->tabledata[] = $data;
/// Recursively iterate through all child elements
if (isset($element['children'])) {
foreach ($element['children'] as $key=>$child) {
$this->fill_table_recursive($element['children'][$key]);
}
}
}
/**
* Prints or returns the HTML from the flexitable.
* @param bool $return Whether or not to return the data instead of printing it directly.
* @return string
*/
public function print_table($return=false) {
$maxspan = $this->maxdepth;
/// Build table structure
$html = "
<table cellspacing='0' cellpadding='0' class='boxaligncenter generaltable user-grade'>
<thead>
<tr>
<th class=\"header\" colspan='$maxspan'>".$this->tableheaders[0]."</th>\n";
for ($i = 1; $i < count($this->tableheaders); $i++) {
$html .= "<th class=\"header\">".$this->tableheaders[$i]."</th>\n";
}
$html .= "
</tr>
</thead>
<tbody>\n";
/// Print out the table data
for ($i = 0; $i < count($this->tabledata); $i++) {
$html .= "<tr>\n";
if (isset($this->tabledata[$i]['leader'])) {
$rowspan = $this->tabledata[$i]['leader']['rowspan'];
$class = $this->tabledata[$i]['leader']['class'];
$html .= "<td class='$class' rowspan='$rowspan'></td>\n";
}
for ($j = 0; $j < count($this->tablecolumns); $j++) {
$name = $this->tablecolumns[$j];
$class = (isset($this->tabledata[$i][$name]['class'])) ? $this->tabledata[$i][$name]['class'] : '';
$colspan = (isset($this->tabledata[$i][$name]['colspan'])) ? "colspan='".$this->tabledata[$i][$name]['colspan']."'" : '';
$content = (isset($this->tabledata[$i][$name]['content'])) ? $this->tabledata[$i][$name]['content'] : null;
if (isset($content)) {
$html .= "<td class='$class' $colspan>$content</td>\n";
}
}
$html .= "</tr>\n";
}
$html .= "</tbody></table>";
if ($return) {
return $html;
} else {
echo $html;
}
}
/**
* Processes the data sent by the form (grades and feedbacks).
* @var array $data
* @return bool Success or Failure (array of errors).
*/
function process_data($data) {
}
function process_action($target, $action) {
}
}
function grade_report_user_settings_definition(&$mform) {
global $CFG;
$options = array(-1 => get_string('default', 'grades'),
0 => get_string('hide'),
1 => get_string('show'));
if (empty($CFG->grade_report_user_showrank)) {
$options[-1] = get_string('defaultprev', 'grades', $options[0]);
} else {
$options[-1] = get_string('defaultprev', 'grades', $options[1]);
}
$mform->addElement('select', 'report_user_showrank', get_string('showrank', 'grades'), $options);
$mform->setHelpButton('report_user_showrank', array('showrank', get_string('showrank', 'grades'), 'grade'));
if (empty($CFG->grade_report_user_showpercentage)) {
$options[-1] = get_string('defaultprev', 'grades', $options[0]);
} else {
$options[-1] = get_string('defaultprev', 'grades', $options[1]);
}
$mform->addElement('select', 'report_user_showpercentage', get_string('showpercentage', 'grades'), $options);
$mform->addHelpButton('report_user_showpercentage', 'showpercentage', 'grades');
$options = array(-1 => get_string('default', 'grades'),
0 => get_string('shownohidden', 'grades'),
1 => get_string('showhiddenuntilonly', 'grades'),
2 => get_string('showallhidden', 'grades'));
if (empty($CFG->grade_report_user_showhiddenitems)) {
$options[-1] = get_string('defaultprev', 'grades', $options[0]);
} else {
$options[-1] = get_string('defaultprev', 'grades', $options[$CFG->grade_report_user_showhiddenitems]);
}
$mform->addElement('select', 'report_user_showhiddenitems', get_string('showhiddenitems', 'grades'), $options);
$mform->addHelpButton('report_user_showhiddenitems', 'showhiddenitems', 'grades');
//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->addHelpButton('report_user_showtotalsifcontainhidden', 'hidetotalifhiddenitems', 'grades');
}
function grade_report_user_profilereport($course, $user) {
global $OUTPUT;
if (!empty($course->showgrades)) {
$context = get_context_instance(CONTEXT_COURSE, $course->id);
//first make sure we have proper final grades - this must be done before constructing of the grade tree
grade_regrade_final_grades($course->id);
/// return tracking object
$gpr = new grade_plugin_return(array('type'=>'report', 'plugin'=>'user', 'courseid'=>$course->id, 'userid'=>$user->id));
// Create a report instance
$report = new grade_report_user($course->id, $gpr, $context, $user->id);
// print the page
echo '<div class="grade-report-user">'; // css fix to share styles with real report page
echo $OUTPUT->heading(get_string('modulename', 'gradereport_user'). ' - '.fullname($report->user));
if ($report->fill_table()) {
echo $report->print_table(true);
}
echo '</div>';
}
}