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