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 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body