[ Index ]

PHP Cross Reference of moodle-2.8

title

Body

[close]

/lib/zend/Zend/Soap/ -> Wsdl.php (source)

   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  }


Generated: Fri Nov 28 20:29:05 2014 Cross-referenced by PHPXref 0.7.1