Differences Between: [Versions 310 and 402] [Versions 311 and 402] [Versions 39 and 402] [Versions 400 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 /** 18 * Class communication 19 * 20 * @package core 21 * @copyright 2017 Marina Glancy 22 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later 23 */ 24 25 namespace core\hub; 26 defined('MOODLE_INTERNAL') || die(); 27 28 use moodle_exception; 29 use curl; 30 use stdClass; 31 use coding_exception; 32 use moodle_url; 33 34 /** 35 * Provides methods to communicate with the hub (sites directory) web services. 36 * 37 * @package core 38 * @copyright 2017 Marina Glancy 39 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later 40 */ 41 class api { 42 43 /** @var File type: Course screenshot */ 44 const HUB_SCREENSHOT_FILE_TYPE = 'screenshot'; 45 46 /** @var File type: Hub screenshot */ 47 const HUB_HUBSCREENSHOT_FILE_TYPE = 'hubscreenshot'; 48 49 /** @var File type: Backup */ 50 const HUB_BACKUP_FILE_TYPE = 'backup'; 51 52 /** 53 * Calls a remote function exposed via web services on the hub. 54 * 55 * @param string $function name of WS function 56 * @param array $data parameters of WS function 57 * @param bool $allowpublic allow request without registration on the hub 58 * @return mixed depends on the function 59 * @throws moodle_exception 60 */ 61 protected static function call($function, array $data = [], $allowpublic = false) { 62 63 $token = registration::get_token() ?: 'publichub'; 64 if (!$allowpublic && $token === 'publichub') { 65 // This will throw an exception. 66 registration::require_registration(); 67 } 68 69 return self::call_rest($token, $function, $data); 70 } 71 72 /** 73 * Performs a REST request to the hub site (using the GET method). 74 * 75 * @param string $token 76 * @param string $function 77 * @param array $data 78 * @return mixed 79 * @throws moodle_exception 80 */ 81 protected static function call_rest($token, $function, array $data) { 82 $params = [ 83 'wstoken' => $token, 84 'wsfunction' => $function, 85 'moodlewsrestformat' => 'json' 86 ] + $data; 87 88 $curl = new curl(); 89 $serverurl = HUB_MOODLEORGHUBURL . "/local/hub/webservice/webservices.php"; 90 $query = http_build_query($params, '', '&'); 91 $curloutput = @json_decode($curl->post($serverurl, $query), true); 92 $info = $curl->get_info(); 93 if ($curl->get_errno()) { 94 // Connection error. 95 throw new moodle_exception('errorconnect', 'hub', '', $curl->error); 96 } else if (isset($curloutput['exception'])) { 97 // Exception occurred on the remote side. 98 self::process_curl_exception($token, $curloutput); 99 } else if ($info['http_code'] != 200) { 100 throw new moodle_exception('errorconnect', 'hub', '', $info['http_code']); 101 } else { 102 return $curloutput; 103 } 104 } 105 106 /** 107 * Analyses exception received from the hub server. 108 * 109 * @param string $token token used for CURL request 110 * @param array $curloutput output from CURL request 111 * @throws moodle_exception 112 */ 113 protected static function process_curl_exception($token, $curloutput) { 114 if (!isset($curloutput['exception'])) { 115 return; 116 } 117 if ($token === registration::get_token()) { 118 // Check if registration token was rejected or there are other problems with registration. 119 if (($curloutput['exception'] === 'moodle_exception' && $curloutput['errorcode'] === 'invalidtoken') 120 || $curloutput['exception'] === 'registration_exception') { 121 // Force admin to repeat site registration process. 122 registration::reset_token(); 123 throw new moodle_exception('errorwstokenreset', 'hub', '', $curloutput['message']); 124 } 125 } 126 throw new moodle_exception('errorws', 'hub', '', $curloutput['message']); 127 } 128 129 /** 130 * Update site registration on the hub. 131 * 132 * @param array $siteinfo 133 * @throws moodle_exception 134 */ 135 public static function update_registration(array $siteinfo) { 136 $params = array('siteinfo' => $siteinfo, 'validateurl' => 1); 137 self::call('hub_update_site_info', $params); 138 } 139 140 /** 141 * Returns information about the hub. 142 * 143 * Example of the return array: 144 * { 145 * "courses": 384, 146 * "description": "Official Moodle sites directory.", 147 * "downloadablecourses": 0, 148 * "enrollablecourses": 0, 149 * "hublogo": 1, 150 * "language": "en", 151 * "name": "moodle", 152 * "sites": 274175, 153 * "url": "https://stats.moodle.org", 154 * "imgurl": "https://stats.moodle.org/local/hub/webservice/download.php?filetype=hubscreenshot" 155 * } 156 * 157 * @return array 158 * @throws moodle_exception 159 */ 160 public static function get_hub_info() { 161 $info = self::call('hub_get_info', [], true); 162 $info['imgurl'] = new moodle_url(HUB_MOODLEORGHUBURL . '/local/hub/webservice/download.php', 163 ['filetype' => self::HUB_HUBSCREENSHOT_FILE_TYPE]); 164 return $info; 165 } 166 167 /** 168 * Calls WS function hub_get_courses 169 * 170 * @deprecated since Moodle 3.8. Moodle.net has been sunsetted making this function useless. 171 * 172 * Parameter $options may have any of these fields: 173 * [ 174 * 'ids' => new external_multiple_structure(new external_value(PARAM_INTEGER, 'id of a course in the hub course 175 * directory'), 'ids of course', VALUE_OPTIONAL), 176 * 'sitecourseids' => new external_multiple_structure(new external_value(PARAM_INTEGER, 'id of a course in the 177 * site'), 'ids of course in the site', VALUE_OPTIONAL), 178 * 'coverage' => new external_value(PARAM_TEXT, 'coverage', VALUE_OPTIONAL), 179 * 'licenceshortname' => new external_value(PARAM_ALPHANUMEXT, 'licence short name', VALUE_OPTIONAL), 180 * 'subject' => new external_value(PARAM_ALPHANUM, 'subject', VALUE_OPTIONAL), 181 * 'audience' => new external_value(PARAM_ALPHA, 'audience', VALUE_OPTIONAL), 182 * 'educationallevel' => new external_value(PARAM_ALPHA, 'educational level', VALUE_OPTIONAL), 183 * 'language' => new external_value(PARAM_ALPHANUMEXT, 'language', VALUE_OPTIONAL), 184 * 'orderby' => new external_value(PARAM_ALPHA, 'orderby method: newest, eldest, publisher, fullname, 185 * ratingaverage', VALUE_OPTIONAL), 186 * 'givememore' => new external_value(PARAM_INT, 'next range of result - range size being set by the hub 187 * server ', VALUE_OPTIONAL), 188 * 'allsitecourses' => new external_value(PARAM_INTEGER, 189 * 'if 1 return all not visible and visible courses whose siteid is the site 190 * matching token. Only courses of this site are returned. 191 * givememore parameter is ignored if this param = 1. 192 * In case of public token access, this param option is ignored', VALUE_DEFAULT, 0), 193 * ] 194 * 195 * Each course in the returned array of courses will have fields: 196 * [ 197 * 'id' => new external_value(PARAM_INTEGER, 'id'), 198 * 'fullname' => new external_value(PARAM_TEXT, 'course name'), 199 * 'shortname' => new external_value(PARAM_TEXT, 'course short name'), 200 * 'description' => new external_value(PARAM_TEXT, 'course description'), 201 * 'language' => new external_value(PARAM_ALPHANUMEXT, 'course language'), 202 * 'publishername' => new external_value(PARAM_TEXT, 'publisher name'), 203 * 'publisheremail' => new external_value(PARAM_EMAIL, 'publisher email', VALUE_OPTIONAL), 204 * 'privacy' => new external_value(PARAM_INT, 'privacy: published or not', VALUE_OPTIONAL), 205 * 'sitecourseid' => new external_value(PARAM_INT, 'course id on the site', VALUE_OPTIONAL), 206 * 'contributornames' => new external_value(PARAM_TEXT, 'contributor names', VALUE_OPTIONAL), 207 * 'coverage' => new external_value(PARAM_TEXT, 'coverage', VALUE_OPTIONAL), 208 * 'creatorname' => new external_value(PARAM_TEXT, 'creator name'), 209 * 'licenceshortname' => new external_value(PARAM_ALPHANUMEXT, 'licence short name'), 210 * 'subject' => new external_value(PARAM_ALPHANUM, 'subject'), 211 * 'audience' => new external_value(PARAM_ALPHA, 'audience'), 212 * 'educationallevel' => new external_value(PARAM_ALPHA, 'educational level'), 213 * 'creatornotes' => new external_value(PARAM_RAW, 'creator notes'), 214 * 'creatornotesformat' => new external_value(PARAM_INTEGER, 'notes format'), 215 * 'demourl' => new external_value(PARAM_URL, 'demo URL', VALUE_OPTIONAL), 216 * 'courseurl' => new external_value(PARAM_URL, 'course URL', VALUE_OPTIONAL), 217 * 'backupsize' => new external_value(PARAM_INT, 'course backup size in bytes', VALUE_OPTIONAL), 218 * 'enrollable' => new external_value(PARAM_BOOL, 'is the course enrollable'), 219 * 'screenshots' => new external_value(PARAM_INT, 'total number of screenshots'), 220 * 'timemodified' => new external_value(PARAM_INT, 'time of last modification - timestamp'), 221 * 'contents' => new external_multiple_structure(new external_single_structure( 222 * array( 223 * 'moduletype' => new external_value(PARAM_ALPHA, 'the type of module (activity/block)'), 224 * 'modulename' => new external_value(PARAM_TEXT, 'the name of the module (forum, resource etc)'), 225 * 'contentcount' => new external_value(PARAM_INT, 'how many time the module is used in the course'), 226 * )), 'contents', VALUE_OPTIONAL), 227 * 'rating' => new external_single_structure ( 228 * array( 229 * 'aggregate' => new external_value(PARAM_FLOAT, 'Rating average', VALUE_OPTIONAL), 230 * 'scaleid' => new external_value(PARAM_INT, 'Rating scale'), 231 * 'count' => new external_value(PARAM_INT, 'Rating count'), 232 * ), 'rating', VALUE_OPTIONAL), 233 * 'comments' => new external_multiple_structure(new external_single_structure ( 234 * array( 235 * 'comment' => new external_value(PARAM_TEXT, 'the comment'), 236 * 'commentator' => new external_value(PARAM_TEXT, 'the name of commentator'), 237 * 'date' => new external_value(PARAM_INT, 'date of the comment'), 238 * )), 'contents', VALUE_OPTIONAL), 239 * 'outcomes' => new external_multiple_structure(new external_single_structure( 240 * array( 241 * 'fullname' => new external_value(PARAM_TEXT, 'the outcome fullname') 242 * )), 'outcomes', VALUE_OPTIONAL) 243 * ] 244 * 245 * Additional fields for each course: 246 * 'screenshotbaseurl' (moodle_url) URL of the first screenshot, only set if $course['screenshots']>0 247 * 'commenturl' (moodle_url) URL for comments 248 * 249 * @param string $search search string 250 * @param bool $downloadable return downloadable courses 251 * @param bool $enrollable return enrollable courses 252 * @param array|\stdClass $options other options from the list of allowed options: 253 * 'ids', 'sitecourseids', 'coverage', 'licenceshortname', 'subject', 'audience', 254 * 'educationallevel', 'language', 'orderby', 'givememore', 'allsitecourses' 255 * @return array of two elements: [$courses, $coursetotal] 256 * @throws \coding_exception 257 * @throws moodle_exception 258 */ 259 public static function get_courses($search, $downloadable, $enrollable, $options) { 260 debugging("This function has been deprecated as part of the Moodle.net sunsetting process."); 261 return [[], 0]; 262 } 263 264 /** 265 * Unregister the site 266 * 267 * @throws moodle_exception 268 */ 269 public static function unregister_site() { 270 global $CFG; 271 self::call('hub_unregister_site', ['url' => [$CFG->wwwroot]]); 272 } 273 274 /** 275 * Unpublish courses 276 * 277 * @deprecated since Moodle 3.8. Moodle.net has been sunsetted making this function useless. 278 * 279 * @param int[]|int $courseids 280 * @throws moodle_exception 281 */ 282 public static function unregister_courses($courseids) { 283 debugging("This function has been deprecated as part of the Moodle.net sunsetting process."); 284 } 285 286 /** 287 * Publish one course 288 * 289 * @deprecated since Moodle 3.8. Moodle.net has been sunsetted making this function useless. 290 * 291 * Expected contents of $courseinfo: 292 * [ 293 * 'sitecourseid' => new external_value(PARAM_INT, 'the id of the course on the publishing site'), 294 * 'fullname' => new external_value(PARAM_TEXT, 'course name'), 295 * 'shortname' => new external_value(PARAM_TEXT, 'course short name'), 296 * 'description' => new external_value(PARAM_TEXT, 'course description'), 297 * 'language' => new external_value(PARAM_ALPHANUMEXT, 'course language'), 298 * 'publishername' => new external_value(PARAM_TEXT, 'publisher name'), 299 * 'publisheremail' => new external_value(PARAM_EMAIL, 'publisher email'), 300 * 'contributornames' => new external_value(PARAM_TEXT, 'contributor names'), 301 * 'coverage' => new external_value(PARAM_TEXT, 'coverage'), 302 * 'creatorname' => new external_value(PARAM_TEXT, 'creator name'), 303 * 'licenceshortname' => new external_value(PARAM_ALPHANUMEXT, 'licence short name'), 304 * 'subject' => new external_value(PARAM_ALPHANUM, 'subject'), 305 * 'audience' => new external_value(PARAM_ALPHA, 'audience'), 306 * 'educationallevel' => new external_value(PARAM_ALPHA, 'educational level'), 307 * 'creatornotes' => new external_value(PARAM_RAW, 'creator notes'), 308 * 'creatornotesformat' => new external_value(PARAM_INTEGER, 'notes format'), 309 * 'demourl' => new external_value(PARAM_URL, 'demo URL', VALUE_OPTIONAL), 310 * 'courseurl' => new external_value(PARAM_URL, 'course URL', VALUE_OPTIONAL), 311 * 'enrollable' => new external_value(PARAM_BOOL, 'is the course enrollable', VALUE_DEFAULT, 0), 312 * 'screenshots' => new external_value(PARAM_INT, 'the number of screenhots', VALUE_OPTIONAL), 313 * 'deletescreenshots' => new external_value(PARAM_INT, 'ask to delete all the existing screenshot files 314 * (it does not reset the screenshot number)', VALUE_DEFAULT, 0), 315 * 'contents' => new external_multiple_structure(new external_single_structure( 316 * array( 317 * 'moduletype' => new external_value(PARAM_ALPHA, 'the type of module (activity/block)'), 318 * 'modulename' => new external_value(PARAM_TEXT, 'the name of the module (forum, resource etc)'), 319 * 'contentcount' => new external_value(PARAM_INT, 'how many time the module is used in the course'), 320 * )), 'contents', VALUE_OPTIONAL), 321 * 'outcomes' => new external_multiple_structure(new external_single_structure( 322 * array( 323 * 'fullname' => new external_value(PARAM_TEXT, 'the outcome fullname') 324 * )), 'outcomes', VALUE_OPTIONAL) 325 * ] 326 * 327 * @param array|\stdClass $courseinfo 328 * @return int id of the published course on the hub 329 * @throws moodle_exception if the communication with the hub failed or the course could not be published 330 */ 331 public static function register_course($courseinfo) { 332 debugging("This function has been deprecated as part of the Moodle.net sunsetting process."); 333 throw new moodle_exception('errorcoursewronglypublished', 'hub'); 334 } 335 336 /** 337 * Uploads a screenshot for the published course 338 * 339 * @deprecated since Moodle 3.8. Moodle.net has been sunsetted making this function useless. 340 * 341 * @param int $hubcourseid id of the published course on the hub, it must be published from this site 342 * @param \stored_file $file 343 * @param int $screenshotnumber ordinal number of the screenshot 344 */ 345 public static function add_screenshot($hubcourseid, \stored_file $file, $screenshotnumber) { 346 debugging("This function has been deprecated as part of the Moodle.net sunsetting process."); 347 } 348 349 /** 350 * Downloads course backup 351 * 352 * @deprecated since Moodle 3.8. Moodle.net has been sunsetted making this function useless. 353 * 354 * @param int $hubcourseid id of the course on the hub 355 * @param string $path local path (in tempdir) to save the downloaded backup to. 356 */ 357 public static function download_course_backup($hubcourseid, $path) { 358 debugging("This function has been deprecated as part of the Moodle.net sunsetting process."); 359 } 360 361 /** 362 * Uploads a course backup 363 * 364 * @deprecated since Moodle 3.8. Moodle.net has been sunsetted making this function useless. 365 * 366 * @param int $hubcourseid id of the published course on the hub, it must be published from this site 367 * @param \stored_file $backupfile 368 */ 369 public static function upload_course_backup($hubcourseid, \stored_file $backupfile) { 370 debugging("This function has been deprecated as part of the Moodle.net sunsetting process."); 371 } 372 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body