Proyectos de Subversion Moodle

Rev

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