MDL-11718 course settings for reports - for now only user report (rank and showing...
[moodle.git] / grade / report / user / lib.php
1 <?php // $Id$
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 ///////////////////////////////////////////////////////////////////////////
25 /**
26  * File in which the user_report class is defined.
27  * @package gradebook
28  */
30 require_once($CFG->dirroot . '/grade/report/lib.php');
31 require_once($CFG->libdir.'/tablelib.php');
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 {
40     /**
41      * The user.
42      * @var object $user
43      */
44     var $user;
46     /**
47      * A flexitable to hold the data.
48      * @var object $table
49      */
50     var $table;
52     /**
53      * Flat structure similar to grade tree
54      */
55     var $gseq;
57     /**
58      * show student ranks
59      */
60     var $showrank;
62     /**
63      * Show hidden items even when user does not have required cap
64      */
65     var $showhiddenitems;
67     /**
68      * Constructor. Sets local copies of user preferences and initialises grade_tree.
69      * @param int $courseid
70      * @param object $gpr grade plugin return tracking object
71      * @param string $context
72      * @param int $userid The id of the user
73      */
74     function grade_report_user($courseid, $gpr, $context, $userid) {
75         global $CFG;
76         parent::grade_report($courseid, $gpr, $context);
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));
81         $switch = grade_get_setting($this->courseid, 'aggregationposition', $CFG->grade_aggregationposition);
83         // Grab the grade_tree for this course
84         $this->gseq = new grade_seq($this->courseid, $switch);
86         // get the user (for full name)
87         $this->user = get_record('user', 'id', $userid);
89         // base url for sorting by first/last name
90         $this->baseurl = $CFG->wwwroot.'/grade/report?id='.$courseid.'&amp;userid='.$userid;
91         $this->pbarurl = $this->baseurl;
93         // always setup groups - no user preference here
94         $this->setup_groups();
96         $this->setup_table();
97     }
99     /**
100      * Prepares the headers and attributes of the flexitable.
101      */
102     function setup_table() {
103         global $CFG;
104         /*
105         * Table has 5-6 columns
106         *| pic  | itemname/description | grade (grade_final) | percentage | rank (optional) | feedback |
107         */
109         // setting up table headers
110         if ($this->showrank) {
111             // TODO: this is broken if hidden grades present!!
112             $tablecolumns = array('itemname', 'category', 'grade', 'percentage', 'rank', 'feedback');
113             $tableheaders = array($this->get_lang_string('gradeitem', 'grades'), $this->get_lang_string('category'), $this->get_lang_string('grade'),
114                 $this->get_lang_string('percent', 'grades'), $this->get_lang_string('rank', 'grades'),
115                 $this->get_lang_string('feedback'));
116         } else {
117             $tablecolumns = array('itemname', 'category', 'grade', 'percentage', 'feedback');
118             $tableheaders = array($this->get_lang_string('gradeitem', 'grades'), $this->get_lang_string('category'), $this->get_lang_string('grade'),
119                 $this->get_lang_string('percent', 'grades'), $this->get_lang_string('feedback'));
120         }
122         $this->table = new flexible_table('grade-report-user-'.$this->courseid);
124         $this->table->define_columns($tablecolumns);
125         $this->table->define_headers($tableheaders);
126         $this->table->define_baseurl($this->baseurl);
128         $this->table->set_attribute('cellspacing', '0');
129         $this->table->set_attribute('id', 'user-grade');
130         $this->table->set_attribute('class', 'boxaligncenter generaltable');
132         // not sure tables should be sortable or not, because if we allow it then sorted resutls distort grade category structure and sortorder
133         $this->table->set_control_variables(array(
134                 TABLE_VAR_SORT    => 'ssort',
135                 TABLE_VAR_HIDE    => 'shide',
136                 TABLE_VAR_SHOW    => 'sshow',
137                 TABLE_VAR_IFIRST  => 'sifirst',
138                 TABLE_VAR_ILAST   => 'silast',
139                 TABLE_VAR_PAGE    => 'spage'
140                 ));
142         $this->table->setup();
143     }
145     function fill_table() {
146         global $CFG;
147         $numusers = $this->get_numusers(false); // total course users
148         $items =& $this->gseq->items;
149         $grades = array();
151         $canviewhidden = has_capability('moodle/grade:viewhidden', get_context_instance(CONTEXT_COURSE, $this->courseid));
153         // fetch or create all grades
154         foreach ($items as $key=>$unused) {
155             if (!$grade_grade = grade_grade::fetch(array('itemid'=>$items[$key]->id, 'userid'=>$this->user->id))) {
156                 $grade_grade = new grade_grade();
157                 $grade_grade->userid = $this->user->id;
158                 $grade_grade->itemid = $items[$key]->id;
159             }
160             $grades[$key] = $grade_grade;
161             $grades[$key]->grade_item =& $items[$key];
162         }
164         if ($canviewhidden) {
165             $altered = array();
166             $unknown = array();
167         } else {
168             $hiding_affected = grade_grade::get_hiding_affected($grades, $items);
169             $altered = $hiding_affected['altered'];
170             $unknown = $hiding_affected['unknown'];
171             unset($hiding_affected);
172         }
174         foreach ($items as $itemid=>$unused) {
175             $grade_item  =& $items[$itemid];
176             $grade_grade =& $grades[$itemid];
178             if (!$this->showhiddenitems and !$canviewhidden and $grade_item->is_hidden()) {
179                 continue;
180             }
182             if (in_array($itemid, $unknown)) {
183                 $gradeval = null;
184             } else if (array_key_exists($itemid, $altered)) {
185                 $gradeval = $altered[$itemid];
186             } else {
187                 $gradeval = $grade_grade->finalgrade;
188             }
190             $data = array();
192             /// prints grade item name
193             if ($grade_item->is_course_item() or $grade_item->is_category_item()) {
194                 $data[] = '<div class="catname">'.$grade_item->get_name().'</div>';
195             } else {
196                 $data[] = '<div class="itemname">'.$this->get_module_link($grade_item->get_name(), $grade_item->itemmodule, $grade_item->iteminstance).'</div>';
197             }
199             /// prints category
200             $cat = $grade_item->get_parent_category();
201             $data[] = $cat->get_name();
203             /// prints the grade
204             if ($grade_grade->is_excluded()) {
205                 $excluded = get_string('excluded', 'grades').' ';
206             } else {
207                 $excluded = '';
208             }
210             if ($grade_item->needsupdate) {
211                 $data[] = '<span class="gradingerror">'.get_string('error').'</span>';
213             } else if (!empty($CFG->grade_hiddenasdate) and !is_null($grade_grade->finalgrade) and !$canviewhidden and $grade_grade->is_hidden()
214                    and !$grade_item->is_category_item() and !$grade_item->is_course_item()) {
215                 // 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
216                 $data[] = $excluded . '<div class="gradeddate">'.get_string('gradedon', 'grades', userdate($grade_grade->timemodified, get_string('strftimedatetimeshort'))).'</div>';
218             } else {
219                 $data[] = $excluded . grade_format_gradevalue($gradeval, $grade_item, true);
220             }
222             /// prints percentage
223             if ($grade_item->needsupdate) {
224                 $data[] = '<span class="gradingerror">'.get_string('error').'</span>';
226             } else {
227                 $data[] = grade_format_gradevalue($gradeval, $grade_item, true, GRADE_DISPLAY_TYPE_PERCENTAGE);
228             }
230             /// prints rank
231             if ($this->showrank) {
232                 // TODO: this is broken if hidden grades present!!
233                 if ($grade_item->needsupdate) {
234                     $data[] = '<span class="gradingerror">'.get_string('error').'</span>';
236                 } else if (is_null($gradeval)) {
237                     // no grade, no rank
238                     $data[] = '-';
240                 } else {
241                     /// find the number of users with a higher grade
242                     $sql = "SELECT COUNT(DISTINCT(userid))
243                               FROM {$CFG->prefix}grade_grades
244                              WHERE finalgrade > {$grade_grade->finalgrade}
245                                    AND itemid = {$grade_item->id}";
246                     $rank = count_records_sql($sql) + 1;
248                     $data[] = "$rank/$numusers";
249                 }
250             }
252             /// prints notes
253             if (empty($grade_grade->feedback)) {
254                 $data[] = '&nbsp;';
256             } else if (!$canviewhidden and $grade_grade->is_hidden()) {
257                 $data[] = '&nbsp;';
259             } else {
260                 $data[] = format_text($grade_grade->feedback, $grade_grade->feedbackformat);
261             }
263             $this->table->add_data($data);
264         }
266         return true;
267     }
269     /**
270      * Prints or returns the HTML from the flexitable.
271      * @param bool $return Whether or not to return the data instead of printing it directly.
272      * @return string
273      */
274     function print_table($return=false) {
275         ob_start();
276         $this->table->print_html();
277         $html = ob_get_clean();
278         if ($return) {
279             return $html;
280         } else {
281             echo $html;
282         }
283     }
285     /**
286      * Processes the data sent by the form (grades and feedbacks).
287      * @var array $data
288      * @return bool Success or Failure (array of errors).
289      */
290     function process_data($data) {
291     }
294 function grade_report_user_settings_definition(&$mform) {
295     global $CFG;
297     $options = array(-1 => get_string('default', 'grades'),
298                       0 => get_string('hide'),
299                       1 => get_string('show'));
301     if (empty($CFG->grade_userreport_showrank)) {
302         $options[-1] = get_string('defaultprev', 'grades', $options[0]);
303     } else {
304         $options[-1] = get_string('defaultprev', 'grades', $options[1]);
305     }
307     $mform->addElement('select', 'report_user_showrank', get_string('showrank', 'grades'), $options);
308     $mform->setHelpButton('report_user_showrank', array(false, get_string('showrank', 'grades'),
309                           false, true, false, get_string('configshowrank', 'grades')));
312     $options = array(-1 => get_string('default', 'grades'),
313                       0 => get_string('hide'),
314                       1 => get_string('show'));
316     if (empty($CFG->grade_userreport_showrank)) {
317         $options[-1] = get_string('defaultprev', 'grades', $options[0]);
318     } else {
319         $options[-1] = get_string('defaultprev', 'grades', $options[1]);
320     }
322     $mform->addElement('select', 'report_user_showhiddenitems', get_string('showhiddenitems', 'grades'), $options);
323     $mform->setHelpButton('report_user_showhiddenitems', array(false, get_string('showhiddenitems', 'grades'),
324                           false, true, false, get_string('configshowhiddenitems', 'grades')));
327 ?>