MDL-57820 mod_feedback: New WS mod_feedback_get_analysis
[moodle.git] / mod / feedback / classes / external.php
blobc3fa0c43810d9d944c4fee0ee7aa778762bb1cee
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.
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/>.
17 /**
18 * Feedback external API
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
27 defined('MOODLE_INTERNAL') || die;
29 require_once("$CFG->libdir/externallib.php");
31 use mod_feedback\external\feedback_summary_exporter;
32 use mod_feedback\external\feedback_completedtmp_exporter;
33 use mod_feedback\external\feedback_item_exporter;
35 /**
36 * Feedback external functions
38 * @package mod_feedback
39 * @category external
40 * @copyright 2017 Juan Leyva <juan@moodle.com>
41 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
42 * @since Moodle 3.3
44 class mod_feedback_external extends external_api {
46 /**
47 * Describes the parameters for get_feedbacks_by_courses.
49 * @return external_function_parameters
50 * @since Moodle 3.3
52 public static function get_feedbacks_by_courses_parameters() {
53 return new external_function_parameters (
54 array(
55 'courseids' => new external_multiple_structure(
56 new external_value(PARAM_INT, 'Course id'), 'Array of course ids', VALUE_DEFAULT, array()
62 /**
63 * Returns a list of feedbacks in a provided list of courses.
64 * If no list is provided all feedbacks that the user can view will be returned.
66 * @param array $courseids course ids
67 * @return array of warnings and feedbacks
68 * @since Moodle 3.3
70 public static function get_feedbacks_by_courses($courseids = array()) {
71 global $PAGE;
73 $warnings = array();
74 $returnedfeedbacks = array();
76 $params = array(
77 'courseids' => $courseids,
79 $params = self::validate_parameters(self::get_feedbacks_by_courses_parameters(), $params);
81 $mycourses = array();
82 if (empty($params['courseids'])) {
83 $mycourses = enrol_get_my_courses();
84 $params['courseids'] = array_keys($mycourses);
87 // Ensure there are courseids to loop through.
88 if (!empty($params['courseids'])) {
90 list($courses, $warnings) = external_util::validate_courses($params['courseids'], $mycourses);
91 $output = $PAGE->get_renderer('core');
93 // Get the feedbacks in this course, this function checks users visibility permissions.
94 // We can avoid then additional validate_context calls.
95 $feedbacks = get_all_instances_in_courses("feedback", $courses);
96 foreach ($feedbacks as $feedback) {
98 $context = context_module::instance($feedback->coursemodule);
100 // Remove fields that are not from the feedback (added by get_all_instances_in_courses).
101 unset($feedback->coursemodule, $feedback->context, $feedback->visible, $feedback->section, $feedback->groupmode,
102 $feedback->groupingid);
104 // Check permissions.
105 if (!has_capability('mod/feedback:edititems', $context)) {
106 // Don't return the optional properties.
107 $properties = feedback_summary_exporter::properties_definition();
108 foreach ($properties as $property => $config) {
109 if (!empty($config['optional'])) {
110 unset($feedback->{$property});
114 $exporter = new feedback_summary_exporter($feedback, array('context' => $context));
115 $returnedfeedbacks[] = $exporter->export($output);
119 $result = array(
120 'feedbacks' => $returnedfeedbacks,
121 'warnings' => $warnings
123 return $result;
127 * Describes the get_feedbacks_by_courses return value.
129 * @return external_single_structure
130 * @since Moodle 3.3
132 public static function get_feedbacks_by_courses_returns() {
133 return new external_single_structure(
134 array(
135 'feedbacks' => new external_multiple_structure(
136 feedback_summary_exporter::get_read_structure()
138 'warnings' => new external_warnings(),
144 * Utility function for validating a feedback.
146 * @param int $feedbackid feedback instance id
147 * @return array array containing the feedback persistent, course, context and course module objects
148 * @since Moodle 3.3
150 protected static function validate_feedback($feedbackid) {
151 global $DB, $USER;
153 // Request and permission validation.
154 $feedback = $DB->get_record('feedback', array('id' => $feedbackid), '*', MUST_EXIST);
155 list($course, $cm) = get_course_and_cm_from_instance($feedback, 'feedback');
157 $context = context_module::instance($cm->id);
158 self::validate_context($context);
160 return array($feedback, $course, $cm, $context);
164 * Utility function for validating access to feedback.
166 * @param stdClass $feedback feedback object
167 * @param stdClass $course course object
168 * @param stdClass $cm course module
169 * @param stdClass $context context object
170 * @throws moodle_exception
171 * @return feedback_completion feedback completion instance
172 * @since Moodle 3.3
174 protected static function validate_feedback_access($feedback, $course, $cm, $context, $checksubmit = false) {
175 $feedbackcompletion = new mod_feedback_completion($feedback, $cm, $course->id);
177 if (!$feedbackcompletion->can_complete()) {
178 throw new required_capability_exception($context, 'mod/feedback:complete', 'nopermission', '');
181 if (!$feedbackcompletion->is_open()) {
182 throw new moodle_exception('feedback_is_not_open', 'feedback');
185 if ($feedbackcompletion->is_empty()) {
186 throw new moodle_exception('no_items_available_yet', 'feedback');
189 if ($checksubmit && !$feedbackcompletion->can_submit()) {
190 throw new moodle_exception('this_feedback_is_already_submitted', 'feedback');
192 return $feedbackcompletion;
196 * Describes the parameters for get_feedback_access_information.
198 * @return external_external_function_parameters
199 * @since Moodle 3.3
201 public static function get_feedback_access_information_parameters() {
202 return new external_function_parameters (
203 array(
204 'feedbackid' => new external_value(PARAM_INT, 'Feedback instance id.')
210 * Return access information for a given feedback.
212 * @param int $feedbackid feedback instance id
213 * @return array of warnings and the access information
214 * @since Moodle 3.3
215 * @throws moodle_exception
217 public static function get_feedback_access_information($feedbackid) {
218 global $PAGE;
220 $params = array(
221 'feedbackid' => $feedbackid
223 $params = self::validate_parameters(self::get_feedback_access_information_parameters(), $params);
225 list($feedback, $course, $cm, $context) = self::validate_feedback($params['feedbackid']);
226 $feedbackcompletion = new mod_feedback_completion($feedback, $cm, $course->id);
228 $result = array();
229 // Capabilities first.
230 $result['canviewanalysis'] = $feedbackcompletion->can_view_analysis();
231 $result['cancomplete'] = $feedbackcompletion->can_complete();
232 $result['cansubmit'] = $feedbackcompletion->can_submit();
233 $result['candeletesubmissions'] = has_capability('mod/feedback:deletesubmissions', $context);
234 $result['canviewreports'] = has_capability('mod/feedback:viewreports', $context);
235 $result['canedititems'] = has_capability('mod/feedback:edititems', $context);
237 // Status information.
238 $result['isempty'] = $feedbackcompletion->is_empty();
239 $result['isopen'] = $feedbackcompletion->is_open();
240 $anycourse = ($course->id == SITEID);
241 $result['isalreadysubmitted'] = $feedbackcompletion->is_already_submitted($anycourse);
242 $result['isanonymous'] = $feedbackcompletion->is_anonymous();
244 $result['warnings'] = [];
245 return $result;
249 * Describes the get_feedback_access_information return value.
251 * @return external_single_structure
252 * @since Moodle 3.3
254 public static function get_feedback_access_information_returns() {
255 return new external_single_structure(
256 array(
257 'canviewanalysis' => new external_value(PARAM_BOOL, 'Whether the user can view the analysis or not.'),
258 'cancomplete' => new external_value(PARAM_BOOL, 'Whether the user can complete the feedback or not.'),
259 'cansubmit' => new external_value(PARAM_BOOL, 'Whether the user can submit the feedback or not.'),
260 'candeletesubmissions' => new external_value(PARAM_BOOL, 'Whether the user can delete submissions or not.'),
261 'canviewreports' => new external_value(PARAM_BOOL, 'Whether the user can view the feedback reports or not.'),
262 'canedititems' => new external_value(PARAM_BOOL, 'Whether the user can edit feedback items or not.'),
263 'isempty' => new external_value(PARAM_BOOL, 'Whether the feedback has questions or not.'),
264 'isopen' => new external_value(PARAM_BOOL, 'Whether the feedback has active access time restrictions or not.'),
265 'isalreadysubmitted' => new external_value(PARAM_BOOL, 'Whether the feedback is already submitted or not.'),
266 'isanonymous' => new external_value(PARAM_BOOL, 'Whether the feedback is anonymous or not.'),
267 'warnings' => new external_warnings(),
273 * Describes the parameters for view_feedback.
275 * @return external_function_parameters
276 * @since Moodle 3.3
278 public static function view_feedback_parameters() {
279 return new external_function_parameters (
280 array(
281 'feedbackid' => new external_value(PARAM_INT, 'Feedback instance id'),
282 'moduleviewed' => new external_value(PARAM_BOOL, 'If we need to mark the module as viewed for completion',
283 VALUE_DEFAULT, false),
289 * Trigger the course module viewed event and update the module completion status.
291 * @param int $feedbackid feedback instance id
292 * @param bool $moduleviewed If we need to mark the module as viewed for completion
293 * @return array of warnings and status result
294 * @since Moodle 3.3
295 * @throws moodle_exception
297 public static function view_feedback($feedbackid, $moduleviewed = false) {
299 $params = array('feedbackid' => $feedbackid, 'moduleviewed' => $moduleviewed);
300 $params = self::validate_parameters(self::view_feedback_parameters(), $params);
301 $warnings = array();
303 list($feedback, $course, $cm, $context) = self::validate_feedback($params['feedbackid']);
304 $feedbackcompletion = new mod_feedback_completion($feedback, $cm, $course->id);
306 // Trigger module viewed event.
307 $feedbackcompletion->trigger_module_viewed($course);
308 if ($params['moduleviewed']) {
309 if (!$feedbackcompletion->is_open()) {
310 throw new moodle_exception('feedback_is_not_open', 'feedback');
312 // Mark activity viewed for completion-tracking.
313 $feedbackcompletion->set_module_viewed($course);
316 $result = array(
317 'status' => true,
318 'warnings' => $warnings,
320 return $result;
324 * Describes the view_feedback return value.
326 * @return external_single_structure
327 * @since Moodle 3.3
329 public static function view_feedback_returns() {
330 return new external_single_structure(
331 array(
332 'status' => new external_value(PARAM_BOOL, 'status: true if success'),
333 'warnings' => new external_warnings(),
339 * Describes the parameters for get_current_completed_tmp.
341 * @return external_function_parameters
342 * @since Moodle 3.3
344 public static function get_current_completed_tmp_parameters() {
345 return new external_function_parameters (
346 array(
347 'feedbackid' => new external_value(PARAM_INT, 'Feedback instance id'),
353 * Returns the temporary completion record for the current user.
355 * @param int $feedbackid feedback instance id
356 * @return array of warnings and status result
357 * @since Moodle 3.3
358 * @throws moodle_exception
360 public static function get_current_completed_tmp($feedbackid) {
361 global $PAGE;
363 $params = array('feedbackid' => $feedbackid);
364 $params = self::validate_parameters(self::get_current_completed_tmp_parameters(), $params);
365 $warnings = array();
367 list($feedback, $course, $cm, $context) = self::validate_feedback($params['feedbackid']);
368 $feedbackcompletion = new mod_feedback_completion($feedback, $cm, $course->id);
370 if ($completed = $feedbackcompletion->get_current_completed_tmp()) {
371 $exporter = new feedback_completedtmp_exporter($completed);
372 return array(
373 'feedback' => $exporter->export($PAGE->get_renderer('core')),
374 'warnings' => $warnings,
377 throw new moodle_exception('not_started', 'feedback');
381 * Describes the get_current_completed_tmp return value.
383 * @return external_single_structure
384 * @since Moodle 3.3
386 public static function get_current_completed_tmp_returns() {
387 return new external_single_structure(
388 array(
389 'feedback' => feedback_completedtmp_exporter::get_read_structure(),
390 'warnings' => new external_warnings(),
396 * Describes the parameters for get_items.
398 * @return external_function_parameters
399 * @since Moodle 3.3
401 public static function get_items_parameters() {
402 return new external_function_parameters (
403 array(
404 'feedbackid' => new external_value(PARAM_INT, 'Feedback instance id'),
410 * Returns the items (questions) in the given feedback.
412 * @param int $feedbackid feedback instance id
413 * @return array of warnings and feedbacks
414 * @since Moodle 3.3
416 public static function get_items($feedbackid) {
417 global $PAGE;
419 $params = array('feedbackid' => $feedbackid);
420 $params = self::validate_parameters(self::get_items_parameters(), $params);
421 $warnings = array();
423 list($feedback, $course, $cm, $context) = self::validate_feedback($params['feedbackid']);
424 self::validate_feedback_access($feedback, $course, $cm, $context);
426 $feedbackstructure = new mod_feedback_structure($feedback, $cm, $course->id);
427 $returneditems = array();
428 if ($items = $feedbackstructure->get_items()) {
429 foreach ($items as $item) {
430 $itemnumber = empty($item->itemnr) ? null : $item->itemnr;
431 unset($item->itemnr); // Added by the function, not part of the record.
432 $exporter = new feedback_item_exporter($item, array('context' => $context, 'itemnumber' => $itemnumber));
433 $returneditems[] = $exporter->export($PAGE->get_renderer('core'));
437 $result = array(
438 'items' => $returneditems,
439 'warnings' => $warnings
441 return $result;
445 * Describes the get_items return value.
447 * @return external_single_structure
448 * @since Moodle 3.3
450 public static function get_items_returns() {
451 return new external_single_structure(
452 array(
453 'items' => new external_multiple_structure(
454 feedback_item_exporter::get_read_structure()
456 'warnings' => new external_warnings(),
462 * Describes the parameters for launch_feedback.
464 * @return external_function_parameters
465 * @since Moodle 3.3
467 public static function launch_feedback_parameters() {
468 return new external_function_parameters (
469 array(
470 'feedbackid' => new external_value(PARAM_INT, 'Feedback instance id'),
476 * Starts or continues a feedback submission
478 * @param array $feedbackid feedback instance id
479 * @return array of warnings and launch information
480 * @since Moodle 3.3
482 public static function launch_feedback($feedbackid) {
483 global $PAGE;
485 $params = array('feedbackid' => $feedbackid);
486 $params = self::validate_parameters(self::launch_feedback_parameters(), $params);
487 $warnings = array();
489 list($feedback, $course, $cm, $context) = self::validate_feedback($params['feedbackid']);
490 // Check we can do a new submission (or continue an existing).
491 $feedbackcompletion = self::validate_feedback_access($feedback, $course, $cm, $context, true);
493 $gopage = $feedbackcompletion->get_resume_page();
494 if ($gopage === null) {
495 $gopage = -1; // Last page.
498 $result = array(
499 'gopage' => $gopage,
500 'warnings' => $warnings
502 return $result;
506 * Describes the launch_feedback return value.
508 * @return external_single_structure
509 * @since Moodle 3.3
511 public static function launch_feedback_returns() {
512 return new external_single_structure(
513 array(
514 'gopage' => new external_value(PARAM_INT, 'The next page to go (-1 if we were already in the last page). 0 for first page.'),
515 'warnings' => new external_warnings(),
521 * Describes the parameters for get_page_items.
523 * @return external_function_parameters
524 * @since Moodle 3.3
526 public static function get_page_items_parameters() {
527 return new external_function_parameters (
528 array(
529 'feedbackid' => new external_value(PARAM_INT, 'Feedback instance id'),
530 'page' => new external_value(PARAM_INT, 'The page to get starting by 0'),
536 * Get a single feedback page items.
538 * @param int $feedbackid feedback instance id
539 * @param int $page the page to get starting by 0
540 * @return array of warnings and launch information
541 * @since Moodle 3.3
543 public static function get_page_items($feedbackid, $page) {
544 global $PAGE;
546 $params = array('feedbackid' => $feedbackid, 'page' => $page);
547 $params = self::validate_parameters(self::get_page_items_parameters(), $params);
548 $warnings = array();
550 list($feedback, $course, $cm, $context) = self::validate_feedback($params['feedbackid']);
552 $feedbackcompletion = new mod_feedback_completion($feedback, $cm, $course->id);
554 $page = $params['page'];
555 $pages = $feedbackcompletion->get_pages();
556 $pageitems = $pages[$page];
557 $hasnextpage = $page < count($pages) - 1; // Until we complete this page we can not trust get_next_page().
558 $hasprevpage = $page && ($feedbackcompletion->get_previous_page($page, false) !== null);
560 $returneditems = array();
561 foreach ($pageitems as $item) {
562 $itemnumber = empty($item->itemnr) ? null : $item->itemnr;
563 unset($item->itemnr); // Added by the function, not part of the record.
564 $exporter = new feedback_item_exporter($item, array('context' => $context, 'itemnumber' => $itemnumber));
565 $returneditems[] = $exporter->export($PAGE->get_renderer('core'));
568 $result = array(
569 'items' => $returneditems,
570 'hasprevpage' => $hasprevpage,
571 'hasnextpage' => $hasnextpage,
572 'warnings' => $warnings
574 return $result;
578 * Describes the get_page_items return value.
580 * @return external_single_structure
581 * @since Moodle 3.3
583 public static function get_page_items_returns() {
584 return new external_single_structure(
585 array(
586 'items' => new external_multiple_structure(
587 feedback_item_exporter::get_read_structure()
589 'hasprevpage' => new external_value(PARAM_BOOL, 'Whether is a previous page.'),
590 'hasnextpage' => new external_value(PARAM_BOOL, 'Whether there are more pages.'),
591 'warnings' => new external_warnings(),
597 * Describes the parameters for process_page.
599 * @return external_function_parameters
600 * @since Moodle 3.3
602 public static function process_page_parameters() {
603 return new external_function_parameters (
604 array(
605 'feedbackid' => new external_value(PARAM_INT, 'Feedback instance id.'),
606 'page' => new external_value(PARAM_INT, 'The page being processed.'),
607 'responses' => new external_multiple_structure(
608 new external_single_structure(
609 array(
610 'name' => new external_value(PARAM_NOTAGS, 'The response name (usually type[index]_id).'),
611 'value' => new external_value(PARAM_RAW, 'The response value.'),
613 ), 'The data to be processed.'
615 'goprevious' => new external_value(PARAM_BOOL, 'Whether we want to jump to previous page.', VALUE_DEFAULT, false),
621 * Process a jump between pages.
623 * @param array $feedbackid feedback instance id
624 * @param array $page the page being processed
625 * @param array $responses the responses to be processed
626 * @param bool $goprevious whether we want to jump to previous page
627 * @return array of warnings and launch information
628 * @since Moodle 3.3
630 public static function process_page($feedbackid, $page, $responses, $goprevious = false) {
631 global $USER, $SESSION;
633 $params = array('feedbackid' => $feedbackid, 'page' => $page, 'responses' => $responses, 'goprevious' => $goprevious);
634 $params = self::validate_parameters(self::process_page_parameters(), $params);
635 $warnings = array();
636 $siteaftersubmit = $completionpagecontents = '';
638 list($feedback, $course, $cm, $context) = self::validate_feedback($params['feedbackid']);
639 // Check we can do a new submission (or continue an existing).
640 $feedbackcompletion = self::validate_feedback_access($feedback, $course, $cm, $context, true);
642 // Create the $_POST object required by the feedback question engine.
643 $_POST = array();
644 foreach ($responses as $response) {
645 $_POST[$response['name']] = $response['value'];
647 // Force fields.
648 $_POST['id'] = $cm->id;
649 $_POST['courseid'] = $course->id;
650 $_POST['gopage'] = $params['page'];
651 $_POST['_qf__mod_feedback_complete_form'] = 1;
652 if (!$params['goprevious']) {
653 if ($feedbackcompletion->get_next_page($params['page'], false) === null) {
654 $_POST['savevalues'] = 1; // If there is no next page, it means we are finishing the feedback.
655 } else {
656 $_POST['gonextpage'] = 1; // If we are not going to previous page or finishing we are going forward.
660 // Ignore sesskey (deep in some APIs), the request is already validated.
661 $USER->ignoresesskey = true;
662 feedback_init_feedback_session();
663 $SESSION->feedback->is_started = true;
665 $feedbackcompletion->process_page($params['page'], $params['goprevious']);
666 $completed = $feedbackcompletion->just_completed();
667 if ($completed) {
668 $jumpto = 0;
669 if ($feedback->page_after_submit) {
670 $completionpagecontents = $feedbackcompletion->page_after_submit();
673 if ($feedback->site_after_submit) {
674 $siteaftersubmit = feedback_encode_target_url($feedback->site_after_submit);
676 } else {
677 $jumpto = $feedbackcompletion->get_jumpto();
680 $result = array(
681 'jumpto' => $jumpto,
682 'completed' => $completed,
683 'completionpagecontents' => $completionpagecontents,
684 'siteaftersubmit' => $siteaftersubmit,
685 'warnings' => $warnings
687 return $result;
691 * Describes the process_page return value.
693 * @return external_single_structure
694 * @since Moodle 3.3
696 public static function process_page_returns() {
697 return new external_single_structure(
698 array(
699 'jumpto' => new external_value(PARAM_INT, 'The page to jump to.'),
700 'completed' => new external_value(PARAM_BOOL, 'If the user completed the feedback.'),
701 'completionpagecontents' => new external_value(PARAM_RAW, 'The completion page contents.'),
702 'siteaftersubmit' => new external_value(PARAM_RAW, 'The link (could be relative) to show after submit.'),
703 'warnings' => new external_warnings(),
709 * Describes the parameters for get_analysis.
711 * @return external_function_parameters
712 * @since Moodle 3.3
714 public static function get_analysis_parameters() {
715 return new external_function_parameters (
716 array(
717 'feedbackid' => new external_value(PARAM_INT, 'Feedback instance id'),
718 'groupid' => new external_value(PARAM_INT, 'Group id, 0 means that the function will determine the user group',
719 VALUE_DEFAULT, 0),
725 * Retrieves the feedback analysis.
727 * @param array $feedbackid feedback instance id
728 * @return array of warnings and launch information
729 * @since Moodle 3.3
731 public static function get_analysis($feedbackid, $groupid = 0) {
732 global $PAGE;
734 $params = array('feedbackid' => $feedbackid, 'groupid' => $groupid);
735 $params = self::validate_parameters(self::get_analysis_parameters(), $params);
736 $warnings = $itemsdata = array();
738 list($feedback, $course, $cm, $context) = self::validate_feedback($params['feedbackid']);
740 // Check permissions.
741 $feedbackstructure = new mod_feedback_structure($feedback, $cm);
742 if (!$feedbackstructure->can_view_analysis()) {
743 throw new required_capability_exception($context, 'mod/feedback:viewanalysepage', 'nopermission', '');
746 if (!empty($params['groupid'])) {
747 $groupid = $params['groupid'];
748 // Determine is the group is visible to user.
749 if (!groups_group_visible($groupid, $course, $cm)) {
750 throw new moodle_exception('notingroup');
752 } else {
753 // Check to see if groups are being used here.
754 if ($groupmode = groups_get_activity_groupmode($cm)) {
755 $groupid = groups_get_activity_group($cm);
756 // Determine is the group is visible to user (this is particullary for the group 0 -> all groups).
757 if (!groups_group_visible($groupid, $course, $cm)) {
758 throw new moodle_exception('notingroup');
760 } else {
761 $groupid = 0;
765 // Summary data.
766 $summary = new mod_feedback\output\summary($feedbackstructure, $groupid);
767 $summarydata = $summary->export_for_template($PAGE->get_renderer('core'));
769 $checkanonymously = true;
770 if ($groupid > 0 AND $feedback->anonymous == FEEDBACK_ANONYMOUS_YES) {
771 $completedcount = $feedbackstructure->count_completed_responses($groupid);
772 if ($completedcount < FEEDBACK_MIN_ANONYMOUS_COUNT_IN_GROUP) {
773 $checkanonymously = false;
777 if ($checkanonymously) {
778 // Get the items of the feedback.
779 $items = $feedbackstructure->get_items(true);
780 foreach ($items as $item) {
781 $itemobj = feedback_get_item_class($item->typ);
782 $itemnumber = empty($item->itemnr) ? null : $item->itemnr;
783 unset($item->itemnr); // Added by the function, not part of the record.
784 $exporter = new feedback_item_exporter($item, array('context' => $context, 'itemnumber' => $itemnumber));
786 $itemsdata[] = array(
787 'item' => $exporter->export($PAGE->get_renderer('core')),
788 'data' => $itemobj->get_analysed_for_external($item, $groupid),
791 } else {
792 $warnings[] = array(
793 'item' => 'feedback',
794 'itemid' => $feedback->id,
795 'warningcode' => 'insufficientresponsesforthisgroup',
796 'message' => s(get_string('insufficient_responses_for_this_group', 'feedback'))
800 $result = array(
801 'completedcount' => $summarydata->completedcount,
802 'itemscount' => $summarydata->itemscount,
803 'itemsdata' => $itemsdata,
804 'warnings' => $warnings
806 return $result;
810 * Describes the get_analysis return value.
812 * @return external_single_structure
813 * @since Moodle 3.3
815 public static function get_analysis_returns() {
816 return new external_single_structure(
817 array(
818 'completedcount' => new external_value(PARAM_INT, 'Number of completed submissions.'),
819 'itemscount' => new external_value(PARAM_INT, 'Number of items (questions).'),
820 'itemsdata' => new external_multiple_structure(
821 new external_single_structure(
822 array(
823 'item' => feedback_item_exporter::get_read_structure(),
824 'data' => new external_multiple_structure(
825 new external_value(PARAM_RAW, 'The analysis data (can be json encoded)')
830 'warnings' => new external_warnings(),