Differences Between: [Versions 310 and 402] [Versions 39 and 402]
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 * Grade item storage for mod_forum. 19 * 20 * @package mod_forum 21 * @copyright Andrew Nicols <andrew@nicols.co.uk> 22 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later 23 */ 24 25 declare(strict_types = 1); 26 27 namespace mod_forum\grades; 28 29 use coding_exception; 30 use context; 31 use core_grades\component_gradeitem; 32 use core_grades\local\gradeitem as gradeitem; 33 use mod_forum\local\container as forum_container; 34 use mod_forum\local\entities\forum as forum_entity; 35 use required_capability_exception; 36 use stdClass; 37 38 /** 39 * Grade item storage for mod_forum. 40 * 41 * @package mod_forum 42 * @copyright Andrew Nicols <andrew@nicols.co.uk> 43 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later 44 */ 45 class forum_gradeitem extends component_gradeitem { 46 /** @var forum_entity The forum entity being graded */ 47 protected $forum; 48 49 /** 50 * Return an instance based on the context in which it is used. 51 * 52 * @param context $context 53 */ 54 public static function load_from_context(context $context): parent { 55 // Get all the factories that are required. 56 $vaultfactory = forum_container::get_vault_factory(); 57 $forumvault = $vaultfactory->get_forum_vault(); 58 59 $forum = $forumvault->get_from_course_module_id((int) $context->instanceid); 60 61 return static::load_from_forum_entity($forum); 62 } 63 64 /** 65 * Return an instance using the forum_entity instance. 66 * 67 * @param forum_entity $forum 68 * 69 * @return forum_gradeitem 70 */ 71 public static function load_from_forum_entity(forum_entity $forum): self { 72 $instance = new static('mod_forum', $forum->get_context(), 'forum'); 73 $instance->forum = $forum; 74 75 return $instance; 76 } 77 78 /** 79 * The table name used for grading. 80 * 81 * @return string 82 */ 83 protected function get_table_name(): string { 84 return 'forum_grades'; 85 } 86 87 /** 88 * Whether grading is enabled for this item. 89 * 90 * @return bool 91 */ 92 public function is_grading_enabled(): bool { 93 return $this->forum->is_grading_enabled(); 94 } 95 96 /** 97 * Whether the grader can grade the gradee. 98 * 99 * @param stdClass $gradeduser The user being graded 100 * @param stdClass $grader The user who is grading 101 * @return bool 102 */ 103 public function user_can_grade(stdClass $gradeduser, stdClass $grader): bool { 104 // Validate the required capabilities. 105 $managerfactory = forum_container::get_manager_factory(); 106 $capabilitymanager = $managerfactory->get_capability_manager($this->forum); 107 108 return $capabilitymanager->can_grade($grader, $gradeduser); 109 } 110 111 /** 112 * Require that the user can grade, throwing an exception if not. 113 * 114 * @param stdClass $gradeduser The user being graded 115 * @param stdClass $grader The user who is grading 116 * @throws required_capability_exception 117 */ 118 public function require_user_can_grade(stdClass $gradeduser, stdClass $grader): void { 119 if (!$this->user_can_grade($gradeduser, $grader)) { 120 throw new required_capability_exception($this->forum->get_context(), 'mod/forum:grade', 'nopermissions', ''); 121 } 122 } 123 124 /** 125 * Get the grade value for this instance. 126 * The itemname is translated to the relevant grade field on the forum entity. 127 * 128 * @return int 129 */ 130 protected function get_gradeitem_value(): int { 131 $getter = "get_grade_for_{$this->itemname}"; 132 133 return $this->forum->{$getter}(); 134 } 135 136 /** 137 * Create an empty forum_grade for the specified user and grader. 138 * 139 * @param stdClass $gradeduser The user being graded 140 * @param stdClass $grader The user who is grading 141 * @return stdClass The newly created grade record 142 * @throws \dml_exception 143 */ 144 public function create_empty_grade(stdClass $gradeduser, stdClass $grader): stdClass { 145 global $DB; 146 147 $grade = (object) [ 148 'forum' => $this->forum->get_id(), 149 'itemnumber' => $this->itemnumber, 150 'userid' => $gradeduser->id, 151 'timemodified' => time(), 152 ]; 153 $grade->timecreated = $grade->timemodified; 154 155 $gradeid = $DB->insert_record($this->get_table_name(), $grade); 156 157 return $DB->get_record($this->get_table_name(), ['id' => $gradeid]); 158 } 159 160 /** 161 * Get the grade for the specified user. 162 * 163 * @param stdClass $gradeduser The user being graded 164 * @param stdClass $grader The user who is grading 165 * @return stdClass The grade value 166 * @throws \dml_exception 167 */ 168 public function get_grade_for_user(stdClass $gradeduser, stdClass $grader = null): ?stdClass { 169 global $DB; 170 171 $params = [ 172 'forum' => $this->forum->get_id(), 173 'itemnumber' => $this->itemnumber, 174 'userid' => $gradeduser->id, 175 ]; 176 177 $grade = $DB->get_record($this->get_table_name(), $params); 178 179 if (empty($grade)) { 180 $grade = $this->create_empty_grade($gradeduser, $grader); 181 } 182 183 return $grade ?: null; 184 } 185 186 /** 187 * Get the grade status for the specified user. 188 * Check if a grade obj exists & $grade->grade !== null. 189 * If the user has a grade return true. 190 * 191 * @param stdClass $gradeduser The user being graded 192 * @return bool The grade exists 193 * @throws \dml_exception 194 */ 195 public function user_has_grade(stdClass $gradeduser): bool { 196 global $DB; 197 198 $params = [ 199 'forum' => $this->forum->get_id(), 200 'itemnumber' => $this->itemnumber, 201 'userid' => $gradeduser->id, 202 ]; 203 204 $grade = $DB->get_record($this->get_table_name(), $params); 205 206 if (empty($grade) || $grade->grade === null) { 207 return false; 208 } 209 return true; 210 } 211 212 /** 213 * Get grades for all users for the specified gradeitem. 214 * 215 * @return stdClass[] The grades 216 * @throws \dml_exception 217 */ 218 public function get_all_grades(): array { 219 global $DB; 220 221 return $DB->get_records($this->get_table_name(), [ 222 'forum' => $this->forum->get_id(), 223 'itemnumber' => $this->itemnumber, 224 ]); 225 } 226 227 /** 228 * Get the grade item instance id. 229 * 230 * This is typically the cmid in the case of an activity, and relates to the iteminstance field in the grade_items 231 * table. 232 * 233 * @return int 234 */ 235 public function get_grade_instance_id(): int { 236 return (int) $this->forum->get_id(); 237 } 238 239 /** 240 * Defines whether only active users in the course should be gradeable. 241 * 242 * @return bool Whether only active users in the course should be gradeable. 243 */ 244 public function should_grade_only_active_users(): bool { 245 global $CFG; 246 247 $showonlyactiveenrolconfig = !empty($CFG->grade_report_showonlyactiveenrol); 248 // Grade only active users enrolled in the course either when the 'grade_report_showonlyactiveenrol' user 249 // preference is set to true or the current user does not have the capability to view suspended users in the 250 // course. In cases where the 'grade_report_showonlyactiveenrol' user preference is not set we are falling back 251 // to the set value for the 'grade_report_showonlyactiveenrol' config. 252 return get_user_preferences('grade_report_showonlyactiveenrol', $showonlyactiveenrolconfig) || 253 !has_capability('moodle/course:viewsuspendedusers', \context_course::instance($this->forum->get_course_id())); 254 } 255 256 /** 257 * Create or update the grade. 258 * 259 * @param stdClass $grade 260 * @return bool Success 261 * @throws \dml_exception 262 * @throws \moodle_exception 263 * @throws coding_exception 264 */ 265 protected function store_grade(stdClass $grade): bool { 266 global $CFG, $DB; 267 require_once("{$CFG->dirroot}/mod/forum/lib.php"); 268 269 if ($grade->forum != $this->forum->get_id()) { 270 throw new coding_exception('Incorrect forum provided for this grade'); 271 } 272 273 if ($grade->itemnumber != $this->itemnumber) { 274 throw new coding_exception('Incorrect itemnumber provided for this grade'); 275 } 276 277 // Ensure that the grade is valid. 278 $this->check_grade_validity($grade->grade); 279 280 $grade->forum = $this->forum->get_id(); 281 $grade->timemodified = time(); 282 283 $DB->update_record($this->get_table_name(), $grade); 284 285 // Update in the gradebook (note that 'cmidnumber' is required in order to update grades). 286 $mapper = forum_container::get_legacy_data_mapper_factory()->get_forum_data_mapper(); 287 $forumrecord = $mapper->to_legacy_object($this->forum); 288 $forumrecord->cmidnumber = $this->forum->get_course_module_record()->idnumber; 289 290 forum_update_grades($forumrecord, $grade->userid); 291 292 return true; 293 } 294 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body