mirror of
https://github.com/moodle/moodle.git
synced 2025-02-13 03:45:49 +01:00
398 lines
16 KiB
PHP
398 lines
16 KiB
PHP
<?php // $Id$
|
|
|
|
///////////////////////////////////////////////////////////////////////////
|
|
// //
|
|
// NOTICE OF COPYRIGHT //
|
|
// //
|
|
// Moodle - Modular Object-Oriented Dynamic Learning Environment //
|
|
// http://moodle.com //
|
|
// //
|
|
// Copyright (C) 1999 onwards Martin Dougiamas http://moodle.com //
|
|
// //
|
|
// This program 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 2 of the License, or //
|
|
// (at your option) any later version. //
|
|
// //
|
|
// This program 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: //
|
|
// //
|
|
// http://www.gnu.org/copyleft/gpl.html //
|
|
// //
|
|
///////////////////////////////////////////////////////////////////////////
|
|
/**
|
|
* 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');
|
|
|
|
/**
|
|
* 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;
|
|
|
|
/**
|
|
* Flat structure similar to grade tree
|
|
*/
|
|
public $gseq;
|
|
|
|
/**
|
|
* show student ranks
|
|
*/
|
|
public $showrank;
|
|
|
|
/**
|
|
* show grade percentages
|
|
*/
|
|
public $showpercentage;
|
|
|
|
/**
|
|
* 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);
|
|
|
|
$switch = grade_get_setting($this->courseid, 'aggregationposition', $CFG->grade_aggregationposition);
|
|
|
|
// Grab the grade_seq for this course
|
|
$this->gseq = new grade_seq($this->courseid, $switch);
|
|
|
|
// 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.'&userid='.$userid;
|
|
$this->pbarurl = $this->baseurl;
|
|
|
|
// no groups on this report - rank is from all course users
|
|
$this->setup_table();
|
|
}
|
|
|
|
/**
|
|
* 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
|
|
$tablecolumns = array('itemname', 'category', 'grade');
|
|
$tableheaders = array($this->get_lang_string('gradeitem', 'grades'),
|
|
$this->get_lang_string('category'),
|
|
$this->get_lang_string('grade'));
|
|
|
|
if ($this->showpercentage) {
|
|
$tablecolumns[] = 'percentage';
|
|
$tableheaders[] = $this->get_lang_string('percentage', 'grades');
|
|
}
|
|
|
|
if ($this->showrank) {
|
|
// TODO: this is broken if hidden grades present!!
|
|
$tablecolumns[] = 'rank';
|
|
$tableheaders[] = $this->get_lang_string('rank');
|
|
}
|
|
|
|
$tablecolumns[] = 'feedback';
|
|
$tableheaders[] = $this->get_lang_string('feedback');
|
|
|
|
$this->table = new flexible_table('grade-report-user-'.$this->courseid);
|
|
|
|
$this->table->define_columns($tablecolumns);
|
|
$this->table->define_headers($tableheaders);
|
|
$this->table->define_baseurl($this->baseurl);
|
|
|
|
$this->table->set_attribute('cellspacing', '0');
|
|
$this->table->set_attribute('class', 'user-grades boxaligncenter generaltable');
|
|
|
|
// not sure tables should be sortable or not, because if we allow it then sorted results distort grade category structure and sortorder
|
|
$this->table->set_control_variables(array(
|
|
TABLE_VAR_SORT => 'ssort',
|
|
TABLE_VAR_HIDE => 'shide',
|
|
TABLE_VAR_SHOW => 'sshow',
|
|
TABLE_VAR_IFIRST => 'sifirst',
|
|
TABLE_VAR_ILAST => 'silast',
|
|
TABLE_VAR_PAGE => 'spage'
|
|
));
|
|
|
|
$this->table->setup();
|
|
}
|
|
|
|
public function fill_table() {
|
|
global $CFG, $DB;
|
|
$numusers = $this->get_numusers(false); // total course users
|
|
$items =& $this->gseq->items;
|
|
$grades = array();
|
|
|
|
$canviewhidden = has_capability('moodle/grade:viewhidden', get_context_instance(CONTEXT_COURSE, $this->courseid));
|
|
|
|
// fetch or create all grades
|
|
foreach ($items as $key=>$unused) {
|
|
if (!$grade_grade = grade_grade::fetch(array('itemid'=>$items[$key]->id, 'userid'=>$this->user->id))) {
|
|
$grade_grade = new grade_grade();
|
|
$grade_grade->userid = $this->user->id;
|
|
$grade_grade->itemid = $items[$key]->id;
|
|
}
|
|
$grades[$key] = $grade_grade;
|
|
$grades[$key]->grade_item =& $items[$key];
|
|
}
|
|
|
|
if ($canviewhidden) {
|
|
$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 $itemid=>$unused) {
|
|
$grade_item =& $items[$itemid];
|
|
$grade_grade =& $grades[$itemid];
|
|
|
|
if (!$canviewhidden and $grade_item->is_hidden()) {
|
|
if ($this->showhiddenitems == 0) {
|
|
// no hidden items at all
|
|
continue;
|
|
} else if ($this->showhiddenitems == 1 and !$grade_item->is_hiddenuntil()) {
|
|
// hidden until that are still hidden are visible
|
|
continue;
|
|
}
|
|
}
|
|
|
|
$class = 'gradeitem';
|
|
if ($grade_item->is_course_item()) {
|
|
$class = 'courseitem';
|
|
} else if ($grade_item->is_category_item()) {
|
|
$class = 'categoryitem';
|
|
}
|
|
|
|
if (in_array($itemid, $unknown)) {
|
|
$gradeval = null;
|
|
} else if (array_key_exists($itemid, $altered)) {
|
|
$gradeval = $altered[$itemid];
|
|
} else {
|
|
$gradeval = $grade_grade->finalgrade;
|
|
}
|
|
|
|
$data = array();
|
|
|
|
// all users should know which items are still hidden
|
|
$hidden = '';
|
|
if ($grade_item->is_hidden()) {
|
|
$hidden = ' hidden ';
|
|
}
|
|
|
|
$element = $this->gseq->locate_element($this->gseq->get_item_eid($grade_item));
|
|
$header = $this->gseq->get_element_header($element, true, true, true);
|
|
|
|
/// prints grade item name
|
|
$data[] = '<span class="'.$hidden.$class.'">'.$header.'</span>';
|
|
|
|
/// prints category
|
|
$cat = $grade_item->get_parent_category();
|
|
$data[] = '<span class="'.$hidden.$class.'">'.$cat->get_name().'</span>';
|
|
|
|
$hidden = '';
|
|
if ($grade_item->is_hidden()) {
|
|
// can not see grades in hidden items
|
|
$hidden = ' hidden ';
|
|
} else if ($canviewhidden and $grade_grade->is_hidden()) {
|
|
// if user can see hidden grades, indicate which ones are hidden
|
|
$hidden = ' hidden ';
|
|
}
|
|
|
|
/// prints the grade
|
|
if ($grade_grade->is_excluded()) {
|
|
$excluded = get_string('excluded', 'grades').' ';
|
|
} else {
|
|
$excluded = '';
|
|
}
|
|
|
|
if ($grade_item->needsupdate) {
|
|
$data[] = '<span class="'.$hidden.$class.' gradingerror">'.get_string('error').'</span>';
|
|
|
|
} else if (!empty($CFG->grade_hiddenasdate) and $grade_grade->get_datesubmitted() 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[] = '<span class="'.$hidden.$class.' datesubmitted">'.$excluded.get_string('submittedon', 'grades', userdate($grade_grade->get_datesubmitted(), get_string('strftimedatetimeshort'))).'</span>';
|
|
|
|
} else {
|
|
$data[] = '<span class="'.$hidden.$class.'">'.$excluded.grade_format_gradevalue($gradeval, $grade_item, true).'</span>';
|
|
}
|
|
|
|
/// prints percentage
|
|
if ($this->showpercentage) {
|
|
if ($grade_item->needsupdate) {
|
|
$data[] = '<span class="'.$hidden.$class.'gradingerror">'.get_string('error').'</span>';
|
|
|
|
} else {
|
|
$data[] = '<span class="'.$hidden.$class.'">'.grade_format_gradevalue($gradeval, $grade_item, true, GRADE_DISPLAY_TYPE_PERCENTAGE).'</span>';
|
|
}
|
|
}
|
|
|
|
/// prints rank
|
|
if ($this->showrank) {
|
|
// TODO: this is broken if hidden grades present!!
|
|
if ($grade_item->needsupdate) {
|
|
$data[] = '<span class="'.$hidden.$class.'gradingerror">'.get_string('error').'</span>';
|
|
|
|
} else if (is_null($gradeval)) {
|
|
// no grade, no rank
|
|
$data[] = '<span class="'.$hidden.$class.'">-</span>';;
|
|
|
|
} 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_item->id)) + 1;
|
|
|
|
$data[] = '<span class="'.$hidden.$class.'">'."$rank/$numusers".'</span>';
|
|
}
|
|
}
|
|
|
|
/// prints feedback
|
|
if (empty($grade_grade->feedback) or (!$canviewhidden and $grade_grade->is_hidden())) {
|
|
$data[] = '<div class="'.$hidden.'feedbacktext"> </div>';
|
|
|
|
} else {
|
|
$data[] = '<div class="'.$hidden.'feedbacktext">'.format_text($grade_grade->feedback, $grade_grade->feedbackformat).'</div>';
|
|
}
|
|
|
|
$this->table->add_data($data);
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
/**
|
|
* 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) {
|
|
ob_start();
|
|
$this->table->print_html();
|
|
$html = ob_get_clean();
|
|
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).
|
|
*/
|
|
public function process_data($data) {
|
|
}
|
|
|
|
public 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->setHelpButton('report_user_showpercentage', array('showpercentage', get_string('showpercentage', 'grades'), 'grade'));
|
|
|
|
$options = array(-1 => get_string('default', 'grades'),
|
|
0 => get_string('hide'),
|
|
1 => get_string('showhiddenuntilonly', 'grades'),
|
|
2 => get_string('show'));
|
|
|
|
if (empty($CFG->grade_report_user_showhiddenitems)) {
|
|
$options[-1] = get_string('defaultprev', 'grades', $options[0]);
|
|
} else {
|
|
$options[-1] = get_string('defaultprev', 'grades', $options[1]);
|
|
}
|
|
|
|
$mform->addElement('select', 'report_user_showhiddenitems', get_string('showhiddenitems', 'grades'), $options);
|
|
$mform->setHelpButton('report_user_showhiddenitems', array('showhiddenitems', get_string('showhiddenitems', 'grades'), 'grade'));
|
|
}
|
|
|
|
function grade_report_user_profilereport($course, $user) {
|
|
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
|
|
print_heading(get_string('modulename', 'gradereport_user'). ' - '.fullname($report->user));
|
|
|
|
if ($report->fill_table()) {
|
|
echo $report->print_table(true);
|
|
}
|
|
echo '</div>';
|
|
}
|
|
}
|
|
|
|
?>
|