|
Moodle
2.2.1
http://www.collinsharper.com
|
00001 <?php 00026 require_once 'Zend/Server/Interface.php'; 00030 require_once 'Zend/Soap/Wsdl.php'; 00034 require_once 'Zend/Server/Reflection.php'; 00038 require_once 'Zend/Server/Abstract.php'; 00042 require_once 'Zend/Uri.php'; 00043 00051 class Zend_Soap_AutoDiscover implements Zend_Server_Interface 00052 { 00056 protected $_wsdl = null; 00057 00061 protected $_reflection = null; 00062 00066 protected $_functions = array(); 00067 00071 protected $_strategy; 00072 00078 protected $_uri; 00079 00085 protected $_operationBodyStyle = array('use' => 'encoded', 'encodingStyle' => "http://schemas.xmlsoap.org/soap/encoding/"); 00086 00092 protected $_bindingStyle = array('style' => 'rpc', 'transport' => 'http://schemas.xmlsoap.org/soap/http'); 00093 00100 public function __construct($strategy = true, $uri=null) 00101 { 00102 $this->_reflection = new Zend_Server_Reflection(); 00103 $this->setComplexTypeStrategy($strategy); 00104 00105 if($uri !== null) { 00106 $this->setUri($uri); 00107 } 00108 } 00109 00118 public function setUri($uri) 00119 { 00120 if(!is_string($uri) && !($uri instanceof Zend_Uri)) { 00121 require_once "Zend/Soap/AutoDiscover/Exception.php"; 00122 throw new Zend_Soap_AutoDiscover_Exception("No uri given to Zend_Soap_AutoDiscover::setUri as string or Zend_Uri instance."); 00123 } 00124 $this->_uri = $uri; 00125 00126 // change uri in WSDL file also if existant 00127 if($this->_wsdl instanceof Zend_Soap_Wsdl) { 00128 $this->_wsdl->setUri($uri); 00129 } 00130 00131 return $this; 00132 } 00133 00139 public function getUri() 00140 { 00141 if($this->_uri !== null) { 00142 $uri = $this->_uri; 00143 } else { 00144 $schema = $this->getSchema(); 00145 $host = $this->getHostName(); 00146 $scriptName = $this->getRequestUriWithoutParameters(); 00147 $uri = Zend_Uri::factory($schema . '://' . $host . $scriptName); 00148 $this->setUri($uri); 00149 } 00150 return $uri; 00151 } 00152 00163 public function setOperationBodyStyle(array $operationStyle=array()) 00164 { 00165 if(!isset($operationStyle['use'])) { 00166 require_once "Zend/Soap/AutoDiscover/Exception.php"; 00167 throw new Zend_Soap_AutoDiscover_Exception("Key 'use' is required in Operation soap:body style."); 00168 } 00169 $this->_operationBodyStyle = $operationStyle; 00170 return $this; 00171 } 00172 00181 public function setBindingStyle(array $bindingStyle=array()) 00182 { 00183 if(isset($bindingStyle['style'])) { 00184 $this->_bindingStyle['style'] = $bindingStyle['style']; 00185 } 00186 if(isset($bindingStyle['transport'])) { 00187 $this->_bindingStyle['transport'] = $bindingStyle['transport']; 00188 } 00189 return $this; 00190 } 00191 00197 protected function getSchema() 00198 { 00199 $schema = "http"; 00200 if (isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] == 'on') { 00201 $schema = 'https'; 00202 } 00203 return $schema; 00204 } 00205 00211 protected function getHostName() 00212 { 00213 if(isset($_SERVER['HTTP_HOST'])) { 00214 $host = $_SERVER['HTTP_HOST']; 00215 } else { 00216 $host = $_SERVER['SERVER_NAME']; 00217 } 00218 return $host; 00219 } 00220 00226 protected function getRequestUriWithoutParameters() 00227 { 00228 if (isset($_SERVER['HTTP_X_REWRITE_URL'])) { // check this first so IIS will catch 00229 $requestUri = $_SERVER['HTTP_X_REWRITE_URL']; 00230 } elseif (isset($_SERVER['REQUEST_URI'])) { 00231 $requestUri = $_SERVER['REQUEST_URI']; 00232 } elseif (isset($_SERVER['ORIG_PATH_INFO'])) { // IIS 5.0, PHP as CGI 00233 $requestUri = $_SERVER['ORIG_PATH_INFO']; 00234 } else { 00235 $requestUri = $_SERVER['SCRIPT_NAME']; 00236 } 00237 if( ($pos = strpos($requestUri, "?")) !== false) { 00238 $requestUri = substr($requestUri, 0, $pos); 00239 } 00240 00241 return $requestUri; 00242 } 00243 00250 public function setComplexTypeStrategy($strategy) 00251 { 00252 $this->_strategy = $strategy; 00253 if($this->_wsdl instanceof Zend_Soap_Wsdl) { 00254 $this->_wsdl->setComplexTypeStrategy($strategy); 00255 } 00256 00257 return $this; 00258 } 00259 00267 public function setClass($class, $namespace = '', $argv = null) 00268 { 00269 $uri = $this->getUri(); 00270 00271 $wsdl = new Zend_Soap_Wsdl($class, $uri, $this->_strategy); 00272 00273 // The wsdl:types element must precede all other elements (WS-I Basic Profile 1.1 R2023) 00274 $wsdl->addSchemaTypeSection(); 00275 00276 $port = $wsdl->addPortType($class . 'Port'); 00277 $binding = $wsdl->addBinding($class . 'Binding', 'tns:' .$class. 'Port'); 00278 00279 $wsdl->addSoapBinding($binding, $this->_bindingStyle['style'], $this->_bindingStyle['transport']); 00280 $wsdl->addService($class . 'Service', $class . 'Port', 'tns:' . $class . 'Binding', $uri); 00281 foreach ($this->_reflection->reflectClass($class)->getMethods() as $method) { 00282 $this->_addFunctionToWsdl($method, $wsdl, $port, $binding); 00283 } 00284 $this->_wsdl = $wsdl; 00285 } 00286 00293 public function addFunction($function, $namespace = '') 00294 { 00295 static $port; 00296 static $operation; 00297 static $binding; 00298 00299 if (!is_array($function)) { 00300 $function = (array) $function; 00301 } 00302 00303 $uri = $this->getUri(); 00304 00305 if (!($this->_wsdl instanceof Zend_Soap_Wsdl)) { 00306 $parts = explode('.', basename($_SERVER['SCRIPT_NAME'])); 00307 $name = $parts[0]; 00308 $wsdl = new Zend_Soap_Wsdl($name, $uri, $this->_strategy); 00309 00310 // The wsdl:types element must precede all other elements (WS-I Basic Profile 1.1 R2023) 00311 $wsdl->addSchemaTypeSection(); 00312 00313 $port = $wsdl->addPortType($name . 'Port'); 00314 $binding = $wsdl->addBinding($name . 'Binding', 'tns:' .$name. 'Port'); 00315 00316 $wsdl->addSoapBinding($binding, $this->_bindingStyle['style'], $this->_bindingStyle['transport']); 00317 $wsdl->addService($name . 'Service', $name . 'Port', 'tns:' . $name . 'Binding', $uri); 00318 } else { 00319 $wsdl = $this->_wsdl; 00320 } 00321 00322 foreach ($function as $func) { 00323 $method = $this->_reflection->reflectFunction($func); 00324 $this->_addFunctionToWsdl($method, $wsdl, $port, $binding); 00325 } 00326 $this->_wsdl = $wsdl; 00327 } 00328 00338 protected function _addFunctionToWsdl($function, $wsdl, $port, $binding) 00339 { 00340 $uri = $this->getUri(); 00341 00342 // We only support one prototype: the one with the maximum number of arguments 00343 $prototype = null; 00344 $maxNumArgumentsOfPrototype = -1; 00345 foreach ($function->getPrototypes() as $tmpPrototype) { 00346 $numParams = count($tmpPrototype->getParameters()); 00347 if ($numParams > $maxNumArgumentsOfPrototype) { 00348 $maxNumArgumentsOfPrototype = $numParams; 00349 $prototype = $tmpPrototype; 00350 } 00351 } 00352 if ($prototype === null) { 00353 require_once "Zend/Soap/AutoDiscover/Exception.php"; 00354 throw new Zend_Soap_AutoDiscover_Exception("No prototypes could be found for the '" . $function->getName() . "' function"); 00355 } 00356 00357 // Add the input message (parameters) 00358 $args = array(); 00359 if ($this->_bindingStyle['style'] == 'document') { 00360 // Document style: wrap all parameters in a sequence element 00361 $sequence = array(); 00362 foreach ($prototype->getParameters() as $param) { 00363 $sequenceElement = array( 00364 'name' => $param->getName(), 00365 'type' => $wsdl->getType($param->getType()) 00366 ); 00367 if ($param->isOptional()) { 00368 $sequenceElement['nillable'] = 'true'; 00369 } 00370 $sequence[] = $sequenceElement; 00371 } 00372 $element = array( 00373 'name' => $function->getName(), 00374 'sequence' => $sequence 00375 ); 00376 // Add the wrapper element part, which must be named 'parameters' 00377 $args['parameters'] = array('element' => $wsdl->addElement($element)); 00378 } else { 00379 // RPC style: add each parameter as a typed part 00380 foreach ($prototype->getParameters() as $param) { 00381 $args[$param->getName()] = array('type' => $wsdl->getType($param->getType())); 00382 } 00383 } 00384 $wsdl->addMessage($function->getName() . 'In', $args); 00385 00386 $isOneWayMessage = false; 00387 if($prototype->getReturnType() == "void") { 00388 $isOneWayMessage = true; 00389 } 00390 00391 if($isOneWayMessage == false) { 00392 // Add the output message (return value) 00393 $args = array(); 00394 if ($this->_bindingStyle['style'] == 'document') { 00395 // Document style: wrap the return value in a sequence element 00396 $sequence = array(); 00397 if ($prototype->getReturnType() != "void") { 00398 $sequence[] = array( 00399 'name' => $function->getName() . 'Result', 00400 'type' => $wsdl->getType($prototype->getReturnType()) 00401 ); 00402 } 00403 $element = array( 00404 'name' => $function->getName() . 'Response', 00405 'sequence' => $sequence 00406 ); 00407 // Add the wrapper element part, which must be named 'parameters' 00408 $args['parameters'] = array('element' => $wsdl->addElement($element)); 00409 } else if ($prototype->getReturnType() != "void") { 00410 // RPC style: add the return value as a typed part 00411 $args['return'] = array('type' => $wsdl->getType($prototype->getReturnType())); 00412 } 00413 $wsdl->addMessage($function->getName() . 'Out', $args); 00414 } 00415 00416 // Add the portType operation 00417 if($isOneWayMessage == false) { 00418 $portOperation = $wsdl->addPortOperation($port, $function->getName(), 'tns:' . $function->getName() . 'In', 'tns:' . $function->getName() . 'Out'); 00419 } else { 00420 $portOperation = $wsdl->addPortOperation($port, $function->getName(), 'tns:' . $function->getName() . 'In', false); 00421 } 00422 $desc = $function->getDescription(); 00423 if (strlen($desc) > 0) { 00424 $wsdl->addDocumentation($portOperation, $desc); 00425 } 00426 00427 // When using the RPC style, make sure the operation style includes a 'namespace' attribute (WS-I Basic Profile 1.1 R2717) 00428 if ($this->_bindingStyle['style'] == 'rpc' && !isset($this->_operationBodyStyle['namespace'])) { 00429 $this->_operationBodyStyle['namespace'] = ''.$uri; 00430 } 00431 00432 // Add the binding operation 00433 $operation = $wsdl->addBindingOperation($binding, $function->getName(), $this->_operationBodyStyle, $this->_operationBodyStyle); 00434 $wsdl->addSoapOperation($operation, $uri . '#' .$function->getName()); 00435 00436 // Add the function name to the list 00437 $this->_functions[] = $function->getName(); 00438 } 00439 00446 public function fault($fault = null, $code = null) 00447 { 00448 require_once "Zend/Soap/AutoDiscover/Exception.php"; 00449 throw new Zend_Soap_AutoDiscover_Exception("Function has no use in AutoDiscover."); 00450 } 00451 00457 public function handle($request = false) 00458 { 00459 if (!headers_sent()) { 00460 header('Content-Type: text/xml'); 00461 } 00462 $this->_wsdl->dump(); 00463 } 00464 00470 public function dump($filename) 00471 { 00472 if($this->_wsdl !== null) { 00473 return $this->_wsdl->dump($filename); 00474 } else { 00478 require_once "Zend/Soap/AutoDiscover/Exception.php"; 00479 throw new Zend_Soap_AutoDiscover_Exception("Cannot dump autodiscovered contents, WSDL file has not been generated yet."); 00480 } 00481 } 00482 00486 public function toXml() 00487 { 00488 if($this->_wsdl !== null) { 00489 return $this->_wsdl->toXml(); 00490 } else { 00494 require_once "Zend/Soap/AutoDiscover/Exception.php"; 00495 throw new Zend_Soap_AutoDiscover_Exception("Cannot return autodiscovered contents, WSDL file has not been generated yet."); 00496 } 00497 } 00498 00504 public function getFunctions() 00505 { 00506 return $this->_functions; 00507 } 00508 00514 public function loadFunctions($definition) 00515 { 00516 require_once "Zend/Soap/AutoDiscover/Exception.php"; 00517 throw new Zend_Soap_AutoDiscover_Exception("Function has no use in AutoDiscover."); 00518 } 00519 00525 public function setPersistence($mode) 00526 { 00527 require_once "Zend/Soap/AutoDiscover/Exception.php"; 00528 throw new Zend_Soap_AutoDiscover_Exception("Function has no use in AutoDiscover."); 00529 } 00530 00537 public function getType($type) 00538 { 00539 if (!($this->_wsdl instanceof Zend_Soap_Wsdl)) { 00542 // WSDL is not defined yet, so we can't recognize type in context of current service 00543 return ''; 00544 } else { 00545 return $this->_wsdl->getType($type); 00546 } 00547 } 00548 }