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 | |
30 | require_once($CFG->dirroot . '/grade/report/lib.php'); |
31 | require_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 | */ |
38 | class 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 | |
26ed0305 |
78 | $this->showrank = grade_get_setting($this->courseid, 'report_user_showrank', !empty($CFG->grade_report_user_showrank)); |
79 | $this->showhiddenitems = grade_get_setting($this->courseid, 'report_user_showhiddenitems', !empty($CFG->grade_report_user_showhiddenitems)); |
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.'&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 | |
26ed0305 |
176 | if (!$this->showhiddenitems and !$canviewhidden and $grade_item->is_hidden()) { |
02973505 |
177 | continue; |
178 | } |
179 | |
d1214909 |
180 | $class = 'gradeitem'; |
181 | if ($grade_item->is_course_item()) { |
182 | $class = 'courseitem'; |
183 | } else if ($grade_item->is_category_item()) { |
184 | $class = 'categoryitem'; |
185 | } |
186 | |
d297269d |
187 | if (in_array($itemid, $unknown)) { |
188 | $gradeval = null; |
189 | } else if (array_key_exists($itemid, $altered)) { |
190 | $gradeval = $altered[$itemid]; |
191 | } else { |
192 | $gradeval = $grade_grade->finalgrade; |
193 | } |
6391ebe7 |
194 | |
195 | $data = array(); |
f7998fbc |
196 | |
e0724506 |
197 | /// prints grade item name |
198 | if ($grade_item->is_course_item() or $grade_item->is_category_item()) { |
d1214909 |
199 | $data[] = '<span class="'.$class.'">'.$grade_item->get_name().'</span>'; |
e0724506 |
200 | } else { |
d1214909 |
201 | $data[] = '<span class="'.$class.'">'.$this->get_module_link($grade_item->get_name(), $grade_item->itemmodule, $grade_item->iteminstance).'</span>'; |
e0724506 |
202 | } |
f7998fbc |
203 | |
e0724506 |
204 | /// prints category |
205 | $cat = $grade_item->get_parent_category(); |
d1214909 |
206 | $data[] = '<span class="'.$class.'">'.$cat->get_name().'</span>'; |
4c8d9481 |
207 | |
e0724506 |
208 | /// prints the grade |
e0724506 |
209 | if ($grade_grade->is_excluded()) { |
210 | $excluded = get_string('excluded', 'grades').' '; |
211 | } else { |
212 | $excluded = ''; |
213 | } |
f7998fbc |
214 | |
b89a70ce |
215 | if ($grade_item->needsupdate) { |
d1214909 |
216 | $data[] = '<span class="'.$class.' gradingerror">'.get_string('error').'</span>'; |
b89a70ce |
217 | |
d297269d |
218 | } else if (!empty($CFG->grade_hiddenasdate) and !is_null($grade_grade->finalgrade) and !$canviewhidden and $grade_grade->is_hidden() |
219 | and !$grade_item->is_category_item() and !$grade_item->is_course_item()) { |
220 | // 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 |
221 | $data[] = '<span class="'.$class.' gradeddate">'.$excluded.get_string('gradedon', 'grades', userdate($grade_grade->timemodified, get_string('strftimedatetimeshort'))).'</span>'; |
6391ebe7 |
222 | |
e0724506 |
223 | } else { |
d1214909 |
224 | $data[] = '<span class="'.$class.'">'.$excluded.grade_format_gradevalue($gradeval, $grade_item, true); |
e0724506 |
225 | } |
226 | |
227 | /// prints percentage |
b89a70ce |
228 | if ($grade_item->needsupdate) { |
d1214909 |
229 | $data[] = '<span class="'.$class.'gradingerror">'.get_string('error').'</span>'; |
23207a1a |
230 | |
6391ebe7 |
231 | } else { |
d1214909 |
232 | $data[] = '<span class="'.$class.'">'.grade_format_gradevalue($gradeval, $grade_item, true, GRADE_DISPLAY_TYPE_PERCENTAGE).'</span>'; |
e0724506 |
233 | } |
6391ebe7 |
234 | |
e0724506 |
235 | /// prints rank |
26ed0305 |
236 | if ($this->showrank) { |
02973505 |
237 | // TODO: this is broken if hidden grades present!! |
238 | if ($grade_item->needsupdate) { |
d1214909 |
239 | $data[] = '<span class="'.$class.'gradingerror">'.get_string('error').'</span>'; |
26ed0305 |
240 | |
02973505 |
241 | } else if (is_null($gradeval)) { |
242 | // no grade, no rank |
d1214909 |
243 | $data[] = '<span class="'.$class.'">-</span>';; |
26ed0305 |
244 | |
02973505 |
245 | } else { |
246 | /// find the number of users with a higher grade |
247 | $sql = "SELECT COUNT(DISTINCT(userid)) |
248 | FROM {$CFG->prefix}grade_grades |
249 | WHERE finalgrade > {$grade_grade->finalgrade} |
250 | AND itemid = {$grade_item->id}"; |
251 | $rank = count_records_sql($sql) + 1; |
26ed0305 |
252 | |
d1214909 |
253 | $data[] = '<span class="'.$class.'">'."$rank/$numusers".'</span>'; |
02973505 |
254 | } |
f7998fbc |
255 | } |
256 | |
d1214909 |
257 | /// prints feedback |
258 | if (empty($grade_grade->feedback) or (!$canviewhidden and $grade_grade->is_hidden())) { |
259 | $data[] = '<div class="feedbacktext"> </div>'; |
6391ebe7 |
260 | |
261 | } else { |
d1214909 |
262 | $data[] = '<div class="feedbacktext">'.format_text($grade_grade->feedback, $grade_grade->feedbackformat).'</div>'; |
e0724506 |
263 | } |
6391ebe7 |
264 | |
e0724506 |
265 | $this->table->add_data($data); |
f7998fbc |
266 | } |
e0724506 |
267 | |
268 | return true; |
f7998fbc |
269 | } |
270 | |
271 | /** |
272 | * Prints or returns the HTML from the flexitable. |
273 | * @param bool $return Whether or not to return the data instead of printing it directly. |
274 | * @return string |
275 | */ |
276 | function print_table($return=false) { |
277 | ob_start(); |
278 | $this->table->print_html(); |
279 | $html = ob_get_clean(); |
280 | if ($return) { |
281 | return $html; |
282 | } else { |
283 | echo $html; |
284 | } |
285 | } |
286 | |
287 | /** |
288 | * Processes the data sent by the form (grades and feedbacks). |
289 | * @var array $data |
290 | * @return bool Success or Failure (array of errors). |
291 | */ |
292 | function process_data($data) { |
293 | } |
26ed0305 |
294 | } |
295 | |
296 | function grade_report_user_settings_definition(&$mform) { |
297 | global $CFG; |
298 | |
299 | $options = array(-1 => get_string('default', 'grades'), |
300 | 0 => get_string('hide'), |
301 | 1 => get_string('show')); |
302 | |
cd52d909 |
303 | if (empty($CFG->grade_report_user_showrank)) { |
26ed0305 |
304 | $options[-1] = get_string('defaultprev', 'grades', $options[0]); |
305 | } else { |
306 | $options[-1] = get_string('defaultprev', 'grades', $options[1]); |
307 | } |
308 | |
309 | $mform->addElement('select', 'report_user_showrank', get_string('showrank', 'grades'), $options); |
310 | $mform->setHelpButton('report_user_showrank', array(false, get_string('showrank', 'grades'), |
311 | false, true, false, get_string('configshowrank', 'grades'))); |
312 | |
313 | |
314 | $options = array(-1 => get_string('default', 'grades'), |
315 | 0 => get_string('hide'), |
316 | 1 => get_string('show')); |
317 | |
cd52d909 |
318 | if (empty($CFG->grade_report_user_showhiddenitems)) { |
26ed0305 |
319 | $options[-1] = get_string('defaultprev', 'grades', $options[0]); |
320 | } else { |
321 | $options[-1] = get_string('defaultprev', 'grades', $options[1]); |
322 | } |
323 | |
324 | $mform->addElement('select', 'report_user_showhiddenitems', get_string('showhiddenitems', 'grades'), $options); |
325 | $mform->setHelpButton('report_user_showhiddenitems', array(false, get_string('showhiddenitems', 'grades'), |
326 | false, true, false, get_string('configshowhiddenitems', 'grades'))); |
0a784551 |
327 | } |
328 | |
329 | function grade_report_user_profilereport($course, $user) { |
330 | if (!empty($course->showgrades)) { |
331 | |
332 | $context = get_context_instance(CONTEXT_COURSE, $course->id); |
333 | |
334 | //first make sure we have proper final grades - this must be done before constructing of the grade tree |
335 | grade_regrade_final_grades($course->id); |
336 | |
337 | /// return tracking object |
338 | $gpr = new grade_plugin_return(array('type'=>'report', 'plugin'=>'user', 'courseid'=>$course->id, 'userid'=>$user->id)); |
339 | // Create a report instance |
340 | $report = new grade_report_user($course->id, $gpr, $context, $user->id); |
f7998fbc |
341 | |
0a784551 |
342 | // print the page |
343 | echo '<div class="grade-report-user">'; // css fix to share styles with real report page |
344 | print_heading(get_string('modulename', 'gradereport_user'). ' - '.fullname($report->user)); |
345 | |
346 | if ($report->fill_table()) { |
347 | echo $report->print_table(true); |
348 | } |
349 | echo '</div>'; |
350 | } |
f7998fbc |
351 | } |
0a784551 |
352 | |
f7998fbc |
353 | ?> |