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