├── .gitignore ├── composer.json ├── LICENSE ├── README.md └── MoodleRest.php /.gitignore: -------------------------------------------------------------------------------- 1 | .history 2 | .vscode 3 | -------------------------------------------------------------------------------- /composer.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "llagerlof/moodlerest", 3 | "description": "MoodleRest is a PHP class to query Moodle REST webservices", 4 | "license": "MIT", 5 | "version": "2.4.0", 6 | "homepage": "https://github.com/llagerlof", 7 | "repository": { 8 | "type": "git", 9 | "url": "git+https://github.com/llagerlof/MoodleRest.git" 10 | }, 11 | "authors": [ 12 | { 13 | "name": "Lawrence Lagerlof", 14 | "email": "llagerlof@gmail.com" 15 | } 16 | ], 17 | "autoload": { 18 | "classmap": ["MoodleRest.php"] 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2018 Lawrence Lagerlof 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # MoodleRest 2 | 3 | MoodleRest is a PHP class to query Moodle REST webservices. You can make GET and POST requests. 4 | 5 | ## Quick start 6 | 7 | Ensure you already have access to a Moodle webservice. To use this class you will need a token (generated by Moodle admin) with the necessary capabilities for the services you want to access. 8 | 9 | **IMPORTANT** 10 | 11 | If you need a detailed explanation about the **$parameters** format of the **request()** method, [read it in wiki](https://github.com/llagerlof/MoodleRest/wiki/Understanding-the-$parameters-in-request()-method). 12 | 13 | ## To the code 14 | 15 | **You have 2 options to add this lib to your project:** 16 | 17 | **Option One:** Use Composer to include it in your project. 18 | 19 | - Inside your project directory create or modify the file `composer.json`: 20 | 21 | ```json 22 | { 23 | "require": { 24 | "llagerlof/moodlerest": "2.4.0" 25 | } 26 | } 27 | ``` 28 | 29 | - In the same directory of the `composer.json`, run: 30 | ```bash 31 | $ composer install 32 | ``` 33 | 34 | - In your project, load the lib using composer autoloader: 35 | 36 | ```php 37 | request('core_group_get_groups', array('groupids' => array(1,2))); 57 | 58 | print_r($groups); 59 | ``` 60 | 61 | ### Example 2 62 | 63 | Set the server and token in constructor and make a request to create a group on Moodle. 64 | 65 | ```php 66 | $MoodleRest = new MoodleRest('http://127.0.0.1/moodle/webservice/rest/server.php', '8f12e614dae30735260a045313caa400'); 67 | 68 | $new_group = array('groups' => array(array('courseid' => 2, 'name' => 'Group name', 'description' => 'Group description'))); 69 | 70 | // The default request's METHOD is to make a GET request, but you can change it to POST. This is recommended when inserting and updating data. 71 | $return = $MoodleRest->request('core_group_create_groups', $new_group, MoodleRest::METHOD_POST); 72 | 73 | // If you want the requested URL 74 | echo $MoodleRest->getUrl(); 75 | ``` 76 | 77 | ### Example 3 78 | 79 | Query 2 pre-existent Moodle groups with IDs 1 and 2 (like example 1, without setting the server and token values in constructor). 80 | 81 | ```php 82 | $MoodleRest = new MoodleRest(); 83 | $MoodleRest->setServerAddress("http://127.0.0.1/moodle/webservice/rest/server.php"); 84 | $MoodleRest->setToken('8f12e614dae30735260a045313caa400'); 85 | $MoodleRest->setReturnFormat(MoodleRest::RETURN_ARRAY); // Array is default. You can use RETURN_JSON or RETURN_XML too. 86 | 87 | // You can enable debugging information using setDebug() 88 | // When debugging is enabled, after each request the built URL and the result returned by the webservice function are printed to the standard output. 89 | $MoodleRest->setDebug(); 90 | $arr = $MoodleRest->request('core_group_get_groups', array('groupids' => array(1,2)), MoodleRest::METHOD_GET); 91 | 92 | // Note: You can make more requests using the same object 93 | ``` 94 | 95 | ### Example 4 96 | 97 | Make a request using chained methods and return the result as json. 98 | 99 | ```php 100 | /* 101 | The $parameters variable below translates in URL as: 102 | userlist[0][userid]=5& 103 | userlist[0][courseid]=2& 104 | userlist[1][userid]=4& 105 | userlist[1][courseid]=2" 106 | */ 107 | $parameters = array('userlist' => array(array('userid' => 5, 'courseid' => 2), array('userid' => 4, 'courseid' => 2))); 108 | 109 | $json = 110 | (new MoodleRest())->setServerAddress("http://127.0.0.1/moodle/webservice/rest/server.php")-> 111 | setToken('8f12e614dae30735260a045313caa400')-> 112 | setReturnFormat(MoodleRest::RETURN_JSON)->request('core_user_get_course_user_profiles', $parameters); 113 | 114 | echo $json; 115 | ``` 116 | 117 | More [examples](https://github.com/llagerlof/MoodleRest/wiki/MoodleRest-examples) in wiki. 118 | -------------------------------------------------------------------------------- /MoodleRest.php: -------------------------------------------------------------------------------- 1 | 10 | * @copyright 2021 Lawrence Lagerlof 11 | * @link http://github.com/llagerlof/MoodleRest 12 | * @license https://opensource.org/licenses/MIT MIT 13 | */ 14 | class MoodleRest 15 | { 16 | /** 17 | * The constant that defines the JSON return format 18 | * @access public 19 | */ 20 | const RETURN_JSON = 'json'; 21 | 22 | /** 23 | * The constant that defines the XML return format 24 | * @access public 25 | */ 26 | const RETURN_XML = 'xml'; 27 | 28 | /** 29 | * The constant that defines the ARRAY return format 30 | * @access public 31 | */ 32 | const RETURN_ARRAY = 'array'; 33 | 34 | /** 35 | * The constant that defines the request method using GET 36 | * @access public 37 | */ 38 | const METHOD_GET = 'get'; 39 | 40 | /** 41 | * The constant that defines the request method using POST 42 | * @access public 43 | */ 44 | const METHOD_POST = 'post'; 45 | 46 | /** 47 | * The full server address to Moodle REST webservices. 48 | * @access private 49 | */ 50 | private $server_address; 51 | 52 | /** 53 | * The Moodle webservice token 54 | * @access private 55 | */ 56 | private $token; 57 | 58 | /** 59 | * The return format (json, xml, array) 60 | * @access private 61 | */ 62 | private $return_format = 'json'; // or xml 63 | 64 | /** 65 | * The RAW return data (as returned by the request. could be json or xml) 66 | * @access private 67 | */ 68 | private $request_return; 69 | 70 | /** 71 | * The PARSED return data (could be json, xml or array) 72 | * @access private 73 | */ 74 | private $parsed_return; 75 | 76 | /** 77 | * The full encoded URL used to access the webservice 78 | * @access private 79 | */ 80 | private $url; 81 | 82 | /** 83 | * The full URL decoded 84 | * @access private 85 | */ 86 | private $url_decoded; 87 | 88 | /** 89 | * The header string to be used in header() output 90 | * @access private 91 | */ 92 | private $output_header; 93 | 94 | /** 95 | * The header string to be used in header() output 96 | * @access private 97 | */ 98 | private $print_on_request = false; 99 | 100 | /** 101 | * The method to be used on request 102 | * @access private 103 | */ 104 | private $method = 'get'; // or post 105 | 106 | /** 107 | * Print debug information to standard output? 108 | * @access private 109 | */ 110 | private $debug = false; 111 | 112 | /** 113 | * Constructor 114 | * 115 | * @param string $server_address The full URL of Moodle rest server script. Eg: http://127.0.0.1/moodle/webservice/rest/server.php 116 | */ 117 | public function __construct($server_address = null, $token = null, $return_format = self::RETURN_ARRAY) 118 | { 119 | $this->server_address = $server_address; 120 | $this->token = $token; 121 | if (!is_null($return_format) && $return_format <> 'json' && $return_format <> 'xml' && $return_format <> 'array') { 122 | throw new Exception("MoodleRest: Invalid return format: '$return_format'."); 123 | } 124 | $this->return_format = $return_format; 125 | } 126 | 127 | /** 128 | * Set the full server address to Moodle REST webservices 129 | * 130 | * @param string $server_address The server address. eg: 131 | * 132 | * @return MoodleRest 133 | */ 134 | public function setServerAddress($server_address) 135 | { 136 | $this->server_address = $server_address; 137 | return $this; 138 | } 139 | 140 | /** 141 | * Get the server address to Moodle REST webservices 142 | * 143 | * @return string The server address 144 | */ 145 | public function getServerAddress() 146 | { 147 | return $this->server_address; 148 | } 149 | 150 | /** 151 | * Set the Moodle token to access Moodle REST webservices 152 | * 153 | * @param string $token The oken generated by Moodle admin 154 | * 155 | * @return MoodleRest 156 | */ 157 | public function setToken($token) 158 | { 159 | $this->token = $token; 160 | 161 | return $this; 162 | } 163 | 164 | /** 165 | * Get the Moodle token 166 | * 167 | * @return string The Moodle token 168 | */ 169 | public function getToken() 170 | { 171 | return $this->token; 172 | } 173 | 174 | /** 175 | * Set the return format (json, xml or array) 176 | * 177 | * @param string $return_format The return format (json, xml or array) 178 | * 179 | * @return MoodleRest 180 | */ 181 | public function setReturnFormat($return_format) // json, xml, array 182 | { 183 | if ($return_format <> 'json' && $return_format <> 'xml' && $return_format <> 'array') { 184 | throw new Exception("MoodleRest: Invalid return format: '$return_format'."); 185 | } 186 | $this->return_format = $return_format; 187 | 188 | return $this; 189 | } 190 | 191 | /** 192 | * Get the return format 193 | * 194 | * @return string The return format (array, json or xml) 195 | */ 196 | public function getReturnFormat() 197 | { 198 | return $this->return_format; 199 | } 200 | 201 | /** 202 | * Store the return data 203 | * 204 | * @param string $request_return The returned data made by request() method 205 | */ 206 | private function setRawData($request_return) 207 | { 208 | $this->request_return = $request_return; 209 | } 210 | 211 | /** 212 | * Get the returned data previously made by request() method 213 | * 214 | * @return mixed 215 | */ 216 | public function getRawData() 217 | { 218 | return $this->request_return; 219 | } 220 | 221 | /** 222 | * Store the parsed return data 223 | * 224 | * @param string $parsed_return The parsed returned data made by request() method 225 | */ 226 | private function setData($parsed_return) 227 | { 228 | $this->parsed_return = $parsed_return; 229 | } 230 | 231 | /** 232 | * Get the parsed returned data previously made by request() method 233 | * 234 | * @return mixed The returned data in his final form 235 | */ 236 | public function getData() 237 | { 238 | return $this->parsed_return; 239 | } 240 | 241 | /** 242 | * Store the full URL when querying the server 243 | * 244 | * @param string $url The parsed returned data made by request() method 245 | */ 246 | private function setUrl($url) 247 | { 248 | $this->url = $url; 249 | $this->url_decoded = urldecode($url); 250 | } 251 | 252 | /** 253 | * Get the full URL stored when the query was made 254 | * 255 | * @return string The requested URL 256 | */ 257 | public function getUrl($decoded = true) 258 | { 259 | return $decoded ? $this->url_decoded : $this->url; 260 | } 261 | 262 | /** 263 | * Store the output header 264 | * 265 | * @param string $output_header The header 266 | */ 267 | private function setHeader($output_header) 268 | { 269 | $this->output_header = $output_header; 270 | } 271 | 272 | /** 273 | * Get the output header string 274 | * 275 | * @return string Get the output header 276 | */ 277 | public function getHeader() 278 | { 279 | return $this->output_header; 280 | } 281 | 282 | /** 283 | * Set the request method 284 | * 285 | * @param string $method The method to be used on request: MoodleRest::METHOD_GET or METHOD_POST 286 | */ 287 | public function setMethod($method) 288 | { 289 | $this->method = $method; 290 | } 291 | 292 | /** 293 | * Get the method 294 | * 295 | * @return string Get the request method 296 | */ 297 | public function getMethod() 298 | { 299 | return $this->method; 300 | } 301 | 302 | /** 303 | * Enable debugging information 304 | * 305 | * @param bool $enabled Enable or disable debugging information 306 | */ 307 | public function setDebug($enabled = true) 308 | { 309 | $this->debug = $enabled; 310 | } 311 | 312 | /** 313 | * Print debug information 314 | * 315 | * @param string $url The full url used to request the Moodle REST server 316 | * @param string $webservice_function The name of the Moodle function 317 | * @param string $method The method used to request data (get or post) 318 | * @param string $returned_data The data returned by Moodle webservice 319 | */ 320 | private function debug($url, $webservice_function, $method, $returned_data) 321 | { 322 | if ($this->debug) { 323 | $line_break = php_sapi_name() == 'cli' ? "\n" : '
'; 324 | $open_html_pre = php_sapi_name() == 'cli' ? '' : '
';
325 |             $close_html_pre = php_sapi_name() == 'cli' ? '' : '
'; 326 | echo $open_html_pre; 327 | echo $line_break; 328 | echo '[debug][' . strtoupper($method) . '] ' . get_class($this) . "::request( $webservice_function )$line_break"; 329 | echo "$url $line_break"; 330 | if (is_array($returned_data) || is_object($returned_data)) { 331 | print_r($returned_data); 332 | } else { 333 | if ((strlen(trim($returned_data)) > 0) && in_array($returned_data[0], array('[', '{'))) { 334 | print_r(json_decode(trim($returned_data), true)); 335 | } else { 336 | echo gettype($returned_data) . " '$returned_data'$line_break"; 337 | } 338 | } 339 | echo $line_break; 340 | echo $close_html_pre; 341 | } 342 | } 343 | 344 | /** 345 | * Set the option to print the requested data to standard output 346 | * 347 | * @param bool $print_on_request Set to TRUE if you want to output the result 348 | */ 349 | public function setPrintOnRequest($print_on_request = true) 350 | { 351 | $this->print_on_request = $print_on_request; 352 | } 353 | 354 | /** 355 | * Check if the object is configured to print the result to standard output 356 | * 357 | * @return bool Print the returned data to the standard output? 358 | */ 359 | public function getPrintOnRequest() 360 | { 361 | return $this->print_on_request; 362 | } 363 | 364 | /** 365 | * Output the result if the requested data format is json or xml, or print_r if is an array 366 | */ 367 | public function printRequest() 368 | { 369 | if (($this->getReturnFormat() == 'json') || ($this->getReturnFormat() == 'xml')) { 370 | if (empty($this->output_header)) { 371 | if ($this->getReturnFormat() == 'json') { 372 | header('Content-Type: application/json'); 373 | } elseif ($this->getReturnFormat() == 'xml') { 374 | header('Content-Type: application/xml'); 375 | } 376 | } 377 | echo $this->getData(); 378 | } else { 379 | print_r($this->getData()); 380 | } 381 | } 382 | 383 | /** 384 | * Make the request 385 | * 386 | * @param string $function A Moodle function 387 | * @param array $parameters The parameters to be passed to the Moodle function. eg: array('groupids' => array(1,2)) | This translates as "groupids[0]=1&groupids[1]=2" in URL 388 | * 389 | * @return mixed The final requested data 390 | */ 391 | public function request($function, $parameters = null, $method = self::METHOD_GET) 392 | { 393 | if (empty($this->server_address)) { 394 | throw new Exception('MoodleRest: Empty server address. Use setServerAddress() or put the address on constructor.'); 395 | } 396 | if (empty($this->token)) { 397 | throw new Exception('MoodleRest: Empty token. Use setToken() or put the token on constructor.'); 398 | } 399 | if (empty($this->return_format)) { 400 | throw new Exception('MoodleRest: Empty return format. Use setReturnFormat().'); 401 | } 402 | if (empty($function)) { 403 | throw new Exception('MoodleRest: Empty function. Fill the first parameter of request().'); 404 | } 405 | if (!is_null($parameters)) { 406 | if (!is_array($parameters)) { 407 | throw new Exception('MoodleRest: The second parameter of request() should be an array.'); 408 | } 409 | } 410 | 411 | if ($this->getReturnFormat() == 'array' || $this->getReturnFormat() == 'json') { 412 | $return_format = 'json'; 413 | } else { 414 | $return_format = 'xml'; 415 | } 416 | 417 | $this->setMethod($method); 418 | 419 | $query_string = is_array($parameters) ? http_build_query($parameters) : ''; 420 | 421 | $this->setUrl( 422 | $this->getServerAddress() . 423 | '?wstoken=' . $this->getToken() . 424 | '&moodlewsrestformat=' . $return_format . 425 | '&wsfunction=' . $function . 426 | '&' . $query_string 427 | ); 428 | 429 | $post_url = 430 | $this->getServerAddress() . 431 | '?wstoken=' . $this->getToken() . 432 | '&moodlewsrestformat=' . $return_format . 433 | '&wsfunction=' . $function; 434 | 435 | if ($this->getMethod() != self::METHOD_POST) { 436 | // GET 437 | $moodle_request = file_get_contents($this->getUrl(false)); 438 | 439 | if ($moodle_request === false) { 440 | throw new Exception('MoodleRest: Error trying to connect to Moodle server on GET request. Check PHP warning messages.'); 441 | } 442 | 443 | $this->debug($this->getUrl(), $function, self::METHOD_GET, $moodle_request); 444 | } else { 445 | // POST 446 | $options = array('http' => 447 | array( 448 | 'method' => 'POST', 449 | 'header' => 'Content-type: application/x-www-form-urlencoded', 450 | 'content' => $query_string 451 | ) 452 | ); 453 | $context = stream_context_create($options); 454 | $moodle_request = file_get_contents($post_url, false, $context); 455 | 456 | if ($moodle_request === false) { 457 | throw new Exception('MoodleRest: Error trying to connect to Moodle server on POST request. Check PHP warning messages.'); 458 | } 459 | 460 | $this->debug($this->getUrl(), $function, self::METHOD_POST, $moodle_request); 461 | } 462 | 463 | $this->setRawData($moodle_request); 464 | 465 | if ($this->getReturnFormat() == 'array') { 466 | $this->setData(json_decode($moodle_request, true)); 467 | } else { 468 | $this->setData($moodle_request); 469 | } 470 | 471 | if ($this->getPrintOnRequest()) { 472 | $this->printRequest(); 473 | } 474 | 475 | return $this->getData(); 476 | } 477 | } 478 | --------------------------------------------------------------------------------