├── .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 | --------------------------------------------------------------------------------