[ Index ] |
PHP Cross Reference of Unnamed Project |
[Summary view] [Print] [Text view]
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 /** 19 * REST web service implementation classes and methods. 20 * 21 * @package webservice_rest 22 * @copyright 2009 Jerome Mouneyrac 23 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later 24 */ 25 26 require_once("$CFG->dirroot/webservice/lib.php"); 27 28 /** 29 * REST service server implementation. 30 * 31 * @package webservice_rest 32 * @copyright 2009 Petr Skoda (skodak) 33 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later 34 */ 35 class webservice_rest_server extends webservice_base_server { 36 37 /** @var string return method ('xml' or 'json') */ 38 protected $restformat; 39 40 /** 41 * Contructor 42 * 43 * @param string $authmethod authentication method of the web service (WEBSERVICE_AUTHMETHOD_PERMANENT_TOKEN, ...) 44 * @param string $restformat Format of the return values: 'xml' or 'json' 45 */ 46 public function __construct($authmethod) { 47 parent::__construct($authmethod); 48 $this->wsname = 'rest'; 49 } 50 51 /** 52 * This method parses the $_POST and $_GET superglobals and looks for 53 * the following information: 54 * 1/ user authentication - username+password or token (wsusername, wspassword and wstoken parameters) 55 * 2/ function name (wsfunction parameter) 56 * 3/ function parameters (all other parameters except those above) 57 * 4/ text format parameters 58 * 5/ return rest format xml/json 59 */ 60 protected function parse_request() { 61 62 // Retrieve and clean the POST/GET parameters from the parameters specific to the server. 63 parent::set_web_service_call_settings(); 64 65 // Get GET and POST parameters. 66 $methodvariables = array_merge($_GET, $_POST); 67 68 // Retrieve REST format parameter - 'xml' (default) or 'json'. 69 $restformatisset = isset($methodvariables['moodlewsrestformat']) 70 && (($methodvariables['moodlewsrestformat'] == 'xml' || $methodvariables['moodlewsrestformat'] == 'json')); 71 $this->restformat = $restformatisset ? $methodvariables['moodlewsrestformat'] : 'xml'; 72 unset($methodvariables['moodlewsrestformat']); 73 74 if ($this->authmethod == WEBSERVICE_AUTHMETHOD_USERNAME) { 75 $this->username = isset($methodvariables['wsusername']) ? $methodvariables['wsusername'] : null; 76 unset($methodvariables['wsusername']); 77 78 $this->password = isset($methodvariables['wspassword']) ? $methodvariables['wspassword'] : null; 79 unset($methodvariables['wspassword']); 80 81 $this->functionname = isset($methodvariables['wsfunction']) ? $methodvariables['wsfunction'] : null; 82 unset($methodvariables['wsfunction']); 83 84 $this->parameters = $methodvariables; 85 86 } else { 87 $this->token = isset($methodvariables['wstoken']) ? $methodvariables['wstoken'] : null; 88 unset($methodvariables['wstoken']); 89 90 $this->functionname = isset($methodvariables['wsfunction']) ? $methodvariables['wsfunction'] : null; 91 unset($methodvariables['wsfunction']); 92 93 $this->parameters = $methodvariables; 94 } 95 } 96 97 /** 98 * Send the result of function call to the WS client 99 * formatted as XML document. 100 */ 101 protected function send_response() { 102 103 //Check that the returned values are valid 104 try { 105 if ($this->function->returns_desc != null) { 106 $validatedvalues = external_api::clean_returnvalue($this->function->returns_desc, $this->returns); 107 } else { 108 $validatedvalues = null; 109 } 110 } catch (Exception $ex) { 111 $exception = $ex; 112 } 113 114 if (!empty($exception)) { 115 $response = $this->generate_error($exception); 116 } else { 117 //We can now convert the response to the requested REST format 118 if ($this->restformat == 'json') { 119 $response = json_encode($validatedvalues); 120 } else { 121 $response = '<?xml version="1.0" encoding="UTF-8" ?>'."\n"; 122 $response .= '<RESPONSE>'."\n"; 123 $response .= self::xmlize_result($validatedvalues, $this->function->returns_desc); 124 $response .= '</RESPONSE>'."\n"; 125 } 126 } 127 128 $this->send_headers(); 129 echo $response; 130 } 131 132 /** 133 * Send the error information to the WS client 134 * formatted as XML document. 135 * Note: the exception is never passed as null, 136 * it only matches the abstract function declaration. 137 * @param exception $ex the exception that we are sending 138 */ 139 protected function send_error($ex=null) { 140 $this->send_headers(); 141 echo $this->generate_error($ex); 142 } 143 144 /** 145 * Build the error information matching the REST returned value format (JSON or XML) 146 * @param exception $ex the exception we are converting in the server rest format 147 * @return string the error in the requested REST format 148 */ 149 protected function generate_error($ex) { 150 if ($this->restformat == 'json') { 151 $errorobject = new stdClass; 152 $errorobject->exception = get_class($ex); 153 $errorobject->errorcode = $ex->errorcode; 154 $errorobject->message = $ex->getMessage(); 155 if (debugging() and isset($ex->debuginfo)) { 156 $errorobject->debuginfo = $ex->debuginfo; 157 } 158 $error = json_encode($errorobject); 159 } else { 160 $error = '<?xml version="1.0" encoding="UTF-8" ?>'."\n"; 161 $error .= '<EXCEPTION class="'.get_class($ex).'">'."\n"; 162 $error .= '<ERRORCODE>' . htmlspecialchars($ex->errorcode, ENT_COMPAT, 'UTF-8') 163 . '</ERRORCODE>' . "\n"; 164 $error .= '<MESSAGE>'.htmlspecialchars($ex->getMessage(), ENT_COMPAT, 'UTF-8').'</MESSAGE>'."\n"; 165 if (debugging() and isset($ex->debuginfo)) { 166 $error .= '<DEBUGINFO>'.htmlspecialchars($ex->debuginfo, ENT_COMPAT, 'UTF-8').'</DEBUGINFO>'."\n"; 167 } 168 $error .= '</EXCEPTION>'."\n"; 169 } 170 return $error; 171 } 172 173 /** 174 * Internal implementation - sending of page headers. 175 */ 176 protected function send_headers() { 177 if ($this->restformat == 'json') { 178 header('Content-type: application/json'); 179 } else { 180 header('Content-Type: application/xml; charset=utf-8'); 181 header('Content-Disposition: inline; filename="response.xml"'); 182 } 183 header('Cache-Control: private, must-revalidate, pre-check=0, post-check=0, max-age=0'); 184 header('Expires: '. gmdate('D, d M Y H:i:s', 0) .' GMT'); 185 header('Pragma: no-cache'); 186 header('Accept-Ranges: none'); 187 // Allow cross-origin requests only for Web Services. 188 // This allow to receive requests done by Web Workers or webapps in different domains. 189 header('Access-Control-Allow-Origin: *'); 190 } 191 192 /** 193 * Internal implementation - recursive function producing XML markup. 194 * 195 * @param mixed $returns the returned values 196 * @param external_description $desc 197 * @return string 198 */ 199 protected static function xmlize_result($returns, $desc) { 200 if ($desc === null) { 201 return ''; 202 203 } else if ($desc instanceof external_value) { 204 if (is_bool($returns)) { 205 // we want 1/0 instead of true/false here 206 $returns = (int)$returns; 207 } 208 if (is_null($returns)) { 209 return '<VALUE null="null"/>'."\n"; 210 } else { 211 return '<VALUE>'.htmlspecialchars($returns, ENT_COMPAT, 'UTF-8').'</VALUE>'."\n"; 212 } 213 214 } else if ($desc instanceof external_multiple_structure) { 215 $mult = '<MULTIPLE>'."\n"; 216 if (!empty($returns)) { 217 foreach ($returns as $val) { 218 $mult .= self::xmlize_result($val, $desc->content); 219 } 220 } 221 $mult .= '</MULTIPLE>'."\n"; 222 return $mult; 223 224 } else if ($desc instanceof external_single_structure) { 225 $single = '<SINGLE>'."\n"; 226 foreach ($desc->keys as $key=>$subdesc) { 227 $value = isset($returns[$key]) ? $returns[$key] : null; 228 $single .= '<KEY name="'.$key.'">'.self::xmlize_result($value, $subdesc).'</KEY>'."\n"; 229 } 230 $single .= '</SINGLE>'."\n"; 231 return $single; 232 } 233 } 234 } 235 236 237 /** 238 * REST test client class 239 * 240 * @package webservice_rest 241 * @copyright 2009 Petr Skoda (skodak) 242 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later 243 */ 244 class webservice_rest_test_client implements webservice_test_client_interface { 245 /** 246 * Execute test client WS request 247 * @param string $serverurl server url (including token parameter or username/password parameters) 248 * @param string $function function name 249 * @param array $params parameters of the called function 250 * @return mixed 251 */ 252 public function simpletest($serverurl, $function, $params) { 253 return download_file_content($serverurl.'&wsfunction='.$function, null, $params); 254 } 255 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body
Generated: Thu Aug 11 10:00:09 2016 | Cross-referenced by PHPXref 0.7.1 |