MDL-48273 singleview: add load_user method and other group validations
[moodle.git] / grade / report / singleview / classes / local / screen / user.php
CommitLineData
57fac09a
DW
1<?php
2// This file is part of Moodle - http://moodle.org/
3//
4// Moodle is free software: you can redistribute it and/or modify
5// it under the terms of the GNU General Public License as published by
6// the Free Software Foundation, either version 3 of the License, or
7// (at your option) any later version.
8//
9// Moodle is distributed in the hope that it will be useful,
10// but WITHOUT ANY WARRANTY; without even the implied warranty of
11// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12// GNU General Public License for more details.
13//
14// You should have received a copy of the GNU General Public License
15// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
16
17/**
18 * The user screen.
19 *
20 * @package gradereport_singleview
21 * @copyright 2014 Moodle Pty Ltd (http://moodle.com)
22 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
23 */
24
25namespace gradereport_singleview\local\screen;
26
27use grade_seq;
28use gradereport_singleview;
29use moodle_url;
30use pix_icon;
31use html_writer;
32use gradereport_singleview\local\ui\range;
33use gradereport_singleview\local\ui\bulk_insert;
34use grade_item;
35use grade_grade;
0ce46428 36use stdClass;
57fac09a
DW
37
38defined('MOODLE_INTERNAL') || die;
39
40/**
41 * The user screen.
42 *
43 * @package gradereport_singleview
44 * @copyright 2014 Moodle Pty Ltd (http://moodle.com)
45 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
46 */
47class user extends tablelike implements selectable_items {
48
49 /** @var array $categories A cache for grade_item categories */
50 private $categories = array();
51
52 /** @var int $requirespaging Do we have more items than the paging limit? */
53 private $requirespaging = true;
54
55 /**
56 * Get the description for the screen.
57 *
58 * @return string
59 */
60 public function description() {
61 return get_string('gradeitems', 'grades');
62 }
63
64 /**
65 * Convert the list of items to a list of options.
66 *
67 * @return array
68 */
69 public function options() {
70 $result = array();
71 foreach ($this->items as $itemid => $item) {
72 $result[$itemid] = $item->get_name();
73 }
74 return $result;
75 }
76
77 /**
78 * Get the type of items on this screen.
79 *
80 * @return string
81 */
82 public function item_type() {
83 return 'grade';
84 }
85
86 /**
87 * Should we show the group selector on this screen?
88 *
89 * @return bool
90 */
91 public function display_group_selector() {
92 return false;
93 }
94
95 /**
96 * Init the screen
97 *
98 * @param bool $selfitemisempty Have we selected an item yet?
99 */
100 public function init($selfitemisempty = false) {
101 global $DB;
102
103 if (!$selfitemisempty) {
aac66bef
SL
104 $validusers = $this->load_users();
105 if (!isset($validusers[$this->itemid])) {
106 print_error('invaliduserid');
107 }
108 $this->item = $validusers[$this->itemid];
57fac09a
DW
109 }
110
111 $params = array('courseid' => $this->courseid);
112
113 $seq = new grade_seq($this->courseid, true);
114 foreach ($seq->items as $key => $item) {
115 if (isset($item->itemmodule)) {
116 list($courseid, $cmid) = get_course_and_cm_from_instance($item->iteminstance, $item->itemmodule);
117 $seq->items[$key]->cmid = $cmid->id;
118 }
119 }
120
121 $this->items = array();
122 foreach ($seq->items as $itemid => $item) {
123 if (grade::filter($item)) {
124 $this->items[$itemid] = $item;
125 }
126 }
127
128 $this->requirespaging = count($this->items) > $this->perpage;
129
57fac09a
DW
130 $this->setup_structure();
131
132 $this->definition = array(
133 'finalgrade', 'feedback', 'override', 'exclude'
134 );
135 $this->set_headers($this->original_headers());
136 }
137
138 /**
139 * Get the list of headers for the table.
140 *
141 * @return array List of headers
142 */
143 public function original_headers() {
144 return array(
145 '', // For filter icon.
57fac09a
DW
146 get_string('assessmentname', 'gradereport_singleview'),
147 get_string('gradecategory', 'grades'),
148 get_string('range', 'grades'),
149 get_string('grade', 'grades'),
150 get_string('feedback', 'grades'),
151 $this->make_toggle_links('override'),
152 $this->make_toggle_links('exclude')
153 );
154 }
155
156 /**
157 * Format each row of the table.
158 *
159 * @param grade_item $item
160 * @return string
161 */
162 public function format_line($item) {
163 global $OUTPUT;
164
165 $grade = $this->fetch_grade_or_default($item, $this->item->id);
166 $lockicon = '';
167
168 $lockeditem = $lockeditemgrade = 0;
169 if (!empty($grade->locked)) {
170 $lockeditem = 1;
171 }
172 if (!empty($grade->grade_item->locked)) {
173 $lockeditemgrade = 1;
174 }
175 // Check both grade and grade item.
176 if ($lockeditem || $lockeditemgrade) {
177 $lockicon = $OUTPUT->pix_icon('t/locked', 'grade is locked');
178 }
179
180 $realmodid = '';
181 if (isset($item->cmid)) {
182 $realmodid = $item->cmid;
183 }
237f76ce 184
57fac09a 185 $iconstring = get_string('filtergrades', 'gradereport_singleview', $item->get_name());
57fac09a 186
0ce46428
DW
187 // Create a fake gradetreeitem so we can call get_element_header().
188 // The type logic below is from grade_category->_get_children_recursion().
189 $gradetreeitem = array();
190 if (in_array($item->itemtype, array('course', 'category'))) {
191 $gradetreeitem['type'] = $item->itemtype.'item';
192 } else {
193 $gradetreeitem['type'] = 'item';
237f76ce 194 }
0ce46428
DW
195 $gradetreeitem['object'] = $item;
196 $gradetreeitem['userid'] = $this->item->id;
197
41e62a90 198 $itemlabel = $this->structure->get_element_header($gradetreeitem, true, false, false, false, true);
0ce46428 199 $grade->label = $item->get_name();
237f76ce 200
7c5721f9
ZD
201 $itemlabel = $item->get_name();
202 if (!empty($realmodid)) {
203 $url = new moodle_url('/mod/' . $item->itemmodule . '/view.php', array('id' => $realmodid));
204 $itemlabel = html_writer::link($url, $item->get_name());
205 }
206
57fac09a
DW
207 $line = array(
208 $OUTPUT->action_icon($this->format_link('grade', $item->id), new pix_icon('t/editstring', $iconstring)),
43cd76e8
JC
209 $this->format_icon($item) . $lockicon . $itemlabel,
210 $this->category($item),
211 new range($item)
57fac09a 212 );
43cd76e8
JC
213 $lineclasses = array(
214 "action",
215 "gradeitem",
216 "category",
217 "range"
218 );
219
220 $outputline = array();
221 $i = 0;
222 foreach ($line as $key => $value) {
223 $cell = new \html_table_cell($value);
224 if ($isheader = $i == 1) {
225 $cell->header = $isheader;
226 $cell->scope = "row";
227 }
228 if (array_key_exists($key, $lineclasses)) {
229 $cell->attributes['class'] = $lineclasses[$key];
230 }
231 $outputline[] = $cell;
232 $i++;
233 }
234
235 return $this->format_definition($outputline, $grade);
57fac09a
DW
236 }
237
238 /**
239 * Helper to get the icon for an item.
240 *
241 * @param grade_item $item
242 * @return string
243 */
244 private function format_icon($item) {
245 $element = array('type' => 'item', 'object' => $item);
246 return $this->structure->get_element_icon($element);
247 }
248
249 /**
250 * Helper to get the category for an item.
251 *
252 * @param grade_item $item
253 * @return grade_category
254 */
255 private function category($item) {
992159f4
DP
256 global $DB;
257
57fac09a
DW
258 if (empty($item->categoryid)) {
259
260 if ($item->itemtype == 'course') {
261 return $this->course->fullname;
262 }
263
57fac09a
DW
264 $params = array('id' => $item->iteminstance);
265 $elem = $DB->get_record('grade_categories', $params);
266
267 return $elem->fullname;
268 }
269
270 if (!isset($this->categories[$item->categoryid])) {
271 $category = $item->get_parent_category();
272
273 $this->categories[$category->id] = $category;
274 }
275
276 return $this->categories[$item->categoryid]->get_name();
277 }
278
279 /**
280 * Get the heading for the page.
281 *
282 * @return string
283 */
284 public function heading() {
285 return fullname($this->item);
286 }
287
43cd76e8
JC
288 /**
289 * Get the summary for this table.
290 *
291 * @return string
292 */
293 public function summary() {
294 return get_string('summaryuser', 'gradereport_singleview');
295 }
296
57fac09a
DW
297 /**
298 * Default pager
299 *
300 * @return string
301 */
302 public function pager() {
992159f4
DP
303 global $OUTPUT;
304
57fac09a
DW
305 if (!$this->supports_paging()) {
306 return '';
307 }
308
57fac09a
DW
309 return $OUTPUT->paging_bar(
310 count($this->items), $this->page, $this->perpage,
311 new moodle_url('/grade/report/singleview/index.php', array(
312 'perpage' => $this->perpage,
313 'id' => $this->courseid,
aac66bef 314 'group' => $this->groupid,
57fac09a
DW
315 'itemid' => $this->itemid,
316 'item' => 'user'
317 ))
318 );
319 }
320
321 /**
322 * Does this page require paging?
323 *
324 * @return bool
325 */
326 public function supports_paging() {
327 return $this->requirespaging;
328 }
329
330
331 /**
332 * Process the data from the form.
333 *
334 * @param array $data
335 * @return array of warnings
336 */
337 public function process($data) {
338 $bulk = new bulk_insert($this->item);
339 // Bulk insert messages the data to be passed in
340 // ie: for all grades of empty grades apply the specified value.
341 if ($bulk->is_applied($data)) {
342 $filter = $bulk->get_type($data);
343 $insertvalue = $bulk->get_insert_value($data);
57fac09a
DW
344
345 $userid = $this->item->id;
57fac09a
DW
346 foreach ($this->items as $gradeitemid => $gradeitem) {
347 $null = $gradeitem->gradetype == GRADE_TYPE_SCALE ? -1 : '';
5467cc05 348 $field = "finalgrade_{$gradeitem->id}_{$this->itemid}";
57fac09a
DW
349 if (isset($data->$field)) {
350 continue;
351 }
352
353 $grade = grade_grade::fetch(array(
5467cc05 354 'itemid' => $this->itemid,
57fac09a
DW
355 'userid' => $userid
356 ));
357
358 $data->$field = empty($grade) ? $null : $grade->finalgrade;
359 $data->{"old$field"} = $data->$field;
4fb6b62c
ZD
360
361 preg_match('/_(\d+)_(\d+)/', $field, $oldoverride);
362 $oldoverride = 'oldoverride' . $oldoverride[0];
363 if (empty($data->$oldoverride)) {
364 $data->$field = (!isset($grade->rawgrade)) ? $null : $grade->rawgrade;
365 }
366
57fac09a
DW
367 }
368
369 foreach ($data as $varname => $value) {
50e30bd4
ZD
370 if (preg_match('/override_(\d+)_(\d+)/', $varname, $matches)) {
371 $data->$matches[0] = '1';
372 }
5467cc05 373 if (!preg_match('/^finalgrade_(\d+)_(\d+)/', $varname, $matches)) {
57fac09a
DW
374 continue;
375 }
376
377 $gradeitem = grade_item::fetch(array(
378 'courseid' => $this->courseid,
379 'id' => $matches[1]
380 ));
381
382 $isscale = ($gradeitem->gradetype == GRADE_TYPE_SCALE);
383
384 $empties = (trim($value) === '' or ($isscale and $value == -1));
385
386 if ($filter == 'all' or $empties) {
387 $data->$varname = ($isscale and empty($insertvalue)) ?
388 -1 : $insertvalue;
389 }
390 }
391 }
57fac09a
DW
392 return parent::process($data);
393 }
394}