Moodle  2.2.1
http://www.collinsharper.com
C:/xampp/htdocs/moodle/webservice/soap/locallib.php
Go to the documentation of this file.
00001 <?php
00002 
00003 // This file is part of Moodle - http://moodle.org/
00004 //
00005 // Moodle is free software: you can redistribute it and/or modify
00006 // it under the terms of the GNU General Public License as published by
00007 // the Free Software Foundation, either version 3 of the License, or
00008 // (at your option) any later version.
00009 //
00010 // Moodle is distributed in the hope that it will be useful,
00011 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00012 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00013 // GNU General Public License for more details.
00014 //
00015 // You should have received a copy of the GNU General Public License
00016 // along with Moodle.  If not, see <http://www.gnu.org/licenses/>.
00017 
00026 require_once("$CFG->dirroot/webservice/lib.php");
00027 require_once 'Zend/Soap/Server.php';
00028 
00032 class moodle_zend_soap_server extends Zend_Soap_Server {
00033 
00051     public function fault($fault = null, $code = "Receiver")
00052     {
00053         //intercept any exceptions with debug info and transform it in Moodle exception
00054         if ($fault instanceof Exception) {
00055             //add the debuginfo to the exception message if debuginfo must be returned
00056             if (debugging() and isset($fault->debuginfo)) {
00057                 $fault = new SoapFault('Receiver', $fault->getMessage() . ' | DEBUG INFO: ' . $fault->debuginfo);
00058             }
00059         }
00060 
00061         return parent::fault($fault, $code);
00062     }
00063 }
00064 
00069 class webservice_soap_server extends webservice_zend_server {
00074     public function __construct($authmethod) {
00075          // must not cache wsdl - the list of functions is created on the fly
00076         ini_set('soap.wsdl_cache_enabled', '0');
00077         require_once 'Zend/Soap/Server.php';
00078         require_once 'Zend/Soap/AutoDiscover.php';
00079 
00080         if (optional_param('wsdl', 0, PARAM_BOOL)) {
00081             parent::__construct($authmethod, 'Zend_Soap_AutoDiscover');
00082         } else {
00083             parent::__construct($authmethod, 'moodle_zend_soap_server');
00084         }
00085         $this->wsname = 'soap';
00086     }
00087 
00092     protected function init_zend_server() {
00093         global $CFG;
00094 
00095         parent::init_zend_server();
00096 
00097         if ($this->authmethod == WEBSERVICE_AUTHMETHOD_USERNAME) {
00098             $username = optional_param('wsusername', '', PARAM_RAW);
00099             $password = optional_param('wspassword', '', PARAM_RAW);
00100             // aparently some clients and zend soap server does not work well with "&" in urls :-(
00101             //TODO: the zend error has been fixed in the last Zend SOAP version, check that is fixed and remove obsolete code
00102             $url = $CFG->wwwroot.'/webservice/soap/simpleserver.php/'.urlencode($username).'/'.urlencode($password);
00103             // the Zend server is using this uri directly in xml - weird :-(
00104             $this->zend_server->setUri(htmlentities($url));
00105         } else {
00106             $wstoken = optional_param('wstoken', '', PARAM_RAW);
00107             $url = $CFG->wwwroot.'/webservice/soap/server.php?wstoken='.urlencode($wstoken);
00108             // the Zend server is using this uri directly in xml - weird :-(
00109             $this->zend_server->setUri(htmlentities($url));
00110         }
00111 
00112         if (!optional_param('wsdl', 0, PARAM_BOOL)) {
00113             $this->zend_server->setReturnResponse(true);
00114             //TODO: the error handling in Zend Soap server is useless, XML-RPC is much, much better :-(
00115             $this->zend_server->registerFaultException('moodle_exception');
00116             $this->zend_server->registerFaultException('webservice_parameter_exception'); //deprecated since Moodle 2.2 - kept for backward compatibility
00117             $this->zend_server->registerFaultException('invalid_parameter_exception');
00118             $this->zend_server->registerFaultException('invalid_response_exception');
00119             //when DEBUG >= NORMAL then the thrown exceptions are "casted" into a PHP SoapFault expception
00120             //in order to diplay the $debuginfo (see moodle_zend_soap_server class - MDL-29435)
00121             if (debugging()) {
00122                 $this->zend_server->registerFaultException('SoapFault');
00123             }
00124         }
00125     }
00126 
00134     protected function parse_request() {
00135         parent::parse_request();
00136 
00137         if (!$this->username or !$this->password) {
00138             //note: this is the workaround for the trouble with & in soap urls
00139             $authdata = get_file_argument();
00140             $authdata = explode('/', trim($authdata, '/'));
00141             if (count($authdata) == 2) {
00142                 list($this->username, $this->password) = $authdata;
00143             }
00144         }
00145     }
00146 
00153     protected function send_error($ex=null) {
00154         // Zend Soap server fault handling is incomplete compared to XML-RPC :-(
00155         // we can not use: echo $this->zend_server->fault($ex);
00156         //TODO: send some better response in XML
00157         if ($ex) {
00158             $info = $ex->getMessage();
00159             if (debugging() and isset($ex->debuginfo)) {
00160                 $info .= ' - '.$ex->debuginfo;
00161             }
00162         } else {
00163             $info = 'Unknown error';
00164         }
00165 
00166         $xml = '<?xml version="1.0" encoding="UTF-8"?>
00167 <SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/">
00168 <SOAP-ENV:Body><SOAP-ENV:Fault>
00169 <faultcode>MOODLE:error</faultcode>
00170 <faultstring>'.$info.'</faultstring>
00171 </SOAP-ENV:Fault></SOAP-ENV:Body></SOAP-ENV:Envelope>';
00172 
00173         $this->send_headers();
00174         header('Content-Type: application/xml; charset=utf-8');
00175         header('Content-Disposition: inline; filename="response.xml"');
00176 
00177         echo $xml;
00178     }
00179 
00180     protected function generate_simple_struct_class(external_single_structure $structdesc) {
00181         global $USER;
00182         // let's use unique class name, there might be problem in unit tests
00183         $classname = 'webservices_struct_class_000000';
00184         while(class_exists($classname)) {
00185             $classname++;
00186         }
00187 
00188         $fields = array();
00189         foreach ($structdesc->keys as $name => $fieldsdesc) {
00190             $type = $this->get_phpdoc_type($fieldsdesc);
00191             $fields[] = '    /** @var '.$type." */\n" .
00192                         '    public $'.$name.';';
00193         }
00194 
00195         $code = '
00199 class '.$classname.' {
00200 '.implode("\n", $fields).'
00201 }
00202 ';
00203         eval($code);
00204         return $classname;
00205     }
00206 }
00207 
00211 class webservice_soap_test_client implements webservice_test_client_interface {
00219     public function simpletest($serverurl, $function, $params) {
00220         //zend expects 0 based array with numeric indexes
00221         $params = array_values($params);
00222         require_once 'Zend/Soap/Client.php';
00223         $client = new Zend_Soap_Client($serverurl.'&wsdl=1');
00224         return $client->__call($function, $params);
00225     }
00226 }
 All Data Structures Namespaces Files Functions Variables Enumerations