See Release Notes
Long Term Support Release
Differences Between: [Versions 39 and 400] [Versions 39 and 401] [Versions 39 and 402] [Versions 39 and 403]
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 * Feedback external API 19 * 20 * @package mod_feedback 21 * @category external 22 * @copyright 2017 Juan Leyva <juan@moodle.com> 23 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later 24 * @since Moodle 3.3 25 */ 26 27 defined('MOODLE_INTERNAL') || die; 28 29 require_once("$CFG->libdir/externallib.php"); 30 31 use mod_feedback\external\feedback_summary_exporter; 32 use mod_feedback\external\feedback_completedtmp_exporter; 33 use mod_feedback\external\feedback_item_exporter; 34 use mod_feedback\external\feedback_valuetmp_exporter; 35 use mod_feedback\external\feedback_value_exporter; 36 use mod_feedback\external\feedback_completed_exporter; 37 38 /** 39 * Feedback external functions 40 * 41 * @package mod_feedback 42 * @category external 43 * @copyright 2017 Juan Leyva <juan@moodle.com> 44 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later 45 * @since Moodle 3.3 46 */ 47 class mod_feedback_external extends external_api { 48 49 /** 50 * Describes the parameters for get_feedbacks_by_courses. 51 * 52 * @return external_function_parameters 53 * @since Moodle 3.3 54 */ 55 public static function get_feedbacks_by_courses_parameters() { 56 return new external_function_parameters ( 57 array( 58 'courseids' => new external_multiple_structure( 59 new external_value(PARAM_INT, 'Course id'), 'Array of course ids', VALUE_DEFAULT, array() 60 ), 61 ) 62 ); 63 } 64 65 /** 66 * Returns a list of feedbacks in a provided list of courses. 67 * If no list is provided all feedbacks that the user can view will be returned. 68 * 69 * @param array $courseids course ids 70 * @return array of warnings and feedbacks 71 * @since Moodle 3.3 72 */ 73 public static function get_feedbacks_by_courses($courseids = array()) { 74 global $PAGE; 75 76 $warnings = array(); 77 $returnedfeedbacks = array(); 78 79 $params = array( 80 'courseids' => $courseids, 81 ); 82 $params = self::validate_parameters(self::get_feedbacks_by_courses_parameters(), $params); 83 84 $mycourses = array(); 85 if (empty($params['courseids'])) { 86 $mycourses = enrol_get_my_courses(); 87 $params['courseids'] = array_keys($mycourses); 88 } 89 90 // Ensure there are courseids to loop through. 91 if (!empty($params['courseids'])) { 92 93 list($courses, $warnings) = external_util::validate_courses($params['courseids'], $mycourses); 94 $output = $PAGE->get_renderer('core'); 95 96 // Get the feedbacks in this course, this function checks users visibility permissions. 97 // We can avoid then additional validate_context calls. 98 $feedbacks = get_all_instances_in_courses("feedback", $courses); 99 foreach ($feedbacks as $feedback) { 100 101 $context = context_module::instance($feedback->coursemodule); 102 103 // Remove fields that are not from the feedback (added by get_all_instances_in_courses). 104 unset($feedback->coursemodule, $feedback->context, $feedback->visible, $feedback->section, $feedback->groupmode, 105 $feedback->groupingid); 106 107 // Check permissions. 108 if (!has_capability('mod/feedback:edititems', $context)) { 109 // Don't return the optional properties. 110 $properties = feedback_summary_exporter::properties_definition(); 111 foreach ($properties as $property => $config) { 112 if (!empty($config['optional'])) { 113 unset($feedback->{$property}); 114 } 115 } 116 } 117 $exporter = new feedback_summary_exporter($feedback, array('context' => $context)); 118 $returnedfeedbacks[] = $exporter->export($output); 119 } 120 } 121 122 $result = array( 123 'feedbacks' => $returnedfeedbacks, 124 'warnings' => $warnings 125 ); 126 return $result; 127 } 128 129 /** 130 * Describes the get_feedbacks_by_courses return value. 131 * 132 * @return external_single_structure 133 * @since Moodle 3.3 134 */ 135 public static function get_feedbacks_by_courses_returns() { 136 return new external_single_structure( 137 array( 138 'feedbacks' => new external_multiple_structure( 139 feedback_summary_exporter::get_read_structure() 140 ), 141 'warnings' => new external_warnings(), 142 ) 143 ); 144 } 145 146 /** 147 * Utility function for validating a feedback. 148 * 149 * @param int $feedbackid feedback instance id 150 * @param int $courseid courseid course where user completes the feedback (for site feedbacks only) 151 * @return array containing the feedback, feedback course, context, course module and the course where is being completed. 152 * @throws moodle_exception 153 * @since Moodle 3.3 154 */ 155 protected static function validate_feedback($feedbackid, $courseid = 0) { 156 global $DB, $USER; 157 158 // Request and permission validation. 159 $feedback = $DB->get_record('feedback', array('id' => $feedbackid), '*', MUST_EXIST); 160 list($feedbackcourse, $cm) = get_course_and_cm_from_instance($feedback, 'feedback'); 161 162 $context = context_module::instance($cm->id); 163 self::validate_context($context); 164 165 // Set default completion course. 166 $completioncourse = (object) array('id' => 0); 167 if ($feedbackcourse->id == SITEID && $courseid) { 168 $completioncourse = get_course($courseid); 169 self::validate_context(context_course::instance($courseid)); 170 171 $feedbackcompletion = new mod_feedback_completion($feedback, $cm, $courseid); 172 if (!$feedbackcompletion->check_course_is_mapped()) { 173 throw new moodle_exception('cannotaccess', 'mod_feedback'); 174 } 175 } 176 177 return array($feedback, $feedbackcourse, $cm, $context, $completioncourse); 178 } 179 180 /** 181 * Utility function for validating access to feedback. 182 * 183 * @param stdClass $feedback feedback object 184 * @param stdClass $course course where user completes the feedback (for site feedbacks only) 185 * @param stdClass $cm course module 186 * @param stdClass $context context object 187 * @throws moodle_exception 188 * @return mod_feedback_completion feedback completion instance 189 * @since Moodle 3.3 190 */ 191 protected static function validate_feedback_access($feedback, $course, $cm, $context, $checksubmit = false) { 192 $feedbackcompletion = new mod_feedback_completion($feedback, $cm, $course->id); 193 194 if (!$feedbackcompletion->can_complete()) { 195 throw new required_capability_exception($context, 'mod/feedback:complete', 'nopermission', ''); 196 } 197 198 if (!$feedbackcompletion->is_open()) { 199 throw new moodle_exception('feedback_is_not_open', 'feedback'); 200 } 201 202 if ($feedbackcompletion->is_empty()) { 203 throw new moodle_exception('no_items_available_yet', 'feedback'); 204 } 205 206 if ($checksubmit && !$feedbackcompletion->can_submit()) { 207 throw new moodle_exception('this_feedback_is_already_submitted', 'feedback'); 208 } 209 return $feedbackcompletion; 210 } 211 212 /** 213 * Describes the parameters for get_feedback_access_information. 214 * 215 * @return external_external_function_parameters 216 * @since Moodle 3.3 217 */ 218 public static function get_feedback_access_information_parameters() { 219 return new external_function_parameters ( 220 array( 221 'feedbackid' => new external_value(PARAM_INT, 'Feedback instance id.'), 222 'courseid' => new external_value(PARAM_INT, 'Course where user completes the feedback (for site feedbacks only).', 223 VALUE_DEFAULT, 0), 224 ) 225 ); 226 } 227 228 /** 229 * Return access information for a given feedback. 230 * 231 * @param int $feedbackid feedback instance id 232 * @param int $courseid course where user completes the feedback (for site feedbacks only) 233 * @return array of warnings and the access information 234 * @since Moodle 3.3 235 * @throws moodle_exception 236 */ 237 public static function get_feedback_access_information($feedbackid, $courseid = 0) { 238 global $PAGE; 239 240 $params = array( 241 'feedbackid' => $feedbackid, 242 'courseid' => $courseid, 243 ); 244 $params = self::validate_parameters(self::get_feedback_access_information_parameters(), $params); 245 246 list($feedback, $course, $cm, $context, $completioncourse) = self::validate_feedback($params['feedbackid'], 247 $params['courseid']); 248 $feedbackcompletion = new mod_feedback_completion($feedback, $cm, $completioncourse->id); 249 250 $result = array(); 251 // Capabilities first. 252 $result['canviewanalysis'] = $feedbackcompletion->can_view_analysis(); 253 $result['cancomplete'] = $feedbackcompletion->can_complete(); 254 $result['cansubmit'] = $feedbackcompletion->can_submit(); 255 $result['candeletesubmissions'] = has_capability('mod/feedback:deletesubmissions', $context); 256 $result['canviewreports'] = has_capability('mod/feedback:viewreports', $context); 257 $result['canedititems'] = has_capability('mod/feedback:edititems', $context); 258 259 // Status information. 260 $result['isempty'] = $feedbackcompletion->is_empty(); 261 $result['isopen'] = $feedbackcompletion->is_open(); 262 $anycourse = ($course->id == SITEID); 263 $result['isalreadysubmitted'] = $feedbackcompletion->is_already_submitted($anycourse); 264 $result['isanonymous'] = $feedbackcompletion->is_anonymous(); 265 266 $result['warnings'] = []; 267 return $result; 268 } 269 270 /** 271 * Describes the get_feedback_access_information return value. 272 * 273 * @return external_single_structure 274 * @since Moodle 3.3 275 */ 276 public static function get_feedback_access_information_returns() { 277 return new external_single_structure( 278 array( 279 'canviewanalysis' => new external_value(PARAM_BOOL, 'Whether the user can view the analysis or not.'), 280 'cancomplete' => new external_value(PARAM_BOOL, 'Whether the user can complete the feedback or not.'), 281 'cansubmit' => new external_value(PARAM_BOOL, 'Whether the user can submit the feedback or not.'), 282 'candeletesubmissions' => new external_value(PARAM_BOOL, 'Whether the user can delete submissions or not.'), 283 'canviewreports' => new external_value(PARAM_BOOL, 'Whether the user can view the feedback reports or not.'), 284 'canedititems' => new external_value(PARAM_BOOL, 'Whether the user can edit feedback items or not.'), 285 'isempty' => new external_value(PARAM_BOOL, 'Whether the feedback has questions or not.'), 286 'isopen' => new external_value(PARAM_BOOL, 'Whether the feedback has active access time restrictions or not.'), 287 'isalreadysubmitted' => new external_value(PARAM_BOOL, 'Whether the feedback is already submitted or not.'), 288 'isanonymous' => new external_value(PARAM_BOOL, 'Whether the feedback is anonymous or not.'), 289 'warnings' => new external_warnings(), 290 ) 291 ); 292 } 293 294 /** 295 * Describes the parameters for view_feedback. 296 * 297 * @return external_function_parameters 298 * @since Moodle 3.3 299 */ 300 public static function view_feedback_parameters() { 301 return new external_function_parameters ( 302 array( 303 'feedbackid' => new external_value(PARAM_INT, 'Feedback instance id'), 304 'moduleviewed' => new external_value(PARAM_BOOL, 'If we need to mark the module as viewed for completion', 305 VALUE_DEFAULT, false), 306 'courseid' => new external_value(PARAM_INT, 'Course where user completes the feedback (for site feedbacks only).', 307 VALUE_DEFAULT, 0), 308 ) 309 ); 310 } 311 312 /** 313 * Trigger the course module viewed event and update the module completion status. 314 * 315 * @param int $feedbackid feedback instance id 316 * @param bool $moduleviewed If we need to mark the module as viewed for completion 317 * @param int $courseid course where user completes the feedback (for site feedbacks only) 318 * @return array of warnings and status result 319 * @since Moodle 3.3 320 * @throws moodle_exception 321 */ 322 public static function view_feedback($feedbackid, $moduleviewed = false, $courseid = 0) { 323 324 $params = array('feedbackid' => $feedbackid, 'moduleviewed' => $moduleviewed, 'courseid' => $courseid); 325 $params = self::validate_parameters(self::view_feedback_parameters(), $params); 326 $warnings = array(); 327 328 list($feedback, $course, $cm, $context, $completioncourse) = self::validate_feedback($params['feedbackid'], 329 $params['courseid']); 330 $feedbackcompletion = new mod_feedback_completion($feedback, $cm, $completioncourse->id); 331 332 // Trigger module viewed event. 333 $feedbackcompletion->trigger_module_viewed(); 334 if ($params['moduleviewed']) { 335 if (!$feedbackcompletion->is_open()) { 336 throw new moodle_exception('feedback_is_not_open', 'feedback'); 337 } 338 // Mark activity viewed for completion-tracking. 339 $feedbackcompletion->set_module_viewed(); 340 } 341 342 $result = array( 343 'status' => true, 344 'warnings' => $warnings, 345 ); 346 return $result; 347 } 348 349 /** 350 * Describes the view_feedback return value. 351 * 352 * @return external_single_structure 353 * @since Moodle 3.3 354 */ 355 public static function view_feedback_returns() { 356 return new external_single_structure( 357 array( 358 'status' => new external_value(PARAM_BOOL, 'status: true if success'), 359 'warnings' => new external_warnings(), 360 ) 361 ); 362 } 363 364 /** 365 * Describes the parameters for get_current_completed_tmp. 366 * 367 * @return external_function_parameters 368 * @since Moodle 3.3 369 */ 370 public static function get_current_completed_tmp_parameters() { 371 return new external_function_parameters ( 372 array( 373 'feedbackid' => new external_value(PARAM_INT, 'Feedback instance id'), 374 'courseid' => new external_value(PARAM_INT, 'Course where user completes the feedback (for site feedbacks only).', 375 VALUE_DEFAULT, 0), 376 ) 377 ); 378 } 379 380 /** 381 * Returns the temporary completion record for the current user. 382 * 383 * @param int $feedbackid feedback instance id 384 * @param int $courseid course where user completes the feedback (for site feedbacks only) 385 * @return array of warnings and status result 386 * @since Moodle 3.3 387 * @throws moodle_exception 388 */ 389 public static function get_current_completed_tmp($feedbackid, $courseid = 0) { 390 global $PAGE; 391 392 $params = array('feedbackid' => $feedbackid, 'courseid' => $courseid); 393 $params = self::validate_parameters(self::get_current_completed_tmp_parameters(), $params); 394 $warnings = array(); 395 396 list($feedback, $course, $cm, $context, $completioncourse) = self::validate_feedback($params['feedbackid'], 397 $params['courseid']); 398 $feedbackcompletion = new mod_feedback_completion($feedback, $cm, $completioncourse->id); 399 400 if ($completed = $feedbackcompletion->get_current_completed_tmp()) { 401 $exporter = new feedback_completedtmp_exporter($completed); 402 return array( 403 'feedback' => $exporter->export($PAGE->get_renderer('core')), 404 'warnings' => $warnings, 405 ); 406 } 407 throw new moodle_exception('not_started', 'feedback'); 408 } 409 410 /** 411 * Describes the get_current_completed_tmp return value. 412 * 413 * @return external_single_structure 414 * @since Moodle 3.3 415 */ 416 public static function get_current_completed_tmp_returns() { 417 return new external_single_structure( 418 array( 419 'feedback' => feedback_completedtmp_exporter::get_read_structure(), 420 'warnings' => new external_warnings(), 421 ) 422 ); 423 } 424 425 /** 426 * Describes the parameters for get_items. 427 * 428 * @return external_function_parameters 429 * @since Moodle 3.3 430 */ 431 public static function get_items_parameters() { 432 return new external_function_parameters ( 433 array( 434 'feedbackid' => new external_value(PARAM_INT, 'Feedback instance id'), 435 'courseid' => new external_value(PARAM_INT, 'Course where user completes the feedback (for site feedbacks only).', 436 VALUE_DEFAULT, 0), 437 ) 438 ); 439 } 440 441 /** 442 * Returns the items (questions) in the given feedback. 443 * 444 * @param int $feedbackid feedback instance id 445 * @param int $courseid course where user completes the feedback (for site feedbacks only) 446 * @return array of warnings and feedbacks 447 * @since Moodle 3.3 448 */ 449 public static function get_items($feedbackid, $courseid = 0) { 450 global $PAGE; 451 452 $params = array('feedbackid' => $feedbackid, 'courseid' => $courseid); 453 $params = self::validate_parameters(self::get_items_parameters(), $params); 454 $warnings = array(); 455 456 list($feedback, $course, $cm, $context, $completioncourse) = self::validate_feedback($params['feedbackid'], 457 $params['courseid']); 458 459 $feedbackstructure = new mod_feedback_structure($feedback, $cm, $completioncourse->id); 460 $returneditems = array(); 461 if ($items = $feedbackstructure->get_items()) { 462 foreach ($items as $item) { 463 $itemnumber = empty($item->itemnr) ? null : $item->itemnr; 464 unset($item->itemnr); // Added by the function, not part of the record. 465 $exporter = new feedback_item_exporter($item, array('context' => $context, 'itemnumber' => $itemnumber)); 466 $returneditems[] = $exporter->export($PAGE->get_renderer('core')); 467 } 468 } 469 470 $result = array( 471 'items' => $returneditems, 472 'warnings' => $warnings 473 ); 474 return $result; 475 } 476 477 /** 478 * Describes the get_items return value. 479 * 480 * @return external_single_structure 481 * @since Moodle 3.3 482 */ 483 public static function get_items_returns() { 484 return new external_single_structure( 485 array( 486 'items' => new external_multiple_structure( 487 feedback_item_exporter::get_read_structure() 488 ), 489 'warnings' => new external_warnings(), 490 ) 491 ); 492 } 493 494 /** 495 * Describes the parameters for launch_feedback. 496 * 497 * @return external_function_parameters 498 * @since Moodle 3.3 499 */ 500 public static function launch_feedback_parameters() { 501 return new external_function_parameters ( 502 array( 503 'feedbackid' => new external_value(PARAM_INT, 'Feedback instance id'), 504 'courseid' => new external_value(PARAM_INT, 'Course where user completes the feedback (for site feedbacks only).', 505 VALUE_DEFAULT, 0), 506 ) 507 ); 508 } 509 510 /** 511 * Starts or continues a feedback submission 512 * 513 * @param array $feedbackid feedback instance id 514 * @param int $courseid course where user completes a feedback (for site feedbacks only). 515 * @return array of warnings and launch information 516 * @since Moodle 3.3 517 */ 518 public static function launch_feedback($feedbackid, $courseid = 0) { 519 global $PAGE; 520 521 $params = array('feedbackid' => $feedbackid, 'courseid' => $courseid); 522 $params = self::validate_parameters(self::launch_feedback_parameters(), $params); 523 $warnings = array(); 524 525 list($feedback, $course, $cm, $context, $completioncourse) = self::validate_feedback($params['feedbackid'], 526 $params['courseid']); 527 // Check we can do a new submission (or continue an existing). 528 $feedbackcompletion = self::validate_feedback_access($feedback, $completioncourse, $cm, $context, true); 529 530 $gopage = $feedbackcompletion->get_resume_page(); 531 if ($gopage === null) { 532 $gopage = -1; // Last page. 533 } 534 535 $result = array( 536 'gopage' => $gopage, 537 'warnings' => $warnings 538 ); 539 return $result; 540 } 541 542 /** 543 * Describes the launch_feedback return value. 544 * 545 * @return external_single_structure 546 * @since Moodle 3.3 547 */ 548 public static function launch_feedback_returns() { 549 return new external_single_structure( 550 array( 551 'gopage' => new external_value(PARAM_INT, 'The next page to go (-1 if we were already in the last page). 0 for first page.'), 552 'warnings' => new external_warnings(), 553 ) 554 ); 555 } 556 557 /** 558 * Describes the parameters for get_page_items. 559 * 560 * @return external_function_parameters 561 * @since Moodle 3.3 562 */ 563 public static function get_page_items_parameters() { 564 return new external_function_parameters ( 565 array( 566 'feedbackid' => new external_value(PARAM_INT, 'Feedback instance id'), 567 'page' => new external_value(PARAM_INT, 'The page to get starting by 0'), 568 'courseid' => new external_value(PARAM_INT, 'Course where user completes the feedback (for site feedbacks only).', 569 VALUE_DEFAULT, 0), 570 ) 571 ); 572 } 573 574 /** 575 * Get a single feedback page items. 576 * 577 * @param int $feedbackid feedback instance id 578 * @param int $page the page to get starting by 0 579 * @param int $courseid course where user completes the feedback (for site feedbacks only) 580 * @return array of warnings and launch information 581 * @since Moodle 3.3 582 */ 583 public static function get_page_items($feedbackid, $page, $courseid = 0) { 584 global $PAGE; 585 586 $params = array('feedbackid' => $feedbackid, 'page' => $page, 'courseid' => $courseid); 587 $params = self::validate_parameters(self::get_page_items_parameters(), $params); 588 $warnings = array(); 589 590 list($feedback, $course, $cm, $context, $completioncourse) = self::validate_feedback($params['feedbackid'], 591 $params['courseid']); 592 593 $feedbackcompletion = new mod_feedback_completion($feedback, $cm, $completioncourse->id); 594 595 $page = $params['page']; 596 $pages = $feedbackcompletion->get_pages(); 597 $pageitems = $pages[$page]; 598 $hasnextpage = $page < count($pages) - 1; // Until we complete this page we can not trust get_next_page(). 599 $hasprevpage = $page && ($feedbackcompletion->get_previous_page($page, false) !== null); 600 601 $returneditems = array(); 602 foreach ($pageitems as $item) { 603 $itemnumber = empty($item->itemnr) ? null : $item->itemnr; 604 unset($item->itemnr); // Added by the function, not part of the record. 605 $exporter = new feedback_item_exporter($item, array('context' => $context, 'itemnumber' => $itemnumber)); 606 $returneditems[] = $exporter->export($PAGE->get_renderer('core')); 607 } 608 609 $result = array( 610 'items' => $returneditems, 611 'hasprevpage' => $hasprevpage, 612 'hasnextpage' => $hasnextpage, 613 'warnings' => $warnings 614 ); 615 return $result; 616 } 617 618 /** 619 * Describes the get_page_items return value. 620 * 621 * @return external_single_structure 622 * @since Moodle 3.3 623 */ 624 public static function get_page_items_returns() { 625 return new external_single_structure( 626 array( 627 'items' => new external_multiple_structure( 628 feedback_item_exporter::get_read_structure() 629 ), 630 'hasprevpage' => new external_value(PARAM_BOOL, 'Whether is a previous page.'), 631 'hasnextpage' => new external_value(PARAM_BOOL, 'Whether there are more pages.'), 632 'warnings' => new external_warnings(), 633 ) 634 ); 635 } 636 637 /** 638 * Describes the parameters for process_page. 639 * 640 * @return external_function_parameters 641 * @since Moodle 3.3 642 */ 643 public static function process_page_parameters() { 644 return new external_function_parameters ( 645 array( 646 'feedbackid' => new external_value(PARAM_INT, 'Feedback instance id.'), 647 'page' => new external_value(PARAM_INT, 'The page being processed.'), 648 'responses' => new external_multiple_structure( 649 new external_single_structure( 650 array( 651 'name' => new external_value(PARAM_NOTAGS, 'The response name (usually type[index]_id).'), 652 'value' => new external_value(PARAM_RAW, 'The response value.'), 653 ) 654 ), 'The data to be processed.', VALUE_DEFAULT, array() 655 ), 656 'goprevious' => new external_value(PARAM_BOOL, 'Whether we want to jump to previous page.', VALUE_DEFAULT, false), 657 'courseid' => new external_value(PARAM_INT, 'Course where user completes the feedback (for site feedbacks only).', 658 VALUE_DEFAULT, 0), 659 ) 660 ); 661 } 662 663 /** 664 * Process a jump between pages. 665 * 666 * @param array $feedbackid feedback instance id 667 * @param array $page the page being processed 668 * @param array $responses the responses to be processed 669 * @param bool $goprevious whether we want to jump to previous page 670 * @param int $courseid course where user completes the feedback (for site feedbacks only) 671 * @return array of warnings and launch information 672 * @since Moodle 3.3 673 */ 674 public static function process_page($feedbackid, $page, $responses = [], $goprevious = false, $courseid = 0) { 675 global $USER, $SESSION; 676 677 $params = array('feedbackid' => $feedbackid, 'page' => $page, 'responses' => $responses, 'goprevious' => $goprevious, 678 'courseid' => $courseid); 679 $params = self::validate_parameters(self::process_page_parameters(), $params); 680 $warnings = array(); 681 $siteaftersubmit = $completionpagecontents = ''; 682 683 list($feedback, $course, $cm, $context, $completioncourse) = self::validate_feedback($params['feedbackid'], 684 $params['courseid']); 685 // Check we can do a new submission (or continue an existing). 686 $feedbackcompletion = self::validate_feedback_access($feedback, $completioncourse, $cm, $context, true); 687 688 // Create the $_POST object required by the feedback question engine. 689 $_POST = array(); 690 foreach ($responses as $response) { 691 // First check if we are handling array parameters. 692 if (preg_match('/(.+)\[(.+)\]$/', $response['name'], $matches)) { 693 $_POST[$matches[1]][$matches[2]] = $response['value']; 694 } else { 695 $_POST[$response['name']] = $response['value']; 696 } 697 } 698 // Force fields. 699 $_POST['id'] = $cm->id; 700 $_POST['courseid'] = $courseid; 701 $_POST['gopage'] = $params['page']; 702 $_POST['_qf__mod_feedback_complete_form'] = 1; 703 704 // Determine where to go, backwards or forward. 705 if (!$params['goprevious']) { 706 $_POST['gonextpage'] = 1; // Even if we are saving values we need this set. 707 if ($feedbackcompletion->get_next_page($params['page'], false) === null) { 708 $_POST['savevalues'] = 1; // If there is no next page, it means we are finishing the feedback. 709 } 710 } 711 712 // Ignore sesskey (deep in some APIs), the request is already validated. 713 $USER->ignoresesskey = true; 714 feedback_init_feedback_session(); 715 $SESSION->feedback->is_started = true; 716 717 $feedbackcompletion->process_page($params['page'], $params['goprevious']); 718 $completed = $feedbackcompletion->just_completed(); 719 if ($completed) { 720 $jumpto = 0; 721 if ($feedback->page_after_submit) { 722 $completionpagecontents = $feedbackcompletion->page_after_submit(); 723 } 724 725 if ($feedback->site_after_submit) { 726 $siteaftersubmit = feedback_encode_target_url($feedback->site_after_submit); 727 } 728 } else { 729 $jumpto = $feedbackcompletion->get_jumpto(); 730 } 731 732 $result = array( 733 'jumpto' => $jumpto, 734 'completed' => $completed, 735 'completionpagecontents' => $completionpagecontents, 736 'siteaftersubmit' => $siteaftersubmit, 737 'warnings' => $warnings 738 ); 739 return $result; 740 } 741 742 /** 743 * Describes the process_page return value. 744 * 745 * @return external_single_structure 746 * @since Moodle 3.3 747 */ 748 public static function process_page_returns() { 749 return new external_single_structure( 750 array( 751 'jumpto' => new external_value(PARAM_INT, 'The page to jump to.'), 752 'completed' => new external_value(PARAM_BOOL, 'If the user completed the feedback.'), 753 'completionpagecontents' => new external_value(PARAM_RAW, 'The completion page contents.'), 754 'siteaftersubmit' => new external_value(PARAM_RAW, 'The link (could be relative) to show after submit.'), 755 'warnings' => new external_warnings(), 756 ) 757 ); 758 } 759 760 /** 761 * Describes the parameters for get_analysis. 762 * 763 * @return external_function_parameters 764 * @since Moodle 3.3 765 */ 766 public static function get_analysis_parameters() { 767 return new external_function_parameters ( 768 array( 769 'feedbackid' => new external_value(PARAM_INT, 'Feedback instance id'), 770 'groupid' => new external_value(PARAM_INT, 'Group id, 0 means that the function will determine the user group', 771 VALUE_DEFAULT, 0), 772 'courseid' => new external_value(PARAM_INT, 'Course where user completes the feedback (for site feedbacks only).', 773 VALUE_DEFAULT, 0), 774 ) 775 ); 776 } 777 778 /** 779 * Retrieves the feedback analysis. 780 * 781 * @param array $feedbackid feedback instance id 782 * @param int $groupid group id, 0 means that the function will determine the user group 783 * @param int $courseid course where user completes the feedback (for site feedbacks only) 784 * @return array of warnings and launch information 785 * @since Moodle 3.3 786 */ 787 public static function get_analysis($feedbackid, $groupid = 0, $courseid = 0) { 788 global $PAGE; 789 790 $params = array('feedbackid' => $feedbackid, 'groupid' => $groupid, 'courseid' => $courseid); 791 $params = self::validate_parameters(self::get_analysis_parameters(), $params); 792 $warnings = $itemsdata = array(); 793 794 list($feedback, $course, $cm, $context, $completioncourse) = self::validate_feedback($params['feedbackid'], 795 $params['courseid']); 796 797 // Check permissions. 798 $feedbackstructure = new mod_feedback_structure($feedback, $cm, $completioncourse->id); 799 if (!$feedbackstructure->can_view_analysis()) { 800 throw new required_capability_exception($context, 'mod/feedback:viewanalysepage', 'nopermission', ''); 801 } 802 803 if (!empty($params['groupid'])) { 804 $groupid = $params['groupid']; 805 // Determine is the group is visible to user. 806 if (!groups_group_visible($groupid, $course, $cm)) { 807 throw new moodle_exception('notingroup'); 808 } 809 } else { 810 // Check to see if groups are being used here. 811 if ($groupmode = groups_get_activity_groupmode($cm)) { 812 $groupid = groups_get_activity_group($cm); 813 // Determine is the group is visible to user (this is particullary for the group 0 -> all groups). 814 if (!groups_group_visible($groupid, $course, $cm)) { 815 throw new moodle_exception('notingroup'); 816 } 817 } else { 818 $groupid = 0; 819 } 820 } 821 822 // Summary data. 823 $summary = new mod_feedback\output\summary($feedbackstructure, $groupid); 824 $summarydata = $summary->export_for_template($PAGE->get_renderer('core')); 825 826 $checkanonymously = true; 827 if ($groupid > 0 AND $feedback->anonymous == FEEDBACK_ANONYMOUS_YES) { 828 $completedcount = $feedbackstructure->count_completed_responses($groupid); 829 if ($completedcount < FEEDBACK_MIN_ANONYMOUS_COUNT_IN_GROUP) { 830 $checkanonymously = false; 831 } 832 } 833 834 if ($checkanonymously) { 835 // Get the items of the feedback. 836 $items = $feedbackstructure->get_items(true); 837 foreach ($items as $item) { 838 $itemobj = feedback_get_item_class($item->typ); 839 $itemnumber = empty($item->itemnr) ? null : $item->itemnr; 840 unset($item->itemnr); // Added by the function, not part of the record. 841 $exporter = new feedback_item_exporter($item, array('context' => $context, 'itemnumber' => $itemnumber)); 842 843 $itemsdata[] = array( 844 'item' => $exporter->export($PAGE->get_renderer('core')), 845 'data' => $itemobj->get_analysed_for_external($item, $groupid), 846 ); 847 } 848 } else { 849 $warnings[] = array( 850 'item' => 'feedback', 851 'itemid' => $feedback->id, 852 'warningcode' => 'insufficientresponsesforthisgroup', 853 'message' => s(get_string('insufficient_responses_for_this_group', 'feedback')) 854 ); 855 } 856 857 $result = array( 858 'completedcount' => $summarydata->completedcount, 859 'itemscount' => $summarydata->itemscount, 860 'itemsdata' => $itemsdata, 861 'warnings' => $warnings 862 ); 863 return $result; 864 } 865 866 /** 867 * Describes the get_analysis return value. 868 * 869 * @return external_single_structure 870 * @since Moodle 3.3 871 */ 872 public static function get_analysis_returns() { 873 return new external_single_structure( 874 array( 875 'completedcount' => new external_value(PARAM_INT, 'Number of completed submissions.'), 876 'itemscount' => new external_value(PARAM_INT, 'Number of items (questions).'), 877 'itemsdata' => new external_multiple_structure( 878 new external_single_structure( 879 array( 880 'item' => feedback_item_exporter::get_read_structure(), 881 'data' => new external_multiple_structure( 882 new external_value(PARAM_RAW, 'The analysis data (can be json encoded)') 883 ), 884 ) 885 ) 886 ), 887 'warnings' => new external_warnings(), 888 ) 889 ); 890 } 891 892 /** 893 * Describes the parameters for get_unfinished_responses. 894 * 895 * @return external_function_parameters 896 * @since Moodle 3.3 897 */ 898 public static function get_unfinished_responses_parameters() { 899 return new external_function_parameters ( 900 array( 901 'feedbackid' => new external_value(PARAM_INT, 'Feedback instance id.'), 902 'courseid' => new external_value(PARAM_INT, 'Course where user completes the feedback (for site feedbacks only).', 903 VALUE_DEFAULT, 0), 904 ) 905 ); 906 } 907 908 /** 909 * Retrieves responses from the current unfinished attempt. 910 * 911 * @param array $feedbackid feedback instance id 912 * @param int $courseid course where user completes the feedback (for site feedbacks only) 913 * @return array of warnings and launch information 914 * @since Moodle 3.3 915 */ 916 public static function get_unfinished_responses($feedbackid, $courseid = 0) { 917 global $PAGE; 918 919 $params = array('feedbackid' => $feedbackid, 'courseid' => $courseid); 920 $params = self::validate_parameters(self::get_unfinished_responses_parameters(), $params); 921 $warnings = $itemsdata = array(); 922 923 list($feedback, $course, $cm, $context, $completioncourse) = self::validate_feedback($params['feedbackid'], 924 $params['courseid']); 925 $feedbackcompletion = new mod_feedback_completion($feedback, $cm, $completioncourse->id); 926 927 $responses = array(); 928 $unfinished = $feedbackcompletion->get_unfinished_responses(); 929 foreach ($unfinished as $u) { 930 $exporter = new feedback_valuetmp_exporter($u); 931 $responses[] = $exporter->export($PAGE->get_renderer('core')); 932 } 933 934 $result = array( 935 'responses' => $responses, 936 'warnings' => $warnings 937 ); 938 return $result; 939 } 940 941 /** 942 * Describes the get_unfinished_responses return value. 943 * 944 * @return external_single_structure 945 * @since Moodle 3.3 946 */ 947 public static function get_unfinished_responses_returns() { 948 return new external_single_structure( 949 array( 950 'responses' => new external_multiple_structure( 951 feedback_valuetmp_exporter::get_read_structure() 952 ), 953 'warnings' => new external_warnings(), 954 ) 955 ); 956 } 957 958 /** 959 * Describes the parameters for get_finished_responses. 960 * 961 * @return external_function_parameters 962 * @since Moodle 3.3 963 */ 964 public static function get_finished_responses_parameters() { 965 return new external_function_parameters ( 966 array( 967 'feedbackid' => new external_value(PARAM_INT, 'Feedback instance id.'), 968 'courseid' => new external_value(PARAM_INT, 'Course where user completes the feedback (for site feedbacks only).', 969 VALUE_DEFAULT, 0), 970 ) 971 ); 972 } 973 974 /** 975 * Retrieves responses from the last finished attempt. 976 * 977 * @param array $feedbackid feedback instance id 978 * @param int $courseid course where user completes the feedback (for site feedbacks only) 979 * @return array of warnings and the responses 980 * @since Moodle 3.3 981 */ 982 public static function get_finished_responses($feedbackid, $courseid = 0) { 983 global $PAGE; 984 985 $params = array('feedbackid' => $feedbackid, 'courseid' => $courseid); 986 $params = self::validate_parameters(self::get_finished_responses_parameters(), $params); 987 $warnings = $itemsdata = array(); 988 989 list($feedback, $course, $cm, $context, $completioncourse) = self::validate_feedback($params['feedbackid'], 990 $params['courseid']); 991 $feedbackcompletion = new mod_feedback_completion($feedback, $cm, $completioncourse->id); 992 993 $responses = array(); 994 // Load and get the responses from the last completed feedback. 995 $feedbackcompletion->find_last_completed(); 996 $unfinished = $feedbackcompletion->get_finished_responses(); 997 foreach ($unfinished as $u) { 998 $exporter = new feedback_value_exporter($u); 999 $responses[] = $exporter->export($PAGE->get_renderer('core')); 1000 } 1001 1002 $result = array( 1003 'responses' => $responses, 1004 'warnings' => $warnings 1005 ); 1006 return $result; 1007 } 1008 1009 /** 1010 * Describes the get_finished_responses return value. 1011 * 1012 * @return external_single_structure 1013 * @since Moodle 3.3 1014 */ 1015 public static function get_finished_responses_returns() { 1016 return new external_single_structure( 1017 array( 1018 'responses' => new external_multiple_structure( 1019 feedback_value_exporter::get_read_structure() 1020 ), 1021 'warnings' => new external_warnings(), 1022 ) 1023 ); 1024 } 1025 1026 /** 1027 * Describes the parameters for get_non_respondents. 1028 * 1029 * @return external_function_parameters 1030 * @since Moodle 3.3 1031 */ 1032 public static function get_non_respondents_parameters() { 1033 return new external_function_parameters ( 1034 array( 1035 'feedbackid' => new external_value(PARAM_INT, 'Feedback instance id'), 1036 'groupid' => new external_value(PARAM_INT, 'Group id, 0 means that the function will determine the user group.', 1037 VALUE_DEFAULT, 0), 1038 'sort' => new external_value(PARAM_ALPHA, 'Sort param, must be firstname, lastname or lastaccess (default).', 1039 VALUE_DEFAULT, 'lastaccess'), 1040 'page' => new external_value(PARAM_INT, 'The page of records to return.', VALUE_DEFAULT, 0), 1041 'perpage' => new external_value(PARAM_INT, 'The number of records to return per page.', VALUE_DEFAULT, 0), 1042 'courseid' => new external_value(PARAM_INT, 'Course where user completes the feedback (for site feedbacks only).', 1043 VALUE_DEFAULT, 0), 1044 ) 1045 ); 1046 } 1047 1048 /** 1049 * Retrieves a list of students who didn't submit the feedback. 1050 * 1051 * @param int $feedbackid feedback instance id 1052 * @param int $groupid Group id, 0 means that the function will determine the user group' 1053 * @param str $sort sort param, must be firstname, lastname or lastaccess (default) 1054 * @param int $page the page of records to return 1055 * @param int $perpage the number of records to return per page 1056 * @param int $courseid course where user completes the feedback (for site feedbacks only) 1057 * @return array of warnings and users ids 1058 * @since Moodle 3.3 1059 */ 1060 public static function get_non_respondents($feedbackid, $groupid = 0, $sort = 'lastaccess', $page = 0, $perpage = 0, 1061 $courseid = 0) { 1062 1063 global $CFG; 1064 require_once($CFG->dirroot . '/mod/feedback/lib.php'); 1065 1066 $params = array('feedbackid' => $feedbackid, 'groupid' => $groupid, 'sort' => $sort, 'page' => $page, 1067 'perpage' => $perpage, 'courseid' => $courseid); 1068 $params = self::validate_parameters(self::get_non_respondents_parameters(), $params); 1069 $warnings = $nonrespondents = array(); 1070 1071 list($feedback, $course, $cm, $context, $completioncourse) = self::validate_feedback($params['feedbackid'], 1072 $params['courseid']); 1073 $feedbackcompletion = new mod_feedback_completion($feedback, $cm, $completioncourse->id); 1074 $completioncourseid = $feedbackcompletion->get_courseid(); 1075 1076 if ($feedback->anonymous != FEEDBACK_ANONYMOUS_NO || $feedback->course == SITEID) { 1077 throw new moodle_exception('anonymous', 'feedback'); 1078 } 1079 1080 // Check permissions. 1081 require_capability('mod/feedback:viewreports', $context); 1082 1083 if (!empty($params['groupid'])) { 1084 $groupid = $params['groupid']; 1085 // Determine is the group is visible to user. 1086 if (!groups_group_visible($groupid, $course, $cm)) { 1087 throw new moodle_exception('notingroup'); 1088 } 1089 } else { 1090 // Check to see if groups are being used here. 1091 if ($groupmode = groups_get_activity_groupmode($cm)) { 1092 $groupid = groups_get_activity_group($cm); 1093 // Determine is the group is visible to user (this is particullary for the group 0 -> all groups). 1094 if (!groups_group_visible($groupid, $course, $cm)) { 1095 throw new moodle_exception('notingroup'); 1096 } 1097 } else { 1098 $groupid = 0; 1099 } 1100 } 1101 1102 if ($params['sort'] !== 'firstname' && $params['sort'] !== 'lastname' && $params['sort'] !== 'lastaccess') { 1103 throw new invalid_parameter_exception('Invalid sort param, must be firstname, lastname or lastaccess.'); 1104 } 1105 1106 // Check if we are page filtering. 1107 if ($params['perpage'] == 0) { 1108 $page = $params['page']; 1109 $perpage = FEEDBACK_DEFAULT_PAGE_COUNT; 1110 } else { 1111 $perpage = $params['perpage']; 1112 $page = $perpage * $params['page']; 1113 } 1114 $users = feedback_get_incomplete_users($cm, $groupid, $params['sort'], $page, $perpage, true); 1115 foreach ($users as $user) { 1116 $nonrespondents[] = [ 1117 'courseid' => $completioncourseid, 1118 'userid' => $user->id, 1119 'fullname' => fullname($user), 1120 'started' => $user->feedbackstarted 1121 ]; 1122 } 1123 1124 $result = array( 1125 'users' => $nonrespondents, 1126 'total' => feedback_count_incomplete_users($cm, $groupid), 1127 'warnings' => $warnings 1128 ); 1129 return $result; 1130 } 1131 1132 /** 1133 * Describes the get_non_respondents return value. 1134 * 1135 * @return external_single_structure 1136 * @since Moodle 3.3 1137 */ 1138 public static function get_non_respondents_returns() { 1139 return new external_single_structure( 1140 array( 1141 'users' => new external_multiple_structure( 1142 new external_single_structure( 1143 array( 1144 'courseid' => new external_value(PARAM_INT, 'Course id'), 1145 'userid' => new external_value(PARAM_INT, 'The user id'), 1146 'fullname' => new external_value(PARAM_TEXT, 'User full name'), 1147 'started' => new external_value(PARAM_BOOL, 'If the user has started the attempt'), 1148 ) 1149 ) 1150 ), 1151 'total' => new external_value(PARAM_INT, 'Total number of non respondents'), 1152 'warnings' => new external_warnings(), 1153 ) 1154 ); 1155 } 1156 1157 /** 1158 * Describes the parameters for get_responses_analysis. 1159 * 1160 * @return external_function_parameters 1161 * @since Moodle 3.3 1162 */ 1163 public static function get_responses_analysis_parameters() { 1164 return new external_function_parameters ( 1165 array( 1166 'feedbackid' => new external_value(PARAM_INT, 'Feedback instance id'), 1167 'groupid' => new external_value(PARAM_INT, 'Group id, 0 means that the function will determine the user group', 1168 VALUE_DEFAULT, 0), 1169 'page' => new external_value(PARAM_INT, 'The page of records to return.', VALUE_DEFAULT, 0), 1170 'perpage' => new external_value(PARAM_INT, 'The number of records to return per page', VALUE_DEFAULT, 0), 1171 'courseid' => new external_value(PARAM_INT, 'Course where user completes the feedback (for site feedbacks only).', 1172 VALUE_DEFAULT, 0), 1173 ) 1174 ); 1175 } 1176 1177 /** 1178 * Return the feedback user responses. 1179 * 1180 * @param int $feedbackid feedback instance id 1181 * @param int $groupid Group id, 0 means that the function will determine the user group 1182 * @param int $page the page of records to return 1183 * @param int $perpage the number of records to return per page 1184 * @param int $courseid course where user completes the feedback (for site feedbacks only) 1185 * @return array of warnings and users attemps and responses 1186 * @throws moodle_exception 1187 * @since Moodle 3.3 1188 */ 1189 public static function get_responses_analysis($feedbackid, $groupid = 0, $page = 0, $perpage = 0, $courseid = 0) { 1190 1191 $params = array('feedbackid' => $feedbackid, 'groupid' => $groupid, 'page' => $page, 'perpage' => $perpage, 1192 'courseid' => $courseid); 1193 $params = self::validate_parameters(self::get_responses_analysis_parameters(), $params); 1194 $warnings = $itemsdata = array(); 1195 1196 list($feedback, $course, $cm, $context, $completioncourse) = self::validate_feedback($params['feedbackid'], 1197 $params['courseid']); 1198 1199 // Check permissions. 1200 require_capability('mod/feedback:viewreports', $context); 1201 1202 if (!empty($params['groupid'])) { 1203 $groupid = $params['groupid']; 1204 // Determine is the group is visible to user. 1205 if (!groups_group_visible($groupid, $course, $cm)) { 1206 throw new moodle_exception('notingroup'); 1207 } 1208 } else { 1209 // Check to see if groups are being used here. 1210 if ($groupmode = groups_get_activity_groupmode($cm)) { 1211 $groupid = groups_get_activity_group($cm); 1212 // Determine is the group is visible to user (this is particullary for the group 0 -> all groups). 1213 if (!groups_group_visible($groupid, $course, $cm)) { 1214 throw new moodle_exception('notingroup'); 1215 } 1216 } else { 1217 $groupid = 0; 1218 } 1219 } 1220 1221 $feedbackstructure = new mod_feedback_structure($feedback, $cm, $completioncourse->id); 1222 $responsestable = new mod_feedback_responses_table($feedbackstructure, $groupid); 1223 // Ensure responses number is correct prior returning them. 1224 $feedbackstructure->shuffle_anonym_responses(); 1225 $anonresponsestable = new mod_feedback_responses_anon_table($feedbackstructure, $groupid); 1226 1227 $result = array( 1228 'attempts' => $responsestable->export_external_structure($params['page'], $params['perpage']), 1229 'totalattempts' => $responsestable->get_total_responses_count(), 1230 'anonattempts' => $anonresponsestable->export_external_structure($params['page'], $params['perpage']), 1231 'totalanonattempts' => $anonresponsestable->get_total_responses_count(), 1232 'warnings' => $warnings 1233 ); 1234 return $result; 1235 } 1236 1237 /** 1238 * Describes the get_responses_analysis return value. 1239 * 1240 * @return external_single_structure 1241 * @since Moodle 3.3 1242 */ 1243 public static function get_responses_analysis_returns() { 1244 $responsestructure = new external_multiple_structure( 1245 new external_single_structure( 1246 array( 1247 'id' => new external_value(PARAM_INT, 'Response id'), 1248 'name' => new external_value(PARAM_RAW, 'Response name'), 1249 'printval' => new external_value(PARAM_RAW, 'Response ready for output'), 1250 'rawval' => new external_value(PARAM_RAW, 'Response raw value'), 1251 ) 1252 ) 1253 ); 1254 1255 return new external_single_structure( 1256 array( 1257 'attempts' => new external_multiple_structure( 1258 new external_single_structure( 1259 array( 1260 'id' => new external_value(PARAM_INT, 'Completed id'), 1261 'courseid' => new external_value(PARAM_INT, 'Course id'), 1262 'userid' => new external_value(PARAM_INT, 'User who responded'), 1263 'timemodified' => new external_value(PARAM_INT, 'Time modified for the response'), 1264 'fullname' => new external_value(PARAM_TEXT, 'User full name'), 1265 'responses' => $responsestructure 1266 ) 1267 ) 1268 ), 1269 'totalattempts' => new external_value(PARAM_INT, 'Total responses count.'), 1270 'anonattempts' => new external_multiple_structure( 1271 new external_single_structure( 1272 array( 1273 'id' => new external_value(PARAM_INT, 'Completed id'), 1274 'courseid' => new external_value(PARAM_INT, 'Course id'), 1275 'number' => new external_value(PARAM_INT, 'Response number'), 1276 'responses' => $responsestructure 1277 ) 1278 ) 1279 ), 1280 'totalanonattempts' => new external_value(PARAM_INT, 'Total anonymous responses count.'), 1281 'warnings' => new external_warnings(), 1282 ) 1283 ); 1284 } 1285 1286 /** 1287 * Describes the parameters for get_last_completed. 1288 * 1289 * @return external_function_parameters 1290 * @since Moodle 3.3 1291 */ 1292 public static function get_last_completed_parameters() { 1293 return new external_function_parameters ( 1294 array( 1295 'feedbackid' => new external_value(PARAM_INT, 'Feedback instance id'), 1296 'courseid' => new external_value(PARAM_INT, 'Course where user completes the feedback (for site feedbacks only).', 1297 VALUE_DEFAULT, 0), 1298 ) 1299 ); 1300 } 1301 1302 /** 1303 * Retrieves the last completion record for the current user. 1304 * 1305 * @param int $feedbackid feedback instance id 1306 * @return array of warnings and the last completed record 1307 * @since Moodle 3.3 1308 * @throws moodle_exception 1309 */ 1310 public static function get_last_completed($feedbackid, $courseid = 0) { 1311 global $PAGE; 1312 1313 $params = array('feedbackid' => $feedbackid, 'courseid' => $courseid); 1314 $params = self::validate_parameters(self::get_last_completed_parameters(), $params); 1315 $warnings = array(); 1316 1317 list($feedback, $course, $cm, $context, $completioncourse) = self::validate_feedback($params['feedbackid'], 1318 $params['courseid']); 1319 $feedbackcompletion = new mod_feedback_completion($feedback, $cm, $completioncourse->id); 1320 1321 if ($feedbackcompletion->is_anonymous()) { 1322 throw new moodle_exception('anonymous', 'feedback'); 1323 } 1324 if ($completed = $feedbackcompletion->find_last_completed()) { 1325 $exporter = new feedback_completed_exporter($completed); 1326 return array( 1327 'completed' => $exporter->export($PAGE->get_renderer('core')), 1328 'warnings' => $warnings, 1329 ); 1330 } 1331 throw new moodle_exception('not_completed_yet', 'feedback'); 1332 } 1333 1334 /** 1335 * Describes the get_last_completed return value. 1336 * 1337 * @return external_single_structure 1338 * @since Moodle 3.3 1339 */ 1340 public static function get_last_completed_returns() { 1341 return new external_single_structure( 1342 array( 1343 'completed' => feedback_completed_exporter::get_read_structure(), 1344 'warnings' => new external_warnings(), 1345 ) 1346 ); 1347 } 1348 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body