Proyectos de Subversion Moodle

Rev

Rev 1 | | Comparar con el anterior | Ultima modificación | Ver Log |

Rev Autor Línea Nro. Línea
1 efrain 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
 
25
namespace gradereport_singleview\local\screen;
26
 
1441 ariadna 27
use context_course;
1 efrain 28
use grade_seq;
29
use gradereport_singleview;
30
use moodle_url;
31
use pix_icon;
32
use html_writer;
33
use gradereport_singleview\local\ui\range;
34
use gradereport_singleview\local\ui\bulk_insert;
35
use grade_item;
36
use grade_grade;
37
use stdClass;
38
 
39
defined('MOODLE_INTERNAL') || die;
40
 
41
/**
42
 * The user screen.
43
 *
44
 * @package   gradereport_singleview
45
 * @copyright 2014 Moodle Pty Ltd (http://moodle.com)
46
 * @license   http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
47
 */
48
class user extends tablelike implements selectable_items {
49
 
50
    /** @var array $categories A cache for grade_item categories */
51
    private $categories = [];
52
 
53
    /** @var int $requirespaging Do we have more items than the paging limit? */
54
    private $requirespaging = true;
55
 
56
    /** @var array get a valid user.  */
57
    public $item = [];
58
 
59
    /**
60
     * Get the label for the select box that chooses items for this page.
61
     * @return string
62
     */
63
    public function select_label(): string {
64
        return get_string('selectgrade', 'gradereport_singleview');
65
    }
66
 
67
    /**
68
     * Get the description for the screen.
69
     *
70
     * @return string
71
     */
72
    public function description(): string {
73
        return get_string('gradeitems', 'grades');
74
    }
75
 
76
    /**
77
     * Convert the list of items to a list of options.
78
     *
79
     * @return array
80
     */
81
    public function options(): array {
82
        $result = [];
83
        foreach ($this->items as $itemid => $item) {
84
            $result[$itemid] = $item->get_name();
85
        }
86
        return $result;
87
    }
88
 
89
    /**
90
     * Get the type of items on this screen.
91
     *
92
     * @return string
93
     */
94
    public function item_type(): string {
95
        return 'grade';
96
    }
97
 
98
    /**
99
     * Init the screen
100
     *
101
     * @param bool $selfitemisempty Have we selected an item yet?
102
     */
103
    public function init($selfitemisempty = false) {
104
 
105
        if (!$selfitemisempty) {
106
            $validusers = \grade_report::get_gradable_users($this->courseid, $this->groupid);
107
            if (!isset($validusers[$this->itemid])) {
108
                // If the passed user id is not valid, show the first user from the list instead.
109
                $this->item = reset($validusers);
110
                $this->itemid = $this->item->id;
111
            } else {
112
                $this->item = $validusers[$this->itemid];
113
            }
114
        }
115
 
116
        $seq = new grade_seq($this->courseid, true);
117
 
118
        $this->items = [];
119
        foreach ($seq->items as $itemid => $item) {
120
            if (grade::filter($item)) {
121
                $this->items[$itemid] = $item;
122
            }
123
        }
124
 
125
        // If we change perpage on pagination we might end up with a page that doesn't exist.
126
        if ($this->perpage) {
127
            $numpages = intval(count($this->items) / $this->perpage) + 1;
128
            if ($numpages <= $this->page) {
129
                $this->page = 0;
130
            }
131
        } else {
132
            $this->page = 0;
133
        }
134
 
135
        $this->requirespaging = count($this->items) > $this->perpage;
136
 
137
        $this->setup_structure();
138
 
139
        $this->definition = [
140
            'finalgrade', 'feedback', 'override', 'exclude'
141
        ];
142
        $this->set_headers($this->original_headers());
143
    }
144
 
145
    /**
146
     * Get the list of headers for the table.
147
     *
148
     * @return array List of headers
149
     */
150
    public function original_headers(): array {
151
        return [
152
            get_string('assessmentname', 'gradereport_singleview'),
153
            '', // For filter icon.
154
            get_string('gradecategory', 'grades'),
155
            get_string('gradenoun'),
156
            get_string('range', 'grades'),
157
            get_string('feedback', 'grades'),
158
            get_string('override', 'gradereport_singleview'),
159
            get_string('exclude', 'gradereport_singleview'),
160
        ];
161
    }
162
 
163
    /**
164
     * Format each row of the table.
165
     *
166
     * @param grade_item $item
167
     * @return array
168
     */
169
    public function format_line($item): array {
170
        global $OUTPUT;
171
 
172
        $grade = $this->fetch_grade_or_default($item, $this->item->id);
173
        $gradestatus = '';
174
 
1441 ariadna 175
        // Show hidden icon if the grade is hidden and the user has permission to view hidden grades.
176
        $showhiddenicon = ($grade->is_hidden() || $item->is_hidden()) &&
177
            has_capability('moodle/grade:viewhidden', context_course::instance($item->courseid));
178
 
1 efrain 179
        $context = [
1441 ariadna 180
            'hidden' => $showhiddenicon,
1 efrain 181
            'locked' => $grade->is_locked(),
182
        ];
183
 
184
        if (in_array(true, $context)) {
185
            $context['classes'] = 'gradestatus';
186
            $gradestatus = $OUTPUT->render_from_template('core_grades/status_icons', $context);
187
        }
188
 
189
        // Create a fake gradetreeitem so we can call get_element_header().
190
        // The type logic below is from grade_category->_get_children_recursion().
191
        $gradetreeitem = [];
192
 
193
        $type = in_array($item->itemtype, ['course', 'category']) ? "{$item->itemtype}item" : 'item';
194
        $gradetreeitem['type'] = $type;
195
        $gradetreeitem['object'] = $item;
196
        $gradetreeitem['userid'] = $this->item->id;
197
 
198
        $itemname = \grade_helper::get_element_header($gradetreeitem, true, false, false, false, true);
199
        $grade->label = $item->get_name();
200
 
201
        $formatteddefinition = $this->format_definition($grade);
202
 
1441 ariadna 203
        $itemicon = html_writer::div($this->format_icon($item), 'me-1');
1 efrain 204
        $itemtype = \html_writer::span(\grade_helper::get_element_type_string($gradetreeitem),
205
            'd-block text-uppercase small dimmed_text');
206
 
207
        $itemtitle = html_writer::div($itemname, 'rowtitle');
208
        $itemcontent = html_writer::div($itemtype . $itemtitle);
209
 
210
        $line = [
211
            html_writer::div($itemicon . $itemcontent, "{$type} d-flex align-items-center"),
212
            $this->get_item_action_menu($item),
213
            $this->category($item),
214
            $formatteddefinition['finalgrade'] . $gradestatus,
215
            new range($item),
216
            $formatteddefinition['feedback'],
217
            $formatteddefinition['override'],
218
            $formatteddefinition['exclude'],
219
        ];
220
        $lineclasses = [
221
            'gradeitem',
222
            'action',
223
            'category',
224
            'grade',
225
            'range',
226
        ];
227
 
228
        $outputline = [];
229
        $i = 0;
230
        foreach ($line as $key => $value) {
231
            $cell = new \html_table_cell($value);
232
            if ($isheader = $i == 0) {
233
                $cell->header = $isheader;
234
                $cell->scope = "row";
235
            }
236
            if (array_key_exists($key, $lineclasses)) {
237
                $cell->attributes['class'] = $lineclasses[$key];
238
            }
239
            $outputline[] = $cell;
240
            $i++;
241
        }
242
 
243
        return $outputline;
244
    }
245
 
246
    /**
247
     * Helper to get the icon for an item.
248
     *
249
     * @param grade_item $item
250
     * @return string
251
     */
252
    private function format_icon($item): string {
253
        $element = ['type' => 'item', 'object' => $item];
254
        return \grade_helper::get_element_icon($element);
255
    }
256
 
257
    /**
258
     * Return the action menu HTML for the grade item.
259
     *
260
     * @param grade_item $item
261
     * @return mixed
262
     */
263
    private function get_item_action_menu(grade_item $item) {
264
        global $OUTPUT;
265
 
266
        $menuitems = [];
267
        $url = new moodle_url($this->format_link('grade', $item->id));
268
        $title = get_string('showallgrades', 'core_grades');
269
        $menuitems[] = new \action_menu_link_secondary($url, null, $title);
270
        $menu = new \action_menu($menuitems);
271
        $icon = $OUTPUT->pix_icon('i/moremenu', get_string('actions'));
1441 ariadna 272
        $extraclasses = 'btn btn-icon d-flex';
1 efrain 273
        $menu->set_menu_trigger($icon, $extraclasses);
274
        $menu->set_menu_left();
275
        $menu->set_boundary('window');
276
 
277
        return $OUTPUT->render($menu);
278
    }
279
 
280
    /**
281
     * Helper to get the category for an item.
282
     *
283
     * @param grade_item $item
284
     * @return string
285
     */
286
    private function category(grade_item $item): string {
287
        global $DB;
288
 
289
        if (empty($item->categoryid)) {
290
 
291
            if ($item->itemtype == 'course') {
292
                return $this->course->fullname;
293
            }
294
 
295
            $params = ['id' => $item->iteminstance];
296
            $elem = $DB->get_record('grade_categories', $params);
297
 
298
            return $elem->fullname;
299
        }
300
 
301
        if (!isset($this->categories[$item->categoryid])) {
302
            $category = $item->get_parent_category();
303
 
304
            $this->categories[$category->id] = $category;
305
        }
306
 
307
        return $this->categories[$item->categoryid]->get_name();
308
    }
309
 
310
    /**
311
     * Get the heading for the page.
312
     *
313
     * @return string
314
     */
315
    public function heading(): string {
316
        global $PAGE;
317
        $headinglangstring = $PAGE->user_is_editing() ? 'gradeuseredit' : 'gradeuser';
318
        return get_string($headinglangstring, 'gradereport_singleview', fullname($this->item));
319
    }
320
 
321
    /**
322
     * Get the summary for this table.
323
     *
324
     * @return string
325
     */
326
    public function summary(): string {
327
        return get_string('summaryuser', 'gradereport_singleview');
328
    }
329
 
330
    /**
331
     * Default pager
332
     *
333
     * @return string
334
     */
335
    public function pager(): string {
336
        global $OUTPUT;
337
 
338
        if (!$this->supports_paging()) {
339
            return '';
340
        }
341
 
342
        return $OUTPUT->paging_bar(
343
            count($this->items), $this->page, $this->perpage,
344
            new moodle_url('/grade/report/singleview/index.php', [
345
                'perpage' => $this->perpage,
346
                'id' => $this->courseid,
347
                'group' => $this->groupid,
348
                'itemid' => $this->itemid,
349
                'item' => 'user'
350
            ])
351
        );
352
    }
353
 
354
    /**
355
     * Does this page require paging?
356
     *
357
     * @return bool
358
     */
359
    public function supports_paging(): bool {
360
        return $this->requirespaging;
361
    }
362
 
363
 
364
    /**
365
     * Process the data from the form.
366
     *
367
     * @param array $data
368
     * @return stdClass of warnings
369
     */
370
    public function process($data): stdClass {
371
        $bulk = new bulk_insert($this->item);
372
        // Bulk insert messages the data to be passed in
373
        // ie: for all grades of empty grades apply the specified value.
374
        if ($bulk->is_applied($data)) {
375
            $filter = $bulk->get_type($data);
376
            $insertvalue = $bulk->get_insert_value($data);
377
 
378
            $userid = $this->item->id;
379
            foreach ($this->items as $gradeitemid => $gradeitem) {
380
                $null = $gradeitem->gradetype == GRADE_TYPE_SCALE ? -1 : '';
381
                $field = "finalgrade_{$gradeitem->id}_{$this->itemid}";
382
                if (isset($data->$field)) {
383
                    continue;
384
                }
385
 
386
                $oldfinalgradefield = "oldfinalgrade_{$gradeitem->id}_{$this->itemid}";
387
                // Bulk grade changes for all grades need to be processed and shouldn't be skipped if they had a previous grade.
388
                if ($gradeitem->is_course_item() || ($filter != 'all' && !empty($data->$oldfinalgradefield))) {
389
                    if ($gradeitem->is_course_item()) {
390
                        // The course total should not be overridden.
391
                        unset($data->$field);
392
                        unset($data->oldfinalgradefield);
393
                        $oldoverride = "oldoverride_{$gradeitem->id}_{$this->itemid}";
394
                        unset($data->$oldoverride);
395
                        $oldfeedback = "oldfeedback_{$gradeitem->id}_{$this->itemid}";
396
                        unset($data->$oldfeedback);
397
                    }
398
                    continue;
399
                }
400
                $grade = grade_grade::fetch([
401
                    'itemid' => $gradeitemid,
402
                    'userid' => $userid
403
                ]);
404
 
405
                $data->$field = empty($grade) ? $null : $grade->finalgrade;
406
                $data->{"old$field"} = $data->$field;
407
            }
408
 
409
            foreach ($data as $varname => $value) {
410
                if (preg_match('/^oldoverride_(\d+)_(\d+)/', $varname, $matches)) {
411
                    // If we've selected overriding all grades.
412
                    if ($filter == 'all') {
413
                        $override = "override_{$matches[1]}_{$matches[2]}";
414
                        $data->$override = '1';
415
                    }
416
                }
417
                if (!preg_match('/^finalgrade_(\d+)_(\d+)/', $varname, $matches)) {
418
                    continue;
419
                }
420
 
421
                $gradeitem = grade_item::fetch([
422
                    'courseid' => $this->courseid,
423
                    'id' => $matches[1],
424
                ]);
425
 
426
                $isscale = ($gradeitem->gradetype == GRADE_TYPE_SCALE);
427
 
428
                $empties = (trim($value ?? '') === '' || ($isscale && $value == -1));
429
 
430
                if ($filter == 'all' || $empties) {
431
                    $data->$varname = ($isscale && empty($insertvalue)) ? -1 : $insertvalue;
432
                }
433
            }
434
        }
435
        return parent::process($data);
436
    }
437
}