Test for empty dataset to suppress a warning
[moodle.git] / grade / report / user / lib.php
CommitLineData
f7998fbc 1<?php // $Id$
8ad36f4c 2
3///////////////////////////////////////////////////////////////////////////
4// //
5// NOTICE OF COPYRIGHT //
6// //
7// Moodle - Modular Object-Oriented Dynamic Learning Environment //
8// http://moodle.com //
9// //
10// Copyright (C) 1999 onwards Martin Dougiamas http://moodle.com //
11// //
12// This program is free software; you can redistribute it and/or modify //
13// it under the terms of the GNU General Public License as published by //
14// the Free Software Foundation; either version 2 of the License, or //
15// (at your option) any later version. //
16// //
17// This program is distributed in the hope that it will be useful, //
18// but WITHOUT ANY WARRANTY; without even the implied warranty of //
19// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the //
20// GNU General Public License for more details: //
21// //
22// http://www.gnu.org/copyleft/gpl.html //
23// //
24///////////////////////////////////////////////////////////////////////////
f7998fbc 25/**
26 * File in which the user_report class is defined.
27 * @package gradebook
28 */
29
30require_once($CFG->dirroot . '/grade/report/lib.php');
31require_once($CFG->libdir.'/tablelib.php');
32
33/**
34 * Class providing an API for the user report building and displaying.
35 * @uses grade_report
36 * @package gradebook
37 */
38class grade_report_user extends grade_report {
39
40 /**
41 * The user.
42 * @var object $user
43 */
44 var $user;
45
46 /**
47 * A flexitable to hold the data.
48 * @var object $table
49 */
50 var $table;
51
e0724506 52 /**
53 * Flat structure similar to grade tree
54 */
55 var $gseq;
56
26ed0305 57 /**
58 * show student ranks
59 */
60 var $showrank;
61
62 /**
63 * Show hidden items even when user does not have required cap
64 */
65 var $showhiddenitems;
66
f7998fbc 67 /**
68 * Constructor. Sets local copies of user preferences and initialises grade_tree.
69 * @param int $courseid
d30c4481 70 * @param object $gpr grade plugin return tracking object
f7998fbc 71 * @param string $context
72 * @param int $userid The id of the user
73 */
d30c4481 74 function grade_report_user($courseid, $gpr, $context, $userid) {
f7998fbc 75 global $CFG;
d30c4481 76 parent::grade_report($courseid, $gpr, $context);
f7998fbc 77
597f50e6 78 $this->showrank = grade_get_setting($this->courseid, 'report_user_showrank', $CFG->grade_report_user_showrank);
79 $this->showhiddenitems = grade_get_setting($this->courseid, 'report_user_showhiddenitems', $CFG->grade_report_user_showhiddenitems);
26ed0305 80
e0724506 81 $switch = grade_get_setting($this->courseid, 'aggregationposition', $CFG->grade_aggregationposition);
82
d1214909 83 // Grab the grade_seq for this course
e0724506 84 $this->gseq = new grade_seq($this->courseid, $switch);
4faf5f99 85
f7998fbc 86 // get the user (for full name)
87 $this->user = get_record('user', 'id', $userid);
88
89 // base url for sorting by first/last name
90 $this->baseurl = $CFG->wwwroot.'/grade/report?id='.$courseid.'&amp;userid='.$userid;
90d3960c 91 $this->pbarurl = $this->baseurl;
f7998fbc 92
d1214909 93 // no groups on this report - rank is from all course users
90d3960c 94 $this->setup_table();
f7998fbc 95 }
96
97 /**
98 * Prepares the headers and attributes of the flexitable.
99 */
100 function setup_table() {
02973505 101 global $CFG;
f7998fbc 102 /*
d1214909 103 * Table has 5-6 columns
104 *| itemname/description | final grade | percentage final grade | rank (optional) | feedback |
105 */
f7998fbc 106
107 // setting up table headers
26ed0305 108 if ($this->showrank) {
02973505 109 // TODO: this is broken if hidden grades present!!
110 $tablecolumns = array('itemname', 'category', 'grade', 'percentage', 'rank', 'feedback');
111 $tableheaders = array($this->get_lang_string('gradeitem', 'grades'), $this->get_lang_string('category'), $this->get_lang_string('grade'),
112 $this->get_lang_string('percent', 'grades'), $this->get_lang_string('rank', 'grades'),
113 $this->get_lang_string('feedback'));
114 } else {
115 $tablecolumns = array('itemname', 'category', 'grade', 'percentage', 'feedback');
116 $tableheaders = array($this->get_lang_string('gradeitem', 'grades'), $this->get_lang_string('category'), $this->get_lang_string('grade'),
117 $this->get_lang_string('percent', 'grades'), $this->get_lang_string('feedback'));
118 }
f7998fbc 119
120 $this->table = new flexible_table('grade-report-user-'.$this->courseid);
121
122 $this->table->define_columns($tablecolumns);
123 $this->table->define_headers($tableheaders);
124 $this->table->define_baseurl($this->baseurl);
125
126 $this->table->set_attribute('cellspacing', '0');
127 $this->table->set_attribute('id', 'user-grade');
128 $this->table->set_attribute('class', 'boxaligncenter generaltable');
129
cd52d909 130 // not sure tables should be sortable or not, because if we allow it then sorted results distort grade category structure and sortorder
f7998fbc 131 $this->table->set_control_variables(array(
132 TABLE_VAR_SORT => 'ssort',
133 TABLE_VAR_HIDE => 'shide',
134 TABLE_VAR_SHOW => 'sshow',
135 TABLE_VAR_IFIRST => 'sifirst',
136 TABLE_VAR_ILAST => 'silast',
137 TABLE_VAR_PAGE => 'spage'
138 ));
139
140 $this->table->setup();
141 }
142
143 function fill_table() {
144 global $CFG;
6ef84f6f 145 $numusers = $this->get_numusers(false); // total course users
6391ebe7 146 $items =& $this->gseq->items;
147 $grades = array();
f7998fbc 148
b89a70ce 149 $canviewhidden = has_capability('moodle/grade:viewhidden', get_context_instance(CONTEXT_COURSE, $this->courseid));
f7998fbc 150
4c8893ed 151 // fetch or create all grades
6391ebe7 152 foreach ($items as $key=>$unused) {
4c8893ed 153 if (!$grade_grade = grade_grade::fetch(array('itemid'=>$items[$key]->id, 'userid'=>$this->user->id))) {
154 $grade_grade = new grade_grade();
155 $grade_grade->userid = $this->user->id;
156 $grade_grade->itemid = $items[$key]->id;
157 }
6391ebe7 158 $grades[$key] = $grade_grade;
4c8893ed 159 $grades[$key]->grade_item =& $items[$key];
6391ebe7 160 }
161
b89a70ce 162 if ($canviewhidden) {
d297269d 163 $altered = array();
164 $unknown = array();
b89a70ce 165 } else {
166 $hiding_affected = grade_grade::get_hiding_affected($grades, $items);
d297269d 167 $altered = $hiding_affected['altered'];
168 $unknown = $hiding_affected['unknown'];
169 unset($hiding_affected);
b89a70ce 170 }
6391ebe7 171
d297269d 172 foreach ($items as $itemid=>$unused) {
173 $grade_item =& $items[$itemid];
174 $grade_grade =& $grades[$itemid];
175
597f50e6 176 if (!$canviewhidden and $grade_item->is_hidden()) {
177 if ($this->showhiddenitems == 0) {
178 // no hidden items at all
179 continue;
180 } else if ($this->showhiddenitems == 1 and !$grade_item->is_hiddenuntil()) {
181 // hidden until that are still hidden are visible
182 continue;
183 }
02973505 184 }
185
d1214909 186 $class = 'gradeitem';
187 if ($grade_item->is_course_item()) {
188 $class = 'courseitem';
189 } else if ($grade_item->is_category_item()) {
190 $class = 'categoryitem';
191 }
192
d297269d 193 if (in_array($itemid, $unknown)) {
194 $gradeval = null;
195 } else if (array_key_exists($itemid, $altered)) {
196 $gradeval = $altered[$itemid];
197 } else {
198 $gradeval = $grade_grade->finalgrade;
199 }
6391ebe7 200
201 $data = array();
f7998fbc 202
e0724506 203 /// prints grade item name
204 if ($grade_item->is_course_item() or $grade_item->is_category_item()) {
d1214909 205 $data[] = '<span class="'.$class.'">'.$grade_item->get_name().'</span>';
e0724506 206 } else {
d1214909 207 $data[] = '<span class="'.$class.'">'.$this->get_module_link($grade_item->get_name(), $grade_item->itemmodule, $grade_item->iteminstance).'</span>';
e0724506 208 }
f7998fbc 209
e0724506 210 /// prints category
211 $cat = $grade_item->get_parent_category();
d1214909 212 $data[] = '<span class="'.$class.'">'.$cat->get_name().'</span>';
4c8d9481 213
e0724506 214 /// prints the grade
e0724506 215 if ($grade_grade->is_excluded()) {
216 $excluded = get_string('excluded', 'grades').' ';
217 } else {
218 $excluded = '';
219 }
f7998fbc 220
b89a70ce 221 if ($grade_item->needsupdate) {
d1214909 222 $data[] = '<span class="'.$class.' gradingerror">'.get_string('error').'</span>';
b89a70ce 223
d297269d 224 } else if (!empty($CFG->grade_hiddenasdate) and !is_null($grade_grade->finalgrade) and !$canviewhidden and $grade_grade->is_hidden()
225 and !$grade_item->is_category_item() and !$grade_item->is_course_item()) {
226 // 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
d1214909 227 $data[] = '<span class="'.$class.' gradeddate">'.$excluded.get_string('gradedon', 'grades', userdate($grade_grade->timemodified, get_string('strftimedatetimeshort'))).'</span>';
6391ebe7 228
e0724506 229 } else {
d1214909 230 $data[] = '<span class="'.$class.'">'.$excluded.grade_format_gradevalue($gradeval, $grade_item, true);
e0724506 231 }
232
233 /// prints percentage
b89a70ce 234 if ($grade_item->needsupdate) {
d1214909 235 $data[] = '<span class="'.$class.'gradingerror">'.get_string('error').'</span>';
23207a1a 236
6391ebe7 237 } else {
d1214909 238 $data[] = '<span class="'.$class.'">'.grade_format_gradevalue($gradeval, $grade_item, true, GRADE_DISPLAY_TYPE_PERCENTAGE).'</span>';
e0724506 239 }
6391ebe7 240
e0724506 241 /// prints rank
26ed0305 242 if ($this->showrank) {
02973505 243 // TODO: this is broken if hidden grades present!!
244 if ($grade_item->needsupdate) {
d1214909 245 $data[] = '<span class="'.$class.'gradingerror">'.get_string('error').'</span>';
26ed0305 246
02973505 247 } else if (is_null($gradeval)) {
248 // no grade, no rank
d1214909 249 $data[] = '<span class="'.$class.'">-</span>';;
26ed0305 250
02973505 251 } else {
252 /// find the number of users with a higher grade
253 $sql = "SELECT COUNT(DISTINCT(userid))
254 FROM {$CFG->prefix}grade_grades
255 WHERE finalgrade > {$grade_grade->finalgrade}
256 AND itemid = {$grade_item->id}";
257 $rank = count_records_sql($sql) + 1;
26ed0305 258
d1214909 259 $data[] = '<span class="'.$class.'">'."$rank/$numusers".'</span>';
02973505 260 }
f7998fbc 261 }
262
d1214909 263 /// prints feedback
264 if (empty($grade_grade->feedback) or (!$canviewhidden and $grade_grade->is_hidden())) {
265 $data[] = '<div class="feedbacktext">&nbsp;</div>';
6391ebe7 266
267 } else {
d1214909 268 $data[] = '<div class="feedbacktext">'.format_text($grade_grade->feedback, $grade_grade->feedbackformat).'</div>';
e0724506 269 }
6391ebe7 270
e0724506 271 $this->table->add_data($data);
f7998fbc 272 }
e0724506 273
274 return true;
f7998fbc 275 }
276
277 /**
278 * Prints or returns the HTML from the flexitable.
279 * @param bool $return Whether or not to return the data instead of printing it directly.
280 * @return string
281 */
282 function print_table($return=false) {
283 ob_start();
284 $this->table->print_html();
285 $html = ob_get_clean();
286 if ($return) {
287 return $html;
288 } else {
289 echo $html;
290 }
291 }
292
293 /**
294 * Processes the data sent by the form (grades and feedbacks).
295 * @var array $data
296 * @return bool Success or Failure (array of errors).
297 */
298 function process_data($data) {
299 }
26ed0305 300}
301
302function grade_report_user_settings_definition(&$mform) {
303 global $CFG;
304
305 $options = array(-1 => get_string('default', 'grades'),
306 0 => get_string('hide'),
307 1 => get_string('show'));
308
cd52d909 309 if (empty($CFG->grade_report_user_showrank)) {
26ed0305 310 $options[-1] = get_string('defaultprev', 'grades', $options[0]);
311 } else {
312 $options[-1] = get_string('defaultprev', 'grades', $options[1]);
313 }
314
315 $mform->addElement('select', 'report_user_showrank', get_string('showrank', 'grades'), $options);
316 $mform->setHelpButton('report_user_showrank', array(false, get_string('showrank', 'grades'),
317 false, true, false, get_string('configshowrank', 'grades')));
318
319
320 $options = array(-1 => get_string('default', 'grades'),
321 0 => get_string('hide'),
597f50e6 322 1 => get_string('showhiddenuntilonly', 'grades'),
323 2 => get_string('show'));
26ed0305 324
cd52d909 325 if (empty($CFG->grade_report_user_showhiddenitems)) {
26ed0305 326 $options[-1] = get_string('defaultprev', 'grades', $options[0]);
327 } else {
328 $options[-1] = get_string('defaultprev', 'grades', $options[1]);
329 }
330
331 $mform->addElement('select', 'report_user_showhiddenitems', get_string('showhiddenitems', 'grades'), $options);
332 $mform->setHelpButton('report_user_showhiddenitems', array(false, get_string('showhiddenitems', 'grades'),
333 false, true, false, get_string('configshowhiddenitems', 'grades')));
0a784551 334}
335
336function grade_report_user_profilereport($course, $user) {
337 if (!empty($course->showgrades)) {
338
339 $context = get_context_instance(CONTEXT_COURSE, $course->id);
340
341 //first make sure we have proper final grades - this must be done before constructing of the grade tree
342 grade_regrade_final_grades($course->id);
343
344 /// return tracking object
345 $gpr = new grade_plugin_return(array('type'=>'report', 'plugin'=>'user', 'courseid'=>$course->id, 'userid'=>$user->id));
346 // Create a report instance
347 $report = new grade_report_user($course->id, $gpr, $context, $user->id);
f7998fbc 348
0a784551 349 // print the page
350 echo '<div class="grade-report-user">'; // css fix to share styles with real report page
351 print_heading(get_string('modulename', 'gradereport_user'). ' - '.fullname($report->user));
352
353 if ($report->fill_table()) {
354 echo $report->print_table(true);
355 }
356 echo '</div>';
357 }
f7998fbc 358}
0a784551 359
f7998fbc 360?>