e060e33d |
1 | <?php |
2 | |
3 | // This file is part of Moodle - http://moodle.org/ |
4 | // |
5 | // Moodle is free software: you can redistribute it and/or modify |
6 | // it under the terms of the GNU General Public License as published by |
7 | // the Free Software Foundation, either version 3 of the License, or |
8 | // (at your option) any later version. |
9 | // |
10 | // Moodle is distributed in the hope that it will be useful, |
11 | // but WITHOUT ANY WARRANTY; without even the implied warranty of |
12 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
13 | // GNU General Public License for more details. |
14 | // |
15 | // You should have received a copy of the GNU General Public License |
16 | // along with Moodle. If not, see <http://www.gnu.org/licenses/>. |
8ad36f4c |
17 | |
38b9e8a8 |
18 | /** |
eea6690a |
19 | * File containing the grade_report class. |
20 | * @package gradebook |
38b9e8a8 |
21 | */ |
eea6690a |
22 | |
23 | require_once($CFG->libdir.'/gradelib.php'); |
24 | |
25 | /** |
26 | * An abstract class containing variables and methods used by all or most reports. |
27 | * @abstract |
28 | * @package gradebook |
29 | */ |
d24832f9 |
30 | abstract class grade_report { |
eea6690a |
31 | /** |
32 | * The courseid. |
33 | * @var int $courseid |
34 | */ |
d24832f9 |
35 | public $courseid; |
eea6690a |
36 | |
b2bc96d1 |
37 | /** |
38 | * The course. |
39 | * @var object $course |
40 | */ |
d24832f9 |
41 | public $course; |
b2bc96d1 |
42 | |
d30c4481 |
43 | /** Grade plugin return tracking object. |
4889285b |
44 | * @var object $gpr |
45 | */ |
46 | public $gpr; |
d30c4481 |
47 | |
eea6690a |
48 | /** |
49 | * The context. |
50 | * @var int $context |
51 | */ |
d24832f9 |
52 | public $context; |
eea6690a |
53 | |
54 | /** |
55 | * The grade_tree object. |
56 | * @var object $gtree |
57 | */ |
d24832f9 |
58 | public $gtree; |
eea6690a |
59 | |
60 | /** |
61 | * User preferences related to this report. |
e50ce569 |
62 | * @var array $prefs |
eea6690a |
63 | */ |
d24832f9 |
64 | public $prefs = array(); |
eea6690a |
65 | |
66 | /** |
67 | * The roles for this report. |
68 | * @var string $gradebookroles |
69 | */ |
d24832f9 |
70 | public $gradebookroles; |
eea6690a |
71 | |
72 | /** |
73 | * base url for sorting by first/last name. |
74 | * @var string $baseurl |
75 | */ |
d24832f9 |
76 | public $baseurl; |
eea6690a |
77 | |
78 | /** |
79 | * base url for paging. |
80 | * @var string $pbarurl |
81 | */ |
d24832f9 |
82 | public $pbarurl; |
eea6690a |
83 | |
84 | /** |
85 | * Current page (for paging). |
86 | * @var int $page |
87 | */ |
d24832f9 |
88 | public $page; |
eea6690a |
89 | |
388234f4 |
90 | /** |
91 | * Array of cached language strings (using get_string() all the time takes a long time!). |
92 | * @var array $lang_strings |
93 | */ |
d24832f9 |
94 | public $lang_strings = array(); |
388234f4 |
95 | |
90d3960c |
96 | //// GROUP VARIABLES (including SQL) |
97 | |
98 | /** |
99 | * The current group being displayed. |
100 | * @var int $currentgroup |
101 | */ |
d24832f9 |
102 | public $currentgroup; |
90d3960c |
103 | |
35079f53 |
104 | /** |
105 | * Current course group mode |
106 | * @var int $groupmode |
107 | */ |
108 | var $groupmode; |
109 | |
90d3960c |
110 | /** |
111 | * A HTML select element used to select the current group. |
112 | * @var string $group_selector |
113 | */ |
d24832f9 |
114 | public $group_selector; |
90d3960c |
115 | |
116 | /** |
117 | * An SQL fragment used to add linking information to the group tables. |
118 | * @var string $groupsql |
119 | */ |
d24832f9 |
120 | protected $groupsql; |
90d3960c |
121 | |
122 | /** |
123 | * An SQL constraint to append to the queries used by this object to build the report. |
124 | * @var string $groupwheresql |
125 | */ |
d24832f9 |
126 | protected $groupwheresql; |
127 | |
128 | /** |
129 | * The ordered params for $groupwheresql |
130 | * @var array $groupwheresql_params |
131 | */ |
132 | protected $groupwheresql_params = array(); |
90d3960c |
133 | |
134 | |
eea6690a |
135 | /** |
136 | * Constructor. Sets local copies of user preferences and initialises grade_tree. |
137 | * @param int $courseid |
d30c4481 |
138 | * @param object $gpr grade plugin return tracking object |
eea6690a |
139 | * @param string $context |
140 | * @param int $page The current page being viewed (when report is paged) |
141 | */ |
d24832f9 |
142 | public function __construct($courseid, $gpr, $context, $page=null) { |
5c75a0a3 |
143 | global $CFG, $COURSE, $DB; |
eea6690a |
144 | |
dde8e548 |
145 | if (empty($CFG->gradebookroles)) { |
771dc7b2 |
146 | print_error('norolesdefined', 'grades'); |
0893aa30 |
147 | } |
284abb09 |
148 | |
0893aa30 |
149 | |
4faf5f99 |
150 | $this->courseid = $courseid; |
b2bc96d1 |
151 | if ($this->courseid == $COURSE->id) { |
152 | $this->course = $COURSE; |
153 | } else { |
5c75a0a3 |
154 | $this->course = $DB->get_record('course', array('id' => $this->courseid)); |
b2bc96d1 |
155 | } |
41f22daa |
156 | |
4faf5f99 |
157 | $this->gpr = $gpr; |
158 | $this->context = $context; |
159 | $this->page = $page; |
eea6690a |
160 | |
161 | // roles to be displayed in the gradebook |
162 | $this->gradebookroles = $CFG->gradebookroles; |
163 | |
dc482cfa |
164 | // Set up link to preferences page |
165 | $this->preferences_page = $CFG->wwwroot.'/grade/report/grader/preferences.php?id='.$courseid; |
166 | |
4faf5f99 |
167 | // init gtree in child class |
38b9e8a8 |
168 | } |
169 | |
eea6690a |
170 | /** |
171 | * Given the name of a user preference (without grade_report_ prefix), locally saves then returns |
172 | * the value of that preference. If the preference has already been fetched before, |
173 | * the saved value is returned. If the preference is not set at the User level, the $CFG equivalent |
174 | * is given (site default). |
501e0e34 |
175 | * @static (Can be called statically, but then doesn't benefit from caching) |
eea6690a |
176 | * @param string $pref The name of the preference (do not include the grade_report_ prefix) |
8c5a416e |
177 | * @param int $objectid An optional itemid or categoryid to check for a more fine-grained preference |
eea6690a |
178 | * @return mixed The value of the preference |
179 | */ |
d24832f9 |
180 | public function get_pref($pref, $objectid=null) { |
eea6690a |
181 | global $CFG; |
501e0e34 |
182 | $fullprefname = 'grade_report_' . $pref; |
54294d3b |
183 | $shortprefname = 'grade_' . $pref; |
38b9e8a8 |
184 | |
e50ce569 |
185 | $retval = null; |
186 | |
438a5aa9 |
187 | if (!isset($this) OR get_class($this) != 'grade_report') { |
8c5a416e |
188 | if (!empty($objectid)) { |
189 | $retval = get_user_preferences($fullprefname . $objectid, grade_report::get_pref($pref)); |
54294d3b |
190 | } elseif (isset($CFG->$fullprefname)) { |
e50ce569 |
191 | $retval = get_user_preferences($fullprefname, $CFG->$fullprefname); |
54294d3b |
192 | } elseif (isset($CFG->$shortprefname)) { |
d24832f9 |
193 | $retval = get_user_preferences($fullprefname, $CFG->$shortprefname); |
54294d3b |
194 | } else { |
195 | $retval = null; |
bb384a8e |
196 | } |
501e0e34 |
197 | } else { |
8c5a416e |
198 | if (empty($this->prefs[$pref.$objectid])) { |
e50ce569 |
199 | |
8c5a416e |
200 | if (!empty($objectid)) { |
201 | $retval = get_user_preferences($fullprefname . $objectid); |
e50ce569 |
202 | if (empty($retval)) { |
203 | // No item pref found, we are returning the global preference |
204 | $retval = $this->get_pref($pref); |
8c5a416e |
205 | $objectid = null; |
e50ce569 |
206 | } |
501e0e34 |
207 | } else { |
e50ce569 |
208 | $retval = get_user_preferences($fullprefname, $CFG->$fullprefname); |
501e0e34 |
209 | } |
8c5a416e |
210 | $this->prefs[$pref.$objectid] = $retval; |
e50ce569 |
211 | } else { |
8c5a416e |
212 | $retval = $this->prefs[$pref.$objectid]; |
501e0e34 |
213 | } |
eea6690a |
214 | } |
e50ce569 |
215 | |
216 | return $retval; |
eea6690a |
217 | } |
bb384a8e |
218 | |
eea6690a |
219 | /** |
501e0e34 |
220 | * Uses set_user_preferences() to update the value of a user preference. If 'default' is given as the value, |
221 | * the preference will be removed in favour of a higher-level preference. |
222 | * @static |
eea6690a |
223 | * @param string $pref_name The name of the preference. |
224 | * @param mixed $pref_value The value of the preference. |
bb384a8e |
225 | * @param int $itemid An optional itemid to which the preference will be assigned |
eea6690a |
226 | * @return bool Success or failure. |
eea6690a |
227 | */ |
d24832f9 |
228 | public function set_pref($pref, $pref_value='default', $itemid=null) { |
bb384a8e |
229 | $fullprefname = 'grade_report_' . $pref; |
501e0e34 |
230 | if ($pref_value == 'default') { |
231 | return unset_user_preference($fullprefname.$itemid); |
232 | } else { |
233 | return set_user_preference($fullprefname.$itemid, $pref_value); |
eea6690a |
234 | } |
38b9e8a8 |
235 | } |
38b9e8a8 |
236 | |
eea6690a |
237 | /** |
238 | * Handles form data sent by this report for this report. Abstract method to implement in all children. |
239 | * @abstract |
240 | * @param array $data |
241 | * @return mixed True or array of errors |
242 | */ |
d24832f9 |
243 | abstract function process_data($data); |
38b9e8a8 |
244 | |
eea6690a |
245 | /** |
246 | * Processes a single action against a category, grade_item or grade. |
247 | * @param string $target Sortorder |
248 | * @param string $action Which action to take (edit, delete etc...) |
249 | * @return |
eea6690a |
250 | */ |
d24832f9 |
251 | abstract function process_action($target, $action); |
eea6690a |
252 | |
388234f4 |
253 | /** |
254 | * First checks the cached language strings, then returns match if found, or uses get_string() |
255 | * to get it from the DB, caches it then returns it. |
256 | * @param string $strcode |
257 | * @param string $section Optional language section |
258 | * @return string |
259 | */ |
d24832f9 |
260 | public function get_lang_string($strcode, $section=null) { |
388234f4 |
261 | if (empty($this->lang_strings[$strcode])) { |
262 | $this->lang_strings[$strcode] = get_string($strcode, $section); |
263 | } |
264 | return $this->lang_strings[$strcode]; |
265 | } |
266 | |
90d3960c |
267 | /** |
268 | * Fetches and returns a count of all the users that will be shown on this page. |
28bcbc38 |
269 | * @param boolean $groups include groups limit |
90d3960c |
270 | * @return int Count of users |
271 | */ |
d24832f9 |
272 | public function get_numusers($groups=true) { |
273 | global $CFG, $DB; |
90d3960c |
274 | |
28bcbc38 |
275 | $groupsql = ""; |
276 | $groupwheresql = ""; |
b50371da |
277 | list($usql, $params) = $DB->get_in_or_equal(explode(',', $this->gradebookroles), SQL_PARAMS_NAMED, 'grbr0'); |
d24832f9 |
278 | |
28bcbc38 |
279 | if ($groups) { |
280 | $groupsql = $this->groupsql; |
bbadce53 |
281 | $groupwheresql = $this->groupwheresql; |
d24832f9 |
282 | $params = array_merge($params, $this->groupwheresql_params); |
28bcbc38 |
283 | } |
284 | |
90d3960c |
285 | $countsql = "SELECT COUNT(DISTINCT u.id) |
b50371da |
286 | FROM {user} u |
287 | JOIN {role_assignments} ra ON u.id = ra.userid |
288 | $groupsql |
289 | WHERE ra.roleid $usql AND u.deleted = 0 |
290 | $groupwheresql |
291 | AND ra.contextid ".get_related_contexts_string($this->context); |
d24832f9 |
292 | return $DB->count_records_sql($countsql, $params); |
90d3960c |
293 | } |
294 | |
295 | /** |
296 | * Sets up this object's group variables, mainly to restrict the selection of users to display. |
297 | */ |
0fd8bc00 |
298 | protected function setup_groups() { |
90d3960c |
299 | /// find out current groups mode |
35079f53 |
300 | if ($this->groupmode = groups_get_course_groupmode($this->course)) { |
7a9ba4b4 |
301 | $this->currentgroup = groups_get_course_group($this->course, true); |
35079f53 |
302 | $this->group_selector = groups_print_course_menu($this->course, $this->pbarurl, true); |
7a9ba4b4 |
303 | |
304 | if ($this->groupmode == SEPARATEGROUPS and !$this->currentgroup and !has_capability('moodle/site:accessallgroups', $this->context)) { |
305 | $this->currentgroup = -2; // means can not accesss any groups at all |
306 | } |
35079f53 |
307 | |
308 | if ($this->currentgroup) { |
309 | $this->groupsql = " JOIN {groups_members} gm ON gm.userid = u.id "; |
310 | $this->groupwheresql = " AND gm.groupid = :gr_grpid "; |
311 | $this->groupwheresql_params = array('gr_grpid'=>$this->currentgroup); |
312 | } |
90d3960c |
313 | } |
314 | } |
2e3987a9 |
315 | |
316 | /** |
317 | * Returns an arrow icon inside an <a> tag, for the purpose of sorting a column. |
318 | * @param string $direction |
319770d7 |
319 | * @param moodle_url $sort_link |
2e3987a9 |
320 | * @param string HTML |
321 | */ |
319770d7 |
322 | protected function get_sort_arrow($direction='move', $sortlink=null) { |
323 | global $OUTPUT; |
dc482cfa |
324 | $matrix = array('up' => 'desc', 'down' => 'asc', 'move' => 'desc'); |
2e3987a9 |
325 | $strsort = $this->get_lang_string('sort' . $matrix[$direction]); |
dc482cfa |
326 | |
2e3987a9 |
327 | $arrow = print_arrow($direction, $strsort, true); |
319770d7 |
328 | $link = html_link::make($sortlink, $arrow); |
329 | $link->title = $strsort; |
330 | $html = $OUTPUT->link($link); |
2e3987a9 |
331 | return $html; |
332 | } |
38b9e8a8 |
333 | } |
6c3ef410 |
334 | |