Merge branch 'MDL-68343-master' of git://github.com/rezaies/moodle
[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
2a6cdc51
DW
55 /**
56 * Get the label for the select box that chooses items for this page.
57 * @return string
58 */
59 public function select_label() {
60 return get_string('selectgrade', 'gradereport_singleview');
61 }
62
57fac09a
DW
63 /**
64 * Get the description for the screen.
65 *
66 * @return string
67 */
68 public function description() {
69 return get_string('gradeitems', 'grades');
70 }
71
72 /**
73 * Convert the list of items to a list of options.
74 *
75 * @return array
76 */
77 public function options() {
78 $result = array();
79 foreach ($this->items as $itemid => $item) {
80 $result[$itemid] = $item->get_name();
81 }
82 return $result;
83 }
84
85 /**
86 * Get the type of items on this screen.
87 *
88 * @return string
89 */
90 public function item_type() {
91 return 'grade';
92 }
93
57fac09a
DW
94 /**
95 * Init the screen
96 *
97 * @param bool $selfitemisempty Have we selected an item yet?
98 */
99 public function init($selfitemisempty = false) {
100 global $DB;
101
102 if (!$selfitemisempty) {
aac66bef
SL
103 $validusers = $this->load_users();
104 if (!isset($validusers[$this->itemid])) {
2a6cdc51
DW
105 // If the passed user id is not valid, show the first user from the list instead.
106 $this->item = reset($validusers);
107 $this->itemid = $this->item->id;
108 } else {
109 $this->item = $validusers[$this->itemid];
aac66bef 110 }
57fac09a
DW
111 }
112
113 $params = array('courseid' => $this->courseid);
114
115 $seq = new grade_seq($this->courseid, true);
57fac09a
DW
116
117 $this->items = array();
118 foreach ($seq->items as $itemid => $item) {
119 if (grade::filter($item)) {
120 $this->items[$itemid] = $item;
121 }
122 }
123
124 $this->requirespaging = count($this->items) > $this->perpage;
125
57fac09a
DW
126 $this->setup_structure();
127
128 $this->definition = array(
129 'finalgrade', 'feedback', 'override', 'exclude'
130 );
131 $this->set_headers($this->original_headers());
132 }
133
134 /**
135 * Get the list of headers for the table.
136 *
137 * @return array List of headers
138 */
139 public function original_headers() {
140 return array(
141 '', // For filter icon.
57fac09a
DW
142 get_string('assessmentname', 'gradereport_singleview'),
143 get_string('gradecategory', 'grades'),
144 get_string('range', 'grades'),
145 get_string('grade', 'grades'),
146 get_string('feedback', 'grades'),
147 $this->make_toggle_links('override'),
148 $this->make_toggle_links('exclude')
149 );
150 }
151
152 /**
153 * Format each row of the table.
154 *
155 * @param grade_item $item
156 * @return string
157 */
158 public function format_line($item) {
159 global $OUTPUT;
160
161 $grade = $this->fetch_grade_or_default($item, $this->item->id);
162 $lockicon = '';
163
164 $lockeditem = $lockeditemgrade = 0;
165 if (!empty($grade->locked)) {
166 $lockeditem = 1;
167 }
168 if (!empty($grade->grade_item->locked)) {
169 $lockeditemgrade = 1;
170 }
171 // Check both grade and grade item.
172 if ($lockeditem || $lockeditemgrade) {
173 $lockicon = $OUTPUT->pix_icon('t/locked', 'grade is locked');
174 }
175
57fac09a 176 $iconstring = get_string('filtergrades', 'gradereport_singleview', $item->get_name());
57fac09a 177
0ce46428
DW
178 // Create a fake gradetreeitem so we can call get_element_header().
179 // The type logic below is from grade_category->_get_children_recursion().
180 $gradetreeitem = array();
181 if (in_array($item->itemtype, array('course', 'category'))) {
182 $gradetreeitem['type'] = $item->itemtype.'item';
183 } else {
184 $gradetreeitem['type'] = 'item';
237f76ce 185 }
0ce46428
DW
186 $gradetreeitem['object'] = $item;
187 $gradetreeitem['userid'] = $this->item->id;
188
41e62a90 189 $itemlabel = $this->structure->get_element_header($gradetreeitem, true, false, false, false, true);
0ce46428 190 $grade->label = $item->get_name();
237f76ce 191
57fac09a 192 $line = array(
4e9b0c42
SR
193 $OUTPUT->action_icon($this->format_link('grade', $item->id), new pix_icon('t/editstring', ''), null,
194 ['title' => $iconstring, 'aria-label' => $iconstring]),
43cd76e8
JC
195 $this->format_icon($item) . $lockicon . $itemlabel,
196 $this->category($item),
197 new range($item)
57fac09a 198 );
43cd76e8
JC
199 $lineclasses = array(
200 "action",
201 "gradeitem",
202 "category",
203 "range"
204 );
205
206 $outputline = array();
207 $i = 0;
208 foreach ($line as $key => $value) {
209 $cell = new \html_table_cell($value);
210 if ($isheader = $i == 1) {
211 $cell->header = $isheader;
212 $cell->scope = "row";
213 }
214 if (array_key_exists($key, $lineclasses)) {
215 $cell->attributes['class'] = $lineclasses[$key];
216 }
217 $outputline[] = $cell;
218 $i++;
219 }
220
221 return $this->format_definition($outputline, $grade);
57fac09a
DW
222 }
223
224 /**
225 * Helper to get the icon for an item.
226 *
227 * @param grade_item $item
228 * @return string
229 */
230 private function format_icon($item) {
231 $element = array('type' => 'item', 'object' => $item);
232 return $this->structure->get_element_icon($element);
233 }
234
235 /**
236 * Helper to get the category for an item.
237 *
238 * @param grade_item $item
239 * @return grade_category
240 */
241 private function category($item) {
992159f4
DP
242 global $DB;
243
57fac09a
DW
244 if (empty($item->categoryid)) {
245
246 if ($item->itemtype == 'course') {
247 return $this->course->fullname;
248 }
249
57fac09a
DW
250 $params = array('id' => $item->iteminstance);
251 $elem = $DB->get_record('grade_categories', $params);
252
253 return $elem->fullname;
254 }
255
256 if (!isset($this->categories[$item->categoryid])) {
257 $category = $item->get_parent_category();
258
259 $this->categories[$category->id] = $category;
260 }
261
262 return $this->categories[$item->categoryid]->get_name();
263 }
264
265 /**
266 * Get the heading for the page.
267 *
268 * @return string
269 */
270 public function heading() {
2a6cdc51 271 return get_string('gradeuser', 'gradereport_singleview', fullname($this->item));
57fac09a
DW
272 }
273
43cd76e8
JC
274 /**
275 * Get the summary for this table.
276 *
277 * @return string
278 */
279 public function summary() {
280 return get_string('summaryuser', 'gradereport_singleview');
281 }
282
57fac09a
DW
283 /**
284 * Default pager
285 *
286 * @return string
287 */
288 public function pager() {
992159f4
DP
289 global $OUTPUT;
290
57fac09a
DW
291 if (!$this->supports_paging()) {
292 return '';
293 }
294
57fac09a
DW
295 return $OUTPUT->paging_bar(
296 count($this->items), $this->page, $this->perpage,
297 new moodle_url('/grade/report/singleview/index.php', array(
298 'perpage' => $this->perpage,
299 'id' => $this->courseid,
aac66bef 300 'group' => $this->groupid,
57fac09a
DW
301 'itemid' => $this->itemid,
302 'item' => 'user'
303 ))
304 );
305 }
306
307 /**
308 * Does this page require paging?
309 *
310 * @return bool
311 */
312 public function supports_paging() {
313 return $this->requirespaging;
314 }
315
316
317 /**
318 * Process the data from the form.
319 *
320 * @param array $data
321 * @return array of warnings
322 */
323 public function process($data) {
324 $bulk = new bulk_insert($this->item);
325 // Bulk insert messages the data to be passed in
326 // ie: for all grades of empty grades apply the specified value.
327 if ($bulk->is_applied($data)) {
328 $filter = $bulk->get_type($data);
329 $insertvalue = $bulk->get_insert_value($data);
57fac09a
DW
330
331 $userid = $this->item->id;
57fac09a
DW
332 foreach ($this->items as $gradeitemid => $gradeitem) {
333 $null = $gradeitem->gradetype == GRADE_TYPE_SCALE ? -1 : '';
5467cc05 334 $field = "finalgrade_{$gradeitem->id}_{$this->itemid}";
57fac09a
DW
335 if (isset($data->$field)) {
336 continue;
337 }
338
bd1537b6 339 $oldfinalgradefield = "oldfinalgrade_{$gradeitem->id}_{$this->itemid}";
81e32515
AG
340 // Bulk grade changes for all grades need to be processed and shouldn't be skipped if they had a previous grade.
341 if ($gradeitem->is_course_item() || ($filter != 'all' && !empty($data->$oldfinalgradefield))) {
342 if ($gradeitem->is_course_item()) {
343 // The course total should not be overridden.
344 unset($data->$field);
345 unset($data->oldfinalgradefield);
346 $oldoverride = "oldoverride_{$gradeitem->id}_{$this->itemid}";
347 unset($data->$oldoverride);
348 $oldfeedback = "oldfeedback_{$gradeitem->id}_{$this->itemid}";
349 unset($data->$oldfeedback);
350 }
bd1537b6
DC
351 continue;
352 }
57fac09a 353 $grade = grade_grade::fetch(array(
81e32515 354 'itemid' => $gradeitemid,
57fac09a
DW
355 'userid' => $userid
356 ));
357
358 $data->$field = empty($grade) ? $null : $grade->finalgrade;
359 $data->{"old$field"} = $data->$field;
360 }
361
362 foreach ($data as $varname => $value) {
bd1537b6 363 if (preg_match('/^oldoverride_(\d+)_(\d+)/', $varname, $matches)) {
81e32515
AG
364 // If we've selected overriding all grades.
365 if ($filter == 'all') {
bd1537b6
DC
366 $override = "override_{$matches[1]}_{$matches[2]}";
367 $data->$override = '1';
368 }
50e30bd4 369 }
5467cc05 370 if (!preg_match('/^finalgrade_(\d+)_(\d+)/', $varname, $matches)) {
57fac09a
DW
371 continue;
372 }
373
374 $gradeitem = grade_item::fetch(array(
375 'courseid' => $this->courseid,
376 'id' => $matches[1]
377 ));
378
379 $isscale = ($gradeitem->gradetype == GRADE_TYPE_SCALE);
380
381 $empties = (trim($value) === '' or ($isscale and $value == -1));
382
383 if ($filter == 'all' or $empties) {
384 $data->$varname = ($isscale and empty($insertvalue)) ?
385 -1 : $insertvalue;
386 }
387 }
388 }
57fac09a
DW
389 return parent::process($data);
390 }
391}