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