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 * Rest API base class mapping rest api methods to endpoints with http methods, args and post body. 19 * 20 * @package core 21 * @copyright 2017 Damyon Wiese 22 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later 23 */ 24 namespace core\oauth2; 25 26 use curl; 27 use coding_exception; 28 use stdClass; 29 30 defined('MOODLE_INTERNAL') || die(); 31 32 require_once($CFG->libdir . '/filelib.php'); 33 34 /** 35 * Rest API base class mapping rest api methods to endpoints with http methods, args and post body. 36 * 37 * @copyright 2017 Damyon Wiese 38 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later 39 */ 40 abstract class rest { 41 42 /** @var curl $curl */ 43 protected $curl; 44 45 /** 46 * Constructor. 47 * 48 * @param curl $curl 49 */ 50 public function __construct(curl $curl) { 51 $this->curl = $curl; 52 } 53 54 /** 55 * Abstract function to define the functions of the rest API. 56 * 57 * @return array Example: 58 * [ 'listFiles' => [ 'method' => 'get', 'args' => [ 'folder' => PARAM_STRING ], 'response' => 'json' ] ] 59 */ 60 public abstract function get_api_functions(); 61 62 /** 63 * Call a function from the Api with a set of arguments and optional data. 64 * 65 * @param string $functionname 66 * @param array $functionargs 67 * @param string $rawpost Optional param to include in the body of a post. 68 * @param string $contenttype The MIME type for the request's Content-Type header. 69 * @return string|stdClass 70 */ 71 public function call($functionname, $functionargs, $rawpost = false, $contenttype = false) { 72 $functions = $this->get_api_functions(); 73 $supportedmethods = [ 'get', 'put', 'post', 'patch', 'head', 'delete' ]; 74 if (empty($functions[$functionname])) { 75 throw new coding_exception('unsupported api functionname: ' . $functionname); 76 } 77 78 $method = $functions[$functionname]['method']; 79 $endpoint = $functions[$functionname]['endpoint']; 80 81 $responsetype = $functions[$functionname]['response']; 82 if (!in_array($method, $supportedmethods)) { 83 throw new coding_exception('unsupported api method: ' . $method); 84 } 85 86 $args = $functions[$functionname]['args']; 87 $callargs = []; 88 foreach ($args as $argname => $argtype) { 89 if (isset($functionargs[$argname])) { 90 $callargs[$argname] = clean_param($functionargs[$argname], $argtype); 91 } 92 } 93 94 // Allow params in the URL path like /me/{parent}/children. 95 foreach ($callargs as $argname => $value) { 96 $newendpoint = str_replace('{' . $argname . '}', $value, $endpoint); 97 if ($newendpoint != $endpoint) { 98 $endpoint = $newendpoint; 99 unset($callargs[$argname]); 100 } 101 } 102 103 if ($rawpost !== false) { 104 $queryparams = $this->curl->build_post_data($callargs); 105 if (!empty($queryparams)) { 106 $endpoint .= '?' . $queryparams; 107 } 108 $callargs = $rawpost; 109 } 110 111 if (empty($contenttype)) { 112 $this->curl->setHeader('Content-type: application/json'); 113 } else { 114 $this->curl->setHeader('Content-type: ' . $contenttype); 115 } 116 $response = $this->curl->$method($endpoint, $callargs); 117 118 if ($this->curl->errno == 0) { 119 if ($responsetype == 'json') { 120 $json = json_decode($response); 121 122 if (!empty($json->error)) { 123 throw new rest_exception($json->error->code . ': ' . $json->error->message); 124 } 125 return $json; 126 } else if ($responsetype == 'headers') { 127 $response = $this->curl->get_raw_response(); 128 } 129 return $response; 130 } else { 131 throw new rest_exception($this->curl->error, $this->curl->errno); 132 } 133 } 134 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body