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
 * H5P activity grader class.
19
 *
20
 * @package    mod_h5pactivity
21
 * @since      Moodle 3.9
22
 * @copyright  2020 Ferran Recio <ferran@moodle.com>
23
 * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
24
 */
25
 
26
namespace mod_h5pactivity\local;
27
 
28
use context_module;
29
use cm_info;
30
use moodle_recordset;
31
use stdClass;
32
 
33
/**
34
 * Class for handling H5P activity grading.
35
 *
36
 * @package    mod_h5pactivity
37
 * @since      Moodle 3.9
38
 * @copyright  2020 Ferran Recio <ferran@moodle.com>
39
 * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
40
 */
41
class grader {
42
 
43
    /** @var stdClass course_module record. */
44
    private $instance;
45
 
46
    /** @var string idnumber course_modules idnumber. */
47
    private $idnumber;
48
 
49
    /**
50
     * Class contructor.
51
     *
52
     * @param stdClass $instance H5Pactivity instance object
53
     * @param string $idnumber course_modules idnumber
54
     */
55
    public function __construct(stdClass $instance, string $idnumber = '') {
56
        $this->instance = $instance;
57
        $this->idnumber = $idnumber;
58
    }
59
 
60
    /**
61
     * Delete grade item for given mod_h5pactivity instance.
62
     *
63
     * @return int Returns GRADE_UPDATE_OK, GRADE_UPDATE_FAILED, GRADE_UPDATE_MULTIPLE or GRADE_UPDATE_ITEM_LOCKED
64
     */
65
    public function grade_item_delete(): ?int {
66
        global $CFG;
67
        require_once($CFG->libdir.'/gradelib.php');
68
 
69
        return grade_update('mod/h5pactivity', $this->instance->course, 'mod', 'h5pactivity',
70
                $this->instance->id, 0, null, ['deleted' => 1]);
71
    }
72
 
73
    /**
74
     * Creates or updates grade item for the given mod_h5pactivity instance.
75
     *
76
     * @param mixed $grades optional array/object of grade(s); 'reset' means reset grades in gradebook
77
     * @return int 0 if ok, error code otherwise
78
     */
79
    public function grade_item_update($grades = null): int {
80
        global $CFG;
81
        require_once($CFG->libdir.'/gradelib.php');
82
 
83
        $item = [];
84
        $item['itemname'] = clean_param($this->instance->name, PARAM_NOTAGS);
85
        $item['gradetype'] = GRADE_TYPE_VALUE;
86
        if (!empty($this->idnumber)) {
87
            $item['idnumber'] = $this->idnumber;
88
        }
89
 
90
        if ($this->instance->grade > 0) {
91
            $item['gradetype'] = GRADE_TYPE_VALUE;
92
            $item['grademax']  = $this->instance->grade;
93
            $item['grademin']  = 0;
94
        } else if ($this->instance->grade < 0) {
95
            $item['gradetype'] = GRADE_TYPE_SCALE;
96
            $item['scaleid']   = -$this->instance->grade;
97
        } else {
98
            $item['gradetype'] = GRADE_TYPE_NONE;
99
        }
100
 
101
        if ($grades === 'reset') {
102
            $item['reset'] = true;
103
            $grades = null;
104
        }
105
 
106
        return grade_update('mod/h5pactivity', $this->instance->course, 'mod',
107
                'h5pactivity', $this->instance->id, 0, $grades, $item);
108
    }
109
 
110
    /**
111
     * Update grades in the gradebook.
112
     *
113
     * @param int $userid Update grade of specific user only, 0 means all participants.
114
     */
115
    public function update_grades(int $userid = 0): void {
116
        // Scaled and none grading doesn't have grade calculation.
117
        if ($this->instance->grade <= 0) {
118
            $this->grade_item_update();
119
            return;
120
        }
121
        // Populate array of grade objects indexed by userid.
122
        $grades = $this->get_user_grades_for_gradebook($userid);
123
 
124
        if (!empty($grades)) {
125
            $this->grade_item_update($grades);
126
        } else {
127
            $this->grade_item_update();
128
        }
129
    }
130
 
131
    /**
132
     * Get an updated list of user grades and feedback for the gradebook.
133
     *
134
     * @param int $userid int or 0 for all users
135
     * @return array of grade data formated for the gradebook api
136
     *         The data required by the gradebook api is userid,
137
     *                                                   rawgrade,
138
     *                                                   feedback,
139
     *                                                   feedbackformat,
140
     *                                                   usermodified,
141
     *                                                   dategraded,
142
     *                                                   datesubmitted
143
     */
144
    private function get_user_grades_for_gradebook(int $userid = 0): array {
145
        $grades = [];
146
 
147
        // In case of using manual grading this update must delete previous automatic gradings.
148
        if ($this->instance->grademethod == manager::GRADEMANUAL || !$this->instance->enabletracking) {
149
            return $this->get_user_grades_for_deletion($userid);
150
        }
151
 
152
        $manager = manager::create_from_instance($this->instance);
153
 
154
        $scores = $manager->get_users_scaled_score($userid);
155
        if (!$scores) {
156
            return $grades;
157
        }
158
 
159
        // Maxgrade depends on the type of grade used:
160
        // - grade > 0: regular quantitative grading.
161
        // - grade = 0: no grading.
162
        // - grade < 0: scale used.
163
        $maxgrade = floatval($this->instance->grade);
164
 
165
        // Convert scaled scores into gradebok compatible objects.
166
        foreach ($scores as $userid => $score) {
167
            $grades[$userid] = [
168
                'userid' => $userid,
169
                'rawgrade' => $maxgrade * $score->scaled,
170
                'dategraded' => $score->timemodified,
171
                'datesubmitted' => $score->timemodified,
172
            ];
173
        }
174
 
175
        return $grades;
176
    }
177
 
178
    /**
179
     * Get an deletion list of user grades and feedback for the gradebook.
180
     *
181
     * This method is used to delete all autmatic gradings when grading method is set to manual.
182
     *
183
     * @param int $userid int or 0 for all users
184
     * @return array of grade data formated for the gradebook api
185
     *         The data required by the gradebook api is userid,
186
     *                                                   rawgrade (null to delete),
187
     *                                                   dategraded,
188
     *                                                   datesubmitted
189
     */
190
    private function get_user_grades_for_deletion(int $userid = 0): array {
191
        $grades = [];
192
 
193
        if ($userid) {
194
            $grades[$userid] = [
195
                'userid' => $userid,
196
                'rawgrade' => null,
197
                'dategraded' => time(),
198
                'datesubmitted' => time(),
199
            ];
200
        } else {
201
            $manager = manager::create_from_instance($this->instance);
202
            $users = get_enrolled_users($manager->get_context(), 'mod/h5pactivity:submit');
203
            foreach ($users as $user) {
204
                $grades[$user->id] = [
205
                    'userid' => $user->id,
206
                    'rawgrade' => null,
207
                    'dategraded' => time(),
208
                    'datesubmitted' => time(),
209
                ];
210
            }
211
        }
212
        return $grades;
213
    }
214
}