[ Index ] |
PHP Cross Reference of moodle-2.8 |
[Summary view] [Print] [Text view]
1 <?php 2 /** 3 * Zend Framework 4 * 5 * LICENSE 6 * 7 * This source file is subject to the new BSD license that is bundled 8 * with this package in the file LICENSE.txt. 9 * It is also available through the world-wide-web at this URL: 10 * http://framework.zend.com/license/new-bsd 11 * If you did not receive a copy of the license and are unable to 12 * obtain it through the world-wide-web, please send an email 13 * to [email protected] so we can send you a copy immediately. 14 * 15 * @category Zend 16 * @package Zend_Soap 17 * @copyright Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com) 18 * @license http://framework.zend.com/license/new-bsd New BSD License 19 * @version $Id$ 20 */ 21 22 /** 23 * @see Zend_Soap_Wsdl_Strategy_Interface 24 */ 25 require_once "Zend/Soap/Wsdl/Strategy/Interface.php"; 26 27 /** 28 * @see Zend_Soap_Wsdl_Strategy_Abstract 29 */ 30 require_once "Zend/Soap/Wsdl/Strategy/Abstract.php"; 31 32 /** 33 * Zend_Soap_Wsdl 34 * 35 * @category Zend 36 * @package Zend_Soap 37 */ 38 class Zend_Soap_Wsdl 39 { 40 /** 41 * @var object DomDocument Instance 42 */ 43 private $_dom; 44 45 /** 46 * @var object WSDL Root XML_Tree_Node 47 */ 48 private $_wsdl; 49 50 /** 51 * @var string URI where the WSDL will be available 52 */ 53 private $_uri; 54 55 /** 56 * @var DOMElement 57 */ 58 private $_schema = null; 59 60 /** 61 * Types defined on schema 62 * 63 * @var array 64 */ 65 private $_includedTypes = array(); 66 67 /** 68 * Strategy for detection of complex types 69 */ 70 protected $_strategy = null; 71 72 73 /** 74 * Constructor 75 * 76 * @param string $name Name of the Web Service being Described 77 * @param string $uri URI where the WSDL will be available 78 * @param boolean|string|Zend_Soap_Wsdl_Strategy_Interface $strategy 79 */ 80 public function __construct($name, $uri, $strategy = true) 81 { 82 if ($uri instanceof Zend_Uri_Http) { 83 $uri = $uri->getUri(); 84 } 85 $this->_uri = $uri; 86 87 /** 88 * @todo change DomDocument object creation from cparsing to construxting using API 89 * It also should authomatically escape $name and $uri values if necessary 90 */ 91 $wsdl = "<?xml version='1.0' ?> 92 <definitions name='$name' targetNamespace='$uri' 93 xmlns='http://schemas.xmlsoap.org/wsdl/' 94 xmlns:tns='$uri' 95 xmlns:soap='http://schemas.xmlsoap.org/wsdl/soap/' 96 xmlns:xsd='http://www.w3.org/2001/XMLSchema' 97 xmlns:soap-enc='http://schemas.xmlsoap.org/soap/encoding/' 98 xmlns:wsdl='http://schemas.xmlsoap.org/wsdl/'></definitions>"; 99 $this->_dom = new DOMDocument(); 100 if (!$this->_dom->loadXML($wsdl)) { 101 require_once 'Zend/Server/Exception.php'; 102 throw new Zend_Server_Exception('Unable to create DomDocument'); 103 } else { 104 $this->_wsdl = $this->_dom->documentElement; 105 } 106 107 $this->setComplexTypeStrategy($strategy); 108 } 109 110 /** 111 * Set a new uri for this WSDL 112 * 113 * @param string|Zend_Uri_Http $uri 114 * @return Zend_Server_Wsdl 115 */ 116 public function setUri($uri) 117 { 118 if ($uri instanceof Zend_Uri_Http) { 119 $uri = $uri->getUri(); 120 } 121 $oldUri = $this->_uri; 122 $this->_uri = $uri; 123 124 if($this->_dom !== null) { 125 // @todo: This is the worst hack ever, but its needed due to design and non BC issues of WSDL generation 126 $xml = $this->_dom->saveXML(); 127 $xml = str_replace($oldUri, $uri, $xml); 128 $this->_dom = new DOMDocument(); 129 $this->_dom->loadXML($xml); 130 } 131 132 return $this; 133 } 134 135 /** 136 * Set a strategy for complex type detection and handling 137 * 138 * @todo Boolean is for backwards compability with extractComplexType object var. Remove it in later versions. 139 * @param boolean|string|Zend_Soap_Wsdl_Strategy_Interface $strategy 140 * @return Zend_Soap_Wsdl 141 */ 142 public function setComplexTypeStrategy($strategy) 143 { 144 if($strategy === true) { 145 require_once "Zend/Soap/Wsdl/Strategy/DefaultComplexType.php"; 146 $strategy = new Zend_Soap_Wsdl_Strategy_DefaultComplexType(); 147 } else if($strategy === false) { 148 require_once "Zend/Soap/Wsdl/Strategy/AnyType.php"; 149 $strategy = new Zend_Soap_Wsdl_Strategy_AnyType(); 150 } else if(is_string($strategy)) { 151 if(class_exists($strategy)) { 152 $strategy = new $strategy(); 153 } else { 154 require_once "Zend/Soap/Wsdl/Exception.php"; 155 throw new Zend_Soap_Wsdl_Exception( 156 sprintf("Strategy with name '%s does not exist.", $strategy 157 )); 158 } 159 } 160 161 if(!($strategy instanceof Zend_Soap_Wsdl_Strategy_Interface)) { 162 require_once "Zend/Soap/Wsdl/Exception.php"; 163 throw new Zend_Soap_Wsdl_Exception("Set a strategy that is not of type 'Zend_Soap_Wsdl_Strategy_Interface'"); 164 } 165 $this->_strategy = $strategy; 166 return $this; 167 } 168 169 /** 170 * Get the current complex type strategy 171 * 172 * @return Zend_Soap_Wsdl_Strategy_Interface 173 */ 174 public function getComplexTypeStrategy() 175 { 176 return $this->_strategy; 177 } 178 179 /** 180 * Add a {@link http://www.w3.org/TR/wsdl#_messages message} element to the WSDL 181 * 182 * @param string $name Name for the {@link http://www.w3.org/TR/wsdl#_messages message} 183 * @param array $parts An array of {@link http://www.w3.org/TR/wsdl#_message parts} 184 * The array is constructed like: 'name of part' => 'part xml schema data type' 185 * or 'name of part' => array('type' => 'part xml schema type') 186 * or 'name of part' => array('element' => 'part xml element name') 187 * @return object The new message's XML_Tree_Node for use in {@link function addDocumentation} 188 */ 189 public function addMessage($name, $parts) 190 { 191 $message = $this->_dom->createElement('message'); 192 193 $message->setAttribute('name', $name); 194 195 if (sizeof($parts) > 0) { 196 foreach ($parts as $name => $type) { 197 $part = $this->_dom->createElement('part'); 198 $part->setAttribute('name', $name); 199 if (is_array($type)) { 200 foreach ($type as $key => $value) { 201 $part->setAttribute($key, $value); 202 } 203 } else { 204 $part->setAttribute('type', $type); 205 } 206 $message->appendChild($part); 207 } 208 } 209 210 $this->_wsdl->appendChild($message); 211 212 return $message; 213 } 214 215 /** 216 * Add a {@link http://www.w3.org/TR/wsdl#_porttypes portType} element to the WSDL 217 * 218 * @param string $name portType element's name 219 * @return object The new portType's XML_Tree_Node for use in {@link function addPortOperation} and {@link function addDocumentation} 220 */ 221 public function addPortType($name) 222 { 223 $portType = $this->_dom->createElement('portType'); 224 $portType->setAttribute('name', $name); 225 $this->_wsdl->appendChild($portType); 226 227 return $portType; 228 } 229 230 /** 231 * Add an {@link http://www.w3.org/TR/wsdl#_request-response operation} element to a portType element 232 * 233 * @param object $portType a portType XML_Tree_Node, from {@link function addPortType} 234 * @param string $name Operation name 235 * @param string $input Input Message 236 * @param string $output Output Message 237 * @param string $fault Fault Message 238 * @return object The new operation's XML_Tree_Node for use in {@link function addDocumentation} 239 */ 240 public function addPortOperation($portType, $name, $input = false, $output = false, $fault = false) 241 { 242 $operation = $this->_dom->createElement('operation'); 243 $operation->setAttribute('name', $name); 244 245 if (is_string($input) && (strlen(trim($input)) >= 1)) { 246 $node = $this->_dom->createElement('input'); 247 $node->setAttribute('message', $input); 248 $operation->appendChild($node); 249 } 250 if (is_string($output) && (strlen(trim($output)) >= 1)) { 251 $node= $this->_dom->createElement('output'); 252 $node->setAttribute('message', $output); 253 $operation->appendChild($node); 254 } 255 if (is_string($fault) && (strlen(trim($fault)) >= 1)) { 256 $node = $this->_dom->createElement('fault'); 257 $node->setAttribute('message', $fault); 258 $operation->appendChild($node); 259 } 260 261 $portType->appendChild($operation); 262 263 return $operation; 264 } 265 266 /** 267 * Add a {@link http://www.w3.org/TR/wsdl#_bindings binding} element to WSDL 268 * 269 * @param string $name Name of the Binding 270 * @param string $type name of the portType to bind 271 * @return object The new binding's XML_Tree_Node for use with {@link function addBindingOperation} and {@link function addDocumentation} 272 */ 273 public function addBinding($name, $portType) 274 { 275 $binding = $this->_dom->createElement('binding'); 276 $binding->setAttribute('name', $name); 277 $binding->setAttribute('type', $portType); 278 279 $this->_wsdl->appendChild($binding); 280 281 return $binding; 282 } 283 284 /** 285 * Add an operation to a binding element 286 * 287 * @param object $binding A binding XML_Tree_Node returned by {@link function addBinding} 288 * @param array $input An array of attributes for the input element, allowed keys are: 'use', 'namespace', 'encodingStyle'. {@link http://www.w3.org/TR/wsdl#_soap:body More Information} 289 * @param array $output An array of attributes for the output element, allowed keys are: 'use', 'namespace', 'encodingStyle'. {@link http://www.w3.org/TR/wsdl#_soap:body More Information} 290 * @param array $fault An array of attributes for the fault element, allowed keys are: 'name', 'use', 'namespace', 'encodingStyle'. {@link http://www.w3.org/TR/wsdl#_soap:body More Information} 291 * @return object The new Operation's XML_Tree_Node for use with {@link function addSoapOperation} and {@link function addDocumentation} 292 */ 293 public function addBindingOperation($binding, $name, $input = false, $output = false, $fault = false) 294 { 295 $operation = $this->_dom->createElement('operation'); 296 $operation->setAttribute('name', $name); 297 298 if (is_array($input)) { 299 $node = $this->_dom->createElement('input'); 300 $soap_node = $this->_dom->createElement('soap:body'); 301 foreach ($input as $name => $value) { 302 $soap_node->setAttribute($name, $value); 303 } 304 $node->appendChild($soap_node); 305 $operation->appendChild($node); 306 } 307 308 if (is_array($output)) { 309 $node = $this->_dom->createElement('output'); 310 $soap_node = $this->_dom->createElement('soap:body'); 311 foreach ($output as $name => $value) { 312 $soap_node->setAttribute($name, $value); 313 } 314 $node->appendChild($soap_node); 315 $operation->appendChild($node); 316 } 317 318 if (is_array($fault)) { 319 $node = $this->_dom->createElement('fault'); 320 if (isset($fault['name'])) { 321 $node->setAttribute('name', $fault['name']); 322 } 323 $soap_node = $this->_dom->createElement('soap:body'); 324 foreach ($output as $name => $value) { 325 $soap_node->setAttribute($name, $value); 326 } 327 $node->appendChild($soap_node); 328 $operation->appendChild($node); 329 } 330 331 $binding->appendChild($operation); 332 333 return $operation; 334 } 335 336 /** 337 * Add a {@link http://www.w3.org/TR/wsdl#_soap:binding SOAP binding} element to a Binding element 338 * 339 * @param object $binding A binding XML_Tree_Node returned by {@link function addBinding} 340 * @param string $style binding style, possible values are "rpc" (the default) and "document" 341 * @param string $transport Transport method (defaults to HTTP) 342 * @return boolean 343 */ 344 public function addSoapBinding($binding, $style = 'document', $transport = 'http://schemas.xmlsoap.org/soap/http') 345 { 346 $soap_binding = $this->_dom->createElement('soap:binding'); 347 $soap_binding->setAttribute('style', $style); 348 $soap_binding->setAttribute('transport', $transport); 349 350 $binding->appendChild($soap_binding); 351 352 return $soap_binding; 353 } 354 355 /** 356 * Add a {@link http://www.w3.org/TR/wsdl#_soap:operation SOAP operation} to an operation element 357 * 358 * @param object $operation An operation XML_Tree_Node returned by {@link function addBindingOperation} 359 * @param string $soap_action SOAP Action 360 * @return boolean 361 */ 362 public function addSoapOperation($binding, $soap_action) 363 { 364 if ($soap_action instanceof Zend_Uri_Http) { 365 $soap_action = $soap_action->getUri(); 366 } 367 $soap_operation = $this->_dom->createElement('soap:operation'); 368 $soap_operation->setAttribute('soapAction', $soap_action); 369 370 $binding->insertBefore($soap_operation, $binding->firstChild); 371 372 return $soap_operation; 373 } 374 375 /** 376 * Add a {@link http://www.w3.org/TR/wsdl#_services service} element to the WSDL 377 * 378 * @param string $name Service Name 379 * @param string $port_name Name of the port for the service 380 * @param string $binding Binding for the port 381 * @param string $location SOAP Address for the service 382 * @return object The new service's XML_Tree_Node for use with {@link function addDocumentation} 383 */ 384 public function addService($name, $port_name, $binding, $location) 385 { 386 if ($location instanceof Zend_Uri_Http) { 387 $location = $location->getUri(); 388 } 389 $service = $this->_dom->createElement('service'); 390 $service->setAttribute('name', $name); 391 392 $port = $this->_dom->createElement('port'); 393 $port->setAttribute('name', $port_name); 394 $port->setAttribute('binding', $binding); 395 396 $soap_address = $this->_dom->createElement('soap:address'); 397 $soap_address->setAttribute('location', $location); 398 399 $port->appendChild($soap_address); 400 $service->appendChild($port); 401 402 $this->_wsdl->appendChild($service); 403 404 return $service; 405 } 406 407 /** 408 * Add a documentation element to any element in the WSDL. 409 * 410 * Note that the WSDL {@link http://www.w3.org/TR/wsdl#_documentation specification} uses 'document', 411 * but the WSDL {@link http://schemas.xmlsoap.org/wsdl/ schema} uses 'documentation' instead. 412 * The {@link http://www.ws-i.org/Profiles/BasicProfile-1.1-2004-08-24.html#WSDL_documentation_Element WS-I Basic Profile 1.1} recommends using 'documentation'. 413 * 414 * @param object $input_node An XML_Tree_Node returned by another method to add the documentation to 415 * @param string $documentation Human readable documentation for the node 416 * @return DOMElement The documentation element 417 */ 418 public function addDocumentation($input_node, $documentation) 419 { 420 if ($input_node === $this) { 421 $node = $this->_dom->documentElement; 422 } else { 423 $node = $input_node; 424 } 425 426 $doc = $this->_dom->createElement('documentation'); 427 $doc_cdata = $this->_dom->createTextNode($documentation); 428 $doc->appendChild($doc_cdata); 429 430 if($node->hasChildNodes()) { 431 $node->insertBefore($doc, $node->firstChild); 432 } else { 433 $node->appendChild($doc); 434 } 435 436 return $doc; 437 } 438 439 /** 440 * Add WSDL Types element 441 * 442 * @param object $types A DomDocument|DomNode|DomElement|DomDocumentFragment with all the XML Schema types defined in it 443 */ 444 public function addTypes($types) 445 { 446 if ($types instanceof DomDocument) { 447 $dom = $this->_dom->importNode($types->documentElement); 448 $this->_wsdl->appendChild($types->documentElement); 449 } elseif ($types instanceof DomNode || $types instanceof DomElement || $types instanceof DomDocumentFragment ) { 450 $dom = $this->_dom->importNode($types); 451 $this->_wsdl->appendChild($dom); 452 } 453 } 454 455 /** 456 * Add a complex type name that is part of this WSDL and can be used in signatures. 457 * 458 * @param string $type 459 * @return Zend_Soap_Wsdl 460 */ 461 public function addType($type) 462 { 463 if(!in_array($type, $this->_includedTypes)) { 464 $this->_includedTypes[] = $type; 465 } 466 return $this; 467 } 468 469 /** 470 * Return an array of all currently included complex types 471 * 472 * @return array 473 */ 474 public function getTypes() 475 { 476 return $this->_includedTypes; 477 } 478 479 /** 480 * Return the Schema node of the WSDL 481 * 482 * @return DOMElement 483 */ 484 public function getSchema() 485 { 486 if($this->_schema == null) { 487 $this->addSchemaTypeSection(); 488 } 489 490 return $this->_schema; 491 } 492 493 /** 494 * Return the WSDL as XML 495 * 496 * @return string WSDL as XML 497 */ 498 public function toXML() 499 { 500 return $this->_dom->saveXML(); 501 } 502 503 /** 504 * Return DOM Document 505 * 506 * @return object DomDocum ent 507 */ 508 public function toDomDocument() 509 { 510 return $this->_dom; 511 } 512 513 /** 514 * Echo the WSDL as XML 515 * 516 * @return boolean 517 */ 518 public function dump($filename = false) 519 { 520 if (!$filename) { 521 echo $this->toXML(); 522 return true; 523 } else { 524 return file_put_contents($filename, $this->toXML()); 525 } 526 } 527 528 /** 529 * Returns an XSD Type for the given PHP type 530 * 531 * @param string $type PHP Type to get the XSD type for 532 * @return string 533 */ 534 public function getType($type) 535 { 536 switch (strtolower($type)) { 537 case 'string': 538 case 'str': 539 return 'xsd:string'; 540 break; 541 case 'int': 542 case 'integer': 543 return 'xsd:int'; 544 break; 545 case 'float': 546 case 'double': 547 return 'xsd:float'; 548 break; 549 case 'boolean': 550 case 'bool': 551 return 'xsd:boolean'; 552 break; 553 case 'array': 554 return 'soap-enc:Array'; 555 break; 556 case 'object': 557 return 'xsd:struct'; 558 break; 559 case 'mixed': 560 return 'xsd:anyType'; 561 break; 562 case 'void': 563 return ''; 564 default: 565 // delegate retrieval of complex type to current strategy 566 return $this->addComplexType($type); 567 } 568 } 569 570 /** 571 * This function makes sure a complex types section and schema additions are set. 572 * 573 * @return Zend_Soap_Wsdl 574 */ 575 public function addSchemaTypeSection() 576 { 577 if ($this->_schema === null) { 578 $this->_schema = $this->_dom->createElement('xsd:schema'); 579 $this->_schema->setAttribute('targetNamespace', $this->_uri); 580 $types = $this->_dom->createElement('types'); 581 $types->appendChild($this->_schema); 582 $this->_wsdl->appendChild($types); 583 } 584 return $this; 585 } 586 587 /** 588 * Add a {@link http://www.w3.org/TR/wsdl#_types types} data type definition 589 * 590 * @param string $type Name of the class to be specified 591 * @return string XSD Type for the given PHP type 592 */ 593 public function addComplexType($type) 594 { 595 if (in_array($type, $this->getTypes())) { 596 return "tns:$type"; 597 } 598 $this->addSchemaTypeSection(); 599 600 $strategy = $this->getComplexTypeStrategy(); 601 $strategy->setContext($this); 602 // delegates the detection of a complex type to the current strategy 603 return $strategy->addComplexType($type); 604 } 605 606 /** 607 * Parse an xsd:element represented as an array into a DOMElement. 608 * 609 * @param array $element an xsd:element represented as an array 610 * @return DOMElement parsed element 611 */ 612 private function _parseElement($element) 613 { 614 if (!is_array($element)) { 615 require_once "Zend/Soap/Wsdl/Exception.php"; 616 throw new Zend_Soap_Wsdl_Exception("The 'element' parameter needs to be an associative array."); 617 } 618 619 $elementXml = $this->_dom->createElement('xsd:element'); 620 foreach ($element as $key => $value) { 621 if (in_array($key, array('sequence', 'all', 'choice'))) { 622 if (is_array($value)) { 623 $complexType = $this->_dom->createElement('xsd:complexType'); 624 if (count($value) > 0) { 625 $container = $this->_dom->createElement('xsd:' . $key); 626 foreach ($value as $subelement) { 627 $subelementXml = $this->_parseElement($subelement); 628 $container->appendChild($subelementXml); 629 } 630 $complexType->appendChild($container); 631 } 632 $elementXml->appendChild($complexType); 633 } 634 } else { 635 $elementXml->setAttribute($key, $value); 636 } 637 } 638 return $elementXml; 639 } 640 641 /** 642 * Add an xsd:element represented as an array to the schema. 643 * 644 * Array keys represent attribute names and values their respective value. 645 * The 'sequence', 'all' and 'choice' keys must have an array of elements as their value, 646 * to add them to a nested complexType. 647 * 648 * Example: array( 'name' => 'MyElement', 649 * 'sequence' => array( array('name' => 'myString', 'type' => 'string'), 650 * array('name' => 'myInteger', 'type' => 'int') ) ); 651 * Resulting XML: <xsd:element name="MyElement"><xsd:complexType><xsd:sequence> 652 * <xsd:element name="myString" type="string"/> 653 * <xsd:element name="myInteger" type="int"/> 654 * </xsd:sequence></xsd:complexType></xsd:element> 655 * 656 * @param array $element an xsd:element represented as an array 657 * @return string xsd:element for the given element array 658 */ 659 public function addElement($element) 660 { 661 $schema = $this->getSchema(); 662 $elementXml = $this->_parseElement($element); 663 $schema->appendChild($elementXml); 664 return 'tns:' . $element['name']; 665 } 666 }
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 |