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 the customcert module for 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
 * Provides useful functions related to elements.
19
 *
20
 * @package    mod_customcert
21
 * @copyright  2016 Mark Nelson <markn@moodle.com>
22
 * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
23
 */
24
 
25
namespace mod_customcert;
26
 
27
defined('MOODLE_INTERNAL') || die();
28
 
29
require_once($CFG->libdir . '/grade/constants.php');
30
require_once($CFG->dirroot . '/grade/lib.php');
31
require_once($CFG->dirroot . '/grade/querylib.php');
32
 
33
/**
34
 * Class helper.
35
 *
36
 * Provides useful functions related to elements.
37
 *
38
 * @package    mod_customcert
39
 * @copyright  2016 Mark Nelson <markn@moodle.com>
40
 * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
41
 */
42
class element_helper {
43
 
44
    /**
45
     * @var int the top-left of element
46
     */
47
    const CUSTOMCERT_REF_POINT_TOPLEFT = 0;
48
 
49
    /**
50
     * @var int the top-center of element
51
     */
52
    const CUSTOMCERT_REF_POINT_TOPCENTER = 1;
53
 
54
    /**
55
     * @var int the top-left of element
56
     */
57
    const CUSTOMCERT_REF_POINT_TOPRIGHT = 2;
58
 
59
    /**
60
     * Common behaviour for rendering specified content on the pdf.
61
     *
62
     * @param \pdf $pdf the pdf object
63
     * @param \mod_customcert\element $element the customcert element
64
     * @param string $content the content to render
65
     */
66
    public static function render_content($pdf, $element, $content) {
67
        list($font, $attr) = self::get_font($element);
68
        $pdf->setFont($font, $attr, $element->get_fontsize());
69
        $fontcolour = \TCPDF_COLORS::convertHTMLColorToDec($element->get_colour(), $fontcolour);
70
        $pdf->SetTextColor($fontcolour['R'], $fontcolour['G'], $fontcolour['B']);
71
 
72
        $x = $element->get_posx();
73
        $y = $element->get_posy();
74
        $w = $element->get_width();
75
        $refpoint = $element->get_refpoint();
76
        $actualwidth = $pdf->GetStringWidth($content);
77
        $alignment = $element->get_alignment();
78
 
79
        if ($w && $w < $actualwidth) {
80
            $actualwidth = $w;
81
        }
82
 
83
        switch ($refpoint) {
84
            case self::CUSTOMCERT_REF_POINT_TOPRIGHT:
85
                $x = $element->get_posx() - $actualwidth;
86
                if ($x < 0) {
87
                    $x = 0;
88
                    $w = $element->get_posx();
89
                } else {
90
                    $w = $actualwidth;
91
                }
92
                break;
93
            case self::CUSTOMCERT_REF_POINT_TOPCENTER:
94
                $x = $element->get_posx() - $actualwidth / 2;
95
                if ($x < 0) {
96
                    $x = 0;
97
                    $w = $element->get_posx() * 2;
98
                } else {
99
                    $w = $actualwidth;
100
                }
101
                break;
102
        }
103
 
104
        if ($w) {
105
            $w += 0.0001;
106
        }
107
        $pdf->setCellPaddings(0, 0, 0, 0);
108
        $pdf->writeHTMLCell($w, 0, $x, $y, $content, 0, 0, false, true, $alignment);
109
    }
110
 
111
    /**
112
     * Common behaviour for rendering specified content on the drag and drop page.
113
     *
114
     * @param \mod_customcert\element $element the customcert element
115
     * @param string $content the content to render
116
     * @return string the html
117
     */
118
    public static function render_html_content($element, $content) {
119
        list($font, $attr) = self::get_font($element);
120
        $fontstyle = 'font-family: ' . $font;
121
        if (strpos($attr, 'B') !== false) {
122
            $fontstyle .= '; font-weight: bold';
123
        }
124
        if (strpos($attr, 'I') !== false) {
125
            $fontstyle .= '; font-style: italic';
126
        }
127
 
128
        $style = $fontstyle . '; color: ' . $element->get_colour() . '; font-size: ' . $element->get_fontsize() . 'pt;';
129
        if ($element->get_width()) {
130
            $style .= ' width: ' . $element->get_width() . 'mm';
131
        }
132
        return \html_writer::div($content, '', ['style' => $style]);
133
    }
134
 
135
    /**
136
     * Helper function to render the font elements.
137
     *
138
     * @param \MoodleQuickForm $mform the edit_form instance.
139
     */
140
    public static function render_form_element_font($mform) {
141
        $mform->addElement('select', 'font', get_string('font', 'customcert'), \mod_customcert\certificate::get_fonts());
142
        $mform->setType('font', PARAM_TEXT);
143
        $mform->setDefault('font', 'times');
144
        $mform->addHelpButton('font', 'font', 'customcert');
145
        $mform->addElement('select', 'fontsize', get_string('fontsize', 'customcert'),
146
            \mod_customcert\certificate::get_font_sizes());
147
        $mform->setType('fontsize', PARAM_INT);
148
        $mform->setDefault('fontsize', 12);
149
        $mform->addHelpButton('fontsize', 'fontsize', 'customcert');
150
    }
151
 
152
    /**
153
     * Helper function to render the colour elements.
154
     *
155
     * @param \MoodleQuickForm $mform the edit_form instance.
156
     */
157
    public static function render_form_element_colour($mform) {
158
        $mform->addElement('customcert_colourpicker', 'colour', get_string('fontcolour', 'customcert'));
159
        $mform->setType('colour', PARAM_RAW); // Need to validate that this is a valid colour.
160
        $mform->setDefault('colour', '#000000');
161
        $mform->addHelpButton('colour', 'fontcolour', 'customcert');
162
    }
163
 
164
    /**
165
     * Helper function to render the position elements.
166
     *
167
     * @param \MoodleQuickForm $mform the edit_form instance.
168
     */
169
    public static function render_form_element_position($mform) {
170
        $mform->addElement('text', 'posx', get_string('posx', 'customcert'), ['size' => 10]);
171
        $mform->setType('posx', PARAM_INT);
172
        $mform->setDefault('posx', 0);
173
        $mform->addHelpButton('posx', 'posx', 'customcert');
174
        $mform->addElement('text', 'posy', get_string('posy', 'customcert'), ['size' => 10]);
175
        $mform->setType('posy', PARAM_INT);
176
        $mform->setDefault('posy', 0);
177
        $mform->addHelpButton('posy', 'posy', 'customcert');
178
    }
179
 
180
    /**
181
     * Helper function to render the width element.
182
     *
183
     * @param \MoodleQuickForm $mform the edit_form instance.
184
     */
185
    public static function render_form_element_width($mform) {
186
        $mform->addElement('text', 'width', get_string('elementwidth', 'customcert'), ['size' => 10]);
187
        $mform->setType('width', PARAM_INT);
188
        $mform->setDefault('width', 0);
189
        $mform->addHelpButton('width', 'elementwidth', 'customcert');
190
    }
191
 
192
    /**
193
     * Helper function to render the height element.
194
     *
195
     * @param \MoodleQuickForm $mform the edit_form instance.
196
     */
197
    public static function render_form_element_height($mform) {
198
        $mform->addElement('text', 'height', get_string('elementheight', 'customcert'), ['size' => 10]);
199
        $mform->setType('height', PARAM_INT);
200
        $mform->setDefault('height', 0);
201
        $mform->addHelpButton('height', 'elementheight', 'customcert');
202
    }
203
 
204
    /**
205
     * Helper function to render the refpoint element.
206
     *
207
     * @param \MoodleQuickForm $mform the edit_form instance.
208
     */
209
    public static function render_form_element_refpoint($mform) {
210
        $refpointoptions = [];
211
        $refpointoptions[self::CUSTOMCERT_REF_POINT_TOPLEFT] = get_string('topleft', 'customcert');
212
        $refpointoptions[self::CUSTOMCERT_REF_POINT_TOPCENTER] = get_string('topcenter', 'customcert');
213
        $refpointoptions[self::CUSTOMCERT_REF_POINT_TOPRIGHT] = get_string('topright', 'customcert');
214
 
215
        $mform->addElement('select', 'refpoint', get_string('refpoint', 'customcert'), $refpointoptions);
216
        $mform->setType('refpoint', PARAM_INT);
217
        $mform->setDefault('refpoint', self::CUSTOMCERT_REF_POINT_TOPCENTER);
218
        $mform->addHelpButton('refpoint', 'refpoint', 'customcert');
219
    }
220
 
221
    /**
222
     * Helper function to render the alignment form element.
223
     *
224
     * @param \MoodleQuickForm $mform the edit_form instance.
225
     */
226
    public static function render_form_element_alignment($mform) {
227
        $alignmentoptions = [];
228
        $alignmentoptions[element::ALIGN_LEFT] = get_string('alignleft', 'customcert');
229
        $alignmentoptions[element::ALIGN_CENTER] = get_string('aligncenter', 'customcert');
230
        $alignmentoptions[element::ALIGN_RIGHT] = get_string('alignright', 'customcert');
231
 
232
        $mform->addElement('select', 'alignment', get_string('alignment', 'customcert'), $alignmentoptions);
233
        $mform->setType('alignment', PARAM_ALPHA);
234
        $mform->setDefault('alignment', element::ALIGN_LEFT);
235
        $mform->addHelpButton('alignment', 'alignment', 'customcert');
236
    }
237
 
238
    /**
239
     * Helper function to performs validation on the colour element.
240
     *
241
     * @param array $data the submitted data
242
     * @return array the validation errors
243
     */
244
    public static function validate_form_element_colour($data) {
245
        $errors = [];
246
        // Validate the colour.
247
        if (!self::validate_colour($data['colour'])) {
248
            $errors['colour'] = get_string('invalidcolour', 'customcert');
249
        }
250
        return $errors;
251
    }
252
 
253
    /**
254
     * Helper function to performs validation on the position elements.
255
     *
256
     * @param array $data the submitted data
257
     * @return array the validation errors
258
     */
259
    public static function validate_form_element_position($data) {
260
        $errors = [];
261
 
262
        // Check if posx is not set, or not numeric or less than 0.
263
        if ((!isset($data['posx'])) || (!is_numeric($data['posx'])) || ($data['posx'] < 0)) {
264
            $errors['posx'] = get_string('invalidposition', 'customcert', 'X');
265
        }
266
        // Check if posy is not set, or not numeric or less than 0.
267
        if ((!isset($data['posy'])) || (!is_numeric($data['posy'])) || ($data['posy'] < 0)) {
268
            $errors['posy'] = get_string('invalidposition', 'customcert', 'Y');
269
        }
270
 
271
        return $errors;
272
    }
273
 
274
    /**
275
     * Helper function to perform validation on the width element.
276
     *
277
     * @param array $data the submitted data
278
     * @param bool $allowzero allow zero as a valid value
279
     * @return array the validation errors
280
     */
281
    public static function validate_form_element_width($data, bool $allowzero = true) {
282
        $errors = [];
283
 
284
        // If there is no width element no validation is needed.
285
        if (!isset($data['width'])) {
286
            return [];
287
        }
288
 
289
        // Check if width is less than 0.
290
        if (!is_numeric($data['width'])) {
291
            $errors['width'] = get_string('invalidelementwidthorheightnotnumber', 'customcert');
292
        } else {
293
            if ($allowzero) {
294
                if ($data['width'] < 0) {
295
                    $errors['width'] = get_string('invalidelementwidthorheightzeroallowed', 'customcert');
296
                }
297
            } else {
298
                if ($data['width'] <= 0) {
299
                    $errors['width'] = get_string('invalidelementwidthorheightzeronotallowed', 'customcert');
300
                }
301
            }
302
        }
303
 
304
        return $errors;
305
    }
306
 
307
    /**
308
     * Helper function to perform validation on the height element.
309
     *
310
     * @param array $data the submitted data
311
     * @param bool $allowzero allow zero as a valid value
312
     * @return array the validation errors
313
     */
314
    public static function validate_form_element_height($data, bool $allowzero = true) {
315
        $errors = [];
316
 
317
        // If there is no height element no validation is needed.
318
        if (!isset($data['height'])) {
319
            return [];
320
        }
321
 
322
        // Check if height is less than 0.
323
        if (!is_numeric($data['height'])) {
324
            $errors['height'] = get_string('invalidelementwidthorheightnotnumber', 'customcert');
325
        } else {
326
            if ($allowzero) {
327
                if ($data['height'] < 0) {
328
                    $errors['height'] = get_string('invalidelementwidthorheightzeroallowed', 'customcert');
329
                }
330
            } else {
331
                if ($data['height'] <= 0) {
332
                    $errors['height'] = get_string('invalidelementwidthorheightzeronotallowed', 'customcert');
333
                }
334
            }
335
        }
336
 
337
        return $errors;
338
    }
339
 
340
    /**
341
     * Returns the font used for this element.
342
     *
343
     * @param \mod_customcert\element $element the customcert element
344
     * @return array the font and font attributes
345
     */
346
    public static function get_font($element) {
347
        // Variable for the font.
348
        $font = $element->get_font();
349
        // Get the last two characters of the font name.
350
        $fontlength = strlen($font);
351
        $lastchar = $font[$fontlength - 1];
352
        $secondlastchar = $font[$fontlength - 2];
353
        // The attributes of the font.
354
        $attr = '';
355
        // Check if the last character is 'i'.
356
        if ($lastchar == 'i') {
357
            // Remove the 'i' from the font name.
358
            $font = substr($font, 0, -1);
359
            // Check if the second last char is b.
360
            if ($secondlastchar == 'b') {
361
                // Remove the 'b' from the font name.
362
                $font = substr($font, 0, -1);
363
                $attr .= 'B';
364
            }
365
            $attr .= 'I';
366
        } else if ($lastchar == 'b') {
367
            // Remove the 'b' from the font name.
368
            $font = substr($font, 0, -1);
369
            $attr .= 'B';
370
        }
371
        return [$font, $attr];
372
    }
373
 
374
    /**
375
     * Validates the colour selected.
376
     *
377
     * @param string $colour
378
     * @return bool returns true if the colour is valid, false otherwise
379
     */
380
    public static function validate_colour($colour) {
381
        // List of valid HTML colour names.
382
        $colournames = [
383
            'aliceblue', 'antiquewhite', 'aqua', 'aquamarine', 'azure',
384
            'beige', 'bisque', 'black', 'blanchedalmond', 'blue',
385
            'blueviolet', 'brown', 'burlywood', 'cadetblue', 'chartreuse',
386
            'chocolate', 'coral', 'cornflowerblue', 'cornsilk', 'crimson',
387
            'cyan', 'darkblue', 'darkcyan', 'darkgoldenrod', 'darkgray',
388
            'darkgrey', 'darkgreen', 'darkkhaki', 'darkmagenta',
389
            'darkolivegreen', 'darkorange', 'darkorchid', 'darkred',
390
            'darksalmon', 'darkseagreen', 'darkslateblue', 'darkslategray',
391
            'darkslategrey', 'darkturquoise', 'darkviolet', 'deeppink',
392
            'deepskyblue', 'dimgray', 'dimgrey', 'dodgerblue', 'firebrick',
393
            'floralwhite', 'forestgreen', 'fuchsia', 'gainsboro',
394
            'ghostwhite', 'gold', 'goldenrod', 'gray', 'grey', 'green',
395
            'greenyellow', 'honeydew', 'hotpink', 'indianred', 'indigo',
396
            'ivory', 'khaki', 'lavender', 'lavenderblush', 'lawngreen',
397
            'lemonchiffon', 'lightblue', 'lightcoral', 'lightcyan',
398
            'lightgoldenrodyellow', 'lightgray', 'lightgrey', 'lightgreen',
399
            'lightpink', 'lightsalmon', 'lightseagreen', 'lightskyblue',
400
            'lightslategray', 'lightslategrey', 'lightsteelblue', 'lightyellow',
401
            'lime', 'limegreen', 'linen', 'magenta', 'maroon',
402
            'mediumaquamarine', 'mediumblue', 'mediumorchid', 'mediumpurple',
403
            'mediumseagreen', 'mediumslateblue', 'mediumspringgreen',
404
            'mediumturquoise', 'mediumvioletred', 'midnightblue', 'mintcream',
405
            'mistyrose', 'moccasin', 'navajowhite', 'navy', 'oldlace', 'olive',
406
            'olivedrab', 'orange', 'orangered', 'orchid', 'palegoldenrod',
407
            'palegreen', 'paleturquoise', 'palevioletred', 'papayawhip',
408
            'peachpuff', 'peru', 'pink', 'plum', 'powderblue', 'purple', 'red',
409
            'rosybrown', 'royalblue', 'saddlebrown', 'salmon', 'sandybrown',
410
            'seagreen', 'seashell', 'sienna', 'silver', 'skyblue', 'slateblue',
411
            'slategray', 'slategrey', 'snow', 'springgreen', 'steelblue', 'tan',
412
            'teal', 'thistle', 'tomato', 'turquoise', 'violet', 'wheat', 'white',
413
            'whitesmoke', 'yellow', 'yellowgreen',
414
        ];
415
 
416
        if (preg_match('/^#?([[:xdigit:]]{3}){1,2}$/', $colour)) {
417
            return true;
418
        } else if (in_array(strtolower($colour), $colournames)) {
419
            return true;
420
        }
421
 
422
        return false;
423
    }
424
 
425
    /**
426
     * Helper function that returns the sequence on a specified customcert page for a
427
     * newly created element.
428
     *
429
     * @param int $pageid the id of the page we are adding this element to
430
     * @return int the element number
431
     */
432
    public static function get_element_sequence($pageid) {
433
        global $DB;
434
 
435
        // Set the sequence of the element we are creating.
436
        $sequence = 1;
437
        // Check if there already elements that exist, if so, overwrite value.
438
        $sql = "SELECT MAX(sequence) as maxsequence
439
                  FROM {customcert_elements}
440
                 WHERE pageid = :id";
441
        // Get the current max sequence on this page and add 1 to get the new sequence.
442
        if ($maxseq = $DB->get_record_sql($sql, ['id' => $pageid])) {
443
            $sequence = $maxseq->maxsequence + 1;
444
        }
445
 
446
        return $sequence;
447
    }
448
 
449
    /**
450
     * Helper function that returns the course id for this element.
451
     *
452
     * @param int $elementid The element id
453
     * @return int The course id
454
     */
455
    public static function get_courseid($elementid) {
456
        global $DB, $SITE;
457
 
458
        $sql = "SELECT course
459
                  FROM {customcert} c
460
            INNER JOIN {customcert_pages} cp
461
                    ON c.templateid = cp.templateid
462
            INNER JOIN {customcert_elements} ce
463
                    ON cp.id = ce.pageid
464
                 WHERE ce.id = :elementid";
465
 
466
        // Check if there is a course associated with this element.
467
        if ($course = $DB->get_record_sql($sql, ['elementid' => $elementid])) {
468
            return $course->course;
469
        } else { // Must be in a site template.
470
            return $SITE->id;
471
        }
472
    }
473
 
474
    /**
475
     * Helper function that returns the context for this element.
476
     *
477
     * @param int $elementid The element id
478
     * @return \context The context
479
     */
480
    public static function get_context(int $elementid) : \context {
481
        global $DB;
482
 
483
        $sql = "SELECT ct.contextid
484
                  FROM {customcert_templates} ct
485
            INNER JOIN {customcert_pages} cp
486
                    ON ct.id = cp.templateid
487
            INNER JOIN {customcert_elements} ce
488
                    ON cp.id = ce.pageid
489
                 WHERE ce.id = :elementid";
490
        $contextid = $DB->get_field_sql($sql, ['elementid' => $elementid], MUST_EXIST);
491
 
492
        return \context::instance_by_id($contextid);
493
    }
494
 
495
    /**
496
     * Return the list of possible elements to add.
497
     *
498
     * @return array the list of element types that can be used.
499
     */
500
    public static function get_available_element_types() {
501
        global $CFG;
502
 
503
        // Array to store the element types.
504
        $options = [];
505
 
506
        // Check that the directory exists.
507
        $elementdir = "$CFG->dirroot/mod/customcert/element";
508
        if (file_exists($elementdir)) {
509
            // Get directory contents.
510
            $elementfolders = new \DirectoryIterator($elementdir);
511
            // Loop through the elements folder.
512
            foreach ($elementfolders as $elementfolder) {
513
                // If it is not a directory or it is '.' or '..', skip it.
514
                if (!$elementfolder->isDir() || $elementfolder->isDot()) {
515
                    continue;
516
                }
517
                // Check that the standard class exists, if not we do
518
                // not want to display it as an option as it will not work.
519
                $foldername = $elementfolder->getFilename();
520
                // Get the class name.
521
                $classname = '\\customcertelement_' . $foldername . '\\element';
522
                // Ensure the necessary class exists.
523
                if (class_exists($classname)) {
524
                    // Additionally, check if the user is allowed to add the element at all.
525
                    if ($classname::can_add()) {
526
                        $component = "customcertelement_{$foldername}";
527
                        $options[$foldername] = get_string('pluginname', $component);
528
                    }
529
                }
530
            }
531
        }
532
 
533
        \core_collator::asort($options);
534
        return $options;
535
    }
536
 
537
    /**
538
     * Helper function to return all the grades items for a given course.
539
     *
540
     * @param \stdClass $course The course we want to return the grade items for
541
     * @return array the array of gradeable items in the course
542
     */
543
    public static function get_grade_items($course) {
544
        // Array to store the grade items.
545
        $arrgradeitems = [];
546
 
547
        // Get other non-module related grade items.
548
        if ($gradeitems = \grade_item::fetch_all(['courseid' => $course->id])) {
549
            foreach ($gradeitems as $gi) {
550
                if ($gi->is_course_item()) {
551
                    continue; // Skipping for legacy reasons - this was added to individual elements.
552
                }
553
 
554
                if ($gi->is_external_item()) {
555
                    $cm = get_coursemodule_from_instance($gi->itemmodule, $gi->iteminstance, $course->id);
556
                    $modcontext = \context_module::instance($cm->id);
557
                    $modname = format_string($cm->name, true, ['context' => $modcontext]);
558
                }
559
 
560
                if ($gi->is_external_item() && !$gi->is_outcome_item()) {
561
                    // Due to legacy reasons we are storing the course module ID here rather than the grade item id.
562
                    // If we were to change we would need to provide upgrade steps to convert cm->id to gi->id.
563
                    $arrgradeitems[$cm->id] = get_string('activity', 'mod_customcert') . ' : ' . $gi->get_name();
564
                } else if ($gi->is_external_item() && $gi->is_outcome_item()) {
565
                    // Get the name of the activity.
566
                    $optionname = get_string('gradeoutcome', 'mod_customcert') . ' : '  . $modname . " - " . $gi->get_name();
567
                    $arrgradeitems['gradeitem:' . $gi->id] = $optionname;
568
                } else {
569
                    $arrgradeitems['gradeitem:' . $gi->id] = get_string('gradeitem', 'grades') . ' : ' . $gi->get_name(true);
570
                }
571
            }
572
 
573
            // Alphabetise this.
574
            asort($arrgradeitems);
575
        }
576
 
577
        return $arrgradeitems;
578
    }
579
 
580
    /**
581
     * Helper function to return the grade information for a course for a specified user.
582
     *
583
     * @param int $courseid
584
     * @param int $gradeformat
585
     * @param int $userid
586
     * @return grade_information|bool the grade information, or false if there is none.
587
     */
588
    public static function get_course_grade_info($courseid, $gradeformat, $userid) {
589
        $courseitem = \grade_item::fetch_course_item($courseid);
590
 
591
        if (!$courseitem) {
592
            return false;
593
        }
594
 
595
        $grade = new \grade_grade(['itemid' => $courseitem->id, 'userid' => $userid]);
596
 
597
        return new grade_information(
598
            $courseitem->get_name(),
599
            $grade->finalgrade,
600
            grade_format_gradevalue($grade->finalgrade, $courseitem, true, $gradeformat),
601
            $grade->get_dategraded()
602
        );
603
    }
604
 
605
    /**
606
     * Helper function to return the grade information for a module for a specified user.
607
     *
608
     * @param int $cmid
609
     * @param int $gradeformat
610
     * @param int $userid
611
     * @return grade_information|bool the grade information, or false if there is none.
612
     */
613
    public static function get_mod_grade_info($cmid, $gradeformat, $userid) {
614
        global $DB;
615
 
616
        if (!$cm = $DB->get_record('course_modules', ['id' => $cmid])) {
617
            return false;
618
        }
619
 
620
        if (!$module = $DB->get_record('modules', ['id' => $cm->module])) {
621
            return false;
622
        }
623
 
624
        $params = [
625
            'itemtype' => 'mod',
626
            'itemmodule' => $module->name,
627
            'iteminstance' => $cm->instance,
628
            'courseid' => $cm->course,
629
            'itemnumber' => 0,
630
        ];
631
        $gradeitem = \grade_item::fetch($params);
632
 
633
        if (empty($gradeitem)) {
634
            return false;
635
        }
636
 
637
        $grade = grade_get_grades(
638
            $cm->course,
639
            'mod',
640
            $module->name,
641
            $cm->instance,
642
            $userid
643
        );
644
 
645
        if (!isset($grade->items[0]->grades[$userid])) {
646
            return false;
647
        }
648
 
649
        $gradebookgrade = $grade->items[0]->grades[$userid];
650
 
651
        $dategraded = null;
652
        if (!empty($gradebookgrade->dategraded)) {
653
            $dategraded = $gradebookgrade->dategraded;
654
        }
655
 
656
        $displaygrade = grade_format_gradevalue($gradebookgrade->grade, $gradeitem, true, $gradeformat);
657
 
658
        return new grade_information(
659
            $gradeitem->get_name(),
660
            $gradebookgrade->grade,
661
            $displaygrade,
662
            $dategraded
663
        );
664
    }
665
 
666
    /**
667
     * Helper function to return the grade information for a grade item for a specified user.
668
     *
669
     * @param int $gradeitemid
670
     * @param int $gradeformat
671
     * @param int $userid
672
     * @return grade_information|bool the grade information, or false if there is none.
673
     */
674
    public static function get_grade_item_info($gradeitemid, $gradeformat, $userid) {
675
        if (!$gradeitem = \grade_item::fetch(['id' => $gradeitemid])) {
676
            return false;
677
        }
678
 
679
        $grade = new \grade_grade(['itemid' => $gradeitem->id, 'userid' => $userid]);
680
 
681
        return new grade_information(
682
            $gradeitem->get_name(),
683
            $grade->finalgrade,
684
            grade_format_gradevalue($grade->finalgrade, $gradeitem, true, $gradeformat),
685
            $grade->get_dategraded()
686
        );
687
    }
688
}