[ Index ] |
PHP Cross Reference of moodle-2.8 |
[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 * SOAP web service implementation classes and methods. 20 * 21 * @package webservice_soap 22 * @copyright 2009 Petr Skodak 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 require_once 'Zend/Soap/Server.php'; 28 29 /** 30 * The Zend XMLRPC server but with a fault that returns debuginfo 31 * 32 * @package webservice_soap 33 * @copyright 2011 Jerome Mouneyrac 34 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later 35 * @since Moodle 2.2 36 */ 37 class moodle_zend_soap_server extends Zend_Soap_Server { 38 39 /** 40 * Generate a server fault 41 * 42 * Note that the arguments are the reverse of those used by SoapFault. 43 * 44 * Moodle note: basically we return the faultactor (errorcode) and faultdetails (debuginfo) 45 * 46 * If an exception is passed as the first argument, its message and code 47 * will be used to create the fault object if it has been registered via 48 * {@Link registerFaultException()}. 49 * 50 * @link http://www.w3.org/TR/soap12-part1/#faultcodes 51 * @param string|Exception $fault 52 * @param string $code SOAP Fault Codes 53 * @return SoapFault 54 */ 55 public function fault($fault = null, $code = "Receiver") 56 { 57 58 // Run the zend code that clean/create a soapfault. 59 $soapfault = parent::fault($fault, $code); 60 61 // Intercept any exceptions and add the errorcode and debuginfo (optional). 62 $actor = null; 63 $details = null; 64 if ($fault instanceof Exception) { 65 // Add the debuginfo to the exception message if debuginfo must be returned. 66 $actor = $fault->errorcode; 67 if (debugging() and isset($fault->debuginfo)) { 68 $details = $fault->debuginfo; 69 } 70 } 71 72 return new SoapFault($soapfault->faultcode, 73 $soapfault->getMessage() . ' | ERRORCODE: ' . $fault->errorcode, 74 $actor, $details); 75 } 76 77 /** 78 * Handle a request 79 * 80 * NOTE: this is basically a copy of the Zend handle() 81 * but with $soap->fault returning faultactor + faultdetail 82 * So we don't require coding style checks within this method 83 * to keep it as similar as the original one. 84 * 85 * Instantiates SoapServer object with options set in object, and 86 * dispatches its handle() method. 87 * 88 * $request may be any of: 89 * - DOMDocument; if so, then cast to XML 90 * - DOMNode; if so, then grab owner document and cast to XML 91 * - SimpleXMLElement; if so, then cast to XML 92 * - stdClass; if so, calls __toString() and verifies XML 93 * - string; if so, verifies XML 94 * 95 * If no request is passed, pulls request using php:://input (for 96 * cross-platform compatability purposes). 97 * 98 * @param DOMDocument|DOMNode|SimpleXMLElement|stdClass|string $request Optional request 99 * @return void|string 100 */ 101 public function handle($request = null) 102 { 103 if (null === $request) { 104 $request = file_get_contents('php://input'); 105 } 106 107 // Set Zend_Soap_Server error handler 108 $displayErrorsOriginalState = $this->_initializeSoapErrorContext(); 109 110 $setRequestException = null; 111 /** 112 * @see Zend_Soap_Server_Exception 113 */ 114 require_once 'Zend/Soap/Server/Exception.php'; 115 try { 116 $this->_setRequest($request); 117 } catch (Zend_Soap_Server_Exception $e) { 118 $setRequestException = $e; 119 } 120 121 $soap = $this->_getSoap(); 122 123 ob_start(); 124 if($setRequestException instanceof Exception) { 125 // Send SOAP fault message if we've catched exception 126 $soap->fault("Sender", $setRequestException->getMessage()); 127 } else { 128 try { 129 $soap->handle($request); 130 } catch (Exception $e) { 131 $fault = $this->fault($e); 132 $faultactor = isset($fault->faultactor) ? $fault->faultactor : null; 133 $detail = isset($fault->detail) ? $fault->detail : null; 134 $soap->fault($fault->faultcode, $fault->faultstring, $faultactor, $detail); 135 } 136 } 137 $this->_response = ob_get_clean(); 138 139 // Restore original error handler 140 restore_error_handler(); 141 ini_set('display_errors', $displayErrorsOriginalState); 142 143 if (!$this->_returnResponse) { 144 echo $this->_response; 145 return; 146 } 147 148 return $this->_response; 149 } 150 } 151 152 /** 153 * SOAP service server implementation. 154 * 155 * @package webservice_soap 156 * @copyright 2009 Petr Skodak 157 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later 158 * @since Moodle 2.0 159 */ 160 class webservice_soap_server extends webservice_zend_server { 161 162 /** 163 * Contructor 164 * 165 * @param string $authmethod authentication method of the web service (WEBSERVICE_AUTHMETHOD_PERMANENT_TOKEN, ...) 166 */ 167 public function __construct($authmethod) { 168 // must not cache wsdl - the list of functions is created on the fly 169 ini_set('soap.wsdl_cache_enabled', '0'); 170 require_once 'Zend/Soap/Server.php'; 171 require_once 'Zend/Soap/AutoDiscover.php'; 172 173 if (optional_param('wsdl', 0, PARAM_BOOL)) { 174 parent::__construct($authmethod, 'Zend_Soap_AutoDiscover'); 175 } else { 176 parent::__construct($authmethod, 'moodle_zend_soap_server'); 177 } 178 $this->wsname = 'soap'; 179 } 180 181 /** 182 * Set up zend service class 183 */ 184 protected function init_zend_server() { 185 global $CFG; 186 187 parent::init_zend_server(); 188 189 if ($this->authmethod == WEBSERVICE_AUTHMETHOD_USERNAME) { 190 $username = optional_param('wsusername', '', PARAM_RAW); 191 $password = optional_param('wspassword', '', PARAM_RAW); 192 // aparently some clients and zend soap server does not work well with "&" in urls :-( 193 //TODO MDL-31151 the zend error has been fixed in the last Zend SOAP version, check that is fixed and remove obsolete code 194 $url = $CFG->wwwroot.'/webservice/soap/simpleserver.php/'.urlencode($username).'/'.urlencode($password); 195 // the Zend server is using this uri directly in xml - weird :-( 196 $this->zend_server->setUri(htmlentities($url)); 197 } else { 198 $wstoken = optional_param('wstoken', '', PARAM_RAW); 199 $url = $CFG->wwwroot.'/webservice/soap/server.php?wstoken='.urlencode($wstoken); 200 // the Zend server is using this uri directly in xml - weird :-( 201 $this->zend_server->setUri(htmlentities($url)); 202 } 203 204 if (!optional_param('wsdl', 0, PARAM_BOOL)) { 205 $this->zend_server->setReturnResponse(true); 206 $this->zend_server->registerFaultException('moodle_exception'); 207 $this->zend_server->registerFaultException('webservice_parameter_exception'); //deprecated since Moodle 2.2 - kept for backward compatibility 208 $this->zend_server->registerFaultException('invalid_parameter_exception'); 209 $this->zend_server->registerFaultException('invalid_response_exception'); 210 //when DEBUG >= NORMAL then the thrown exceptions are "casted" into a PHP SoapFault expception 211 //in order to diplay the $debuginfo (see moodle_zend_soap_server class - MDL-29435) 212 if (debugging()) { 213 $this->zend_server->registerFaultException('SoapFault'); 214 } 215 } 216 } 217 218 /** 219 * This method parses the $_POST and $_GET superglobals and looks for 220 * the following information: 221 * user authentication - username+password or token (wsusername, wspassword and wstoken parameters) 222 */ 223 protected function parse_request() { 224 parent::parse_request(); 225 226 if (!$this->username or !$this->password) { 227 //note: this is the workaround for the trouble with & in soap urls 228 $authdata = get_file_argument(); 229 $authdata = explode('/', trim($authdata, '/')); 230 if (count($authdata) == 2) { 231 list($this->username, $this->password) = $authdata; 232 } 233 } 234 } 235 236 /** 237 * Send the error information to the WS client 238 * formatted as an XML document. 239 * 240 * @param exception $ex the exception to send back 241 */ 242 protected function send_error($ex=null) { 243 244 if ($ex) { 245 $info = $ex->getMessage(); 246 if (debugging() and isset($ex->debuginfo)) { 247 $info .= ' - '.$ex->debuginfo; 248 } 249 } else { 250 $info = 'Unknown error'; 251 } 252 253 $xml = '<?xml version="1.0" encoding="UTF-8"?> 254 <SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"> 255 <SOAP-ENV:Body><SOAP-ENV:Fault> 256 <faultcode>MOODLE:error</faultcode> 257 <faultstring>'.$info.'</faultstring> 258 </SOAP-ENV:Fault></SOAP-ENV:Body></SOAP-ENV:Envelope>'; 259 260 $this->send_headers(); 261 header('Content-Type: application/xml; charset=utf-8'); 262 header('Content-Disposition: inline; filename="response.xml"'); 263 264 echo $xml; 265 } 266 267 /** 268 * Generate 'struct' type name 269 * This type name is the name of a class generated on the fly. 270 * 271 * @param external_single_structure $structdesc 272 * @return string 273 */ 274 protected function generate_simple_struct_class(external_single_structure $structdesc) { 275 global $USER; 276 // let's use unique class name, there might be problem in unit tests 277 $classname = 'webservices_struct_class_000000'; 278 while(class_exists($classname)) { 279 $classname++; 280 } 281 282 $fields = array(); 283 foreach ($structdesc->keys as $name => $fieldsdesc) { 284 $type = $this->get_phpdoc_type($fieldsdesc); 285 $fields[] = ' /** @var '.$type." */\n" . 286 ' public $'.$name.';'; 287 } 288 289 $code = ' 290 /** 291 * Virtual struct class for web services for user id '.$USER->id.' in context '.$this->restricted_context->id.'. 292 */ 293 class '.$classname.' { 294 '.implode("\n", $fields).' 295 } 296 '; 297 eval($code); 298 return $classname; 299 } 300 } 301 302 /** 303 * SOAP test client class 304 * 305 * @package webservice_soap 306 * @copyright 2009 Petr Skodak 307 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later 308 * @since Moodle 2.0 309 */ 310 class webservice_soap_test_client implements webservice_test_client_interface { 311 312 /** 313 * Execute test client WS request 314 * 315 * @param string $serverurl server url (including token parameter or username/password parameters) 316 * @param string $function function name 317 * @param array $params parameters of the called function 318 * @return mixed 319 */ 320 public function simpletest($serverurl, $function, $params) { 321 //zend expects 0 based array with numeric indexes 322 $params = array_values($params); 323 require_once 'Zend/Soap/Client.php'; 324 $client = new Zend_Soap_Client($serverurl.'&wsdl=1'); 325 return $client->__call($function, $params); 326 } 327 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body
Generated: Fri Nov 28 20:29:05 2014 | Cross-referenced by PHPXref 0.7.1 |