[ Index ] |
PHP Cross Reference of moodle-2.8 |
[Summary view] [Print] [Text view]
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 * Core grades external functions 19 * 20 * @package core_grades 21 * @copyright 2012 Andrew Davis 22 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later 23 * @since Moodle 2.7 24 */ 25 26 defined('MOODLE_INTERNAL') || die; 27 28 require_once("$CFG->libdir/externallib.php"); 29 require_once("$CFG->libdir/gradelib.php"); 30 require_once("$CFG->dirroot/grade/querylib.php"); 31 32 /** 33 * core grades functions 34 */ 35 class core_grades_external extends external_api { 36 /** 37 * Returns description of method parameters 38 * 39 * @return external_function_parameters 40 * @since Moodle 2.7 41 */ 42 public static function get_grades_parameters() { 43 return new external_function_parameters( 44 array( 45 'courseid' => new external_value(PARAM_INT, 'id of course'), 46 'component' => new external_value( 47 PARAM_COMPONENT, 'A component, for example mod_forum or mod_quiz', VALUE_DEFAULT, ''), 48 'activityid' => new external_value(PARAM_INT, 'The activity ID', VALUE_DEFAULT, null), 49 'userids' => new external_multiple_structure( 50 new external_value(PARAM_INT, 'user ID'), 51 'An array of user IDs, leave empty to just retrieve grade item information', VALUE_DEFAULT, array() 52 ) 53 ) 54 ); 55 } 56 57 /** 58 * Returns student course total grade and grades for activities. 59 * This function does not return category or manual items. 60 * This function is suitable for managers or teachers not students. 61 * 62 * @param int $courseid Course id 63 * @param string $component Component name 64 * @param int $activityid Activity id 65 * @param array $userids Array of user ids 66 * @return array Array of grades 67 * @since Moodle 2.7 68 */ 69 public static function get_grades($courseid, $component = null, $activityid = null, $userids = array()) { 70 global $CFG, $USER, $DB; 71 72 $params = self::validate_parameters(self::get_grades_parameters(), 73 array('courseid' => $courseid, 'component' => $component, 'activityid' => $activityid, 'userids' => $userids)); 74 75 $gradesarray = array( 76 'items' => array(), 77 'outcomes' => array() 78 ); 79 80 $coursecontext = context_course::instance($params['courseid']); 81 82 try { 83 self::validate_context($coursecontext); 84 } catch (Exception $e) { 85 $exceptionparam = new stdClass(); 86 $exceptionparam->message = $e->getMessage(); 87 $exceptionparam->courseid = $params['courseid']; 88 throw new moodle_exception('errorcoursecontextnotvalid' , 'webservice', '', $exceptionparam); 89 } 90 91 require_capability('moodle/grade:viewhidden', $coursecontext); 92 93 $course = $DB->get_record('course', array('id' => $params['courseid']), '*', MUST_EXIST); 94 95 $access = false; 96 if (has_capability('moodle/grade:viewall', $coursecontext)) { 97 // Can view all user's grades in this course. 98 $access = true; 99 100 } else if ($course->showgrades && count($params['userids']) == 1) { 101 // Course showgrades == students/parents can access grades. 102 103 if ($params['userids'][0] == $USER->id and has_capability('moodle/grade:view', $coursecontext)) { 104 // Student can view their own grades in this course. 105 $access = true; 106 107 } else if (has_capability('moodle/grade:viewall', context_user::instance($params['userids'][0]))) { 108 // User can view the grades of this user. Parent most probably. 109 $access = true; 110 } 111 } 112 113 if (!$access) { 114 throw new moodle_exception('nopermissiontoviewgrades', 'error'); 115 } 116 117 $itemtype = null; 118 $itemmodule = null; 119 $iteminstance = null; 120 121 if (!empty($params['component'])) { 122 list($itemtype, $itemmodule) = normalize_component($params['component']); 123 } 124 125 $cm = null; 126 if (!empty($itemmodule) && !empty($params['activityid'])) { 127 if (!$cm = get_coursemodule_from_id($itemmodule, $params['activityid'])) { 128 throw new moodle_exception('invalidcoursemodule'); 129 } 130 $iteminstance = $cm->instance; 131 } 132 133 // Load all the module info. 134 $modinfo = get_fast_modinfo($params['courseid']); 135 $activityinstances = $modinfo->get_instances(); 136 137 $gradeparams = array('courseid' => $params['courseid']); 138 if (!empty($itemtype)) { 139 $gradeparams['itemtype'] = $itemtype; 140 } 141 if (!empty($itemmodule)) { 142 $gradeparams['itemmodule'] = $itemmodule; 143 } 144 if (!empty($iteminstance)) { 145 $gradeparams['iteminstance'] = $iteminstance; 146 } 147 148 if ($activitygrades = grade_item::fetch_all($gradeparams)) { 149 $canviewhidden = has_capability('moodle/grade:viewhidden', context_course::instance($params['courseid'])); 150 151 foreach ($activitygrades as $activitygrade) { 152 153 if ($activitygrade->itemtype != 'course' and $activitygrade->itemtype != 'mod') { 154 // This function currently only supports course and mod grade items. Manual and category not supported. 155 continue; 156 } 157 158 if ($activitygrade->itemtype == 'course') { 159 $item = grade_get_course_grades($course->id, $params['userids']); 160 $item->itemnumber = 0; 161 162 $grades = new stdClass; 163 $grades->items = array($item); 164 $grades->outcomes = array(); 165 166 } else { 167 $cm = $activityinstances[$activitygrade->itemmodule][$activitygrade->iteminstance]; 168 $instance = $cm->instance; 169 $grades = grade_get_grades($params['courseid'], $activitygrade->itemtype, 170 $activitygrade->itemmodule, $instance, $params['userids']); 171 } 172 173 // Convert from objects to arrays so all web service clients are supported. 174 // While we're doing that we also remove grades the current user can't see due to hiding. 175 foreach ($grades->items as $gradeitem) { 176 // Switch the stdClass instance for a grade item instance so we can call is_hidden() and use the ID. 177 $gradeiteminstance = self::get_grade_item( 178 $course->id, $activitygrade->itemtype, $activitygrade->itemmodule, $activitygrade->iteminstance, 0); 179 if (!$canviewhidden && $gradeiteminstance->is_hidden()) { 180 continue; 181 } 182 183 // Format mixed bool/integer parameters. 184 $gradeitem->hidden = (empty($gradeitem->hidden)) ? 0 : $gradeitem->hidden; 185 $gradeitem->locked = (empty($gradeitem->locked)) ? 0 : $gradeitem->locked; 186 187 $gradeitemarray = (array)$gradeitem; 188 $gradeitemarray['grades'] = array(); 189 190 if (!empty($gradeitem->grades)) { 191 foreach ($gradeitem->grades as $studentid => $studentgrade) { 192 if (!$canviewhidden) { 193 // Need to load the grade_grade object to check visibility. 194 $gradegradeinstance = grade_grade::fetch( 195 array( 196 'userid' => $studentid, 197 'itemid' => $gradeiteminstance->id 198 ) 199 ); 200 // The grade grade may be legitimately missing if the student has no grade. 201 if (!empty($gradegradeinstance) && $gradegradeinstance->is_hidden()) { 202 continue; 203 } 204 } 205 206 // Format mixed bool/integer parameters. 207 $studentgrade->hidden = (empty($studentgrade->hidden)) ? 0 : $studentgrade->hidden; 208 $studentgrade->locked = (empty($studentgrade->locked)) ? 0 : $studentgrade->locked; 209 $studentgrade->overridden = (empty($studentgrade->overridden)) ? 0 : $studentgrade->overridden; 210 211 if ($gradeiteminstance->itemtype != 'course' and !empty($studentgrade->feedback)) { 212 list($studentgrade->feedback, $studentgrade->feedbackformat) = 213 external_format_text($studentgrade->feedback, $studentgrade->feedbackformat, 214 $cm->id, $params['component'], 'feedback', null); 215 } 216 217 $gradeitemarray['grades'][$studentid] = (array)$studentgrade; 218 // Add the student ID as some WS clients can't access the array key. 219 $gradeitemarray['grades'][$studentid]['userid'] = $studentid; 220 } 221 } 222 223 if ($gradeiteminstance->itemtype == 'course') { 224 $gradesarray['items']['course'] = $gradeitemarray; 225 $gradesarray['items']['course']['activityid'] = 'course'; 226 } else { 227 $gradesarray['items'][$cm->id] = $gradeitemarray; 228 // Add the activity ID as some WS clients can't access the array key. 229 $gradesarray['items'][$cm->id]['activityid'] = $cm->id; 230 } 231 } 232 233 foreach ($grades->outcomes as $outcome) { 234 // Format mixed bool/integer parameters. 235 $outcome->hidden = (empty($outcome->hidden)) ? 0 : $outcome->hidden; 236 $outcome->locked = (empty($outcome->locked)) ? 0 : $outcome->locked; 237 238 $gradesarray['outcomes'][$cm->id] = (array)$outcome; 239 $gradesarray['outcomes'][$cm->id]['activityid'] = $cm->id; 240 241 $gradesarray['outcomes'][$cm->id]['grades'] = array(); 242 if (!empty($outcome->grades)) { 243 foreach ($outcome->grades as $studentid => $studentgrade) { 244 if (!$canviewhidden) { 245 // Need to load the grade_grade object to check visibility. 246 $gradeiteminstance = self::get_grade_item($course->id, $activitygrade->itemtype, 247 $activitygrade->itemmodule, $activitygrade->iteminstance, 248 $activitygrade->itemnumber); 249 $gradegradeinstance = grade_grade::fetch( 250 array( 251 'userid' => $studentid, 252 'itemid' => $gradeiteminstance->id 253 ) 254 ); 255 // The grade grade may be legitimately missing if the student has no grade. 256 if (!empty($gradegradeinstance ) && $gradegradeinstance->is_hidden()) { 257 continue; 258 } 259 } 260 261 // Format mixed bool/integer parameters. 262 $studentgrade->hidden = (empty($studentgrade->hidden)) ? 0 : $studentgrade->hidden; 263 $studentgrade->locked = (empty($studentgrade->locked)) ? 0 : $studentgrade->locked; 264 265 if (!empty($studentgrade->feedback)) { 266 list($studentgrade->feedback, $studentgrade->feedbackformat) = 267 external_format_text($studentgrade->feedback, $studentgrade->feedbackformat, 268 $cm->id, $params['component'], 'feedback', null); 269 } 270 271 $gradesarray['outcomes'][$cm->id]['grades'][$studentid] = (array)$studentgrade; 272 273 // Add the student ID into the grade structure as some WS clients can't access the key. 274 $gradesarray['outcomes'][$cm->id]['grades'][$studentid]['userid'] = $studentid; 275 } 276 } 277 } 278 } 279 } 280 281 return $gradesarray; 282 } 283 284 /** 285 * Get a grade item 286 * @param int $courseid Course id 287 * @param string $itemtype Item type 288 * @param string $itemmodule Item module 289 * @param int $iteminstance Item instance 290 * @param int $itemnumber Item number 291 * @return grade_item A grade_item instance 292 */ 293 private static function get_grade_item($courseid, $itemtype, $itemmodule = null, $iteminstance = null, $itemnumber = null) { 294 $gradeiteminstance = null; 295 if ($itemtype == 'course') { 296 $gradeiteminstance = grade_item::fetch(array('courseid' => $courseid, 'itemtype' => $itemtype)); 297 } else { 298 $gradeiteminstance = grade_item::fetch( 299 array('courseid' => $courseid, 'itemtype' => $itemtype, 300 'itemmodule' => $itemmodule, 'iteminstance' => $iteminstance, 'itemnumber' => $itemnumber)); 301 } 302 return $gradeiteminstance; 303 } 304 305 /** 306 * Returns description of method result value 307 * 308 * @return external_description 309 * @since Moodle 2.7 310 */ 311 public static function get_grades_returns() { 312 return new external_single_structure( 313 array( 314 'items' => new external_multiple_structure( 315 new external_single_structure( 316 array( 317 'activityid' => new external_value( 318 PARAM_ALPHANUM, 'The ID of the activity or "course" for the course grade item'), 319 'itemnumber' => new external_value(PARAM_INT, 'Will be 0 unless the module has multiple grades'), 320 'scaleid' => new external_value(PARAM_INT, 'The ID of the custom scale or 0'), 321 'name' => new external_value(PARAM_RAW, 'The module name'), 322 'grademin' => new external_value(PARAM_FLOAT, 'Minimum grade'), 323 'grademax' => new external_value(PARAM_FLOAT, 'Maximum grade'), 324 'gradepass' => new external_value(PARAM_FLOAT, 'The passing grade threshold'), 325 'locked' => new external_value(PARAM_INT, '0 means not locked, > 1 is a date to lock until'), 326 'hidden' => new external_value(PARAM_INT, '0 means not hidden, > 1 is a date to hide until'), 327 'grades' => new external_multiple_structure( 328 new external_single_structure( 329 array( 330 'userid' => new external_value( 331 PARAM_INT, 'Student ID'), 332 'grade' => new external_value( 333 PARAM_FLOAT, 'Student grade'), 334 'locked' => new external_value( 335 PARAM_INT, '0 means not locked, > 1 is a date to lock until'), 336 'hidden' => new external_value( 337 PARAM_INT, '0 means not hidden, 1 hidden, > 1 is a date to hide until'), 338 'overridden' => new external_value( 339 PARAM_INT, '0 means not overridden, > 1 means overridden'), 340 'feedback' => new external_value( 341 PARAM_RAW, 'Feedback from the grader'), 342 'feedbackformat' => new external_value( 343 PARAM_INT, 'The format of the feedback'), 344 'usermodified' => new external_value( 345 PARAM_INT, 'The ID of the last user to modify this student grade'), 346 'datesubmitted' => new external_value( 347 PARAM_INT, 'A timestamp indicating when the student submitted the activity'), 348 'dategraded' => new external_value( 349 PARAM_INT, 'A timestamp indicating when the assignment was grades'), 350 'str_grade' => new external_value( 351 PARAM_RAW, 'A string representation of the grade'), 352 'str_long_grade' => new external_value( 353 PARAM_RAW, 'A nicely formatted string representation of the grade'), 354 'str_feedback' => new external_value( 355 PARAM_RAW, 'A formatted string representation of the feedback from the grader'), 356 ) 357 ) 358 ), 359 ) 360 ) 361 ), 362 'outcomes' => new external_multiple_structure( 363 new external_single_structure( 364 array( 365 'activityid' => new external_value( 366 PARAM_ALPHANUM, 'The ID of the activity or "course" for the course grade item'), 367 'itemnumber' => new external_value(PARAM_INT, 'Will be 0 unless the module has multiple grades'), 368 'scaleid' => new external_value(PARAM_INT, 'The ID of the custom scale or 0'), 369 'name' => new external_value(PARAM_RAW, 'The module name'), 370 'locked' => new external_value(PARAM_INT, '0 means not locked, > 1 is a date to lock until'), 371 'hidden' => new external_value(PARAM_INT, '0 means not hidden, > 1 is a date to hide until'), 372 'grades' => new external_multiple_structure( 373 new external_single_structure( 374 array( 375 'userid' => new external_value( 376 PARAM_INT, 'Student ID'), 377 'grade' => new external_value( 378 PARAM_FLOAT, 'Student grade'), 379 'locked' => new external_value( 380 PARAM_INT, '0 means not locked, > 1 is a date to lock until'), 381 'hidden' => new external_value( 382 PARAM_INT, '0 means not hidden, 1 hidden, > 1 is a date to hide until'), 383 'feedback' => new external_value( 384 PARAM_RAW, 'Feedback from the grader'), 385 'feedbackformat' => new external_value( 386 PARAM_INT, 'The feedback format'), 387 'usermodified' => new external_value( 388 PARAM_INT, 'The ID of the last user to modify this student grade'), 389 'str_grade' => new external_value( 390 PARAM_RAW, 'A string representation of the grade'), 391 'str_feedback' => new external_value( 392 PARAM_RAW, 'A formatted string representation of the feedback from the grader'), 393 ) 394 ) 395 ), 396 ) 397 ), 'An array of outcomes associated with the grade items', VALUE_OPTIONAL 398 ) 399 ) 400 ); 401 402 } 403 404 /** 405 * Returns description of method parameters 406 * 407 * @return external_function_parameters 408 * @since Moodle 2.7 409 */ 410 public static function update_grades_parameters() { 411 return new external_function_parameters( 412 array( 413 'source' => new external_value(PARAM_TEXT, 'The source of the grade update'), 414 'courseid' => new external_value(PARAM_INT, 'id of course'), 415 'component' => new external_value(PARAM_COMPONENT, 'A component, for example mod_forum or mod_quiz'), 416 'activityid' => new external_value(PARAM_INT, 'The activity ID'), 417 'itemnumber' => new external_value( 418 PARAM_INT, 'grade item ID number for modules that have multiple grades. Typically this is 0.'), 419 'grades' => new external_multiple_structure( 420 new external_single_structure( 421 array( 422 'studentid' => new external_value(PARAM_INT, 'Student ID'), 423 'grade' => new external_value(PARAM_FLOAT, 'Student grade'), 424 'str_feedback' => new external_value( 425 PARAM_TEXT, 'A string representation of the feedback from the grader', VALUE_OPTIONAL), 426 ) 427 ), 'Any student grades to alter', VALUE_DEFAULT, array()), 428 'itemdetails' => new external_single_structure( 429 array( 430 'itemname' => new external_value( 431 PARAM_ALPHANUMEXT, 'The grade item name', VALUE_OPTIONAL), 432 'idnumber' => new external_value( 433 PARAM_INT, 'Arbitrary ID provided by the module responsible for the grade item', VALUE_OPTIONAL), 434 'gradetype' => new external_value( 435 PARAM_INT, 'The type of grade (0 = none, 1 = value, 2 = scale, 3 = text)', VALUE_OPTIONAL), 436 'grademax' => new external_value( 437 PARAM_FLOAT, 'Maximum grade allowed', VALUE_OPTIONAL), 438 'grademin' => new external_value( 439 PARAM_FLOAT, 'Minimum grade allowed', VALUE_OPTIONAL), 440 'scaleid' => new external_value( 441 PARAM_INT, 'The ID of the custom scale being is used', VALUE_OPTIONAL), 442 'multfactor' => new external_value( 443 PARAM_FLOAT, 'Multiply all grades by this number', VALUE_OPTIONAL), 444 'plusfactor' => new external_value( 445 PARAM_FLOAT, 'Add this to all grades', VALUE_OPTIONAL), 446 'deleted' => new external_value( 447 PARAM_BOOL, 'True if the grade item should be deleted', VALUE_OPTIONAL), 448 'hidden' => new external_value( 449 PARAM_BOOL, 'True if the grade item is hidden', VALUE_OPTIONAL), 450 ), 'Any grade item settings to alter', VALUE_DEFAULT, array() 451 ) 452 ) 453 ); 454 } 455 456 /** 457 * Update a grade item and, optionally, student grades 458 * 459 * @param string $source The source of the grade update 460 * @param int $courseid The course id 461 * @param string $component Component name 462 * @param int $activityid The activity id 463 * @param int $itemnumber The item number 464 * @param array $grades Array of grades 465 * @param array $itemdetails Array of item details 466 * @return int A status flag 467 * @since Moodle 2.7 468 */ 469 public static function update_grades($source, $courseid, $component, $activityid, 470 $itemnumber, $grades = array(), $itemdetails = array()) { 471 global $CFG; 472 473 $params = self::validate_parameters( 474 self::update_grades_parameters(), 475 array( 476 'source' => $source, 477 'courseid' => $courseid, 478 'component' => $component, 479 'activityid' => $activityid, 480 'itemnumber' => $itemnumber, 481 'grades' => $grades, 482 'itemdetails' => $itemdetails 483 ) 484 ); 485 486 list($itemtype, $itemmodule) = normalize_component($params['component']); 487 488 if (! $cm = get_coursemodule_from_id($itemmodule, $activityid)) { 489 throw new moodle_exception('invalidcoursemodule'); 490 } 491 $iteminstance = $cm->instance; 492 493 $coursecontext = context_course::instance($params['courseid']); 494 495 try { 496 self::validate_context($coursecontext); 497 } catch (Exception $e) { 498 $exceptionparam = new stdClass(); 499 $exceptionparam->message = $e->getMessage(); 500 $exceptionparam->courseid = $params['courseid']; 501 throw new moodle_exception('errorcoursecontextnotvalid' , 'webservice', '', $exceptionparam); 502 } 503 504 $hidinggrades = false; 505 $editinggradeitem = false; 506 $editinggrades = false; 507 508 $gradestructure = array(); 509 foreach ($grades as $grade) { 510 $editinggrades = true; 511 $gradestructure[ $grade['studentid'] ] = array('userid' => $grade['studentid'], 'rawgrade' => $grade['grade']); 512 } 513 if (!empty($params['itemdetails'])) { 514 if (isset($params['itemdetails']['hidden'])) { 515 $hidinggrades = true; 516 } else { 517 $editinggradeitem = true; 518 } 519 } 520 521 if ($editinggradeitem && !has_capability('moodle/grade:manage', $coursecontext)) { 522 throw new moodle_exception('nopermissiontoviewgrades', 'error', '', null, 523 'moodle/grade:manage required to edit grade information'); 524 } 525 if ($hidinggrades && !has_capability('moodle/grade:hide', $coursecontext) && 526 !has_capability('moodle/grade:hide', $coursecontext)) { 527 throw new moodle_exception('nopermissiontoviewgrades', 'error', '', null, 528 'moodle/grade:hide required to hide grade items'); 529 } 530 if ($editinggrades && !has_capability('moodle/grade:edit', $coursecontext)) { 531 throw new moodle_exception('nopermissiontoviewgrades', 'error', '', null, 532 'moodle/grade:edit required to edit grades'); 533 } 534 535 return grade_update($params['source'], $params['courseid'], $itemtype, 536 $itemmodule, $iteminstance, $itemnumber, $gradestructure, $params['itemdetails']); 537 } 538 539 /** 540 * Returns description of method result value 541 * 542 * @return external_description 543 * @since Moodle 2.7 544 */ 545 public static function update_grades_returns() { 546 return new external_value( 547 PARAM_INT, 548 'A value like ' . GRADE_UPDATE_OK . ' => OK, ' . GRADE_UPDATE_FAILED . ' => FAILED 549 as defined in lib/grade/constants.php' 550 ); 551 } 552 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body
Generated: Fri Nov 28 20:29:05 2014 | Cross-referenced by PHPXref 0.7.1 |