See Release Notes
Long Term Support Release
Differences Between: [Versions 39 and 310] [Versions 39 and 311] [Versions 39 and 400]
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 * External grade report user API 19 * 20 * @package gradereport_user 21 * @copyright 2015 Juan Leyva <juan@moodle.com> 22 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later 23 */ 24 25 defined('MOODLE_INTERNAL') || die; 26 27 require_once("$CFG->libdir/externallib.php"); 28 29 30 /** 31 * External grade report API implementation 32 * 33 * @package gradereport_user 34 * @copyright 2015 Juan Leyva <juan@moodle.com> 35 * @category external 36 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later 37 */ 38 class gradereport_user_external extends external_api { 39 40 41 /** 42 * Validate access permissions to the report 43 * 44 * @param int $courseid the courseid 45 * @param int $userid the user id to retrieve data from 46 * @param int $groupid the group id 47 * @return array with the parameters cleaned and other required information 48 * @since Moodle 3.2 49 */ 50 protected static function check_report_access($courseid, $userid, $groupid = 0) { 51 global $USER; 52 53 // Validate the parameter. 54 $params = self::validate_parameters(self::get_grades_table_parameters(), 55 array( 56 'courseid' => $courseid, 57 'userid' => $userid, 58 'groupid' => $groupid, 59 ) 60 ); 61 62 // Compact/extract functions are not recommended. 63 $courseid = $params['courseid']; 64 $userid = $params['userid']; 65 $groupid = $params['groupid']; 66 67 // Function get_course internally throws an exception if the course doesn't exist. 68 $course = get_course($courseid); 69 70 $context = context_course::instance($courseid); 71 self::validate_context($context); 72 73 // Specific capabilities. 74 require_capability('gradereport/user:view', $context); 75 76 $user = null; 77 78 if (empty($userid)) { 79 require_capability('moodle/grade:viewall', $context); 80 } else { 81 $user = core_user::get_user($userid, '*', MUST_EXIST); 82 core_user::require_active_user($user); 83 // Check if we can view the user group (if any). 84 // When userid == 0, we are retrieving all the users, we'll check then if a groupid is required. 85 if (!groups_user_groups_visible($course, $user->id)) { 86 throw new moodle_exception('notingroup'); 87 } 88 } 89 90 $access = false; 91 92 if (has_capability('moodle/grade:viewall', $context)) { 93 // Can view all course grades. 94 $access = true; 95 } else if ($userid == $USER->id and has_capability('moodle/grade:view', $context) and $course->showgrades) { 96 // View own grades. 97 $access = true; 98 } 99 100 if (!$access) { 101 throw new moodle_exception('nopermissiontoviewgrades', 'error'); 102 } 103 104 if (!empty($groupid)) { 105 // Determine is the group is visible to user. 106 if (!groups_group_visible($groupid, $course)) { 107 throw new moodle_exception('notingroup'); 108 } 109 } else { 110 // Check to see if groups are being used here. 111 if ($groupmode = groups_get_course_groupmode($course)) { 112 $groupid = groups_get_course_group($course); 113 // Determine is the group is visible to user (this is particullary for the group 0). 114 if (!groups_group_visible($groupid, $course)) { 115 throw new moodle_exception('notingroup'); 116 } 117 } else { 118 $groupid = 0; 119 } 120 } 121 122 return array($params, $course, $context, $user, $groupid); 123 } 124 125 /** 126 * Get the report data 127 * @param stdClass $course course object 128 * @param stdClass $context context object 129 * @param stdClass $user user object (it can be null for all the users) 130 * @param int $userid the user to retrieve data from, 0 for all 131 * @param int $groupid the group id to filter 132 * @param bool $tabledata whether to get the table data (true) or the gradeitemdata 133 * @return array data and possible warnings 134 * @since Moodle 3.2 135 */ 136 protected static function get_report_data($course, $context, $user, $userid, $groupid, $tabledata = true) { 137 global $CFG; 138 139 $warnings = array(); 140 // Require files here to save some memory in case validation fails. 141 require_once($CFG->dirroot . '/group/lib.php'); 142 require_once($CFG->libdir . '/gradelib.php'); 143 require_once($CFG->dirroot . '/grade/lib.php'); 144 require_once($CFG->dirroot . '/grade/report/user/lib.php'); 145 146 // Force regrade to update items marked as 'needupdate'. 147 grade_regrade_final_grades($course->id); 148 149 $gpr = new grade_plugin_return( 150 array( 151 'type' => 'report', 152 'plugin' => 'user', 153 'courseid' => $course->id, 154 'userid' => $userid) 155 ); 156 157 $reportdata = array(); 158 159 // Just one user. 160 if ($user) { 161 $report = new grade_report_user($course->id, $gpr, $context, $userid); 162 $report->fill_table(); 163 164 $gradeuserdata = array( 165 'courseid' => $course->id, 166 'userid' => $user->id, 167 'userfullname' => fullname($user), 168 'maxdepth' => $report->maxdepth, 169 ); 170 if ($tabledata) { 171 $gradeuserdata['tabledata'] = $report->tabledata; 172 } else { 173 $gradeuserdata['gradeitems'] = $report->gradeitemsdata; 174 } 175 $reportdata[] = $gradeuserdata; 176 } else { 177 $defaultgradeshowactiveenrol = !empty($CFG->grade_report_showonlyactiveenrol); 178 $showonlyactiveenrol = get_user_preferences('grade_report_showonlyactiveenrol', $defaultgradeshowactiveenrol); 179 $showonlyactiveenrol = $showonlyactiveenrol || !has_capability('moodle/course:viewsuspendedusers', $context); 180 181 $gui = new graded_users_iterator($course, null, $groupid); 182 $gui->require_active_enrolment($showonlyactiveenrol); 183 $gui->init(); 184 185 while ($userdata = $gui->next_user()) { 186 $currentuser = $userdata->user; 187 $report = new grade_report_user($course->id, $gpr, $context, $currentuser->id); 188 $report->fill_table(); 189 190 $gradeuserdata = array( 191 'courseid' => $course->id, 192 'userid' => $currentuser->id, 193 'userfullname' => fullname($currentuser), 194 'maxdepth' => $report->maxdepth, 195 ); 196 if ($tabledata) { 197 $gradeuserdata['tabledata'] = $report->tabledata; 198 } else { 199 $gradeuserdata['gradeitems'] = $report->gradeitemsdata; 200 } 201 $reportdata[] = $gradeuserdata; 202 } 203 $gui->close(); 204 } 205 return array($reportdata, $warnings); 206 } 207 208 /** 209 * Describes the parameters for get_grades_table. 210 * 211 * @return external_function_parameters 212 * @since Moodle 2.9 213 */ 214 public static function get_grades_table_parameters() { 215 return new external_function_parameters ( 216 array( 217 'courseid' => new external_value(PARAM_INT, 'Course Id', VALUE_REQUIRED), 218 'userid' => new external_value(PARAM_INT, 'Return grades only for this user (optional)', VALUE_DEFAULT, 0), 219 'groupid' => new external_value(PARAM_INT, 'Get users from this group only', VALUE_DEFAULT, 0) 220 ) 221 ); 222 } 223 224 /** 225 * Returns a list of grades tables for users in a course. 226 * 227 * @param int $courseid Course Id 228 * @param int $userid Only this user (optional) 229 * @param int $groupid Get users from this group only 230 * 231 * @return array the grades tables 232 * @since Moodle 2.9 233 */ 234 public static function get_grades_table($courseid, $userid = 0, $groupid = 0) { 235 global $CFG, $USER; 236 237 list($params, $course, $context, $user, $groupid) = self::check_report_access($courseid, $userid, $groupid); 238 $userid = $params['userid']; 239 240 // We pass userid because it can be still 0. 241 list($tables, $warnings) = self::get_report_data($course, $context, $user, $userid, $groupid); 242 243 $result = array(); 244 $result['tables'] = $tables; 245 $result['warnings'] = $warnings; 246 return $result; 247 } 248 249 /** 250 * Creates a table column structure 251 * 252 * @return array 253 * @since Moodle 2.9 254 */ 255 private static function grades_table_column() { 256 return array ( 257 'class' => new external_value(PARAM_RAW, 'class'), 258 'content' => new external_value(PARAM_RAW, 'cell content'), 259 'headers' => new external_value(PARAM_RAW, 'headers') 260 ); 261 } 262 263 /** 264 * Describes tget_grades_table return value. 265 * 266 * @return external_single_structure 267 * @since Moodle 2.9 268 */ 269 public static function get_grades_table_returns() { 270 return new external_single_structure( 271 array( 272 'tables' => new external_multiple_structure( 273 new external_single_structure( 274 array( 275 'courseid' => new external_value(PARAM_INT, 'course id'), 276 'userid' => new external_value(PARAM_INT, 'user id'), 277 'userfullname' => new external_value(PARAM_TEXT, 'user fullname'), 278 'maxdepth' => new external_value(PARAM_INT, 'table max depth (needed for printing it)'), 279 'tabledata' => new external_multiple_structure( 280 new external_single_structure( 281 array( 282 'itemname' => new external_single_structure( 283 array ( 284 'class' => new external_value(PARAM_RAW, 'class'), 285 'colspan' => new external_value(PARAM_INT, 'col span'), 286 'content' => new external_value(PARAM_RAW, 'cell content'), 287 'celltype' => new external_value(PARAM_RAW, 'cell type'), 288 'id' => new external_value(PARAM_ALPHANUMEXT, 'id') 289 ), 'The item returned data', VALUE_OPTIONAL 290 ), 291 'leader' => new external_single_structure( 292 array ( 293 'class' => new external_value(PARAM_RAW, 'class'), 294 'rowspan' => new external_value(PARAM_INT, 'row span') 295 ), 'The item returned data', VALUE_OPTIONAL 296 ), 297 'weight' => new external_single_structure( 298 self::grades_table_column(), 'weight column', VALUE_OPTIONAL 299 ), 300 'grade' => new external_single_structure( 301 self::grades_table_column(), 'grade column', VALUE_OPTIONAL 302 ), 303 'range' => new external_single_structure( 304 self::grades_table_column(), 'range column', VALUE_OPTIONAL 305 ), 306 'percentage' => new external_single_structure( 307 self::grades_table_column(), 'percentage column', VALUE_OPTIONAL 308 ), 309 'lettergrade' => new external_single_structure( 310 self::grades_table_column(), 'lettergrade column', VALUE_OPTIONAL 311 ), 312 'rank' => new external_single_structure( 313 self::grades_table_column(), 'rank column', VALUE_OPTIONAL 314 ), 315 'average' => new external_single_structure( 316 self::grades_table_column(), 'average column', VALUE_OPTIONAL 317 ), 318 'feedback' => new external_single_structure( 319 self::grades_table_column(), 'feedback column', VALUE_OPTIONAL 320 ), 321 'contributiontocoursetotal' => new external_single_structure( 322 self::grades_table_column(), 'contributiontocoursetotal column', VALUE_OPTIONAL 323 ), 324 ), 'table' 325 ) 326 ) 327 ) 328 ) 329 ), 330 'warnings' => new external_warnings() 331 ) 332 ); 333 } 334 335 /** 336 * Returns description of method parameters 337 * 338 * @return external_function_parameters 339 * @since Moodle 2.9 340 */ 341 public static function view_grade_report_parameters() { 342 return new external_function_parameters( 343 array( 344 'courseid' => new external_value(PARAM_INT, 'id of the course'), 345 'userid' => new external_value(PARAM_INT, 'id of the user, 0 means current user', VALUE_DEFAULT, 0), 346 ) 347 ); 348 } 349 350 /** 351 * Trigger the user report events, do the same that the web interface view of the report 352 * 353 * @param int $courseid id of course 354 * @param int $userid id of the user the report belongs to 355 * @return array of warnings and status result 356 * @since Moodle 2.9 357 * @throws moodle_exception 358 */ 359 public static function view_grade_report($courseid, $userid = 0) { 360 global $CFG, $USER; 361 require_once($CFG->dirroot . "/grade/lib.php"); 362 require_once($CFG->dirroot . "/grade/report/user/lib.php"); 363 364 $params = self::validate_parameters(self::view_grade_report_parameters(), 365 array( 366 'courseid' => $courseid, 367 'userid' => $userid 368 )); 369 370 $warnings = array(); 371 372 $course = get_course($params['courseid']); 373 374 $context = context_course::instance($course->id); 375 self::validate_context($context); 376 377 $userid = $params['userid']; 378 if (empty($userid)) { 379 $userid = $USER->id; 380 } else { 381 $user = core_user::get_user($userid, '*', MUST_EXIST); 382 core_user::require_active_user($user); 383 } 384 385 $access = false; 386 387 if (has_capability('moodle/grade:viewall', $context)) { 388 // Can view all course grades (any user). 389 $access = true; 390 } else if ($userid == $USER->id and has_capability('moodle/grade:view', $context) and $course->showgrades) { 391 // View own grades. 392 $access = true; 393 } 394 395 if (!$access) { 396 throw new moodle_exception('nopermissiontoviewgrades', 'error'); 397 } 398 399 // Create a report instance. We don't need the gpr second parameter. 400 $report = new grade_report_user($course->id, null, $context, $userid); 401 $report->viewed(); 402 403 $result = array(); 404 $result['status'] = true; 405 $result['warnings'] = $warnings; 406 return $result; 407 } 408 409 /** 410 * Returns description of method result value 411 * 412 * @return external_description 413 * @since Moodle 2.9 414 */ 415 public static function view_grade_report_returns() { 416 return new external_single_structure( 417 array( 418 'status' => new external_value(PARAM_BOOL, 'status: true if success'), 419 'warnings' => new external_warnings() 420 ) 421 ); 422 } 423 424 /** 425 * Describes the parameters for get_grade_items. 426 * 427 * @return external_function_parameters 428 * @since Moodle 3.2 429 */ 430 public static function get_grade_items_parameters() { 431 return self::get_grades_table_parameters(); 432 } 433 434 /** 435 * Returns the complete list of grade items for users in a course. 436 * 437 * @param int $courseid Course Id 438 * @param int $userid Only this user (optional) 439 * @param int $groupid Get users from this group only 440 * 441 * @return array the grades tables 442 * @since Moodle 3.2 443 */ 444 public static function get_grade_items($courseid, $userid = 0, $groupid = 0) { 445 global $CFG, $USER; 446 447 list($params, $course, $context, $user, $groupid) = self::check_report_access($courseid, $userid, $groupid); 448 $userid = $params['userid']; 449 450 // We pass userid because it can be still 0. 451 list($gradeitems, $warnings) = self::get_report_data($course, $context, $user, $userid, $groupid, false); 452 453 foreach ($gradeitems as $gradeitem) { 454 if (isset($gradeitem['feedback']) and isset($gradeitem['feedbackformat'])) { 455 list($gradeitem['feedback'], $gradeitem['feedbackformat']) = 456 external_format_text($gradeitem['feedback'], $gradeitem['feedbackformat'], $context->id); 457 } 458 } 459 460 $result = array(); 461 $result['usergrades'] = $gradeitems; 462 $result['warnings'] = $warnings; 463 return $result; 464 } 465 466 /** 467 * Describes tget_grade_items return value. 468 * 469 * @return external_single_structure 470 * @since Moodle 3.2 471 */ 472 public static function get_grade_items_returns() { 473 return new external_single_structure( 474 array( 475 'usergrades' => new external_multiple_structure( 476 new external_single_structure( 477 array( 478 'courseid' => new external_value(PARAM_INT, 'course id'), 479 'userid' => new external_value(PARAM_INT, 'user id'), 480 'userfullname' => new external_value(PARAM_TEXT, 'user fullname'), 481 'maxdepth' => new external_value(PARAM_INT, 'table max depth (needed for printing it)'), 482 'gradeitems' => new external_multiple_structure( 483 new external_single_structure( 484 array( 485 'id' => new external_value(PARAM_INT, 'Grade item id'), 486 'itemname' => new external_value(PARAM_TEXT, 'Grade item name'), 487 'itemtype' => new external_value(PARAM_ALPHA, 'Grade item type'), 488 'itemmodule' => new external_value(PARAM_PLUGIN, 'Grade item module'), 489 'iteminstance' => new external_value(PARAM_INT, 'Grade item instance'), 490 'itemnumber' => new external_value(PARAM_INT, 'Grade item item number'), 491 'categoryid' => new external_value(PARAM_INT, 'Grade item category id'), 492 'outcomeid' => new external_value(PARAM_INT, 'Outcome id'), 493 'scaleid' => new external_value(PARAM_INT, 'Scale id'), 494 'locked' => new external_value(PARAM_BOOL, 'Grade item for user locked?', VALUE_OPTIONAL), 495 'cmid' => new external_value(PARAM_INT, 'Course module id (if type mod)', VALUE_OPTIONAL), 496 'weightraw' => new external_value(PARAM_FLOAT, 'Weight raw', VALUE_OPTIONAL), 497 'weightformatted' => new external_value(PARAM_NOTAGS, 'Weight', VALUE_OPTIONAL), 498 'status' => new external_value(PARAM_ALPHA, 'Status', VALUE_OPTIONAL), 499 'graderaw' => new external_value(PARAM_FLOAT, 'Grade raw', VALUE_OPTIONAL), 500 'gradedatesubmitted' => new external_value(PARAM_INT, 'Grade submit date', VALUE_OPTIONAL), 501 'gradedategraded' => new external_value(PARAM_INT, 'Grade graded date', VALUE_OPTIONAL), 502 'gradehiddenbydate' => new external_value(PARAM_BOOL, 'Grade hidden by date?', VALUE_OPTIONAL), 503 'gradeneedsupdate' => new external_value(PARAM_BOOL, 'Grade needs update?', VALUE_OPTIONAL), 504 'gradeishidden' => new external_value(PARAM_BOOL, 'Grade is hidden?', VALUE_OPTIONAL), 505 'gradeislocked' => new external_value(PARAM_BOOL, 'Grade is locked?', VALUE_OPTIONAL), 506 'gradeisoverridden' => new external_value(PARAM_BOOL, 'Grade overridden?', VALUE_OPTIONAL), 507 'gradeformatted' => new external_value(PARAM_NOTAGS, 'The grade formatted', VALUE_OPTIONAL), 508 'grademin' => new external_value(PARAM_FLOAT, 'Grade min', VALUE_OPTIONAL), 509 'grademax' => new external_value(PARAM_FLOAT, 'Grade max', VALUE_OPTIONAL), 510 'rangeformatted' => new external_value(PARAM_NOTAGS, 'Range formatted', VALUE_OPTIONAL), 511 'percentageformatted' => new external_value(PARAM_NOTAGS, 'Percentage', VALUE_OPTIONAL), 512 'lettergradeformatted' => new external_value(PARAM_NOTAGS, 'Letter grade', VALUE_OPTIONAL), 513 'rank' => new external_value(PARAM_INT, 'Rank in the course', VALUE_OPTIONAL), 514 'numusers' => new external_value(PARAM_INT, 'Num users in course', VALUE_OPTIONAL), 515 'averageformatted' => new external_value(PARAM_NOTAGS, 'Grade average', VALUE_OPTIONAL), 516 'feedback' => new external_value(PARAM_RAW, 'Grade feedback', VALUE_OPTIONAL), 517 'feedbackformat' => new external_format_value('feedback', VALUE_OPTIONAL), 518 ), 'Grade items' 519 ) 520 ) 521 ) 522 ) 523 ), 524 'warnings' => new external_warnings() 525 ) 526 ); 527 } 528 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body