See Release Notes
Long Term Support Release
Differences Between: [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 * This is the external method for getting the information needed to present an attempts report. 19 * 20 * @package mod_h5pactivity 21 * @since Moodle 3.9 22 * @copyright 2020 Ferran Recio <ferran@moodle.com> 23 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later 24 */ 25 26 namespace mod_h5pactivity\external; 27 28 defined('MOODLE_INTERNAL') || die(); 29 30 global $CFG; 31 require_once($CFG->libdir . '/externallib.php'); 32 33 use mod_h5pactivity\local\manager; 34 use mod_h5pactivity\local\attempt; 35 use mod_h5pactivity\local\report\attempts as report_attempts; 36 use external_api; 37 use external_function_parameters; 38 use external_value; 39 use external_multiple_structure; 40 use external_single_structure; 41 use external_warnings; 42 use moodle_exception; 43 use context_module; 44 use stdClass; 45 46 /** 47 * This is the external method for getting the information needed to present an attempts report. 48 * 49 * @copyright 2020 Ferran Recio <ferran@moodle.com> 50 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later 51 */ 52 class get_attempts extends external_api { 53 54 /** 55 * Webservice parameters. 56 * 57 * @return external_function_parameters 58 */ 59 public static function execute_parameters(): external_function_parameters { 60 return new external_function_parameters( 61 [ 62 'h5pactivityid' => new external_value(PARAM_INT, 'h5p activity instance id'), 63 'userids' => new external_multiple_structure( 64 new external_value(PARAM_INT, 'The user ids to get attempts (null means only current user)', VALUE_DEFAULT), 65 'User ids', VALUE_DEFAULT, [] 66 ), 67 ] 68 ); 69 } 70 71 /** 72 * Return user attempts information in a h5p activity. 73 * 74 * @throws moodle_exception if the user cannot see the report 75 * @param int $h5pactivityid The h5p activity id 76 * @param int[]|null $userids The user ids (if no provided $USER will be used) 77 * @return stdClass report data 78 */ 79 public static function execute(int $h5pactivityid, ?array $userids = []): stdClass { 80 global $USER; 81 82 $params = external_api::validate_parameters(self::execute_parameters(), [ 83 'h5pactivityid' => $h5pactivityid, 84 'userids' => $userids, 85 ]); 86 $h5pactivityid = $params['h5pactivityid']; 87 $userids = $params['userids']; 88 89 if (empty($userids)) { 90 $userids = [$USER->id]; 91 } 92 93 $warnings = []; 94 95 // Request and permission validation. 96 list ($course, $cm) = get_course_and_cm_from_instance($h5pactivityid, 'h5pactivity'); 97 98 $context = context_module::instance($cm->id); 99 self::validate_context($context); 100 101 $manager = manager::create_from_coursemodule($cm); 102 103 $instance = $manager->get_instance(); 104 105 $usersattempts = []; 106 foreach ($userids as $userid) { 107 $report = $manager->get_report($userid); 108 if ($report && $report instanceof report_attempts) { 109 $usersattempts[] = self::export_user_attempts($report, $userid); 110 } else { 111 $warnings[] = [ 112 'item' => 'user', 113 'itemid' => $userid, 114 'warningcode' => '1', 115 'message' => "Cannot access user attempts", 116 ]; 117 } 118 } 119 120 $result = (object)[ 121 'activityid' => $instance->id, 122 'usersattempts' => $usersattempts, 123 'warnings' => $warnings, 124 ]; 125 126 return $result; 127 } 128 129 /** 130 * Export attempts data for a specific user. 131 * 132 * @param report_attempts $report the report attempts object 133 * @param int $userid the user id 134 * @return stdClass 135 */ 136 public static function export_user_attempts(report_attempts $report, int $userid): stdClass { 137 138 $scored = $report->get_scored(); 139 $attempts = $report->get_attempts(); 140 141 $result = (object)[ 142 'userid' => $userid, 143 'attempts' => [], 144 ]; 145 146 foreach ($attempts as $attempt) { 147 $result->attempts[] = self::export_attempt($attempt); 148 } 149 150 if (!empty($scored)) { 151 $result->scored = (object)[ 152 'title' => $scored->title, 153 'grademethod' => $scored->grademethod, 154 'attempts' => [self::export_attempt($scored->attempt)], 155 ]; 156 } 157 158 return $result; 159 } 160 161 /** 162 * Return a data object from an attempt. 163 * 164 * @param attempt $attempt the attempt object 165 * @return stdClass a WS compatible version of the attempt 166 */ 167 private static function export_attempt(attempt $attempt): stdClass { 168 $result = (object)[ 169 'id' => $attempt->get_id(), 170 'h5pactivityid' => $attempt->get_h5pactivityid(), 171 'userid' => $attempt->get_userid(), 172 'timecreated' => $attempt->get_timecreated(), 173 'timemodified' => $attempt->get_timemodified(), 174 'attempt' => $attempt->get_attempt(), 175 'rawscore' => $attempt->get_rawscore(), 176 'maxscore' => $attempt->get_maxscore(), 177 'duration' => $attempt->get_duration(), 178 'scaled' => $attempt->get_scaled(), 179 ]; 180 if ($attempt->get_completion() !== null) { 181 $result->completion = $attempt->get_completion(); 182 } 183 if ($attempt->get_success() !== null) { 184 $result->success = $attempt->get_success(); 185 } 186 return $result; 187 } 188 189 /** 190 * Describes the get_h5pactivity_access_information return value. 191 * 192 * @return external_single_structure 193 */ 194 public static function execute_returns(): external_single_structure { 195 return new external_single_structure([ 196 'activityid' => new external_value(PARAM_INT, 'Activity course module ID'), 197 'usersattempts' => new external_multiple_structure( 198 self::get_user_attempts_returns(), 'The complete users attempts list' 199 ), 200 'warnings' => new external_warnings(), 201 ], 'Activity attempts data'); 202 } 203 204 /** 205 * Describes the get_h5pactivity_access_information return value. 206 * 207 * @return external_single_structure 208 */ 209 public static function get_user_attempts_returns(): external_single_structure { 210 $structure = [ 211 'userid' => new external_value(PARAM_INT, 'The user id'), 212 'attempts' => new external_multiple_structure(self::get_attempt_returns(), 'The complete attempts list'), 213 'scored' => new external_single_structure([ 214 'title' => new external_value(PARAM_NOTAGS, 'Scored attempts title'), 215 'grademethod' => new external_value(PARAM_NOTAGS, 'Scored attempts title'), 216 'attempts' => new external_multiple_structure(self::get_attempt_returns(), 'List of the grading attempts'), 217 ], 'Attempts used to grade the activity', VALUE_OPTIONAL), 218 ]; 219 return new external_single_structure($structure); 220 } 221 222 /** 223 * Return the external structure of an attempt. 224 * 225 * @return external_single_structure 226 */ 227 private static function get_attempt_returns(): external_single_structure { 228 229 $result = new external_single_structure([ 230 'id' => new external_value(PARAM_INT, 'ID of the context'), 231 'h5pactivityid' => new external_value(PARAM_INT, 'ID of the H5P activity'), 232 'userid' => new external_value(PARAM_INT, 'ID of the user'), 233 'timecreated' => new external_value(PARAM_INT, 'Attempt creation'), 234 'timemodified' => new external_value(PARAM_INT, 'Attempt modified'), 235 'attempt' => new external_value(PARAM_INT, 'Attempt number'), 236 'rawscore' => new external_value(PARAM_INT, 'Attempt score value'), 237 'maxscore' => new external_value(PARAM_INT, 'Attempt max score'), 238 'duration' => new external_value(PARAM_INT, 'Attempt duration in seconds'), 239 'completion' => new external_value(PARAM_INT, 'Attempt completion', VALUE_OPTIONAL), 240 'success' => new external_value(PARAM_INT, 'Attempt success', VALUE_OPTIONAL), 241 'scaled' => new external_value(PARAM_FLOAT, 'Attempt scaled'), 242 ]); 243 return $result; 244 } 245 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body