|
Moodle
2.2.1
http://www.collinsharper.com
|
00001 <?php 00025 require_once 'Zend/Server/Interface.php'; 00026 00038 class Zend_Soap_Server implements Zend_Server_Interface 00039 { 00044 protected $_actor; 00045 00050 protected $_class; 00051 00056 protected $_classArgs = array(); 00057 00061 protected $_object; 00062 00067 protected $_classmap; 00068 00073 protected $_encoding; 00074 00080 protected $_features; 00081 00087 protected $_wsdlCache; 00088 00089 00094 protected $_faultExceptions = array(); 00095 00101 protected $_functions = array(); 00102 00107 protected $_persistence; 00108 00113 protected $_request; 00114 00119 protected $_response; 00120 00126 protected $_returnResponse = false; 00127 00132 protected $_soapVersion = SOAP_1_2; 00133 00138 protected $_wsdl; 00139 00144 protected $_uri; 00145 00160 public function __construct($wsdl = null, array $options = null) 00161 { 00162 if (!extension_loaded('soap')) { 00163 require_once 'Zend/Soap/Server/Exception.php'; 00164 throw new Zend_Soap_Server_Exception('SOAP extension is not loaded.'); 00165 } 00166 00167 if (null !== $wsdl) { 00168 $this->setWsdl($wsdl); 00169 } 00170 00171 if (null !== $options) { 00172 $this->setOptions($options); 00173 } 00174 } 00175 00184 public function setOptions($options) 00185 { 00186 if($options instanceof Zend_Config) { 00187 $options = $options->toArray(); 00188 } 00189 00190 foreach ($options as $key => $value) { 00191 switch ($key) { 00192 case 'actor': 00193 $this->setActor($value); 00194 break; 00195 case 'classmap': 00196 case 'classMap': 00197 $this->setClassmap($value); 00198 break; 00199 case 'encoding': 00200 $this->setEncoding($value); 00201 break; 00202 case 'soapVersion': 00203 case 'soap_version': 00204 $this->setSoapVersion($value); 00205 break; 00206 case 'uri': 00207 $this->setUri($value); 00208 break; 00209 case 'wsdl': 00210 $this->setWsdl($value); 00211 break; 00212 case 'featues': 00213 $this->setSoapFeatures($value); 00214 break; 00215 case 'cache_wsdl': 00216 $this->setWsdlCache($value); 00217 break; 00218 default: 00219 break; 00220 } 00221 } 00222 00223 return $this; 00224 } 00225 00231 public function getOptions() 00232 { 00233 $options = array(); 00234 if (null !== $this->_actor) { 00235 $options['actor'] = $this->_actor; 00236 } 00237 00238 if (null !== $this->_classmap) { 00239 $options['classmap'] = $this->_classmap; 00240 } 00241 00242 if (null !== $this->_encoding) { 00243 $options['encoding'] = $this->_encoding; 00244 } 00245 00246 if (null !== $this->_soapVersion) { 00247 $options['soap_version'] = $this->_soapVersion; 00248 } 00249 00250 if (null !== $this->_uri) { 00251 $options['uri'] = $this->_uri; 00252 } 00253 00254 if(null !== $this->_features) { 00255 $options['features'] = $this->_features; 00256 } 00257 00258 if(null !== $this->_wsdlCache) { 00259 $options['cache_wsdl'] = $this->_wsdlCache; 00260 } 00261 00262 return $options; 00263 } 00264 00272 public function setEncoding($encoding) 00273 { 00274 if (!is_string($encoding)) { 00275 require_once 'Zend/Soap/Server/Exception.php'; 00276 throw new Zend_Soap_Server_Exception('Invalid encoding specified'); 00277 } 00278 00279 $this->_encoding = $encoding; 00280 return $this; 00281 } 00282 00288 public function getEncoding() 00289 { 00290 return $this->_encoding; 00291 } 00292 00300 public function setSoapVersion($version) 00301 { 00302 if (!in_array($version, array(SOAP_1_1, SOAP_1_2))) { 00303 require_once 'Zend/Soap/Server/Exception.php'; 00304 throw new Zend_Soap_Server_Exception('Invalid soap version specified'); 00305 } 00306 00307 $this->_soapVersion = $version; 00308 return $this; 00309 } 00310 00316 public function getSoapVersion() 00317 { 00318 return $this->_soapVersion; 00319 } 00320 00328 public function validateUrn($urn) 00329 { 00330 $scheme = parse_url($urn, PHP_URL_SCHEME); 00331 if ($scheme === false || $scheme === null) { 00332 require_once 'Zend/Soap/Server/Exception.php'; 00333 throw new Zend_Soap_Server_Exception('Invalid URN'); 00334 } 00335 00336 return true; 00337 } 00338 00347 public function setActor($actor) 00348 { 00349 $this->validateUrn($actor); 00350 $this->_actor = $actor; 00351 return $this; 00352 } 00353 00359 public function getActor() 00360 { 00361 return $this->_actor; 00362 } 00363 00373 public function setUri($uri) 00374 { 00375 $this->validateUrn($uri); 00376 $this->_uri = $uri; 00377 return $this; 00378 } 00379 00385 public function getUri() 00386 { 00387 return $this->_uri; 00388 } 00389 00397 public function setClassmap($classmap) 00398 { 00399 if (!is_array($classmap)) { 00403 require_once 'Zend/Soap/Server/Exception.php'; 00404 throw new Zend_Soap_Server_Exception('Classmap must be an array'); 00405 } 00406 foreach ($classmap as $type => $class) { 00407 if (!class_exists($class)) { 00411 require_once 'Zend/Soap/Server/Exception.php'; 00412 throw new Zend_Soap_Server_Exception('Invalid class in class map'); 00413 } 00414 } 00415 00416 $this->_classmap = $classmap; 00417 return $this; 00418 } 00419 00425 public function getClassmap() 00426 { 00427 return $this->_classmap; 00428 } 00429 00436 public function setWsdl($wsdl) 00437 { 00438 $this->_wsdl = $wsdl; 00439 return $this; 00440 } 00441 00447 public function getWsdl() 00448 { 00449 return $this->_wsdl; 00450 } 00451 00458 public function setSoapFeatures($feature) 00459 { 00460 $this->_features = $feature; 00461 return $this; 00462 } 00463 00469 public function getSoapFeatures() 00470 { 00471 return $this->_features; 00472 } 00473 00480 public function setWsdlCache($options) 00481 { 00482 $this->_wsdlCache = $options; 00483 return $this; 00484 } 00485 00489 public function getWsdlCache() 00490 { 00491 return $this->_wsdlCache; 00492 } 00493 00503 public function addFunction($function, $namespace = '') 00504 { 00505 // Bail early if set to SOAP_FUNCTIONS_ALL 00506 if ($this->_functions == SOAP_FUNCTIONS_ALL) { 00507 return $this; 00508 } 00509 00510 if (is_array($function)) { 00511 foreach ($function as $func) { 00512 if (is_string($func) && function_exists($func)) { 00513 $this->_functions[] = $func; 00514 } else { 00515 require_once 'Zend/Soap/Server/Exception.php'; 00516 throw new Zend_Soap_Server_Exception('One or more invalid functions specified in array'); 00517 } 00518 } 00519 $this->_functions = array_merge($this->_functions, $function); 00520 } elseif (is_string($function) && function_exists($function)) { 00521 $this->_functions[] = $function; 00522 } elseif ($function == SOAP_FUNCTIONS_ALL) { 00523 $this->_functions = SOAP_FUNCTIONS_ALL; 00524 } else { 00525 require_once 'Zend/Soap/Server/Exception.php'; 00526 throw new Zend_Soap_Server_Exception('Invalid function specified'); 00527 } 00528 00529 if (is_array($this->_functions)) { 00530 $this->_functions = array_unique($this->_functions); 00531 } 00532 00533 return $this; 00534 } 00535 00549 public function setClass($class, $namespace = '', $argv = null) 00550 { 00551 if (isset($this->_class)) { 00552 require_once 'Zend/Soap/Server/Exception.php'; 00553 throw new Zend_Soap_Server_Exception('A class has already been registered with this soap server instance'); 00554 } 00555 00556 if (!is_string($class)) { 00557 require_once 'Zend/Soap/Server/Exception.php'; 00558 throw new Zend_Soap_Server_Exception('Invalid class argument (' . gettype($class) . ')'); 00559 } 00560 00561 if (!class_exists($class)) { 00562 require_once 'Zend/Soap/Server/Exception.php'; 00563 throw new Zend_Soap_Server_Exception('Class "' . $class . '" does not exist'); 00564 } 00565 00566 $this->_class = $class; 00567 if (1 < func_num_args()) { 00568 $argv = func_get_args(); 00569 array_shift($argv); 00570 $this->_classArgs = $argv; 00571 } 00572 00573 return $this; 00574 } 00575 00584 public function setObject($object) 00585 { 00586 if(!is_object($object)) { 00587 require_once 'Zend/Soap/Server/Exception.php'; 00588 throw new Zend_Soap_Server_Exception('Invalid object argument ('.gettype($object).')'); 00589 } 00590 00591 if(isset($this->_object)) { 00592 require_once 'Zend/Soap/Server/Exception.php'; 00593 throw new Zend_Soap_Server_Exception('An object has already been registered with this soap server instance'); 00594 } 00595 00596 $this->_object = $object; 00597 00598 return $this; 00599 } 00600 00611 public function getFunctions() 00612 { 00613 $functions = array(); 00614 if (null !== $this->_class) { 00615 $functions = get_class_methods($this->_class); 00616 } elseif (null !== $this->_object) { 00617 $functions = get_class_methods($this->_object); 00618 } 00619 00620 return array_merge((array) $this->_functions, $functions); 00621 } 00622 00630 public function loadFunctions($definition) 00631 { 00632 require_once 'Zend/Soap/Server/Exception.php'; 00633 throw new Zend_Soap_Server_Exception('Unimplemented'); 00634 } 00635 00642 public function setPersistence($mode) 00643 { 00644 if (!in_array($mode, array(SOAP_PERSISTENCE_SESSION, SOAP_PERSISTENCE_REQUEST))) { 00645 require_once 'Zend/Soap/Server/Exception.php'; 00646 throw new Zend_Soap_Server_Exception('Invalid persistence mode specified'); 00647 } 00648 00649 $this->_persistence = $mode; 00650 return $this; 00651 } 00652 00658 public function getPersistence() 00659 { 00660 return $this->_persistence; 00661 } 00662 00676 protected function _setRequest($request) 00677 { 00678 if ($request instanceof DOMDocument) { 00679 $xml = $request->saveXML(); 00680 } elseif ($request instanceof DOMNode) { 00681 $xml = $request->ownerDocument->saveXML(); 00682 } elseif ($request instanceof SimpleXMLElement) { 00683 $xml = $request->asXML(); 00684 } elseif (is_object($request) || is_string($request)) { 00685 if (is_object($request)) { 00686 $xml = $request->__toString(); 00687 } else { 00688 $xml = $request; 00689 } 00690 00691 $dom = new DOMDocument(); 00692 if(strlen($xml) == 0 || !$dom->loadXML($xml)) { 00693 require_once 'Zend/Soap/Server/Exception.php'; 00694 throw new Zend_Soap_Server_Exception('Invalid XML'); 00695 } 00696 } 00697 $this->_request = $xml; 00698 return $this; 00699 } 00700 00706 public function getLastRequest() 00707 { 00708 return $this->_request; 00709 } 00710 00722 public function setReturnResponse($flag) 00723 { 00724 $this->_returnResponse = ($flag) ? true : false; 00725 return $this; 00726 } 00727 00733 public function getReturnResponse() 00734 { 00735 return $this->_returnResponse; 00736 } 00737 00743 public function getLastResponse() 00744 { 00745 return $this->_response; 00746 } 00747 00757 protected function _getSoap() 00758 { 00759 $options = $this->getOptions(); 00760 $server = new SoapServer($this->_wsdl, $options); 00761 00762 if (!empty($this->_functions)) { 00763 $server->addFunction($this->_functions); 00764 } 00765 00766 if (!empty($this->_class)) { 00767 $args = $this->_classArgs; 00768 array_unshift($args, $this->_class); 00769 call_user_func_array(array($server, 'setClass'), $args); 00770 } 00771 00772 if (!empty($this->_object)) { 00773 $server->setObject($this->_object); 00774 } 00775 00776 if (null !== $this->_persistence) { 00777 $server->setPersistence($this->_persistence); 00778 } 00779 00780 return $server; 00781 } 00782 00802 public function handle($request = null) 00803 { 00804 if (null === $request) { 00805 $request = file_get_contents('php://input'); 00806 } 00807 00808 // Set Zend_Soap_Server error handler 00809 $displayErrorsOriginalState = $this->_initializeSoapErrorContext(); 00810 00811 $setRequestException = null; 00815 require_once 'Zend/Soap/Server/Exception.php'; 00816 try { 00817 $this->_setRequest($request); 00818 } catch (Zend_Soap_Server_Exception $e) { 00819 $setRequestException = $e; 00820 } 00821 00822 $soap = $this->_getSoap(); 00823 00824 ob_start(); 00825 if($setRequestException instanceof Exception) { 00826 // Send SOAP fault message if we've catched exception 00827 $soap->fault("Sender", $setRequestException->getMessage()); 00828 } else { 00829 try { 00830 $soap->handle($request); 00831 } catch (Exception $e) { 00832 $fault = $this->fault($e); 00833 $soap->fault($fault->faultcode, $fault->faultstring); 00834 } 00835 } 00836 $this->_response = ob_get_clean(); 00837 00838 // Restore original error handler 00839 restore_error_handler(); 00840 ini_set('display_errors', $displayErrorsOriginalState); 00841 00842 if (!$this->_returnResponse) { 00843 echo $this->_response; 00844 return; 00845 } 00846 00847 return $this->_response; 00848 } 00849 00855 protected function _initializeSoapErrorContext() 00856 { 00857 $displayErrorsOriginalState = ini_get('display_errors'); 00858 ini_set('display_errors', false); 00859 set_error_handler(array($this, 'handlePhpErrors'), E_USER_ERROR); 00860 return $displayErrorsOriginalState; 00861 } 00862 00869 public function registerFaultException($class) 00870 { 00871 $this->_faultExceptions = array_merge($this->_faultExceptions, (array) $class); 00872 return $this; 00873 } 00874 00881 public function deregisterFaultException($class) 00882 { 00883 if (in_array($class, $this->_faultExceptions, true)) { 00884 $index = array_search($class, $this->_faultExceptions); 00885 unset($this->_faultExceptions[$index]); 00886 return true; 00887 } 00888 00889 return false; 00890 } 00891 00897 public function getFaultExceptions() 00898 { 00899 return $this->_faultExceptions; 00900 } 00901 00916 public function fault($fault = null, $code = "Receiver") 00917 { 00918 if ($fault instanceof Exception) { 00919 $class = get_class($fault); 00920 if (in_array($class, $this->_faultExceptions)) { 00921 $message = $fault->getMessage(); 00922 $eCode = $fault->getCode(); 00923 $code = empty($eCode) ? $code : $eCode; 00924 } else { 00925 $message = 'Unknown error'; 00926 } 00927 } elseif(is_string($fault)) { 00928 $message = $fault; 00929 } else { 00930 $message = 'Unknown error'; 00931 } 00932 00933 $allowedFaultModes = array( 00934 'VersionMismatch', 'MustUnderstand', 'DataEncodingUnknown', 00935 'Sender', 'Receiver', 'Server' 00936 ); 00937 if(!in_array($code, $allowedFaultModes)) { 00938 $code = "Receiver"; 00939 } 00940 00941 return new SoapFault($code, $message); 00942 } 00943 00955 public function handlePhpErrors($errno, $errstr, $errfile = null, $errline = null, array $errcontext = null) 00956 { 00957 throw $this->fault($errstr, "Receiver"); 00958 } 00959 }