See Release Notes
Long Term Support Release
Differences Between: [Versions 310 and 401] [Versions 311 and 401] [Versions 39 and 401] [Versions 401 and 402] [Versions 401 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 $returneditems = array(); 456 457 list($feedback, $course, $cm, $context, $completioncourse) = self::validate_feedback($params['feedbackid'], 458 $params['courseid']); 459 460 $userhasaccess = true; 461 try { 462 // Check the user has access to the feedback. 463 self::validate_feedback_access($feedback, $completioncourse, $cm, $context, true); 464 } catch (moodle_exception $e) { 465 $userhasaccess = false; 466 $warnings[] = [ 467 'item' => $feedback->id, 468 'warningcode' => clean_param($e->errorcode, PARAM_ALPHANUM), 469 'message' => $e->getMessage(), 470 ]; 471 } 472 473 // For consistency with the web behaviour, the items should be returned only when the user can edit or view reports (to 474 // include non-editing teachers too). 475 $capabilities = [ 476 'mod/feedback:edititems', 477 'mod/feedback:viewreports', 478 ]; 479 if ($userhasaccess || has_any_capability($capabilities, $context)) { 480 // Remove previous warnings because, although the user might not have access, they have the proper capability. 481 $warnings = []; 482 $feedbackstructure = new mod_feedback_structure($feedback, $cm, $completioncourse->id); 483 if ($items = $feedbackstructure->get_items()) { 484 foreach ($items as $item) { 485 $itemnumber = empty($item->itemnr) ? null : $item->itemnr; 486 unset($item->itemnr); // Added by the function, not part of the record. 487 $exporter = new feedback_item_exporter($item, array('context' => $context, 'itemnumber' => $itemnumber)); 488 $returneditems[] = $exporter->export($PAGE->get_renderer('core')); 489 } 490 } 491 } else if ($userhasaccess) { 492 $warnings[] = [ 493 'item' => $feedback->id, 494 'warningcode' => 'nopermission', 495 'message' => 'nopermission', 496 ]; 497 } 498 499 $result = array( 500 'items' => $returneditems, 501 'warnings' => $warnings 502 ); 503 return $result; 504 } 505 506 /** 507 * Describes the get_items return value. 508 * 509 * @return external_single_structure 510 * @since Moodle 3.3 511 */ 512 public static function get_items_returns() { 513 return new external_single_structure( 514 array( 515 'items' => new external_multiple_structure( 516 feedback_item_exporter::get_read_structure() 517 ), 518 'warnings' => new external_warnings(), 519 ) 520 ); 521 } 522 523 /** 524 * Describes the parameters for launch_feedback. 525 * 526 * @return external_function_parameters 527 * @since Moodle 3.3 528 */ 529 public static function launch_feedback_parameters() { 530 return new external_function_parameters ( 531 array( 532 'feedbackid' => new external_value(PARAM_INT, 'Feedback instance id'), 533 'courseid' => new external_value(PARAM_INT, 'Course where user completes the feedback (for site feedbacks only).', 534 VALUE_DEFAULT, 0), 535 ) 536 ); 537 } 538 539 /** 540 * Starts or continues a feedback submission 541 * 542 * @param array $feedbackid feedback instance id 543 * @param int $courseid course where user completes a feedback (for site feedbacks only). 544 * @return array of warnings and launch information 545 * @since Moodle 3.3 546 */ 547 public static function launch_feedback($feedbackid, $courseid = 0) { 548 global $PAGE; 549 550 $params = array('feedbackid' => $feedbackid, 'courseid' => $courseid); 551 $params = self::validate_parameters(self::launch_feedback_parameters(), $params); 552 $warnings = array(); 553 554 list($feedback, $course, $cm, $context, $completioncourse) = self::validate_feedback($params['feedbackid'], 555 $params['courseid']); 556 // Check we can do a new submission (or continue an existing). 557 $feedbackcompletion = self::validate_feedback_access($feedback, $completioncourse, $cm, $context, true); 558 559 $gopage = $feedbackcompletion->get_resume_page(); 560 if ($gopage === null) { 561 $gopage = -1; // Last page. 562 } 563 564 $result = array( 565 'gopage' => $gopage, 566 'warnings' => $warnings 567 ); 568 return $result; 569 } 570 571 /** 572 * Describes the launch_feedback return value. 573 * 574 * @return external_single_structure 575 * @since Moodle 3.3 576 */ 577 public static function launch_feedback_returns() { 578 return new external_single_structure( 579 array( 580 'gopage' => new external_value(PARAM_INT, 'The next page to go (-1 if we were already in the last page). 0 for first page.'), 581 'warnings' => new external_warnings(), 582 ) 583 ); 584 } 585 586 /** 587 * Describes the parameters for get_page_items. 588 * 589 * @return external_function_parameters 590 * @since Moodle 3.3 591 */ 592 public static function get_page_items_parameters() { 593 return new external_function_parameters ( 594 array( 595 'feedbackid' => new external_value(PARAM_INT, 'Feedback instance id'), 596 'page' => new external_value(PARAM_INT, 'The page to get starting by 0'), 597 'courseid' => new external_value(PARAM_INT, 'Course where user completes the feedback (for site feedbacks only).', 598 VALUE_DEFAULT, 0), 599 ) 600 ); 601 } 602 603 /** 604 * Get a single feedback page items. 605 * 606 * @param int $feedbackid feedback instance id 607 * @param int $page the page to get starting by 0 608 * @param int $courseid course where user completes the feedback (for site feedbacks only) 609 * @return array of warnings and launch information 610 * @since Moodle 3.3 611 */ 612 public static function get_page_items($feedbackid, $page, $courseid = 0) { 613 global $PAGE; 614 615 $params = array('feedbackid' => $feedbackid, 'page' => $page, 'courseid' => $courseid); 616 $params = self::validate_parameters(self::get_page_items_parameters(), $params); 617 $warnings = array(); 618 $returneditems = array(); 619 $hasprevpage = false; 620 $hasnextpage = false; 621 622 list($feedback, $course, $cm, $context, $completioncourse) = self::validate_feedback($params['feedbackid'], 623 $params['courseid']); 624 625 $userhasaccess = true; 626 $feedbackcompletion = null; 627 try { 628 // Check the user has access to the feedback. 629 $feedbackcompletion = self::validate_feedback_access($feedback, $completioncourse, $cm, $context, true); 630 } catch (moodle_exception $e) { 631 $userhasaccess = false; 632 $warnings[] = [ 633 'item' => $feedback->id, 634 'warningcode' => str_replace('_', '', $e->errorcode), 635 'message' => $e->getMessage(), 636 ]; 637 } 638 639 // For consistency with the web behaviour, the items should be returned only when the user can edit or view reports (to 640 // include non-editing teachers too). 641 $capabilities = [ 642 'mod/feedback:edititems', 643 'mod/feedback:viewreports', 644 ]; 645 if ($userhasaccess || has_any_capability($capabilities, $context)) { 646 // Remove previous warnings because, although the user might not have access, they have the proper capability. 647 $warnings = []; 648 649 if ($feedbackcompletion == null) { 650 $feedbackcompletion = new mod_feedback_completion($feedback, $cm, $completioncourse->id); 651 } 652 653 $page = $params['page']; 654 $pages = $feedbackcompletion->get_pages(); 655 $pageitems = $pages[$page]; 656 $hasnextpage = $page < count($pages) - 1; // Until we complete this page we can not trust get_next_page(). 657 $hasprevpage = $page && ($feedbackcompletion->get_previous_page($page, false) !== null); 658 659 foreach ($pageitems as $item) { 660 $itemnumber = empty($item->itemnr) ? null : $item->itemnr; 661 unset($item->itemnr); // Added by the function, not part of the record. 662 $exporter = new feedback_item_exporter($item, array('context' => $context, 'itemnumber' => $itemnumber)); 663 $returneditems[] = $exporter->export($PAGE->get_renderer('core')); 664 } 665 } else if ($userhasaccess) { 666 $warnings[] = [ 667 'item' => $feedback->id, 668 'warningcode' => 'nopermission', 669 'message' => get_string('nopermission', 'mod_feedback'), 670 ]; 671 } 672 673 $result = array( 674 'items' => $returneditems, 675 'hasprevpage' => $hasprevpage, 676 'hasnextpage' => $hasnextpage, 677 'warnings' => $warnings 678 ); 679 return $result; 680 } 681 682 /** 683 * Describes the get_page_items return value. 684 * 685 * @return external_single_structure 686 * @since Moodle 3.3 687 */ 688 public static function get_page_items_returns() { 689 return new external_single_structure( 690 array( 691 'items' => new external_multiple_structure( 692 feedback_item_exporter::get_read_structure() 693 ), 694 'hasprevpage' => new external_value(PARAM_BOOL, 'Whether is a previous page.'), 695 'hasnextpage' => new external_value(PARAM_BOOL, 'Whether there are more pages.'), 696 'warnings' => new external_warnings(), 697 ) 698 ); 699 } 700 701 /** 702 * Describes the parameters for process_page. 703 * 704 * @return external_function_parameters 705 * @since Moodle 3.3 706 */ 707 public static function process_page_parameters() { 708 return new external_function_parameters ( 709 array( 710 'feedbackid' => new external_value(PARAM_INT, 'Feedback instance id.'), 711 'page' => new external_value(PARAM_INT, 'The page being processed.'), 712 'responses' => new external_multiple_structure( 713 new external_single_structure( 714 array( 715 'name' => new external_value(PARAM_NOTAGS, 'The response name (usually type[index]_id).'), 716 'value' => new external_value(PARAM_RAW, 'The response value.'), 717 ) 718 ), 'The data to be processed.', VALUE_DEFAULT, array() 719 ), 720 'goprevious' => new external_value(PARAM_BOOL, 'Whether we want to jump to previous page.', VALUE_DEFAULT, false), 721 'courseid' => new external_value(PARAM_INT, 'Course where user completes the feedback (for site feedbacks only).', 722 VALUE_DEFAULT, 0), 723 ) 724 ); 725 } 726 727 /** 728 * Process a jump between pages. 729 * 730 * @param array $feedbackid feedback instance id 731 * @param array $page the page being processed 732 * @param array $responses the responses to be processed 733 * @param bool $goprevious whether we want to jump to previous page 734 * @param int $courseid course where user completes the feedback (for site feedbacks only) 735 * @return array of warnings and launch information 736 * @since Moodle 3.3 737 */ 738 public static function process_page($feedbackid, $page, $responses = [], $goprevious = false, $courseid = 0) { 739 global $USER, $SESSION; 740 741 $params = array('feedbackid' => $feedbackid, 'page' => $page, 'responses' => $responses, 'goprevious' => $goprevious, 742 'courseid' => $courseid); 743 $params = self::validate_parameters(self::process_page_parameters(), $params); 744 $warnings = array(); 745 $siteaftersubmit = $completionpagecontents = ''; 746 747 list($feedback, $course, $cm, $context, $completioncourse) = self::validate_feedback($params['feedbackid'], 748 $params['courseid']); 749 // Check we can do a new submission (or continue an existing). 750 $feedbackcompletion = self::validate_feedback_access($feedback, $completioncourse, $cm, $context, true); 751 752 // Create the $_POST object required by the feedback question engine. 753 $_POST = array(); 754 foreach ($responses as $response) { 755 // First check if we are handling array parameters. 756 if (preg_match('/(.+)\[(.+)\]$/', $response['name'], $matches)) { 757 $_POST[$matches[1]][$matches[2]] = $response['value']; 758 } else { 759 $_POST[$response['name']] = $response['value']; 760 } 761 } 762 // Force fields. 763 $_POST['id'] = $cm->id; 764 $_POST['courseid'] = $courseid; 765 $_POST['gopage'] = $params['page']; 766 $_POST['_qf__mod_feedback_complete_form'] = 1; 767 768 // Determine where to go, backwards or forward. 769 if (!$params['goprevious']) { 770 $_POST['gonextpage'] = 1; // Even if we are saving values we need this set. 771 if ($feedbackcompletion->get_next_page($params['page'], false) === null) { 772 $_POST['savevalues'] = 1; // If there is no next page, it means we are finishing the feedback. 773 } 774 } 775 776 // Ignore sesskey (deep in some APIs), the request is already validated. 777 $USER->ignoresesskey = true; 778 feedback_init_feedback_session(); 779 $SESSION->feedback->is_started = true; 780 781 $feedbackcompletion->process_page($params['page'], $params['goprevious']); 782 $completed = $feedbackcompletion->just_completed(); 783 if ($completed) { 784 $jumpto = 0; 785 if ($feedback->page_after_submit) { 786 $completionpagecontents = $feedbackcompletion->page_after_submit(); 787 } 788 789 if ($feedback->site_after_submit) { 790 $siteaftersubmit = feedback_encode_target_url($feedback->site_after_submit); 791 } 792 } else { 793 $jumpto = $feedbackcompletion->get_jumpto(); 794 } 795 796 $result = array( 797 'jumpto' => $jumpto, 798 'completed' => $completed, 799 'completionpagecontents' => $completionpagecontents, 800 'siteaftersubmit' => $siteaftersubmit, 801 'warnings' => $warnings 802 ); 803 return $result; 804 } 805 806 /** 807 * Describes the process_page return value. 808 * 809 * @return external_single_structure 810 * @since Moodle 3.3 811 */ 812 public static function process_page_returns() { 813 return new external_single_structure( 814 array( 815 'jumpto' => new external_value(PARAM_INT, 'The page to jump to.'), 816 'completed' => new external_value(PARAM_BOOL, 'If the user completed the feedback.'), 817 'completionpagecontents' => new external_value(PARAM_RAW, 'The completion page contents.'), 818 'siteaftersubmit' => new external_value(PARAM_RAW, 'The link (could be relative) to show after submit.'), 819 'warnings' => new external_warnings(), 820 ) 821 ); 822 } 823 824 /** 825 * Describes the parameters for get_analysis. 826 * 827 * @return external_function_parameters 828 * @since Moodle 3.3 829 */ 830 public static function get_analysis_parameters() { 831 return new external_function_parameters ( 832 array( 833 'feedbackid' => new external_value(PARAM_INT, 'Feedback instance id'), 834 'groupid' => new external_value(PARAM_INT, 'Group id, 0 means that the function will determine the user group', 835 VALUE_DEFAULT, 0), 836 'courseid' => new external_value(PARAM_INT, 'Course where user completes the feedback (for site feedbacks only).', 837 VALUE_DEFAULT, 0), 838 ) 839 ); 840 } 841 842 /** 843 * Retrieves the feedback analysis. 844 * 845 * @param array $feedbackid feedback instance id 846 * @param int $groupid group id, 0 means that the function will determine the user group 847 * @param int $courseid course where user completes the feedback (for site feedbacks only) 848 * @return array of warnings and launch information 849 * @since Moodle 3.3 850 */ 851 public static function get_analysis($feedbackid, $groupid = 0, $courseid = 0) { 852 global $PAGE; 853 854 $params = array('feedbackid' => $feedbackid, 'groupid' => $groupid, 'courseid' => $courseid); 855 $params = self::validate_parameters(self::get_analysis_parameters(), $params); 856 $warnings = $itemsdata = array(); 857 858 list($feedback, $course, $cm, $context, $completioncourse) = self::validate_feedback($params['feedbackid'], 859 $params['courseid']); 860 861 // Check permissions. 862 $feedbackstructure = new mod_feedback_structure($feedback, $cm, $completioncourse->id); 863 if (!$feedbackstructure->can_view_analysis()) { 864 throw new required_capability_exception($context, 'mod/feedback:viewanalysepage', 'nopermission', ''); 865 } 866 867 if (!empty($params['groupid'])) { 868 $groupid = $params['groupid']; 869 // Determine is the group is visible to user. 870 if (!groups_group_visible($groupid, $course, $cm)) { 871 throw new moodle_exception('notingroup'); 872 } 873 } else { 874 // Check to see if groups are being used here. 875 if ($groupmode = groups_get_activity_groupmode($cm)) { 876 $groupid = groups_get_activity_group($cm); 877 // Determine is the group is visible to user (this is particullary for the group 0 -> all groups). 878 if (!groups_group_visible($groupid, $course, $cm)) { 879 throw new moodle_exception('notingroup'); 880 } 881 } else { 882 $groupid = 0; 883 } 884 } 885 886 // Summary data. 887 $summary = new mod_feedback\output\summary($feedbackstructure, $groupid); 888 $summarydata = $summary->export_for_template($PAGE->get_renderer('core')); 889 890 $checkanonymously = true; 891 if ($groupid > 0 AND $feedback->anonymous == FEEDBACK_ANONYMOUS_YES) { 892 $completedcount = $feedbackstructure->count_completed_responses($groupid); 893 if ($completedcount < FEEDBACK_MIN_ANONYMOUS_COUNT_IN_GROUP) { 894 $checkanonymously = false; 895 } 896 } 897 898 if ($checkanonymously) { 899 // Get the items of the feedback. 900 $items = $feedbackstructure->get_items(true); 901 foreach ($items as $item) { 902 $itemobj = feedback_get_item_class($item->typ); 903 $itemnumber = empty($item->itemnr) ? null : $item->itemnr; 904 unset($item->itemnr); // Added by the function, not part of the record. 905 $exporter = new feedback_item_exporter($item, array('context' => $context, 'itemnumber' => $itemnumber)); 906 907 $itemsdata[] = array( 908 'item' => $exporter->export($PAGE->get_renderer('core')), 909 'data' => $itemobj->get_analysed_for_external($item, $groupid), 910 ); 911 } 912 } else { 913 $warnings[] = array( 914 'item' => 'feedback', 915 'itemid' => $feedback->id, 916 'warningcode' => 'insufficientresponsesforthisgroup', 917 'message' => s(get_string('insufficient_responses_for_this_group', 'feedback')) 918 ); 919 } 920 921 $result = array( 922 'completedcount' => $summarydata->completedcount, 923 'itemscount' => $summarydata->itemscount, 924 'itemsdata' => $itemsdata, 925 'warnings' => $warnings 926 ); 927 return $result; 928 } 929 930 /** 931 * Describes the get_analysis return value. 932 * 933 * @return external_single_structure 934 * @since Moodle 3.3 935 */ 936 public static function get_analysis_returns() { 937 return new external_single_structure( 938 array( 939 'completedcount' => new external_value(PARAM_INT, 'Number of completed submissions.'), 940 'itemscount' => new external_value(PARAM_INT, 'Number of items (questions).'), 941 'itemsdata' => new external_multiple_structure( 942 new external_single_structure( 943 array( 944 'item' => feedback_item_exporter::get_read_structure(), 945 'data' => new external_multiple_structure( 946 new external_value(PARAM_RAW, 'The analysis data (can be json encoded)') 947 ), 948 ) 949 ) 950 ), 951 'warnings' => new external_warnings(), 952 ) 953 ); 954 } 955 956 /** 957 * Describes the parameters for get_unfinished_responses. 958 * 959 * @return external_function_parameters 960 * @since Moodle 3.3 961 */ 962 public static function get_unfinished_responses_parameters() { 963 return new external_function_parameters ( 964 array( 965 'feedbackid' => new external_value(PARAM_INT, 'Feedback instance id.'), 966 'courseid' => new external_value(PARAM_INT, 'Course where user completes the feedback (for site feedbacks only).', 967 VALUE_DEFAULT, 0), 968 ) 969 ); 970 } 971 972 /** 973 * Retrieves responses from the current unfinished attempt. 974 * 975 * @param array $feedbackid feedback instance id 976 * @param int $courseid course where user completes the feedback (for site feedbacks only) 977 * @return array of warnings and launch information 978 * @since Moodle 3.3 979 */ 980 public static function get_unfinished_responses($feedbackid, $courseid = 0) { 981 global $PAGE; 982 983 $params = array('feedbackid' => $feedbackid, 'courseid' => $courseid); 984 $params = self::validate_parameters(self::get_unfinished_responses_parameters(), $params); 985 $warnings = $itemsdata = array(); 986 987 list($feedback, $course, $cm, $context, $completioncourse) = self::validate_feedback($params['feedbackid'], 988 $params['courseid']); 989 $feedbackcompletion = new mod_feedback_completion($feedback, $cm, $completioncourse->id); 990 991 $responses = array(); 992 $unfinished = $feedbackcompletion->get_unfinished_responses(); 993 foreach ($unfinished as $u) { 994 $exporter = new feedback_valuetmp_exporter($u); 995 $responses[] = $exporter->export($PAGE->get_renderer('core')); 996 } 997 998 $result = array( 999 'responses' => $responses, 1000 'warnings' => $warnings 1001 ); 1002 return $result; 1003 } 1004 1005 /** 1006 * Describes the get_unfinished_responses return value. 1007 * 1008 * @return external_single_structure 1009 * @since Moodle 3.3 1010 */ 1011 public static function get_unfinished_responses_returns() { 1012 return new external_single_structure( 1013 array( 1014 'responses' => new external_multiple_structure( 1015 feedback_valuetmp_exporter::get_read_structure() 1016 ), 1017 'warnings' => new external_warnings(), 1018 ) 1019 ); 1020 } 1021 1022 /** 1023 * Describes the parameters for get_finished_responses. 1024 * 1025 * @return external_function_parameters 1026 * @since Moodle 3.3 1027 */ 1028 public static function get_finished_responses_parameters() { 1029 return new external_function_parameters ( 1030 array( 1031 'feedbackid' => new external_value(PARAM_INT, 'Feedback instance id.'), 1032 'courseid' => new external_value(PARAM_INT, 'Course where user completes the feedback (for site feedbacks only).', 1033 VALUE_DEFAULT, 0), 1034 ) 1035 ); 1036 } 1037 1038 /** 1039 * Retrieves responses from the last finished attempt. 1040 * 1041 * @param array $feedbackid feedback instance id 1042 * @param int $courseid course where user completes the feedback (for site feedbacks only) 1043 * @return array of warnings and the responses 1044 * @since Moodle 3.3 1045 */ 1046 public static function get_finished_responses($feedbackid, $courseid = 0) { 1047 global $PAGE; 1048 1049 $params = array('feedbackid' => $feedbackid, 'courseid' => $courseid); 1050 $params = self::validate_parameters(self::get_finished_responses_parameters(), $params); 1051 $warnings = $itemsdata = array(); 1052 1053 list($feedback, $course, $cm, $context, $completioncourse) = self::validate_feedback($params['feedbackid'], 1054 $params['courseid']); 1055 $feedbackcompletion = new mod_feedback_completion($feedback, $cm, $completioncourse->id); 1056 1057 $responses = array(); 1058 // Load and get the responses from the last completed feedback. 1059 $feedbackcompletion->find_last_completed(); 1060 $unfinished = $feedbackcompletion->get_finished_responses(); 1061 foreach ($unfinished as $u) { 1062 $exporter = new feedback_value_exporter($u); 1063 $responses[] = $exporter->export($PAGE->get_renderer('core')); 1064 } 1065 1066 $result = array( 1067 'responses' => $responses, 1068 'warnings' => $warnings 1069 ); 1070 return $result; 1071 } 1072 1073 /** 1074 * Describes the get_finished_responses return value. 1075 * 1076 * @return external_single_structure 1077 * @since Moodle 3.3 1078 */ 1079 public static function get_finished_responses_returns() { 1080 return new external_single_structure( 1081 array( 1082 'responses' => new external_multiple_structure( 1083 feedback_value_exporter::get_read_structure() 1084 ), 1085 'warnings' => new external_warnings(), 1086 ) 1087 ); 1088 } 1089 1090 /** 1091 * Describes the parameters for get_non_respondents. 1092 * 1093 * @return external_function_parameters 1094 * @since Moodle 3.3 1095 */ 1096 public static function get_non_respondents_parameters() { 1097 return new external_function_parameters ( 1098 array( 1099 'feedbackid' => new external_value(PARAM_INT, 'Feedback instance id'), 1100 'groupid' => new external_value(PARAM_INT, 'Group id, 0 means that the function will determine the user group.', 1101 VALUE_DEFAULT, 0), 1102 'sort' => new external_value(PARAM_ALPHA, 'Sort param, must be firstname, lastname or lastaccess (default).', 1103 VALUE_DEFAULT, 'lastaccess'), 1104 'page' => new external_value(PARAM_INT, 'The page of records to return.', VALUE_DEFAULT, 0), 1105 'perpage' => new external_value(PARAM_INT, 'The number of records to return per page.', VALUE_DEFAULT, 0), 1106 'courseid' => new external_value(PARAM_INT, 'Course where user completes the feedback (for site feedbacks only).', 1107 VALUE_DEFAULT, 0), 1108 ) 1109 ); 1110 } 1111 1112 /** 1113 * Retrieves a list of students who didn't submit the feedback. 1114 * 1115 * @param int $feedbackid feedback instance id 1116 * @param int $groupid Group id, 0 means that the function will determine the user group' 1117 * @param str $sort sort param, must be firstname, lastname or lastaccess (default) 1118 * @param int $page the page of records to return 1119 * @param int $perpage the number of records to return per page 1120 * @param int $courseid course where user completes the feedback (for site feedbacks only) 1121 * @return array of warnings and users ids 1122 * @since Moodle 3.3 1123 */ 1124 public static function get_non_respondents($feedbackid, $groupid = 0, $sort = 'lastaccess', $page = 0, $perpage = 0, 1125 $courseid = 0) { 1126 1127 global $CFG; 1128 require_once($CFG->dirroot . '/mod/feedback/lib.php'); 1129 1130 $params = array('feedbackid' => $feedbackid, 'groupid' => $groupid, 'sort' => $sort, 'page' => $page, 1131 'perpage' => $perpage, 'courseid' => $courseid); 1132 $params = self::validate_parameters(self::get_non_respondents_parameters(), $params); 1133 $warnings = $nonrespondents = array(); 1134 1135 list($feedback, $course, $cm, $context, $completioncourse) = self::validate_feedback($params['feedbackid'], 1136 $params['courseid']); 1137 $feedbackcompletion = new mod_feedback_completion($feedback, $cm, $completioncourse->id); 1138 $completioncourseid = $feedbackcompletion->get_courseid(); 1139 1140 if ($feedback->anonymous != FEEDBACK_ANONYMOUS_NO || $feedback->course == SITEID) { 1141 throw new moodle_exception('anonymous', 'feedback'); 1142 } 1143 1144 // Check permissions. 1145 require_capability('mod/feedback:viewreports', $context); 1146 1147 if (!empty($params['groupid'])) { 1148 $groupid = $params['groupid']; 1149 // Determine is the group is visible to user. 1150 if (!groups_group_visible($groupid, $course, $cm)) { 1151 throw new moodle_exception('notingroup'); 1152 } 1153 } else { 1154 // Check to see if groups are being used here. 1155 if ($groupmode = groups_get_activity_groupmode($cm)) { 1156 $groupid = groups_get_activity_group($cm); 1157 // Determine is the group is visible to user (this is particullary for the group 0 -> all groups). 1158 if (!groups_group_visible($groupid, $course, $cm)) { 1159 throw new moodle_exception('notingroup'); 1160 } 1161 } else { 1162 $groupid = 0; 1163 } 1164 } 1165 1166 if ($params['sort'] !== 'firstname' && $params['sort'] !== 'lastname' && $params['sort'] !== 'lastaccess') { 1167 throw new invalid_parameter_exception('Invalid sort param, must be firstname, lastname or lastaccess.'); 1168 } 1169 1170 // Check if we are page filtering. 1171 if ($params['perpage'] == 0) { 1172 $page = $params['page']; 1173 $perpage = FEEDBACK_DEFAULT_PAGE_COUNT; 1174 } else { 1175 $perpage = $params['perpage']; 1176 $page = $perpage * $params['page']; 1177 } 1178 $users = feedback_get_incomplete_users($cm, $groupid, $params['sort'], $page, $perpage, true); 1179 foreach ($users as $user) { 1180 $nonrespondents[] = [ 1181 'courseid' => $completioncourseid, 1182 'userid' => $user->id, 1183 'fullname' => fullname($user), 1184 'started' => $user->feedbackstarted 1185 ]; 1186 } 1187 1188 $result = array( 1189 'users' => $nonrespondents, 1190 'total' => feedback_count_incomplete_users($cm, $groupid), 1191 'warnings' => $warnings 1192 ); 1193 return $result; 1194 } 1195 1196 /** 1197 * Describes the get_non_respondents return value. 1198 * 1199 * @return external_single_structure 1200 * @since Moodle 3.3 1201 */ 1202 public static function get_non_respondents_returns() { 1203 return new external_single_structure( 1204 array( 1205 'users' => new external_multiple_structure( 1206 new external_single_structure( 1207 array( 1208 'courseid' => new external_value(PARAM_INT, 'Course id'), 1209 'userid' => new external_value(PARAM_INT, 'The user id'), 1210 'fullname' => new external_value(PARAM_TEXT, 'User full name'), 1211 'started' => new external_value(PARAM_BOOL, 'If the user has started the attempt'), 1212 ) 1213 ) 1214 ), 1215 'total' => new external_value(PARAM_INT, 'Total number of non respondents'), 1216 'warnings' => new external_warnings(), 1217 ) 1218 ); 1219 } 1220 1221 /** 1222 * Describes the parameters for get_responses_analysis. 1223 * 1224 * @return external_function_parameters 1225 * @since Moodle 3.3 1226 */ 1227 public static function get_responses_analysis_parameters() { 1228 return new external_function_parameters ( 1229 array( 1230 'feedbackid' => new external_value(PARAM_INT, 'Feedback instance id'), 1231 'groupid' => new external_value(PARAM_INT, 'Group id, 0 means that the function will determine the user group', 1232 VALUE_DEFAULT, 0), 1233 'page' => new external_value(PARAM_INT, 'The page of records to return.', VALUE_DEFAULT, 0), 1234 'perpage' => new external_value(PARAM_INT, 'The number of records to return per page', VALUE_DEFAULT, 0), 1235 'courseid' => new external_value(PARAM_INT, 'Course where user completes the feedback (for site feedbacks only).', 1236 VALUE_DEFAULT, 0), 1237 ) 1238 ); 1239 } 1240 1241 /** 1242 * Return the feedback user responses. 1243 * 1244 * @param int $feedbackid feedback instance id 1245 * @param int $groupid Group id, 0 means that the function will determine the user group 1246 * @param int $page the page of records to return 1247 * @param int $perpage the number of records to return per page 1248 * @param int $courseid course where user completes the feedback (for site feedbacks only) 1249 * @return array of warnings and users attemps and responses 1250 * @throws moodle_exception 1251 * @since Moodle 3.3 1252 */ 1253 public static function get_responses_analysis($feedbackid, $groupid = 0, $page = 0, $perpage = 0, $courseid = 0) { 1254 1255 $params = array('feedbackid' => $feedbackid, 'groupid' => $groupid, 'page' => $page, 'perpage' => $perpage, 1256 'courseid' => $courseid); 1257 $params = self::validate_parameters(self::get_responses_analysis_parameters(), $params); 1258 $warnings = $itemsdata = array(); 1259 1260 list($feedback, $course, $cm, $context, $completioncourse) = self::validate_feedback($params['feedbackid'], 1261 $params['courseid']); 1262 1263 // Check permissions. 1264 require_capability('mod/feedback:viewreports', $context); 1265 1266 if (!empty($params['groupid'])) { 1267 $groupid = $params['groupid']; 1268 // Determine is the group is visible to user. 1269 if (!groups_group_visible($groupid, $course, $cm)) { 1270 throw new moodle_exception('notingroup'); 1271 } 1272 } else { 1273 // Check to see if groups are being used here. 1274 if ($groupmode = groups_get_activity_groupmode($cm)) { 1275 $groupid = groups_get_activity_group($cm); 1276 // Determine is the group is visible to user (this is particullary for the group 0 -> all groups). 1277 if (!groups_group_visible($groupid, $course, $cm)) { 1278 throw new moodle_exception('notingroup'); 1279 } 1280 } else { 1281 $groupid = 0; 1282 } 1283 } 1284 1285 $feedbackstructure = new mod_feedback_structure($feedback, $cm, $completioncourse->id); 1286 $responsestable = new mod_feedback_responses_table($feedbackstructure, $groupid); 1287 // Ensure responses number is correct prior returning them. 1288 $feedbackstructure->shuffle_anonym_responses(); 1289 $anonresponsestable = new mod_feedback_responses_anon_table($feedbackstructure, $groupid); 1290 1291 $result = array( 1292 'attempts' => $responsestable->export_external_structure($params['page'], $params['perpage']), 1293 'totalattempts' => $responsestable->get_total_responses_count(), 1294 'anonattempts' => $anonresponsestable->export_external_structure($params['page'], $params['perpage']), 1295 'totalanonattempts' => $anonresponsestable->get_total_responses_count(), 1296 'warnings' => $warnings 1297 ); 1298 return $result; 1299 } 1300 1301 /** 1302 * Describes the get_responses_analysis return value. 1303 * 1304 * @return external_single_structure 1305 * @since Moodle 3.3 1306 */ 1307 public static function get_responses_analysis_returns() { 1308 $responsestructure = new external_multiple_structure( 1309 new external_single_structure( 1310 array( 1311 'id' => new external_value(PARAM_INT, 'Response id'), 1312 'name' => new external_value(PARAM_RAW, 'Response name'), 1313 'printval' => new external_value(PARAM_RAW, 'Response ready for output'), 1314 'rawval' => new external_value(PARAM_RAW, 'Response raw value'), 1315 ) 1316 ) 1317 ); 1318 1319 return new external_single_structure( 1320 array( 1321 'attempts' => new external_multiple_structure( 1322 new external_single_structure( 1323 array( 1324 'id' => new external_value(PARAM_INT, 'Completed id'), 1325 'courseid' => new external_value(PARAM_INT, 'Course id'), 1326 'userid' => new external_value(PARAM_INT, 'User who responded'), 1327 'timemodified' => new external_value(PARAM_INT, 'Time modified for the response'), 1328 'fullname' => new external_value(PARAM_TEXT, 'User full name'), 1329 'responses' => $responsestructure 1330 ) 1331 ) 1332 ), 1333 'totalattempts' => new external_value(PARAM_INT, 'Total responses count.'), 1334 'anonattempts' => new external_multiple_structure( 1335 new external_single_structure( 1336 array( 1337 'id' => new external_value(PARAM_INT, 'Completed id'), 1338 'courseid' => new external_value(PARAM_INT, 'Course id'), 1339 'number' => new external_value(PARAM_INT, 'Response number'), 1340 'responses' => $responsestructure 1341 ) 1342 ) 1343 ), 1344 'totalanonattempts' => new external_value(PARAM_INT, 'Total anonymous responses count.'), 1345 'warnings' => new external_warnings(), 1346 ) 1347 ); 1348 } 1349 1350 /** 1351 * Describes the parameters for get_last_completed. 1352 * 1353 * @return external_function_parameters 1354 * @since Moodle 3.3 1355 */ 1356 public static function get_last_completed_parameters() { 1357 return new external_function_parameters ( 1358 array( 1359 'feedbackid' => new external_value(PARAM_INT, 'Feedback instance id'), 1360 'courseid' => new external_value(PARAM_INT, 'Course where user completes the feedback (for site feedbacks only).', 1361 VALUE_DEFAULT, 0), 1362 ) 1363 ); 1364 } 1365 1366 /** 1367 * Retrieves the last completion record for the current user. 1368 * 1369 * @param int $feedbackid feedback instance id 1370 * @return array of warnings and the last completed record 1371 * @since Moodle 3.3 1372 * @throws moodle_exception 1373 */ 1374 public static function get_last_completed($feedbackid, $courseid = 0) { 1375 global $PAGE; 1376 1377 $params = array('feedbackid' => $feedbackid, 'courseid' => $courseid); 1378 $params = self::validate_parameters(self::get_last_completed_parameters(), $params); 1379 $warnings = array(); 1380 1381 list($feedback, $course, $cm, $context, $completioncourse) = self::validate_feedback($params['feedbackid'], 1382 $params['courseid']); 1383 $feedbackcompletion = new mod_feedback_completion($feedback, $cm, $completioncourse->id); 1384 1385 if ($feedbackcompletion->is_anonymous()) { 1386 throw new moodle_exception('anonymous', 'feedback'); 1387 } 1388 if ($completed = $feedbackcompletion->find_last_completed()) { 1389 $exporter = new feedback_completed_exporter($completed); 1390 return array( 1391 'completed' => $exporter->export($PAGE->get_renderer('core')), 1392 'warnings' => $warnings, 1393 ); 1394 } 1395 throw new moodle_exception('not_completed_yet', 'feedback'); 1396 } 1397 1398 /** 1399 * Describes the get_last_completed return value. 1400 * 1401 * @return external_single_structure 1402 * @since Moodle 3.3 1403 */ 1404 public static function get_last_completed_returns() { 1405 return new external_single_structure( 1406 array( 1407 'completed' => feedback_completed_exporter::get_read_structure(), 1408 'warnings' => new external_warnings(), 1409 ) 1410 ); 1411 } 1412 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body