File indexing completed on 2025-03-02 05:29:52
0001 <?php 0002 /** 0003 * Zend Framework 0004 * 0005 * LICENSE 0006 * 0007 * This source file is subject to the new BSD license that is bundled 0008 * with this package in the file LICENSE.txt. 0009 * It is also available through the world-wide-web at this URL: 0010 * http://framework.zend.com/license/new-bsd 0011 * If you did not receive a copy of the license and are unable to 0012 * obtain it through the world-wide-web, please send an email 0013 * to license@zend.com so we can send you a copy immediately. 0014 * 0015 * @category Zend 0016 * @package Zend_Soap 0017 * @subpackage Server 0018 * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) 0019 * @license http://framework.zend.com/license/new-bsd New BSD License 0020 */ 0021 0022 /** 0023 * @see Zend_Server_Interface 0024 */ 0025 // require_once 'Zend/Server/Interface.php'; 0026 0027 /** @see Zend_Xml_Security */ 0028 // require_once 'Zend/Xml/Security.php'; 0029 0030 /** @see Zend_Xml_Exception */ 0031 // require_once 'Zend/Xml/Exception.php'; 0032 0033 /** 0034 * Zend_Soap_Server 0035 * 0036 * @category Zend 0037 * @package Zend_Soap 0038 * @subpackage Server 0039 * @uses Zend_Server_Interface 0040 * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) 0041 * @license http://framework.zend.com/license/new-bsd New BSD License 0042 * @version $Id$ 0043 */ 0044 class Zend_Soap_Server implements Zend_Server_Interface 0045 { 0046 /** 0047 * Actor URI 0048 * @var string URI 0049 */ 0050 protected $_actor; 0051 0052 /** 0053 * Class registered with this server 0054 * @var string 0055 */ 0056 protected $_class; 0057 0058 /** 0059 * Arguments to pass to {@link $_class} constructor 0060 * @var array 0061 */ 0062 protected $_classArgs = array(); 0063 0064 /** 0065 * Object registered with this server 0066 */ 0067 protected $_object; 0068 0069 /** 0070 * Array of SOAP type => PHP class pairings for handling return/incoming values 0071 * @var array 0072 */ 0073 protected $_classmap; 0074 0075 /** 0076 * Encoding 0077 * @var string 0078 */ 0079 protected $_encoding; 0080 0081 /** 0082 * SOAP Server Features 0083 * 0084 * @var int 0085 */ 0086 protected $_features; 0087 0088 /** 0089 * WSDL Caching Options of SOAP Server 0090 * 0091 * @var mixed 0092 */ 0093 protected $_wsdlCache; 0094 0095 /** 0096 * WS-I compliant 0097 * 0098 * @var boolean 0099 */ 0100 protected $_wsiCompliant; 0101 0102 /** 0103 * Registered fault exceptions 0104 * @var array 0105 */ 0106 protected $_faultExceptions = array(); 0107 0108 /** 0109 * Functions registered with this server; may be either an array or the SOAP_FUNCTIONS_ALL 0110 * constant 0111 * @var array|int 0112 */ 0113 protected $_functions = array(); 0114 0115 /** 0116 * Persistence mode; should be one of the SOAP persistence constants 0117 * @var int 0118 */ 0119 protected $_persistence; 0120 0121 /** 0122 * Request XML 0123 * @var string 0124 */ 0125 protected $_request; 0126 0127 /** 0128 * Response XML 0129 * @var string 0130 */ 0131 protected $_response; 0132 0133 /** 0134 * Flag: whether or not {@link handle()} should return a response instead 0135 * of automatically emitting it. 0136 * @var boolean 0137 */ 0138 protected $_returnResponse = false; 0139 0140 /** 0141 * SOAP version to use; SOAP_1_2 by default, to allow processing of headers 0142 * @var int 0143 */ 0144 protected $_soapVersion = SOAP_1_2; 0145 0146 /** 0147 * URI or path to WSDL 0148 * @var string 0149 */ 0150 protected $_wsdl; 0151 0152 /** 0153 * URI namespace for SOAP server 0154 * @var string URI 0155 */ 0156 protected $_uri; 0157 0158 /** 0159 * Constructor 0160 * 0161 * Sets display_errors INI setting to off (prevent client errors due to bad 0162 * XML in response). Registers {@link handlePhpErrors()} as error handler 0163 * for E_USER_ERROR. 0164 * 0165 * If $wsdl is provided, it is passed on to {@link setWsdl()}; if any 0166 * options are specified, they are passed on to {@link setOptions()}. 0167 * 0168 * @param string $wsdl 0169 * @param array $options 0170 * @return void 0171 */ 0172 public function __construct($wsdl = null, array $options = null) 0173 { 0174 if (!extension_loaded('soap')) { 0175 // require_once 'Zend/Soap/Server/Exception.php'; 0176 throw new Zend_Soap_Server_Exception('SOAP extension is not loaded.'); 0177 } 0178 0179 if (null !== $wsdl) { 0180 $this->setWsdl($wsdl); 0181 } 0182 0183 if (null !== $options) { 0184 $this->setOptions($options); 0185 } 0186 } 0187 0188 /** 0189 * Set Options 0190 * 0191 * Allows setting options as an associative array of option => value pairs. 0192 * 0193 * @param array|Zend_Config $options 0194 * @return Zend_Soap_Server 0195 */ 0196 public function setOptions($options) 0197 { 0198 if($options instanceof Zend_Config) { 0199 $options = $options->toArray(); 0200 } 0201 0202 foreach ($options as $key => $value) { 0203 switch ($key) { 0204 case 'actor': 0205 $this->setActor($value); 0206 break; 0207 case 'classmap': 0208 case 'classMap': 0209 $this->setClassmap($value); 0210 break; 0211 case 'encoding': 0212 $this->setEncoding($value); 0213 break; 0214 case 'soapVersion': 0215 case 'soap_version': 0216 $this->setSoapVersion($value); 0217 break; 0218 case 'uri': 0219 $this->setUri($value); 0220 break; 0221 case 'wsdl': 0222 $this->setWsdl($value); 0223 break; 0224 case 'featues': 0225 trigger_error(__METHOD__ . ': the option "featues" is deprecated as of 1.10.x and will be removed with 2.0.0; use "features" instead', E_USER_NOTICE); 0226 case 'features': 0227 $this->setSoapFeatures($value); 0228 break; 0229 case 'cache_wsdl': 0230 $this->setWsdlCache($value); 0231 break; 0232 case 'wsi_compliant': 0233 $this->setWsiCompliant($value); 0234 break; 0235 default: 0236 break; 0237 } 0238 } 0239 0240 return $this; 0241 } 0242 0243 /** 0244 * Return array of options suitable for using with SoapServer constructor 0245 * 0246 * @return array 0247 */ 0248 public function getOptions() 0249 { 0250 $options = array(); 0251 if (null !== $this->_actor) { 0252 $options['actor'] = $this->_actor; 0253 } 0254 0255 if (null !== $this->_classmap) { 0256 $options['classmap'] = $this->_classmap; 0257 } 0258 0259 if (null !== $this->_encoding) { 0260 $options['encoding'] = $this->_encoding; 0261 } 0262 0263 if (null !== $this->_soapVersion) { 0264 $options['soap_version'] = $this->_soapVersion; 0265 } 0266 0267 if (null !== $this->_uri) { 0268 $options['uri'] = $this->_uri; 0269 } 0270 0271 if (null !== $this->_features) { 0272 $options['features'] = $this->_features; 0273 } 0274 0275 if (null !== $this->_wsdlCache) { 0276 $options['cache_wsdl'] = $this->_wsdlCache; 0277 } 0278 0279 if (null !== $this->_wsiCompliant) { 0280 $options['wsi_compliant'] = $this->_wsiCompliant; 0281 } 0282 0283 return $options; 0284 } 0285 /** 0286 * Set WS-I compliant 0287 * 0288 * @param boolean $value 0289 * @return Zend_Soap_Server 0290 */ 0291 public function setWsiCompliant($value) 0292 { 0293 if (is_bool($value)) { 0294 $this->_wsiCompliant = $value; 0295 } 0296 return $this; 0297 } 0298 /** 0299 * Gt WS-I compliant 0300 * 0301 * @return boolean 0302 */ 0303 public function getWsiCompliant() 0304 { 0305 return $this->_wsiCompliant; 0306 } 0307 /** 0308 * Set encoding 0309 * 0310 * @param string $encoding 0311 * @return Zend_Soap_Server 0312 * @throws Zend_Soap_Server_Exception with invalid encoding argument 0313 */ 0314 public function setEncoding($encoding) 0315 { 0316 if (!is_string($encoding)) { 0317 // require_once 'Zend/Soap/Server/Exception.php'; 0318 throw new Zend_Soap_Server_Exception('Invalid encoding specified'); 0319 } 0320 0321 $this->_encoding = $encoding; 0322 return $this; 0323 } 0324 0325 /** 0326 * Get encoding 0327 * 0328 * @return string 0329 */ 0330 public function getEncoding() 0331 { 0332 return $this->_encoding; 0333 } 0334 0335 /** 0336 * Set SOAP version 0337 * 0338 * @param int $version One of the SOAP_1_1 or SOAP_1_2 constants 0339 * @return Zend_Soap_Server 0340 * @throws Zend_Soap_Server_Exception with invalid soap version argument 0341 */ 0342 public function setSoapVersion($version) 0343 { 0344 if (!in_array($version, array(SOAP_1_1, SOAP_1_2))) { 0345 // require_once 'Zend/Soap/Server/Exception.php'; 0346 throw new Zend_Soap_Server_Exception('Invalid soap version specified'); 0347 } 0348 0349 $this->_soapVersion = $version; 0350 return $this; 0351 } 0352 0353 /** 0354 * Get SOAP version 0355 * 0356 * @return int 0357 */ 0358 public function getSoapVersion() 0359 { 0360 return $this->_soapVersion; 0361 } 0362 0363 /** 0364 * Check for valid URN 0365 * 0366 * @param string $urn 0367 * @return true 0368 * @throws Zend_Soap_Server_Exception on invalid URN 0369 */ 0370 public function validateUrn($urn) 0371 { 0372 $scheme = parse_url($urn, PHP_URL_SCHEME); 0373 if ($scheme === false || $scheme === null) { 0374 // require_once 'Zend/Soap/Server/Exception.php'; 0375 throw new Zend_Soap_Server_Exception('Invalid URN'); 0376 } 0377 0378 return true; 0379 } 0380 0381 /** 0382 * Set actor 0383 * 0384 * Actor is the actor URI for the server. 0385 * 0386 * @param string $actor 0387 * @return Zend_Soap_Server 0388 */ 0389 public function setActor($actor) 0390 { 0391 $this->validateUrn($actor); 0392 $this->_actor = $actor; 0393 return $this; 0394 } 0395 0396 /** 0397 * Retrieve actor 0398 * 0399 * @return string 0400 */ 0401 public function getActor() 0402 { 0403 return $this->_actor; 0404 } 0405 0406 /** 0407 * Set URI 0408 * 0409 * URI in SoapServer is actually the target namespace, not a URI; $uri must begin with 'urn:'. 0410 * 0411 * @param string $uri 0412 * @return Zend_Soap_Server 0413 * @throws Zend_Soap_Server_Exception with invalid uri argument 0414 */ 0415 public function setUri($uri) 0416 { 0417 $this->validateUrn($uri); 0418 $this->_uri = $uri; 0419 return $this; 0420 } 0421 0422 /** 0423 * Retrieve URI 0424 * 0425 * @return string 0426 */ 0427 public function getUri() 0428 { 0429 return $this->_uri; 0430 } 0431 0432 /** 0433 * Set classmap 0434 * 0435 * @param array $classmap 0436 * @return Zend_Soap_Server 0437 * @throws Zend_Soap_Server_Exception for any invalid class in the class map 0438 */ 0439 public function setClassmap($classmap) 0440 { 0441 if (!is_array($classmap)) { 0442 /** 0443 * @see Zend_Soap_Server_Exception 0444 */ 0445 // require_once 'Zend/Soap/Server/Exception.php'; 0446 throw new Zend_Soap_Server_Exception('Classmap must be an array'); 0447 } 0448 foreach ($classmap as $type => $class) { 0449 if (!class_exists($class)) { 0450 /** 0451 * @see Zend_Soap_Server_Exception 0452 */ 0453 // require_once 'Zend/Soap/Server/Exception.php'; 0454 throw new Zend_Soap_Server_Exception('Invalid class in class map'); 0455 } 0456 } 0457 0458 $this->_classmap = $classmap; 0459 return $this; 0460 } 0461 0462 /** 0463 * Retrieve classmap 0464 * 0465 * @return mixed 0466 */ 0467 public function getClassmap() 0468 { 0469 return $this->_classmap; 0470 } 0471 0472 /** 0473 * Set wsdl 0474 * 0475 * @param string $wsdl URI or path to a WSDL 0476 * @return Zend_Soap_Server 0477 */ 0478 public function setWsdl($wsdl) 0479 { 0480 $this->_wsdl = $wsdl; 0481 return $this; 0482 } 0483 0484 /** 0485 * Retrieve wsdl 0486 * 0487 * @return string 0488 */ 0489 public function getWsdl() 0490 { 0491 return $this->_wsdl; 0492 } 0493 0494 /** 0495 * Set the SOAP Feature options. 0496 * 0497 * @param string|int $feature 0498 * @return Zend_Soap_Server 0499 */ 0500 public function setSoapFeatures($feature) 0501 { 0502 $this->_features = $feature; 0503 return $this; 0504 } 0505 0506 /** 0507 * Return current SOAP Features options 0508 * 0509 * @return int 0510 */ 0511 public function getSoapFeatures() 0512 { 0513 return $this->_features; 0514 } 0515 0516 /** 0517 * Set the SOAP Wsdl Caching Options 0518 * 0519 * @param string|int|boolean $caching 0520 * @return Zend_Soap_Server 0521 */ 0522 public function setWsdlCache($options) 0523 { 0524 $this->_wsdlCache = $options; 0525 return $this; 0526 } 0527 0528 /** 0529 * Get current SOAP Wsdl Caching option 0530 */ 0531 public function getWsdlCache() 0532 { 0533 return $this->_wsdlCache; 0534 } 0535 0536 /** 0537 * Attach a function as a server method 0538 * 0539 * @param array|string $function Function name, array of function names to attach, 0540 * or SOAP_FUNCTIONS_ALL to attach all functions 0541 * @param string $namespace Ignored 0542 * @return Zend_Soap_Server 0543 * @throws Zend_Soap_Server_Exception on invalid functions 0544 */ 0545 public function addFunction($function, $namespace = '') 0546 { 0547 // Bail early if set to SOAP_FUNCTIONS_ALL 0548 if ($this->_functions == SOAP_FUNCTIONS_ALL) { 0549 return $this; 0550 } 0551 0552 if (is_array($function)) { 0553 foreach ($function as $func) { 0554 if (is_string($func) && function_exists($func)) { 0555 $this->_functions[] = $func; 0556 } else { 0557 // require_once 'Zend/Soap/Server/Exception.php'; 0558 throw new Zend_Soap_Server_Exception('One or more invalid functions specified in array'); 0559 } 0560 } 0561 $this->_functions = array_merge($this->_functions, $function); 0562 } elseif (is_string($function) && function_exists($function)) { 0563 $this->_functions[] = $function; 0564 } elseif ($function == SOAP_FUNCTIONS_ALL) { 0565 $this->_functions = SOAP_FUNCTIONS_ALL; 0566 } else { 0567 // require_once 'Zend/Soap/Server/Exception.php'; 0568 throw new Zend_Soap_Server_Exception('Invalid function specified'); 0569 } 0570 0571 if (is_array($this->_functions)) { 0572 $this->_functions = array_unique($this->_functions); 0573 } 0574 0575 return $this; 0576 } 0577 0578 /** 0579 * Attach a class to a server 0580 * 0581 * Accepts a class name to use when handling requests. Any additional 0582 * arguments will be passed to that class' constructor when instantiated. 0583 * 0584 * See {@link setObject()} to set preconfigured object instances as request handlers. 0585 * 0586 * @param string $class Class Name which executes SOAP Requests at endpoint. 0587 * @return Zend_Soap_Server 0588 * @throws Zend_Soap_Server_Exception if called more than once, or if class 0589 * does not exist 0590 */ 0591 public function setClass($class, $namespace = '', $argv = null) 0592 { 0593 if (isset($this->_class)) { 0594 // require_once 'Zend/Soap/Server/Exception.php'; 0595 throw new Zend_Soap_Server_Exception('A class has already been registered with this soap server instance'); 0596 } 0597 0598 if (!is_string($class)) { 0599 // require_once 'Zend/Soap/Server/Exception.php'; 0600 throw new Zend_Soap_Server_Exception('Invalid class argument (' . gettype($class) . ')'); 0601 } 0602 0603 if (!class_exists($class)) { 0604 // require_once 'Zend/Soap/Server/Exception.php'; 0605 throw new Zend_Soap_Server_Exception('Class "' . $class . '" does not exist'); 0606 } 0607 0608 $this->_class = $class; 0609 if (1 < func_num_args()) { 0610 $argv = func_get_args(); 0611 array_shift($argv); 0612 $this->_classArgs = $argv; 0613 } 0614 0615 return $this; 0616 } 0617 0618 /** 0619 * Attach an object to a server 0620 * 0621 * Accepts an instanciated object to use when handling requests. 0622 * 0623 * @param object $object 0624 * @return Zend_Soap_Server 0625 */ 0626 public function setObject($object) 0627 { 0628 if(!is_object($object)) { 0629 // require_once 'Zend/Soap/Server/Exception.php'; 0630 throw new Zend_Soap_Server_Exception('Invalid object argument ('.gettype($object).')'); 0631 } 0632 0633 if(isset($this->_object)) { 0634 // require_once 'Zend/Soap/Server/Exception.php'; 0635 throw new Zend_Soap_Server_Exception('An object has already been registered with this soap server instance'); 0636 } 0637 0638 if ($this->_wsiCompliant) { 0639 // require_once 'Zend/Soap/Server/Proxy.php'; 0640 $this->_object = new Zend_Soap_Server_Proxy($object); 0641 } else { 0642 $this->_object = $object; 0643 } 0644 0645 return $this; 0646 } 0647 0648 /** 0649 * Return a server definition array 0650 * 0651 * Returns a list of all functions registered with {@link addFunction()}, 0652 * merged with all public methods of the class set with {@link setClass()} 0653 * (if any). 0654 * 0655 * @access public 0656 * @return array 0657 */ 0658 public function getFunctions() 0659 { 0660 $functions = array(); 0661 if (null !== $this->_class) { 0662 $functions = get_class_methods($this->_class); 0663 } elseif (null !== $this->_object) { 0664 $functions = get_class_methods($this->_object); 0665 } 0666 0667 return array_merge((array) $this->_functions, $functions); 0668 } 0669 0670 /** 0671 * Unimplemented: Load server definition 0672 * 0673 * @param array $array 0674 * @return void 0675 * @throws Zend_Soap_Server_Exception Unimplemented 0676 */ 0677 public function loadFunctions($definition) 0678 { 0679 // require_once 'Zend/Soap/Server/Exception.php'; 0680 throw new Zend_Soap_Server_Exception('Unimplemented'); 0681 } 0682 0683 /** 0684 * Set server persistence 0685 * 0686 * @param int $mode 0687 * @return Zend_Soap_Server 0688 */ 0689 public function setPersistence($mode) 0690 { 0691 if (!in_array($mode, array(SOAP_PERSISTENCE_SESSION, SOAP_PERSISTENCE_REQUEST))) { 0692 // require_once 'Zend/Soap/Server/Exception.php'; 0693 throw new Zend_Soap_Server_Exception('Invalid persistence mode specified'); 0694 } 0695 0696 $this->_persistence = $mode; 0697 return $this; 0698 } 0699 0700 /** 0701 * Get server persistence 0702 * 0703 * @return Zend_Soap_Server 0704 */ 0705 public function getPersistence() 0706 { 0707 return $this->_persistence; 0708 } 0709 0710 /** 0711 * Set request 0712 * 0713 * $request may be any of: 0714 * - DOMDocument; if so, then cast to XML 0715 * - DOMNode; if so, then grab owner document and cast to XML 0716 * - SimpleXMLElement; if so, then cast to XML 0717 * - stdClass; if so, calls __toString() and verifies XML 0718 * - string; if so, verifies XML 0719 * 0720 * @param DOMDocument|DOMNode|SimpleXMLElement|stdClass|string $request 0721 * @return Zend_Soap_Server 0722 */ 0723 protected function _setRequest($request) 0724 { 0725 if ($request instanceof DOMDocument) { 0726 $xml = $request->saveXML(); 0727 } elseif ($request instanceof DOMNode) { 0728 $xml = $request->ownerDocument->saveXML(); 0729 } elseif ($request instanceof SimpleXMLElement) { 0730 $xml = $request->asXML(); 0731 } elseif (is_object($request) || is_string($request)) { 0732 if (is_object($request)) { 0733 $xml = $request->__toString(); 0734 } else { 0735 $xml = $request; 0736 } 0737 0738 $dom = new DOMDocument(); 0739 try { 0740 if(strlen($xml) == 0 || (!$dom = Zend_Xml_Security::scan($xml, $dom))) { 0741 // require_once 'Zend/Soap/Server/Exception.php'; 0742 throw new Zend_Soap_Server_Exception('Invalid XML'); 0743 } 0744 } catch (Zend_Xml_Exception $e) { 0745 // require_once 'Zend/Soap/Server/Exception.php'; 0746 throw new Zend_Soap_Server_Exception( 0747 $e->getMessage() 0748 ); 0749 } 0750 } 0751 $this->_request = $xml; 0752 return $this; 0753 } 0754 0755 /** 0756 * Retrieve request XML 0757 * 0758 * @return string 0759 */ 0760 public function getLastRequest() 0761 { 0762 return $this->_request; 0763 } 0764 0765 /** 0766 * Set return response flag 0767 * 0768 * If true, {@link handle()} will return the response instead of 0769 * automatically sending it back to the requesting client. 0770 * 0771 * The response is always available via {@link getResponse()}. 0772 * 0773 * @param boolean $flag 0774 * @return Zend_Soap_Server 0775 */ 0776 public function setReturnResponse($flag) 0777 { 0778 $this->_returnResponse = ($flag) ? true : false; 0779 return $this; 0780 } 0781 0782 /** 0783 * Retrieve return response flag 0784 * 0785 * @return boolean 0786 */ 0787 public function getReturnResponse() 0788 { 0789 return $this->_returnResponse; 0790 } 0791 0792 /** 0793 * Get response XML 0794 * 0795 * @return string 0796 */ 0797 public function getLastResponse() 0798 { 0799 return $this->_response; 0800 } 0801 0802 /** 0803 * Get SoapServer object 0804 * 0805 * Uses {@link $_wsdl} and return value of {@link getOptions()} to instantiate 0806 * SoapServer object, and then registers any functions or class with it, as 0807 * well as peristence. 0808 * 0809 * @return SoapServer 0810 */ 0811 protected function _getSoap() 0812 { 0813 $options = $this->getOptions(); 0814 $server = new SoapServer($this->_wsdl, $options); 0815 0816 if (!empty($this->_functions)) { 0817 $server->addFunction($this->_functions); 0818 } 0819 0820 if (!empty($this->_class)) { 0821 $args = $this->_classArgs; 0822 array_unshift($args, $this->_class); 0823 if ($this->_wsiCompliant) { 0824 // require_once 'Zend/Soap/Server/Proxy.php'; 0825 array_unshift($args, 'Zend_Soap_Server_Proxy'); 0826 } 0827 call_user_func_array(array($server, 'setClass'), $args); 0828 } 0829 0830 if (!empty($this->_object)) { 0831 $server->setObject($this->_object); 0832 } 0833 0834 if (null !== $this->_persistence) { 0835 $server->setPersistence($this->_persistence); 0836 } 0837 0838 return $server; 0839 } 0840 0841 /** 0842 * Handle a request 0843 * 0844 * Instantiates SoapServer object with options set in object, and 0845 * dispatches its handle() method. 0846 * 0847 * $request may be any of: 0848 * - DOMDocument; if so, then cast to XML 0849 * - DOMNode; if so, then grab owner document and cast to XML 0850 * - SimpleXMLElement; if so, then cast to XML 0851 * - stdClass; if so, calls __toString() and verifies XML 0852 * - string; if so, verifies XML 0853 * 0854 * If no request is passed, pulls request using php:://input (for 0855 * cross-platform compatability purposes). 0856 * 0857 * @param DOMDocument|DOMNode|SimpleXMLElement|stdClass|string $request Optional request 0858 * @return void|string 0859 */ 0860 public function handle($request = null) 0861 { 0862 if (null === $request) { 0863 $request = file_get_contents('php://input'); 0864 } 0865 0866 // Set Zend_Soap_Server error handler 0867 $displayErrorsOriginalState = $this->_initializeSoapErrorContext(); 0868 0869 $setRequestException = null; 0870 /** 0871 * @see Zend_Soap_Server_Exception 0872 */ 0873 // require_once 'Zend/Soap/Server/Exception.php'; 0874 try { 0875 $this->_setRequest($request); 0876 } catch (Zend_Soap_Server_Exception $e) { 0877 $setRequestException = $e; 0878 } 0879 0880 $soap = $this->_getSoap(); 0881 0882 $fault = false; 0883 ob_start(); 0884 if ($setRequestException instanceof Exception) { 0885 // Create SOAP fault message if we've caught a request exception 0886 $fault = $this->fault($setRequestException->getMessage(), 'Sender'); 0887 } else { 0888 try { 0889 $soap->handle($this->_request); 0890 } catch (Exception $e) { 0891 $fault = $this->fault($e); 0892 } 0893 } 0894 $this->_response = ob_get_clean(); 0895 0896 // Restore original error handler 0897 restore_error_handler(); 0898 ini_set('display_errors', $displayErrorsOriginalState); 0899 0900 // Send a fault, if we have one 0901 if ($fault) { 0902 $soap->fault($fault->faultcode, $fault->faultstring); 0903 } 0904 0905 if (!$this->_returnResponse) { 0906 echo $this->_response; 0907 return; 0908 } 0909 0910 return $this->_response; 0911 } 0912 0913 /** 0914 * Method initalizes the error context that the SOAPServer enviroment will run in. 0915 * 0916 * @return boolean display_errors original value 0917 */ 0918 protected function _initializeSoapErrorContext() 0919 { 0920 $displayErrorsOriginalState = ini_get('display_errors'); 0921 ini_set('display_errors', false); 0922 set_error_handler(array($this, 'handlePhpErrors'), E_USER_ERROR); 0923 return $displayErrorsOriginalState; 0924 } 0925 0926 /** 0927 * Register a valid fault exception 0928 * 0929 * @param string|array $class Exception class or array of exception classes 0930 * @return Zend_Soap_Server 0931 */ 0932 public function registerFaultException($class) 0933 { 0934 $this->_faultExceptions = array_merge($this->_faultExceptions, (array) $class); 0935 return $this; 0936 } 0937 0938 /** 0939 * Deregister a fault exception from the fault exception stack 0940 * 0941 * @param string $class 0942 * @return boolean 0943 */ 0944 public function deregisterFaultException($class) 0945 { 0946 if (in_array($class, $this->_faultExceptions, true)) { 0947 $index = array_search($class, $this->_faultExceptions); 0948 unset($this->_faultExceptions[$index]); 0949 return true; 0950 } 0951 0952 return false; 0953 } 0954 0955 /** 0956 * Return fault exceptions list 0957 * 0958 * @return array 0959 */ 0960 public function getFaultExceptions() 0961 { 0962 return $this->_faultExceptions; 0963 } 0964 0965 /** 0966 * Generate a server fault 0967 * 0968 * Note that the arguments are reverse to those of SoapFault. 0969 * 0970 * If an exception is passed as the first argument, its message and code 0971 * will be used to create the fault object if it has been registered via 0972 * {@Link registerFaultException()}. 0973 * 0974 * @link http://www.w3.org/TR/soap12-part1/#faultcodes 0975 * @param string|Exception $fault 0976 * @param string $code SOAP Fault Codes 0977 * @return SoapFault 0978 */ 0979 public function fault($fault = null, $code = "Receiver") 0980 { 0981 if ($fault instanceof Exception) { 0982 $class = get_class($fault); 0983 if (in_array($class, $this->_faultExceptions)) { 0984 $message = $fault->getMessage(); 0985 $eCode = $fault->getCode(); 0986 $code = empty($eCode) ? $code : $eCode; 0987 } else { 0988 $message = 'Unknown error'; 0989 } 0990 } elseif(is_string($fault)) { 0991 $message = $fault; 0992 } else { 0993 $message = 'Unknown error'; 0994 } 0995 0996 $allowedFaultModes = array( 0997 'VersionMismatch', 'MustUnderstand', 'DataEncodingUnknown', 0998 'Sender', 'Receiver', 'Server' 0999 ); 1000 if(!in_array($code, $allowedFaultModes)) { 1001 $code = "Receiver"; 1002 } 1003 1004 return new SoapFault($code, $message); 1005 } 1006 1007 /** 1008 * Throw PHP errors as SoapFaults 1009 * 1010 * @param int $errno 1011 * @param string $errstr 1012 * @param string $errfile 1013 * @param int $errline 1014 * @param array $errcontext 1015 * @return void 1016 * @throws SoapFault 1017 */ 1018 public function handlePhpErrors($errno, $errstr, $errfile = null, $errline = null, array $errcontext = null) 1019 { 1020 throw $this->fault($errstr, "Receiver"); 1021 } 1022 }