Differences Between: [Versions 310 and 311] [Versions 310 and 400] [Versions 39 and 310]
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 'useridnumber' => $user->idnumber, 169 'maxdepth' => $report->maxdepth, 170 ); 171 if ($tabledata) { 172 $gradeuserdata['tabledata'] = $report->tabledata; 173 } else { 174 $gradeuserdata['gradeitems'] = $report->gradeitemsdata; 175 } 176 $reportdata[] = $gradeuserdata; 177 } else { 178 $defaultgradeshowactiveenrol = !empty($CFG->grade_report_showonlyactiveenrol); 179 $showonlyactiveenrol = get_user_preferences('grade_report_showonlyactiveenrol', $defaultgradeshowactiveenrol); 180 $showonlyactiveenrol = $showonlyactiveenrol || !has_capability('moodle/course:viewsuspendedusers', $context); 181 182 $gui = new graded_users_iterator($course, null, $groupid); 183 $gui->require_active_enrolment($showonlyactiveenrol); 184 $gui->init(); 185 186 while ($userdata = $gui->next_user()) { 187 $currentuser = $userdata->user; 188 $report = new grade_report_user($course->id, $gpr, $context, $currentuser->id); 189 $report->fill_table(); 190 191 $gradeuserdata = array( 192 'courseid' => $course->id, 193 'userid' => $currentuser->id, 194 'userfullname' => fullname($currentuser), 195 'useridnumber' => $currentuser->idnumber, 196 'maxdepth' => $report->maxdepth, 197 ); 198 if ($tabledata) { 199 $gradeuserdata['tabledata'] = $report->tabledata; 200 } else { 201 $gradeuserdata['gradeitems'] = $report->gradeitemsdata; 202 } 203 $reportdata[] = $gradeuserdata; 204 } 205 $gui->close(); 206 } 207 return array($reportdata, $warnings); 208 } 209 210 /** 211 * Describes the parameters for get_grades_table. 212 * 213 * @return external_function_parameters 214 * @since Moodle 2.9 215 */ 216 public static function get_grades_table_parameters() { 217 return new external_function_parameters ( 218 array( 219 'courseid' => new external_value(PARAM_INT, 'Course Id', VALUE_REQUIRED), 220 'userid' => new external_value(PARAM_INT, 'Return grades only for this user (optional)', VALUE_DEFAULT, 0), 221 'groupid' => new external_value(PARAM_INT, 'Get users from this group only', VALUE_DEFAULT, 0) 222 ) 223 ); 224 } 225 226 /** 227 * Returns a list of grades tables for users in a course. 228 * 229 * @param int $courseid Course Id 230 * @param int $userid Only this user (optional) 231 * @param int $groupid Get users from this group only 232 * 233 * @return array the grades tables 234 * @since Moodle 2.9 235 */ 236 public static function get_grades_table($courseid, $userid = 0, $groupid = 0) { 237 global $CFG, $USER; 238 239 list($params, $course, $context, $user, $groupid) = self::check_report_access($courseid, $userid, $groupid); 240 $userid = $params['userid']; 241 242 // We pass userid because it can be still 0. 243 list($tables, $warnings) = self::get_report_data($course, $context, $user, $userid, $groupid); 244 245 $result = array(); 246 $result['tables'] = $tables; 247 $result['warnings'] = $warnings; 248 return $result; 249 } 250 251 /** 252 * Creates a table column structure 253 * 254 * @return array 255 * @since Moodle 2.9 256 */ 257 private static function grades_table_column() { 258 return array ( 259 'class' => new external_value(PARAM_RAW, 'class'), 260 'content' => new external_value(PARAM_RAW, 'cell content'), 261 'headers' => new external_value(PARAM_RAW, 'headers') 262 ); 263 } 264 265 /** 266 * Describes tget_grades_table return value. 267 * 268 * @return external_single_structure 269 * @since Moodle 2.9 270 */ 271 public static function get_grades_table_returns() { 272 return new external_single_structure( 273 array( 274 'tables' => new external_multiple_structure( 275 new external_single_structure( 276 array( 277 'courseid' => new external_value(PARAM_INT, 'course id'), 278 'userid' => new external_value(PARAM_INT, 'user id'), 279 'userfullname' => new external_value(PARAM_TEXT, 'user fullname'), 280 'maxdepth' => new external_value(PARAM_INT, 'table max depth (needed for printing it)'), 281 'tabledata' => new external_multiple_structure( 282 new external_single_structure( 283 array( 284 'itemname' => new external_single_structure( 285 array ( 286 'class' => new external_value(PARAM_RAW, 'class'), 287 'colspan' => new external_value(PARAM_INT, 'col span'), 288 'content' => new external_value(PARAM_RAW, 'cell content'), 289 'celltype' => new external_value(PARAM_RAW, 'cell type'), 290 'id' => new external_value(PARAM_ALPHANUMEXT, 'id') 291 ), 'The item returned data', VALUE_OPTIONAL 292 ), 293 'leader' => new external_single_structure( 294 array ( 295 'class' => new external_value(PARAM_RAW, 'class'), 296 'rowspan' => new external_value(PARAM_INT, 'row span') 297 ), 'The item returned data', VALUE_OPTIONAL 298 ), 299 'weight' => new external_single_structure( 300 self::grades_table_column(), 'weight column', VALUE_OPTIONAL 301 ), 302 'grade' => new external_single_structure( 303 self::grades_table_column(), 'grade column', VALUE_OPTIONAL 304 ), 305 'range' => new external_single_structure( 306 self::grades_table_column(), 'range column', VALUE_OPTIONAL 307 ), 308 'percentage' => new external_single_structure( 309 self::grades_table_column(), 'percentage column', VALUE_OPTIONAL 310 ), 311 'lettergrade' => new external_single_structure( 312 self::grades_table_column(), 'lettergrade column', VALUE_OPTIONAL 313 ), 314 'rank' => new external_single_structure( 315 self::grades_table_column(), 'rank column', VALUE_OPTIONAL 316 ), 317 'average' => new external_single_structure( 318 self::grades_table_column(), 'average column', VALUE_OPTIONAL 319 ), 320 'feedback' => new external_single_structure( 321 self::grades_table_column(), 'feedback column', VALUE_OPTIONAL 322 ), 323 'contributiontocoursetotal' => new external_single_structure( 324 self::grades_table_column(), 'contributiontocoursetotal column', VALUE_OPTIONAL 325 ), 326 ), 'table' 327 ) 328 ) 329 ) 330 ) 331 ), 332 'warnings' => new external_warnings() 333 ) 334 ); 335 } 336 337 /** 338 * Returns description of method parameters 339 * 340 * @return external_function_parameters 341 * @since Moodle 2.9 342 */ 343 public static function view_grade_report_parameters() { 344 return new external_function_parameters( 345 array( 346 'courseid' => new external_value(PARAM_INT, 'id of the course'), 347 'userid' => new external_value(PARAM_INT, 'id of the user, 0 means current user', VALUE_DEFAULT, 0), 348 ) 349 ); 350 } 351 352 /** 353 * Trigger the user report events, do the same that the web interface view of the report 354 * 355 * @param int $courseid id of course 356 * @param int $userid id of the user the report belongs to 357 * @return array of warnings and status result 358 * @since Moodle 2.9 359 * @throws moodle_exception 360 */ 361 public static function view_grade_report($courseid, $userid = 0) { 362 global $CFG, $USER; 363 require_once($CFG->dirroot . "/grade/lib.php"); 364 require_once($CFG->dirroot . "/grade/report/user/lib.php"); 365 366 $params = self::validate_parameters(self::view_grade_report_parameters(), 367 array( 368 'courseid' => $courseid, 369 'userid' => $userid 370 )); 371 372 $warnings = array(); 373 374 $course = get_course($params['courseid']); 375 376 $context = context_course::instance($course->id); 377 self::validate_context($context); 378 379 $userid = $params['userid']; 380 if (empty($userid)) { 381 $userid = $USER->id; 382 } else { 383 $user = core_user::get_user($userid, '*', MUST_EXIST); 384 core_user::require_active_user($user); 385 } 386 387 $access = false; 388 389 if (has_capability('moodle/grade:viewall', $context)) { 390 // Can view all course grades (any user). 391 $access = true; 392 } else if ($userid == $USER->id and has_capability('moodle/grade:view', $context) and $course->showgrades) { 393 // View own grades. 394 $access = true; 395 } 396 397 if (!$access) { 398 throw new moodle_exception('nopermissiontoviewgrades', 'error'); 399 } 400 401 // Create a report instance. We don't need the gpr second parameter. 402 $report = new grade_report_user($course->id, null, $context, $userid); 403 $report->viewed(); 404 405 $result = array(); 406 $result['status'] = true; 407 $result['warnings'] = $warnings; 408 return $result; 409 } 410 411 /** 412 * Returns description of method result value 413 * 414 * @return external_description 415 * @since Moodle 2.9 416 */ 417 public static function view_grade_report_returns() { 418 return new external_single_structure( 419 array( 420 'status' => new external_value(PARAM_BOOL, 'status: true if success'), 421 'warnings' => new external_warnings() 422 ) 423 ); 424 } 425 426 /** 427 * Describes the parameters for get_grade_items. 428 * 429 * @return external_function_parameters 430 * @since Moodle 3.2 431 */ 432 public static function get_grade_items_parameters() { 433 return self::get_grades_table_parameters(); 434 } 435 436 /** 437 * Returns the complete list of grade items for users in a course. 438 * 439 * @param int $courseid Course Id 440 * @param int $userid Only this user (optional) 441 * @param int $groupid Get users from this group only 442 * 443 * @return array the grades tables 444 * @since Moodle 3.2 445 */ 446 public static function get_grade_items($courseid, $userid = 0, $groupid = 0) { 447 global $CFG, $USER; 448 449 list($params, $course, $context, $user, $groupid) = self::check_report_access($courseid, $userid, $groupid); 450 $userid = $params['userid']; 451 452 // We pass userid because it can be still 0. 453 list($gradeitems, $warnings) = self::get_report_data($course, $context, $user, $userid, $groupid, false); 454 455 foreach ($gradeitems as $gradeitem) { 456 if (isset($gradeitem['feedback']) and isset($gradeitem['feedbackformat'])) { 457 list($gradeitem['feedback'], $gradeitem['feedbackformat']) = 458 external_format_text($gradeitem['feedback'], $gradeitem['feedbackformat'], $context->id); 459 } 460 } 461 462 $result = array(); 463 $result['usergrades'] = $gradeitems; 464 $result['warnings'] = $warnings; 465 return $result; 466 } 467 468 /** 469 * Describes tget_grade_items return value. 470 * 471 * @return external_single_structure 472 * @since Moodle 3.2 473 */ 474 public static function get_grade_items_returns() { 475 return new external_single_structure( 476 array( 477 'usergrades' => new external_multiple_structure( 478 new external_single_structure( 479 array( 480 'courseid' => new external_value(PARAM_INT, 'course id'), 481 'userid' => new external_value(PARAM_INT, 'user id'), 482 'userfullname' => new external_value(PARAM_TEXT, 'user fullname'), 483 'useridnumber' => new external_value( 484 core_user::get_property_type('idnumber'), 'user idnumber'), 485 'maxdepth' => new external_value(PARAM_INT, 'table max depth (needed for printing it)'), 486 'gradeitems' => new external_multiple_structure( 487 new external_single_structure( 488 array( 489 'id' => new external_value(PARAM_INT, 'Grade item id'), 490 'itemname' => new external_value(PARAM_TEXT, 'Grade item name'), 491 'itemtype' => new external_value(PARAM_ALPHA, 'Grade item type'), 492 'itemmodule' => new external_value(PARAM_PLUGIN, 'Grade item module'), 493 'iteminstance' => new external_value(PARAM_INT, 'Grade item instance'), 494 'itemnumber' => new external_value(PARAM_INT, 'Grade item item number'), 495 'idnumber' => new external_value(PARAM_TEXT, 'Grade item idnumber'), 496 'categoryid' => new external_value(PARAM_INT, 'Grade item category id'), 497 'outcomeid' => new external_value(PARAM_INT, 'Outcome id'), 498 'scaleid' => new external_value(PARAM_INT, 'Scale id'), 499 'locked' => new external_value(PARAM_BOOL, 'Grade item for user locked?', VALUE_OPTIONAL), 500 'cmid' => new external_value(PARAM_INT, 'Course module id (if type mod)', VALUE_OPTIONAL), 501 'weightraw' => new external_value(PARAM_FLOAT, 'Weight raw', VALUE_OPTIONAL), 502 'weightformatted' => new external_value(PARAM_NOTAGS, 'Weight', VALUE_OPTIONAL), 503 'status' => new external_value(PARAM_ALPHA, 'Status', VALUE_OPTIONAL), 504 'graderaw' => new external_value(PARAM_FLOAT, 'Grade raw', VALUE_OPTIONAL), 505 'gradedatesubmitted' => new external_value(PARAM_INT, 'Grade submit date', VALUE_OPTIONAL), 506 'gradedategraded' => new external_value(PARAM_INT, 'Grade graded date', VALUE_OPTIONAL), 507 'gradehiddenbydate' => new external_value(PARAM_BOOL, 'Grade hidden by date?', VALUE_OPTIONAL), 508 'gradeneedsupdate' => new external_value(PARAM_BOOL, 'Grade needs update?', VALUE_OPTIONAL), 509 'gradeishidden' => new external_value(PARAM_BOOL, 'Grade is hidden?', VALUE_OPTIONAL), 510 'gradeislocked' => new external_value(PARAM_BOOL, 'Grade is locked?', VALUE_OPTIONAL), 511 'gradeisoverridden' => new external_value(PARAM_BOOL, 'Grade overridden?', VALUE_OPTIONAL), 512 'gradeformatted' => new external_value(PARAM_NOTAGS, 'The grade formatted', VALUE_OPTIONAL), 513 'grademin' => new external_value(PARAM_FLOAT, 'Grade min', VALUE_OPTIONAL), 514 'grademax' => new external_value(PARAM_FLOAT, 'Grade max', VALUE_OPTIONAL), 515 'rangeformatted' => new external_value(PARAM_NOTAGS, 'Range formatted', VALUE_OPTIONAL), 516 'percentageformatted' => new external_value(PARAM_NOTAGS, 'Percentage', VALUE_OPTIONAL), 517 'lettergradeformatted' => new external_value(PARAM_NOTAGS, 'Letter grade', VALUE_OPTIONAL), 518 'rank' => new external_value(PARAM_INT, 'Rank in the course', VALUE_OPTIONAL), 519 'numusers' => new external_value(PARAM_INT, 'Num users in course', VALUE_OPTIONAL), 520 'averageformatted' => new external_value(PARAM_NOTAGS, 'Grade average', VALUE_OPTIONAL), 521 'feedback' => new external_value(PARAM_RAW, 'Grade feedback', VALUE_OPTIONAL), 522 'feedbackformat' => new external_format_value('feedback', VALUE_OPTIONAL), 523 ), 'Grade items' 524 ) 525 ) 526 ) 527 ) 528 ), 529 'warnings' => new external_warnings() 530 ) 531 ); 532 } 533 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body