[ Index ]
 

Code source de CMS made simple 1.0.5

Accédez au Source d'autres logiciels libresSoutenez Angelica Josefina !

title

Body

[fermer]

/modules/nuSOAP/classes/ -> class.wsdl.php (source)

   1  <?php
   2  
   3  
   4  
   5  
   6  /**

   7  * parses a WSDL file, allows access to it's data, other utility methods

   8  * 

   9  * @author   Dietrich Ayala <dietrich@ganx4.com>

  10  * @version  $Id: class.wsdl.php,v 1.56 2005/08/04 01:27:42 snichol Exp $

  11  * @access public 

  12  */
  13  class wsdl extends nusoap_base {
  14      // URL or filename of the root of this WSDL

  15      var $wsdl; 
  16      // define internal arrays of bindings, ports, operations, messages, etc.

  17      var $schemas = array();
  18      var $currentSchema;
  19      var $message = array();
  20      var $complexTypes = array();
  21      var $messages = array();
  22      var $currentMessage;
  23      var $currentOperation;
  24      var $portTypes = array();
  25      var $currentPortType;
  26      var $bindings = array();
  27      var $currentBinding;
  28      var $ports = array();
  29      var $currentPort;
  30      var $opData = array();
  31      var $status = '';
  32      var $documentation = false;
  33      var $endpoint = ''; 
  34      // array of wsdl docs to import

  35      var $import = array(); 
  36      // parser vars

  37      var $parser;
  38      var $position = 0;
  39      var $depth = 0;
  40      var $depth_array = array();
  41      // for getting wsdl

  42      var $proxyhost = '';
  43      var $proxyport = '';
  44      var $proxyusername = '';
  45      var $proxypassword = '';
  46      var $timeout = 0;
  47      var $response_timeout = 30;
  48  
  49      /**

  50       * constructor

  51       * 

  52       * @param string $wsdl WSDL document URL

  53       * @param string $proxyhost

  54       * @param string $proxyport

  55       * @param string $proxyusername

  56       * @param string $proxypassword

  57       * @param integer $timeout set the connection timeout

  58       * @param integer $response_timeout set the response timeout

  59       * @access public 

  60       */
  61      function wsdl($wsdl = '',$proxyhost=false,$proxyport=false,$proxyusername=false,$proxypassword=false,$timeout=0,$response_timeout=30){
  62          parent::nusoap_base();
  63          $this->wsdl = $wsdl;
  64          $this->proxyhost = $proxyhost;
  65          $this->proxyport = $proxyport;
  66          $this->proxyusername = $proxyusername;
  67          $this->proxypassword = $proxypassword;
  68          $this->timeout = $timeout;
  69          $this->response_timeout = $response_timeout;
  70          
  71          // parse wsdl file

  72          if ($wsdl != "") {
  73              $this->debug('initial wsdl URL: ' . $wsdl);
  74              $this->parseWSDL($wsdl);
  75          }
  76          // imports

  77          // TODO: handle imports more properly, grabbing them in-line and nesting them

  78              $imported_urls = array();
  79              $imported = 1;
  80              while ($imported > 0) {
  81                  $imported = 0;
  82                  // Schema imports

  83                  foreach ($this->schemas as $ns => $list) {
  84                      foreach ($list as $xs) {
  85                          $wsdlparts = parse_url($this->wsdl);    // this is bogusly simple!

  86                          foreach ($xs->imports as $ns2 => $list2) {
  87                              for ($ii = 0; $ii < count($list2); $ii++) {
  88                                  if (! $list2[$ii]['loaded']) {
  89                                      $this->schemas[$ns]->imports[$ns2][$ii]['loaded'] = true;
  90                                      $url = $list2[$ii]['location'];
  91                                      if ($url != '') {
  92                                          $urlparts = parse_url($url);
  93                                          if (!isset($urlparts['host'])) {
  94                                              $url = $wsdlparts['scheme'] . '://' . $wsdlparts['host'] . (isset($wsdlparts['port']) ? ':' .$wsdlparts['port'] : '') .
  95                                                      substr($wsdlparts['path'],0,strrpos($wsdlparts['path'],'/') + 1) .$urlparts['path'];
  96                                          }
  97                                          if (! in_array($url, $imported_urls)) {
  98                                              $this->parseWSDL($url);
  99                                              $imported++;
 100                                              $imported_urls[] = $url;
 101                                          }
 102                                      } else {
 103                                          $this->debug("Unexpected scenario: empty URL for unloaded import");
 104                                      }
 105                                  }
 106                              }
 107                          } 
 108                      }
 109                  }
 110                  // WSDL imports

 111                  $wsdlparts = parse_url($this->wsdl);    // this is bogusly simple!

 112                  foreach ($this->import as $ns => $list) {
 113                      for ($ii = 0; $ii < count($list); $ii++) {
 114                          if (! $list[$ii]['loaded']) {
 115                              $this->import[$ns][$ii]['loaded'] = true;
 116                              $url = $list[$ii]['location'];
 117                              if ($url != '') {
 118                                  $urlparts = parse_url($url);
 119                                  if (!isset($urlparts['host'])) {
 120                                      $url = $wsdlparts['scheme'] . '://' . $wsdlparts['host'] . (isset($wsdlparts['port']) ? ':' . $wsdlparts['port'] : '') .
 121                                              substr($wsdlparts['path'],0,strrpos($wsdlparts['path'],'/') + 1) .$urlparts['path'];
 122                                  }
 123                                  if (! in_array($url, $imported_urls)) {
 124                                      $this->parseWSDL($url);
 125                                      $imported++;
 126                                      $imported_urls[] = $url;
 127                                  }
 128                              } else {
 129                                  $this->debug("Unexpected scenario: empty URL for unloaded import");
 130                              }
 131                          }
 132                      }
 133                  } 
 134              }
 135          // add new data to operation data

 136          foreach($this->bindings as $binding => $bindingData) {
 137              if (isset($bindingData['operations']) && is_array($bindingData['operations'])) {
 138                  foreach($bindingData['operations'] as $operation => $data) {
 139                      $this->debug('post-parse data gathering for ' . $operation);
 140                      $this->bindings[$binding]['operations'][$operation]['input'] = 
 141                          isset($this->bindings[$binding]['operations'][$operation]['input']) ? 
 142                          array_merge($this->bindings[$binding]['operations'][$operation]['input'], $this->portTypes[ $bindingData['portType'] ][$operation]['input']) :
 143                          $this->portTypes[ $bindingData['portType'] ][$operation]['input'];
 144                      $this->bindings[$binding]['operations'][$operation]['output'] = 
 145                          isset($this->bindings[$binding]['operations'][$operation]['output']) ?
 146                          array_merge($this->bindings[$binding]['operations'][$operation]['output'], $this->portTypes[ $bindingData['portType'] ][$operation]['output']) :
 147                          $this->portTypes[ $bindingData['portType'] ][$operation]['output'];
 148                      if(isset($this->messages[ $this->bindings[$binding]['operations'][$operation]['input']['message'] ])){
 149                          $this->bindings[$binding]['operations'][$operation]['input']['parts'] = $this->messages[ $this->bindings[$binding]['operations'][$operation]['input']['message'] ];
 150                      }
 151                      if(isset($this->messages[ $this->bindings[$binding]['operations'][$operation]['output']['message'] ])){
 152                             $this->bindings[$binding]['operations'][$operation]['output']['parts'] = $this->messages[ $this->bindings[$binding]['operations'][$operation]['output']['message'] ];
 153                      }
 154                      if (isset($bindingData['style'])) {
 155                          $this->bindings[$binding]['operations'][$operation]['style'] = $bindingData['style'];
 156                      }
 157                      $this->bindings[$binding]['operations'][$operation]['transport'] = isset($bindingData['transport']) ? $bindingData['transport'] : '';
 158                      $this->bindings[$binding]['operations'][$operation]['documentation'] = isset($this->portTypes[ $bindingData['portType'] ][$operation]['documentation']) ? $this->portTypes[ $bindingData['portType'] ][$operation]['documentation'] : '';
 159                      $this->bindings[$binding]['operations'][$operation]['endpoint'] = isset($bindingData['endpoint']) ? $bindingData['endpoint'] : '';
 160                  } 
 161              } 
 162          }
 163      }
 164  
 165      /**

 166       * parses the wsdl document

 167       * 

 168       * @param string $wsdl path or URL

 169       * @access private 

 170       */
 171      function parseWSDL($wsdl = '')
 172      {
 173          if ($wsdl == '') {
 174              $this->debug('no wsdl passed to parseWSDL()!!');
 175              $this->setError('no wsdl passed to parseWSDL()!!');
 176              return false;
 177          }
 178          
 179          // parse $wsdl for url format

 180          $wsdl_props = parse_url($wsdl);
 181  
 182          if (isset($wsdl_props['scheme']) && ($wsdl_props['scheme'] == 'http' || $wsdl_props['scheme'] == 'https')) {
 183              $this->debug('getting WSDL http(s) URL ' . $wsdl);
 184              // get wsdl

 185              $tr = new soap_transport_http($wsdl);
 186              $tr->request_method = 'GET';
 187              $tr->useSOAPAction = false;
 188              if($this->proxyhost && $this->proxyport){
 189                  $tr->setProxy($this->proxyhost,$this->proxyport,$this->proxyusername,$this->proxypassword);
 190              }
 191              $tr->setEncoding('gzip, deflate');
 192              $wsdl_string = $tr->send('', $this->timeout, $this->response_timeout);
 193              //$this->debug("WSDL request\n" . $tr->outgoing_payload);

 194              //$this->debug("WSDL response\n" . $tr->incoming_payload);

 195              $this->appendDebug($tr->getDebug());
 196              // catch errors

 197              if($err = $tr->getError() ){
 198                  $errstr = 'HTTP ERROR: '.$err;
 199                  $this->debug($errstr);
 200                  $this->setError($errstr);
 201                  unset($tr);
 202                  return false;
 203              }
 204              unset($tr);
 205              $this->debug("got WSDL URL");
 206          } else {
 207              // $wsdl is not http(s), so treat it as a file URL or plain file path

 208              if (isset($wsdl_props['scheme']) && ($wsdl_props['scheme'] == 'file') && isset($wsdl_props['path'])) {
 209                  $path = isset($wsdl_props['host']) ? ($wsdl_props['host'] . ':' . $wsdl_props['path']) : $wsdl_props['path'];
 210              } else {
 211                  $path = $wsdl;
 212              }
 213              $this->debug('getting WSDL file ' . $path);
 214              if ($fp = @fopen($path, 'r')) {
 215                  $wsdl_string = '';
 216                  while ($data = fread($fp, 32768)) {
 217                      $wsdl_string .= $data;
 218                  } 
 219                  fclose($fp);
 220              } else {
 221                  $errstr = "Bad path to WSDL file $path";
 222                  $this->debug($errstr);
 223                  $this->setError($errstr);
 224                  return false;
 225              } 
 226          }
 227          $this->debug('Parse WSDL');
 228          // end new code added

 229          // Create an XML parser.

 230          $this->parser = xml_parser_create(); 
 231          // Set the options for parsing the XML data.

 232          // xml_parser_set_option($parser, XML_OPTION_SKIP_WHITE, 1);

 233          xml_parser_set_option($this->parser, XML_OPTION_CASE_FOLDING, 0); 
 234          // Set the object for the parser.

 235          xml_set_object($this->parser, $this); 
 236          // Set the element handlers for the parser.

 237          xml_set_element_handler($this->parser, 'start_element', 'end_element');
 238          xml_set_character_data_handler($this->parser, 'character_data');
 239          // Parse the XML file.

 240          if (!xml_parse($this->parser, $wsdl_string, true)) {
 241              // Display an error message.

 242              $errstr = sprintf(
 243                  'XML error parsing WSDL from %s on line %d: %s',
 244                  $wsdl,
 245                  xml_get_current_line_number($this->parser),
 246                  xml_error_string(xml_get_error_code($this->parser))
 247                  );
 248              $this->debug($errstr);
 249              $this->debug("XML payload:\n" . $wsdl_string);
 250              $this->setError($errstr);
 251              return false;
 252          } 
 253          // free the parser

 254          xml_parser_free($this->parser);
 255          $this->debug('Parsing WSDL done');
 256          // catch wsdl parse errors

 257          if($this->getError()){
 258              return false;
 259          }
 260          return true;
 261      } 
 262  
 263      /**

 264       * start-element handler

 265       * 

 266       * @param string $parser XML parser object

 267       * @param string $name element name

 268       * @param string $attrs associative array of attributes

 269       * @access private 

 270       */
 271      function start_element($parser, $name, $attrs)
 272      {
 273          if ($this->status == 'schema') {
 274              $this->currentSchema->schemaStartElement($parser, $name, $attrs);
 275              $this->appendDebug($this->currentSchema->getDebug());
 276              $this->currentSchema->clearDebug();
 277          } elseif (ereg('schema$', $name)) {
 278              $this->debug('Parsing WSDL schema');
 279              // $this->debug("startElement for $name ($attrs[name]). status = $this->status (".$this->getLocalPart($name).")");

 280              $this->status = 'schema';
 281              $this->currentSchema = new xmlschema('', '', $this->namespaces);
 282              $this->currentSchema->schemaStartElement($parser, $name, $attrs);
 283              $this->appendDebug($this->currentSchema->getDebug());
 284              $this->currentSchema->clearDebug();
 285          } else {
 286              // position in the total number of elements, starting from 0

 287              $pos = $this->position++;
 288              $depth = $this->depth++; 
 289              // set self as current value for this depth

 290              $this->depth_array[$depth] = $pos;
 291              $this->message[$pos] = array('cdata' => ''); 
 292              // process attributes

 293              if (count($attrs) > 0) {
 294                  // register namespace declarations

 295                  foreach($attrs as $k => $v) {
 296                      if (ereg("^xmlns", $k)) {
 297                          if ($ns_prefix = substr(strrchr($k, ':'), 1)) {
 298                              $this->namespaces[$ns_prefix] = $v;
 299                          } else {
 300                              $this->namespaces['ns' . (count($this->namespaces) + 1)] = $v;
 301                          } 
 302                          if ($v == 'http://www.w3.org/2001/XMLSchema' || $v == 'http://www.w3.org/1999/XMLSchema' || $v == 'http://www.w3.org/2000/10/XMLSchema') {
 303                              $this->XMLSchemaVersion = $v;
 304                              $this->namespaces['xsi'] = $v . '-instance';
 305                          } 
 306                      }
 307                  }
 308                  // expand each attribute prefix to its namespace

 309                  foreach($attrs as $k => $v) {
 310                      $k = strpos($k, ':') ? $this->expandQname($k) : $k;
 311                      if ($k != 'location' && $k != 'soapAction' && $k != 'namespace') {
 312                          $v = strpos($v, ':') ? $this->expandQname($v) : $v;
 313                      } 
 314                      $eAttrs[$k] = $v;
 315                  } 
 316                  $attrs = $eAttrs;
 317              } else {
 318                  $attrs = array();
 319              } 
 320              // get element prefix, namespace and name

 321              if (ereg(':', $name)) {
 322                  // get ns prefix

 323                  $prefix = substr($name, 0, strpos($name, ':')); 
 324                  // get ns

 325                  $namespace = isset($this->namespaces[$prefix]) ? $this->namespaces[$prefix] : ''; 
 326                  // get unqualified name

 327                  $name = substr(strstr($name, ':'), 1);
 328              } 
 329              // process attributes, expanding any prefixes to namespaces

 330              // find status, register data

 331              switch ($this->status) {
 332                  case 'message':
 333                      if ($name == 'part') {
 334                          if (isset($attrs['type'])) {
 335                              $this->debug("msg " . $this->currentMessage . ": found part $attrs[name]: " . implode(',', $attrs));
 336                              $this->messages[$this->currentMessage][$attrs['name']] = $attrs['type'];
 337                          } 
 338                          if (isset($attrs['element'])) {
 339                              $this->debug("msg " . $this->currentMessage . ": found part $attrs[name]: " . implode(',', $attrs));
 340                              $this->messages[$this->currentMessage][$attrs['name']] = $attrs['element'];
 341                          } 
 342                      } 
 343                      break;
 344                  case 'portType':
 345                      switch ($name) {
 346                          case 'operation':
 347                              $this->currentPortOperation = $attrs['name'];
 348                              $this->debug("portType $this->currentPortType operation: $this->currentPortOperation");
 349                              if (isset($attrs['parameterOrder'])) {
 350                                  $this->portTypes[$this->currentPortType][$attrs['name']]['parameterOrder'] = $attrs['parameterOrder'];
 351                              } 
 352                              break;
 353                          case 'documentation':
 354                              $this->documentation = true;
 355                              break; 
 356                          // merge input/output data

 357                          default:
 358                              $m = isset($attrs['message']) ? $this->getLocalPart($attrs['message']) : '';
 359                              $this->portTypes[$this->currentPortType][$this->currentPortOperation][$name]['message'] = $m;
 360                              break;
 361                      } 
 362                      break;
 363                  case 'binding':
 364                      switch ($name) {
 365                          case 'binding': 
 366                              // get ns prefix

 367                              if (isset($attrs['style'])) {
 368                              $this->bindings[$this->currentBinding]['prefix'] = $prefix;
 369                              } 
 370                              $this->bindings[$this->currentBinding] = array_merge($this->bindings[$this->currentBinding], $attrs);
 371                              break;
 372                          case 'header':
 373                              $this->bindings[$this->currentBinding]['operations'][$this->currentOperation][$this->opStatus]['headers'][] = $attrs;
 374                              break;
 375                          case 'operation':
 376                              if (isset($attrs['soapAction'])) {
 377                                  $this->bindings[$this->currentBinding]['operations'][$this->currentOperation]['soapAction'] = $attrs['soapAction'];
 378                              } 
 379                              if (isset($attrs['style'])) {
 380                                  $this->bindings[$this->currentBinding]['operations'][$this->currentOperation]['style'] = $attrs['style'];
 381                              } 
 382                              if (isset($attrs['name'])) {
 383                                  $this->currentOperation = $attrs['name'];
 384                                  $this->debug("current binding operation: $this->currentOperation");
 385                                  $this->bindings[$this->currentBinding]['operations'][$this->currentOperation]['name'] = $attrs['name'];
 386                                  $this->bindings[$this->currentBinding]['operations'][$this->currentOperation]['binding'] = $this->currentBinding;
 387                                  $this->bindings[$this->currentBinding]['operations'][$this->currentOperation]['endpoint'] = isset($this->bindings[$this->currentBinding]['endpoint']) ? $this->bindings[$this->currentBinding]['endpoint'] : '';
 388                              } 
 389                              break;
 390                          case 'input':
 391                              $this->opStatus = 'input';
 392                              break;
 393                          case 'output':
 394                              $this->opStatus = 'output';
 395                              break;
 396                          case 'body':
 397                              if (isset($this->bindings[$this->currentBinding]['operations'][$this->currentOperation][$this->opStatus])) {
 398                                  $this->bindings[$this->currentBinding]['operations'][$this->currentOperation][$this->opStatus] = array_merge($this->bindings[$this->currentBinding]['operations'][$this->currentOperation][$this->opStatus], $attrs);
 399                              } else {
 400                                  $this->bindings[$this->currentBinding]['operations'][$this->currentOperation][$this->opStatus] = $attrs;
 401                              } 
 402                              break;
 403                      } 
 404                      break;
 405                  case 'service':
 406                      switch ($name) {
 407                          case 'port':
 408                              $this->currentPort = $attrs['name'];
 409                              $this->debug('current port: ' . $this->currentPort);
 410                              $this->ports[$this->currentPort]['binding'] = $this->getLocalPart($attrs['binding']);
 411                      
 412                              break;
 413                          case 'address':
 414                              $this->ports[$this->currentPort]['location'] = $attrs['location'];
 415                              $this->ports[$this->currentPort]['bindingType'] = $namespace;
 416                              $this->bindings[ $this->ports[$this->currentPort]['binding'] ]['bindingType'] = $namespace;
 417                              $this->bindings[ $this->ports[$this->currentPort]['binding'] ]['endpoint'] = $attrs['location'];
 418                              break;
 419                      } 
 420                      break;
 421              } 
 422          // set status

 423          switch ($name) {
 424              case 'import':
 425                  if (isset($attrs['location'])) {
 426                      $this->import[$attrs['namespace']][] = array('location' => $attrs['location'], 'loaded' => false);
 427                      $this->debug('parsing import ' . $attrs['namespace']. ' - ' . $attrs['location'] . ' (' . count($this->import[$attrs['namespace']]).')');
 428                  } else {
 429                      $this->import[$attrs['namespace']][] = array('location' => '', 'loaded' => true);
 430                      if (! $this->getPrefixFromNamespace($attrs['namespace'])) {
 431                          $this->namespaces['ns'.(count($this->namespaces)+1)] = $attrs['namespace'];
 432                      }
 433                      $this->debug('parsing import ' . $attrs['namespace']. ' - [no location] (' . count($this->import[$attrs['namespace']]).')');
 434                  }
 435                  break;
 436              //wait for schema

 437              //case 'types':

 438              //    $this->status = 'schema';

 439              //    break;

 440              case 'message':
 441                  $this->status = 'message';
 442                  $this->messages[$attrs['name']] = array();
 443                  $this->currentMessage = $attrs['name'];
 444                  break;
 445              case 'portType':
 446                  $this->status = 'portType';
 447                  $this->portTypes[$attrs['name']] = array();
 448                  $this->currentPortType = $attrs['name'];
 449                  break;
 450              case "binding":
 451                  if (isset($attrs['name'])) {
 452                  // get binding name

 453                      if (strpos($attrs['name'], ':')) {
 454                          $this->currentBinding = $this->getLocalPart($attrs['name']);
 455                      } else {
 456                          $this->currentBinding = $attrs['name'];
 457                      } 
 458                      $this->status = 'binding';
 459                      $this->bindings[$this->currentBinding]['portType'] = $this->getLocalPart($attrs['type']);
 460                      $this->debug("current binding: $this->currentBinding of portType: " . $attrs['type']);
 461                  } 
 462                  break;
 463              case 'service':
 464                  $this->serviceName = $attrs['name'];
 465                  $this->status = 'service';
 466                  $this->debug('current service: ' . $this->serviceName);
 467                  break;
 468              case 'definitions':
 469                  foreach ($attrs as $name => $value) {
 470                      $this->wsdl_info[$name] = $value;
 471                  } 
 472                  break;
 473              } 
 474          } 
 475      } 
 476  
 477      /**

 478      * end-element handler

 479      * 

 480      * @param string $parser XML parser object

 481      * @param string $name element name

 482      * @access private 

 483      */
 484  	function end_element($parser, $name){ 
 485          // unset schema status

 486          if (/*ereg('types$', $name) ||*/ ereg('schema$', $name)) {
 487              $this->status = "";
 488              $this->appendDebug($this->currentSchema->getDebug());
 489              $this->currentSchema->clearDebug();
 490              $this->schemas[$this->currentSchema->schemaTargetNamespace][] = $this->currentSchema;
 491              $this->debug('Parsing WSDL schema done');
 492          } 
 493          if ($this->status == 'schema') {
 494              $this->currentSchema->schemaEndElement($parser, $name);
 495          } else {
 496              // bring depth down a notch

 497              $this->depth--;
 498          } 
 499          // end documentation

 500          if ($this->documentation) {
 501              //TODO: track the node to which documentation should be assigned; it can be a part, message, etc.

 502              //$this->portTypes[$this->currentPortType][$this->currentPortOperation]['documentation'] = $this->documentation;

 503              $this->documentation = false;
 504          } 
 505      } 
 506  
 507      /**

 508       * element content handler

 509       * 

 510       * @param string $parser XML parser object

 511       * @param string $data element content

 512       * @access private 

 513       */
 514  	function character_data($parser, $data)
 515      {
 516          $pos = isset($this->depth_array[$this->depth]) ? $this->depth_array[$this->depth] : 0;
 517          if (isset($this->message[$pos]['cdata'])) {
 518              $this->message[$pos]['cdata'] .= $data;
 519          } 
 520          if ($this->documentation) {
 521              $this->documentation .= $data;
 522          } 
 523      } 
 524      
 525  	function getBindingData($binding)
 526      {
 527          if (is_array($this->bindings[$binding])) {
 528              return $this->bindings[$binding];
 529          } 
 530      }
 531      
 532      /**

 533       * returns an assoc array of operation names => operation data

 534       * 

 535       * @param string $bindingType eg: soap, smtp, dime (only soap is currently supported)

 536       * @return array 

 537       * @access public 

 538       */
 539  	function getOperations($bindingType = 'soap')
 540      {
 541          $ops = array();
 542          if ($bindingType == 'soap') {
 543              $bindingType = 'http://schemas.xmlsoap.org/wsdl/soap/';
 544          }
 545          // loop thru ports

 546          foreach($this->ports as $port => $portData) {
 547              // binding type of port matches parameter

 548              if ($portData['bindingType'] == $bindingType) {
 549                  //$this->debug("getOperations for port $port");

 550                  //$this->debug("port data: " . $this->varDump($portData));

 551                  //$this->debug("bindings: " . $this->varDump($this->bindings[ $portData['binding'] ]));

 552                  // merge bindings

 553                  if (isset($this->bindings[ $portData['binding'] ]['operations'])) {
 554                      $ops = array_merge ($ops, $this->bindings[ $portData['binding'] ]['operations']);
 555                  }
 556              }
 557          } 
 558          return $ops;
 559      } 
 560      
 561      /**

 562       * returns an associative array of data necessary for calling an operation

 563       * 

 564       * @param string $operation , name of operation

 565       * @param string $bindingType , type of binding eg: soap

 566       * @return array 

 567       * @access public 

 568       */
 569  	function getOperationData($operation, $bindingType = 'soap')
 570      {
 571          if ($bindingType == 'soap') {
 572              $bindingType = 'http://schemas.xmlsoap.org/wsdl/soap/';
 573          }
 574          // loop thru ports

 575          foreach($this->ports as $port => $portData) {
 576              // binding type of port matches parameter

 577              if ($portData['bindingType'] == $bindingType) {
 578                  // get binding

 579                  //foreach($this->bindings[ $portData['binding'] ]['operations'] as $bOperation => $opData) {

 580                  foreach(array_keys($this->bindings[ $portData['binding'] ]['operations']) as $bOperation) {
 581                      // note that we could/should also check the namespace here

 582                      if ($operation == $bOperation) {
 583                          $opData = $this->bindings[ $portData['binding'] ]['operations'][$operation];
 584                          return $opData;
 585                      } 
 586                  } 
 587              }
 588          } 
 589      }
 590      
 591      /**

 592       * returns an associative array of data necessary for calling an operation

 593       * 

 594       * @param string $soapAction soapAction for operation

 595       * @param string $bindingType type of binding eg: soap

 596       * @return array 

 597       * @access public 

 598       */
 599  	function getOperationDataForSoapAction($soapAction, $bindingType = 'soap') {
 600          if ($bindingType == 'soap') {
 601              $bindingType = 'http://schemas.xmlsoap.org/wsdl/soap/';
 602          }
 603          // loop thru ports

 604          foreach($this->ports as $port => $portData) {
 605              // binding type of port matches parameter

 606              if ($portData['bindingType'] == $bindingType) {
 607                  // loop through operations for the binding

 608                  foreach ($this->bindings[ $portData['binding'] ]['operations'] as $bOperation => $opData) {
 609                      if ($opData['soapAction'] == $soapAction) {
 610                          return $opData;
 611                      } 
 612                  } 
 613              }
 614          } 
 615      }
 616      
 617      /**

 618      * returns an array of information about a given type

 619      * returns false if no type exists by the given name

 620      *

 621      *     typeDef = array(

 622      *     'elements' => array(), // refs to elements array

 623      *    'restrictionBase' => '',

 624      *    'phpType' => '',

 625      *    'order' => '(sequence|all)',

 626      *    'attrs' => array() // refs to attributes array

 627      *    )

 628      *

 629      * @param $type string the type

 630      * @param $ns string namespace (not prefix) of the type

 631      * @return mixed

 632      * @access public

 633      * @see xmlschema

 634      */
 635  	function getTypeDef($type, $ns) {
 636          $this->debug("in getTypeDef: type=$type, ns=$ns");
 637          if ((! $ns) && isset($this->namespaces['tns'])) {
 638              $ns = $this->namespaces['tns'];
 639              $this->debug("in getTypeDef: type namespace forced to $ns");
 640          }
 641          if (isset($this->schemas[$ns])) {
 642              $this->debug("in getTypeDef: have schema for namespace $ns");
 643              for ($i = 0; $i < count($this->schemas[$ns]); $i++) {
 644                  $xs = &$this->schemas[$ns][$i];
 645                  $t = $xs->getTypeDef($type);
 646                  $this->appendDebug($xs->getDebug());
 647                  $xs->clearDebug();
 648                  if ($t) {
 649                      if (!isset($t['phpType'])) {
 650                          // get info for type to tack onto the element

 651                          $uqType = substr($t['type'], strrpos($t['type'], ':') + 1);
 652                          $ns = substr($t['type'], 0, strrpos($t['type'], ':'));
 653                          $etype = $this->getTypeDef($uqType, $ns);
 654                          if ($etype) {
 655                              $this->debug("found type for [element] $type:");
 656                              $this->debug($this->varDump($etype));
 657                              if (isset($etype['phpType'])) {
 658                                  $t['phpType'] = $etype['phpType'];
 659                              }
 660                              if (isset($etype['elements'])) {
 661                                  $t['elements'] = $etype['elements'];
 662                              }
 663                              if (isset($etype['attrs'])) {
 664                                  $t['attrs'] = $etype['attrs'];
 665                              }
 666                          }
 667                      }
 668                      return $t;
 669                  }
 670              }
 671          } else {
 672              $this->debug("in getTypeDef: do not have schema for namespace $ns");
 673          }
 674          return false;
 675      }
 676  
 677      /**

 678      * prints html description of services

 679      *

 680      * @access private

 681      */
 682      function webDescription(){
 683          global $HTTP_SERVER_VARS;
 684  
 685          if (isset($_SERVER)) {
 686              $PHP_SELF = $_SERVER['PHP_SELF'];
 687          } elseif (isset($HTTP_SERVER_VARS)) {
 688              $PHP_SELF = $HTTP_SERVER_VARS['PHP_SELF'];
 689          } else {
 690              $this->setError("Neither _SERVER nor HTTP_SERVER_VARS is available");
 691          }
 692  
 693          $b = '
 694          <html><head><title>NuSOAP: '.$this->serviceName.'</title>
 695          <style type="text/css">
 696              body    { font-family: arial; color: #000000; background-color: #ffffff; margin: 0px 0px 0px 0px; }
 697              p       { font-family: arial; color: #000000; margin-top: 0px; margin-bottom: 12px; }
 698              pre { background-color: silver; padding: 5px; font-family: Courier New; font-size: x-small; color: #000000;}
 699              ul      { margin-top: 10px; margin-left: 20px; }
 700              li      { list-style-type: none; margin-top: 10px; color: #000000; }
 701              .content{
 702              margin-left: 0px; padding-bottom: 2em; }
 703              .nav {
 704              padding-top: 10px; padding-bottom: 10px; padding-left: 15px; font-size: .70em;
 705              margin-top: 10px; margin-left: 0px; color: #000000;
 706              background-color: #ccccff; width: 20%; margin-left: 20px; margin-top: 20px; }
 707              .title {
 708              font-family: arial; font-size: 26px; color: #ffffff;
 709              background-color: #999999; width: 105%; margin-left: 0px;
 710              padding-top: 10px; padding-bottom: 10px; padding-left: 15px;}
 711              .hidden {
 712              position: absolute; visibility: hidden; z-index: 200; left: 250px; top: 100px;
 713              font-family: arial; overflow: hidden; width: 600;
 714              padding: 20px; font-size: 10px; background-color: #999999;
 715              layer-background-color:#FFFFFF; }
 716              a,a:active  { color: charcoal; font-weight: bold; }
 717              a:visited   { color: #666666; font-weight: bold; }
 718              a:hover     { color: cc3300; font-weight: bold; }
 719          </style>
 720          <script language="JavaScript" type="text/javascript">
 721          <!--
 722          // POP-UP CAPTIONS...

 723  		function lib_bwcheck(){ //Browsercheck (needed)
 724              this.ver=navigator.appVersion
 725              this.agent=navigator.userAgent
 726              this.dom=document.getElementById?1:0
 727              this.opera5=this.agent.indexOf("Opera 5")>-1
 728              this.ie5=(this.ver.indexOf("MSIE 5")>-1 && this.dom && !this.opera5)?1:0;
 729              this.ie6=(this.ver.indexOf("MSIE 6")>-1 && this.dom && !this.opera5)?1:0;
 730              this.ie4=(document.all && !this.dom && !this.opera5)?1:0;
 731              this.ie=this.ie4||this.ie5||this.ie6
 732              this.mac=this.agent.indexOf("Mac")>-1
 733              this.ns6=(this.dom && parseInt(this.ver) >= 5) ?1:0;
 734              this.ns4=(document.layers && !this.dom)?1:0;
 735              this.bw=(this.ie6 || this.ie5 || this.ie4 || this.ns4 || this.ns6 || this.opera5)
 736              return this
 737          }
 738          var bw = new lib_bwcheck()
 739          //Makes crossbrowser object.

 740  		function makeObj(obj){
 741              this.evnt=bw.dom? document.getElementById(obj):bw.ie4?document.all[obj]:bw.ns4?document.layers[obj]:0;
 742              if(!this.evnt) return false
 743              this.css=bw.dom||bw.ie4?this.evnt.style:bw.ns4?this.evnt:0;
 744              this.wref=bw.dom||bw.ie4?this.evnt:bw.ns4?this.css.document:0;
 745              this.writeIt=b_writeIt;
 746              return this
 747          }
 748          // A unit of measure that will be added when setting the position of a layer.

 749          //var px = bw.ns4||window.opera?"":"px";

 750  		function b_writeIt(text){
 751              if (bw.ns4){this.wref.write(text);this.wref.close()}
 752              else this.wref.innerHTML = text
 753          }
 754          //Shows the messages

 755          var oDesc;
 756  		function popup(divid){
 757              if(oDesc = new makeObj(divid)){
 758              oDesc.css.visibility = "visible"
 759              }
 760          }
 761  		function popout(){ // Hides message
 762              if(oDesc) oDesc.css.visibility = "hidden"
 763          }
 764          //-->

 765          </script>
 766          </head>
 767          <body>
 768          <div class=content>
 769              <br><br>
 770              <div class=title>'.$this->serviceName.'</div>
 771              <div class=nav>
 772                  <p>View the <a href="'.$PHP_SELF.'?wsdl">WSDL</a> for the service.
 773                  Click on an operation name to view it&apos;s details.</p>
 774                  <ul>';
 775                  foreach($this->getOperations() as $op => $data){
 776                      $b .= "<li><a href='#' onclick=\"popout();popup('$op')\">$op</a></li>";
 777                      // create hidden div

 778                      $b .= "<div id='$op' class='hidden'>
 779                      <a href='#' onclick='popout()'><font color='#ffffff'>Close</font></a><br><br>";
 780                      foreach($data as $donnie => $marie){ // loop through opdata
 781                          if($donnie == 'input' || $donnie == 'output'){ // show input/output data
 782                              $b .= "<font color='white'>".ucfirst($donnie).':</font><br>';
 783                              foreach($marie as $captain => $tenille){ // loop through data
 784                                  if($captain == 'parts'){ // loop thru parts
 785                                      $b .= "&nbsp;&nbsp;$captain:<br>";
 786                                      //if(is_array($tenille)){

 787                                          foreach($tenille as $joanie => $chachi){
 788                                              $b .= "&nbsp;&nbsp;&nbsp;&nbsp;$joanie: $chachi<br>";
 789                                          }
 790                                      //}

 791                                  } else {
 792                                      $b .= "&nbsp;&nbsp;$captain: $tenille<br>";
 793                                  }
 794                              }
 795                          } else {
 796                              $b .= "<font color='white'>".ucfirst($donnie).":</font> $marie<br>";
 797                          }
 798                      }
 799                      $b .= '</div>';
 800                  }
 801                  $b .= '
 802                  <ul>
 803              </div>
 804          </div></body></html>';
 805          return $b;
 806      }
 807  
 808      /**

 809      * serialize the parsed wsdl

 810      *

 811      * @param mixed $debug whether to put debug=1 in endpoint URL

 812      * @return string serialization of WSDL

 813      * @access public 

 814      */
 815  	function serialize($debug = 0)
 816      {
 817          $xml = '<?xml version="1.0" encoding="ISO-8859-1"?>';
 818          $xml .= "\n<definitions";
 819          foreach($this->namespaces as $k => $v) {
 820              $xml .= " xmlns:$k=\"$v\"";
 821          } 
 822          // 10.9.02 - add poulter fix for wsdl and tns declarations

 823          if (isset($this->namespaces['wsdl'])) {
 824              $xml .= " xmlns=\"" . $this->namespaces['wsdl'] . "\"";
 825          } 
 826          if (isset($this->namespaces['tns'])) {
 827              $xml .= " targetNamespace=\"" . $this->namespaces['tns'] . "\"";
 828          } 
 829          $xml .= '>'; 
 830          // imports

 831          if (sizeof($this->import) > 0) {
 832              foreach($this->import as $ns => $list) {
 833                  foreach ($list as $ii) {
 834                      if ($ii['location'] != '') {
 835                          $xml .= '<import location="' . $ii['location'] . '" namespace="' . $ns . '" />';
 836                      } else {
 837                          $xml .= '<import namespace="' . $ns . '" />';
 838                      }
 839                  }
 840              } 
 841          } 
 842          // types

 843          if (count($this->schemas)>=1) {
 844              $xml .= "\n<types>";
 845              foreach ($this->schemas as $ns => $list) {
 846                  foreach ($list as $xs) {
 847                      $xml .= $xs->serializeSchema();
 848                  }
 849              }
 850              $xml .= '</types>';
 851          } 
 852          // messages

 853          if (count($this->messages) >= 1) {
 854              foreach($this->messages as $msgName => $msgParts) {
 855                  $xml .= "\n<message name=\"" . $msgName . '">';
 856                  if(is_array($msgParts)){
 857                      foreach($msgParts as $partName => $partType) {
 858                          // print 'serializing '.$partType.', sv: '.$this->XMLSchemaVersion.'<br>';

 859                          if (strpos($partType, ':')) {
 860                              $typePrefix = $this->getPrefixFromNamespace($this->getPrefix($partType));
 861                          } elseif (isset($this->typemap[$this->namespaces['xsd']][$partType])) {
 862                              // print 'checking typemap: '.$this->XMLSchemaVersion.'<br>';

 863                              $typePrefix = 'xsd';
 864                          } else {
 865                              foreach($this->typemap as $ns => $types) {
 866                                  if (isset($types[$partType])) {
 867                                      $typePrefix = $this->getPrefixFromNamespace($ns);
 868                                  } 
 869                              } 
 870                              if (!isset($typePrefix)) {
 871                                  die("$partType has no namespace!");
 872                              } 
 873                          }
 874                          $ns = $this->getNamespaceFromPrefix($typePrefix);
 875                          $typeDef = $this->getTypeDef($this->getLocalPart($partType), $ns);
 876                          if ($typeDef['typeClass'] == 'element') {
 877                              $elementortype = 'element';
 878                          } else {
 879                              $elementortype = 'type';
 880                          }
 881                          $xml .= '<part name="' . $partName . '" ' . $elementortype . '="' . $typePrefix . ':' . $this->getLocalPart($partType) . '" />';
 882                      }
 883                  }
 884                  $xml .= '</message>';
 885              } 
 886          } 
 887          // bindings & porttypes

 888          if (count($this->bindings) >= 1) {
 889              $binding_xml = '';
 890              $portType_xml = '';
 891              foreach($this->bindings as $bindingName => $attrs) {
 892                  $binding_xml .= "\n<binding name=\"" . $bindingName . '" type="tns:' . $attrs['portType'] . '">';
 893                  $binding_xml .= '<soap:binding style="' . $attrs['style'] . '" transport="' . $attrs['transport'] . '"/>';
 894                  $portType_xml .= "\n<portType name=\"" . $attrs['portType'] . '">';
 895                  foreach($attrs['operations'] as $opName => $opParts) {
 896                      $binding_xml .= '<operation name="' . $opName . '">';
 897                      $binding_xml .= '<soap:operation soapAction="' . $opParts['soapAction'] . '" style="'. $opParts['style'] . '"/>';
 898                      if (isset($opParts['input']['encodingStyle']) && $opParts['input']['encodingStyle'] != '') {
 899                          $enc_style = ' encodingStyle="' . $opParts['input']['encodingStyle'] . '"';
 900                      } else {
 901                          $enc_style = '';
 902                      }
 903                      $binding_xml .= '<input><soap:body use="' . $opParts['input']['use'] . '" namespace="' . $opParts['input']['namespace'] . '"' . $enc_style . '/></input>';
 904                      if (isset($opParts['output']['encodingStyle']) && $opParts['output']['encodingStyle'] != '') {
 905                          $enc_style = ' encodingStyle="' . $opParts['output']['encodingStyle'] . '"';
 906                      } else {
 907                          $enc_style = '';
 908                      }
 909                      $binding_xml .= '<output><soap:body use="' . $opParts['output']['use'] . '" namespace="' . $opParts['output']['namespace'] . '"' . $enc_style . '/></output>';
 910                      $binding_xml .= '</operation>';
 911                      $portType_xml .= '<operation name="' . $opParts['name'] . '"';
 912                      if (isset($opParts['parameterOrder'])) {
 913                          $portType_xml .= ' parameterOrder="' . $opParts['parameterOrder'] . '"';
 914                      } 
 915                      $portType_xml .= '>';
 916                      if(isset($opParts['documentation']) && $opParts['documentation'] != '') {
 917                          $portType_xml .= '<documentation>' . htmlspecialchars($opParts['documentation']) . '</documentation>';
 918                      }
 919                      $portType_xml .= '<input message="tns:' . $opParts['input']['message'] . '"/>';
 920                      $portType_xml .= '<output message="tns:' . $opParts['output']['message'] . '"/>';
 921                      $portType_xml .= '</operation>';
 922                  } 
 923                  $portType_xml .= '</portType>';
 924                  $binding_xml .= '</binding>';
 925              } 
 926              $xml .= $portType_xml . $binding_xml;
 927          } 
 928          // services

 929          $xml .= "\n<service name=\"" . $this->serviceName . '">';
 930          if (count($this->ports) >= 1) {
 931              foreach($this->ports as $pName => $attrs) {
 932                  $xml .= '<port name="' . $pName . '" binding="tns:' . $attrs['binding'] . '">';
 933                  $xml .= '<soap:address location="' . $attrs['location'] . ($debug ? '?debug=1' : '') . '"/>';
 934                  $xml .= '</port>';
 935              } 
 936          } 
 937          $xml .= '</service>';
 938          return $xml . "\n</definitions>";
 939      } 
 940      
 941      /**

 942       * serialize PHP values according to a WSDL message definition

 943       *

 944       * TODO

 945       * - multi-ref serialization

 946       * - validate PHP values against type definitions, return errors if invalid

 947       * 

 948       * @param string $operation operation name

 949       * @param string $direction (input|output)

 950       * @param mixed $parameters parameter value(s)

 951       * @return mixed parameters serialized as XML or false on error (e.g. operation not found)

 952       * @access public

 953       */
 954  	function serializeRPCParameters($operation, $direction, $parameters)
 955      {
 956          $this->debug("in serializeRPCParameters: operation=$operation, direction=$direction, XMLSchemaVersion=$this->XMLSchemaVersion"); 
 957          $this->appendDebug('parameters=' . $this->varDump($parameters));
 958          
 959          if ($direction != 'input' && $direction != 'output') {
 960              $this->debug('The value of the \$direction argument needs to be either "input" or "output"');
 961              $this->setError('The value of the \$direction argument needs to be either "input" or "output"');
 962              return false;
 963          } 
 964          if (!$opData = $this->getOperationData($operation)) {
 965              $this->debug('Unable to retrieve WSDL data for operation: ' . $operation);
 966              $this->setError('Unable to retrieve WSDL data for operation: ' . $operation);
 967              return false;
 968          }
 969          $this->debug('opData:');
 970          $this->appendDebug($this->varDump($opData));
 971  
 972          // Get encoding style for output and set to current

 973          $encodingStyle = 'http://schemas.xmlsoap.org/soap/encoding/';
 974          if(($direction == 'input') && isset($opData['output']['encodingStyle']) && ($opData['output']['encodingStyle'] != $encodingStyle)) {
 975              $encodingStyle = $opData['output']['encodingStyle'];
 976              $enc_style = $encodingStyle;
 977          }
 978  
 979          // set input params

 980          $xml = '';
 981          if (isset($opData[$direction]['parts']) && sizeof($opData[$direction]['parts']) > 0) {
 982              
 983              $use = $opData[$direction]['use'];
 984              $this->debug('have ' . count($opData[$direction]['parts']) . ' part(s) to serialize');
 985              if (is_array($parameters)) {
 986                  $parametersArrayType = $this->isArraySimpleOrStruct($parameters);
 987                  $this->debug('have ' . count($parameters) . ' parameter(s) provided as ' . $parametersArrayType . ' to serialize');
 988                  foreach($opData[$direction]['parts'] as $name => $type) {
 989                      $this->debug('serializing part "'.$name.'" of type "'.$type.'"');
 990                      // Track encoding style

 991                      if (isset($opData[$direction]['encodingStyle']) && $encodingStyle != $opData[$direction]['encodingStyle']) {
 992                          $encodingStyle = $opData[$direction]['encodingStyle'];            
 993                          $enc_style = $encodingStyle;
 994                      } else {
 995                          $enc_style = false;
 996                      }
 997                      // NOTE: add error handling here

 998                      // if serializeType returns false, then catch global error and fault

 999                      if ($parametersArrayType == 'arraySimple') {
1000                          $p = array_shift($parameters);
1001                          $this->debug('calling serializeType w/indexed param');
1002                          $xml .= $this->serializeType($name, $type, $p, $use, $enc_style);
1003                      } elseif (isset($parameters[$name])) {
1004                          $this->debug('calling serializeType w/named param');
1005                          $xml .= $this->serializeType($name, $type, $parameters[$name], $use, $enc_style);
1006                      } else {
1007                          // TODO: only send nillable

1008                          $this->debug('calling serializeType w/null param');
1009                          $xml .= $this->serializeType($name, $type, null, $use, $enc_style);
1010                      }
1011                  }
1012              } else {
1013                  $this->debug('no parameters passed.');
1014              }
1015          }
1016          $this->debug("serializeRPCParameters returning: $xml");
1017          return $xml;
1018      } 
1019      
1020      /**

1021       * serialize a PHP value according to a WSDL message definition

1022       * 

1023       * TODO

1024       * - multi-ref serialization

1025       * - validate PHP values against type definitions, return errors if invalid

1026       * 

1027       * @param string $ type name

1028       * @param mixed $ param value

1029       * @return mixed new param or false if initial value didn't validate

1030       * @access public

1031       * @deprecated

1032       */
1033  	function serializeParameters($operation, $direction, $parameters)
1034      {
1035          $this->debug("in serializeParameters: operation=$operation, direction=$direction, XMLSchemaVersion=$this->XMLSchemaVersion"); 
1036          $this->appendDebug('parameters=' . $this->varDump($parameters));
1037          
1038          if ($direction != 'input' && $direction != 'output') {
1039              $this->debug('The value of the \$direction argument needs to be either "input" or "output"');
1040              $this->setError('The value of the \$direction argument needs to be either "input" or "output"');
1041              return false;
1042          } 
1043          if (!$opData = $this->getOperationData($operation)) {
1044              $this->debug('Unable to retrieve WSDL data for operation: ' . $operation);
1045              $this->setError('Unable to retrieve WSDL data for operation: ' . $operation);
1046              return false;
1047          }
1048          $this->debug('opData:');
1049          $this->appendDebug($this->varDump($opData));
1050          
1051          // Get encoding style for output and set to current

1052          $encodingStyle = 'http://schemas.xmlsoap.org/soap/encoding/';
1053          if(($direction == 'input') && isset($opData['output']['encodingStyle']) && ($opData['output']['encodingStyle'] != $encodingStyle)) {
1054              $encodingStyle = $opData['output']['encodingStyle'];
1055              $enc_style = $encodingStyle;
1056          }
1057          
1058          // set input params

1059          $xml = '';
1060          if (isset($opData[$direction]['parts']) && sizeof($opData[$direction]['parts']) > 0) {
1061              
1062              $use = $opData[$direction]['use'];
1063              $this->debug("use=$use");
1064              $this->debug('got ' . count($opData[$direction]['parts']) . ' part(s)');
1065              if (is_array($parameters)) {
1066                  $parametersArrayType = $this->isArraySimpleOrStruct($parameters);
1067                  $this->debug('have ' . $parametersArrayType . ' parameters');
1068                  foreach($opData[$direction]['parts'] as $name => $type) {
1069                      $this->debug('serializing part "'.$name.'" of type "'.$type.'"');
1070                      // Track encoding style

1071                      if(isset($opData[$direction]['encodingStyle']) && $encodingStyle != $opData[$direction]['encodingStyle']) {
1072                          $encodingStyle = $opData[$direction]['encodingStyle'];            
1073                          $enc_style = $encodingStyle;
1074                      } else {
1075                          $enc_style = false;
1076                      }
1077                      // NOTE: add error handling here

1078                      // if serializeType returns false, then catch global error and fault

1079                      if ($parametersArrayType == 'arraySimple') {
1080                          $p = array_shift($parameters);
1081                          $this->debug('calling serializeType w/indexed param');
1082                          $xml .= $this->serializeType($name, $type, $p, $use, $enc_style);
1083                      } elseif (isset($parameters[$name])) {
1084                          $this->debug('calling serializeType w/named param');
1085                          $xml .= $this->serializeType($name, $type, $parameters[$name], $use, $enc_style);
1086                      } else {
1087                          // TODO: only send nillable

1088                          $this->debug('calling serializeType w/null param');
1089                          $xml .= $this->serializeType($name, $type, null, $use, $enc_style);
1090                      }
1091                  }
1092              } else {
1093                  $this->debug('no parameters passed.');
1094              }
1095          }
1096          $this->debug("serializeParameters returning: $xml");
1097          return $xml;
1098      } 
1099      
1100      /**

1101       * serializes a PHP value according a given type definition

1102       * 

1103       * @param string $name name of value (part or element)

1104       * @param string $type XML schema type of value (type or element)

1105       * @param mixed $value a native PHP value (parameter value)

1106       * @param string $use use for part (encoded|literal)

1107       * @param string $encodingStyle SOAP encoding style for the value (if different than the enclosing style)

1108       * @param boolean $unqualified a kludge for what should be XML namespace form handling

1109       * @return string value serialized as an XML string

1110       * @access private

1111       */
1112  	function serializeType($name, $type, $value, $use='encoded', $encodingStyle=false, $unqualified=false)
1113      {
1114          $this->debug("in serializeType: name=$name, type=$type, use=$use, encodingStyle=$encodingStyle, unqualified=" . ($unqualified ? "unqualified" : "qualified"));
1115          $this->appendDebug("value=" . $this->varDump($value));
1116          if($use == 'encoded' && $encodingStyle) {
1117              $encodingStyle = ' SOAP-ENV:encodingStyle="' . $encodingStyle . '"';
1118          }
1119  
1120          // if a soapval has been supplied, let its type override the WSDL

1121          if (is_object($value) && get_class($value) == 'soapval') {
1122              if ($value->type_ns) {
1123                  $type = $value->type_ns . ':' . $value->type;
1124                  $forceType = true;
1125                  $this->debug("in serializeType: soapval overrides type to $type");
1126              } elseif ($value->type) {
1127                  $type = $value->type;
1128                  $forceType = true;
1129                  $this->debug("in serializeType: soapval overrides type to $type");
1130              } else {
1131                  $forceType = false;
1132                  $this->debug("in serializeType: soapval does not override type");
1133              }
1134              $attrs = $value->attributes;
1135              $value = $value->value;
1136              $this->debug("in serializeType: soapval overrides value to $value");
1137              if ($attrs) {
1138                  if (!is_array($value)) {
1139                      $value['!'] = $value;
1140                  }
1141                  foreach ($attrs as $n => $v) {
1142                      $value['!' . $n] = $v;
1143                  }
1144                  $this->debug("in serializeType: soapval provides attributes");
1145              }
1146          } else {
1147              $forceType = false;
1148          }
1149  
1150          $xml = '';
1151          if (strpos($type, ':')) {
1152              $uqType = substr($type, strrpos($type, ':') + 1);
1153              $ns = substr($type, 0, strrpos($type, ':'));
1154              $this->debug("in serializeType: got a prefixed type: $uqType, $ns");
1155              if ($this->getNamespaceFromPrefix($ns)) {
1156                  $ns = $this->getNamespaceFromPrefix($ns);
1157                  $this->debug("in serializeType: expanded prefixed type: $uqType, $ns");
1158              }
1159  
1160              if($ns == $this->XMLSchemaVersion || $ns == 'http://schemas.xmlsoap.org/soap/encoding/'){
1161                  $this->debug('in serializeType: type namespace indicates XML Schema or SOAP Encoding type');
1162                  if ($unqualified  && $use == 'literal') {
1163                      $elementNS = " xmlns=\"\"";
1164                  } else {
1165                      $elementNS = '';
1166                  }
1167                  if (is_null($value)) {
1168                      if ($use == 'literal') {
1169                          // TODO: depends on minOccurs

1170                          $xml = "<$name$elementNS/>";
1171                      } else {
1172                          // TODO: depends on nillable, which should be checked before calling this method

1173                          $xml = "<$name$elementNS xsi:nil=\"true\" xsi:type=\"" . $this->getPrefixFromNamespace($ns) . ":$uqType\"/>";
1174                      }
1175                      $this->debug("in serializeType: returning: $xml");
1176                      return $xml;
1177                  }
1178                  if ($uqType == 'boolean') {
1179                      if ((is_string($value) && $value == 'false') || (! $value)) {
1180                          $value = 'false';
1181                      } else {
1182                          $value = 'true';
1183                      }
1184                  } 
1185                  if ($uqType == 'string' && gettype($value) == 'string') {
1186                      $value = $this->expandEntities($value);
1187                  }
1188                  if (($uqType == 'long' || $uqType == 'unsignedLong') && gettype($value) == 'double') {
1189                      $value = sprintf("%.0lf", $value);
1190                  }
1191                  // it's a scalar

1192                  // TODO: what about null/nil values?

1193                  // check type isn't a custom type extending xmlschema namespace

1194                  if (!$this->getTypeDef($uqType, $ns)) {
1195                      if ($use == 'literal') {
1196                          if ($forceType) {
1197                              $xml = "<$name$elementNS xsi:type=\"" . $this->getPrefixFromNamespace($ns) . ":$uqType\">$value</$name>";
1198                          } else {
1199                              $xml = "<$name$elementNS>$value</$name>";
1200                          }
1201                      } else {
1202                          $xml = "<$name$elementNS xsi:type=\"" . $this->getPrefixFromNamespace($ns) . ":$uqType\"$encodingStyle>$value</$name>";
1203                      }
1204                      $this->debug("in serializeType: returning: $xml");
1205                      return $xml;
1206                  }
1207                  $this->debug('custom type extends XML Schema or SOAP Encoding namespace (yuck)');
1208              } else if ($ns == 'http://xml.apache.org/xml-soap') {
1209                  $this->debug('in serializeType: appears to be Apache SOAP type');
1210                  if ($uqType == 'Map') {
1211                      $tt_prefix = $this->getPrefixFromNamespace('http://xml.apache.org/xml-soap');
1212                      if (! $tt_prefix) {
1213                          $this->debug('in serializeType: Add namespace for Apache SOAP type');
1214                          $tt_prefix = 'ns' . rand(1000, 9999);
1215                          $this->namespaces[$tt_prefix] = 'http://xml.apache.org/xml-soap';
1216                          // force this to be added to usedNamespaces

1217                          $tt_prefix = $this->getPrefixFromNamespace('http://xml.apache.org/xml-soap');
1218                      }
1219                      $contents = '';
1220                      foreach($value as $k => $v) {
1221                          $this->debug("serializing map element: key $k, value $v");
1222                          $contents .= '<item>';
1223                          $contents .= $this->serialize_val($k,'key',false,false,false,false,$use);
1224                          $contents .= $this->serialize_val($v,'value',false,false,false,false,$use);
1225                          $contents .= '</item>';
1226                      }
1227                      if ($use == 'literal') {
1228                          if ($forceType) {
1229                              $xml = "<$name xsi:type=\"" . $tt_prefix . ":$uqType\">$contents</$name>";
1230                          } else {
1231                              $xml = "<$name>$contents</$name>";
1232                          }
1233                      } else {
1234                          $xml = "<$name xsi:type=\"" . $tt_prefix . ":$uqType\"$encodingStyle>$contents</$name>";
1235                      }
1236                      $this->debug("in serializeType: returning: $xml");
1237                      return $xml;
1238                  }
1239                  $this->debug('in serializeType: Apache SOAP type, but only support Map');
1240              }
1241          } else {
1242              // TODO: should the type be compared to types in XSD, and the namespace

1243              // set to XSD if the type matches?

1244              $this->debug("in serializeType: No namespace for type $type");
1245              $ns = '';
1246              $uqType = $type;
1247          }
1248          if(!$typeDef = $this->getTypeDef($uqType, $ns)){
1249              $this->setError("$type ($uqType) is not a supported type.");
1250              $this->debug("in serializeType: $type ($uqType) is not a supported type.");
1251              return false;
1252          } else {
1253              $this->debug("in serializeType: found typeDef");
1254              $this->appendDebug('typeDef=' . $this->varDump($typeDef));
1255          }
1256          $phpType = $typeDef['phpType'];
1257          $this->debug("in serializeType: uqType: $uqType, ns: $ns, phptype: $phpType, arrayType: " . (isset($typeDef['arrayType']) ? $typeDef['arrayType'] : '') ); 
1258          // if php type == struct, map value to the <all> element names

1259          if ($phpType == 'struct') {
1260              if (isset($typeDef['typeClass']) && $typeDef['typeClass'] == 'element') {
1261                  $elementName = $uqType;
1262                  if (isset($typeDef['form']) && ($typeDef['form'] == 'qualified')) {
1263                      $elementNS = " xmlns=\"$ns\"";
1264                  } else {
1265                      $elementNS = " xmlns=\"\"";
1266                  }
1267              } else {
1268                  $elementName = $name;
1269                  if ($unqualified) {
1270                      $elementNS = " xmlns=\"\"";
1271                  } else {
1272                      $elementNS = '';
1273                  }
1274              }
1275              if (is_null($value)) {
1276                  if ($use == 'literal') {
1277                      // TODO: depends on minOccurs

1278                      $xml = "<$elementName$elementNS/>";
1279                  } else {
1280                      $xml = "<$elementName$elementNS xsi:nil=\"true\" xsi:type=\"" . $this->getPrefixFromNamespace($ns) . ":$uqType\"/>";
1281                  }
1282                  $this->debug("in serializeType: returning: $xml");
1283                  return $xml;
1284              }
1285              if (is_object($value)) {
1286                  $value = get_object_vars($value);
1287              }
1288              if (is_array($value)) {
1289                  $elementAttrs = $this->serializeComplexTypeAttributes($typeDef, $value, $ns, $uqType);
1290                  if ($use == 'literal') {
1291                      if ($forceType) {
1292                          $xml = "<$elementName$elementNS$elementAttrs xsi:type=\"" . $this->getPrefixFromNamespace($ns) . ":$uqType\">";
1293                      } else {
1294                          $xml = "<$elementName$elementNS$elementAttrs>";
1295                      }
1296                  } else {
1297                      $xml = "<$elementName$elementNS$elementAttrs xsi:type=\"" . $this->getPrefixFromNamespace($ns) . ":$uqType\"$encodingStyle>";
1298                  }
1299      
1300                  $xml .= $this->serializeComplexTypeElements($typeDef, $value, $ns, $uqType, $use, $encodingStyle);
1301                  $xml .= "</$elementName>";
1302              } else {
1303                  $this->debug("in serializeType: phpType is struct, but value is not an array");
1304                  $this->setError("phpType is struct, but value is not an array: see debug output for details");
1305                  $xml = '';
1306              }
1307          } elseif ($phpType == 'array') {
1308              if (isset($typeDef['form']) && ($typeDef['form'] == 'qualified')) {
1309                  $elementNS = " xmlns=\"$ns\"";
1310              } else {
1311                  if ($unqualified) {
1312                      $elementNS = " xmlns=\"\"";
1313                  } else {
1314                      $elementNS = '';
1315                  }
1316              }
1317              if (is_null($value)) {
1318                  if ($use == 'literal') {
1319                      // TODO: depends on minOccurs

1320                      $xml = "<$name$elementNS/>";
1321                  } else {
1322                      $xml = "<$name$elementNS xsi:nil=\"true\" xsi:type=\"" .
1323                          $this->getPrefixFromNamespace('http://schemas.xmlsoap.org/soap/encoding/') .
1324                          ":Array\" " .
1325                          $this->getPrefixFromNamespace('http://schemas.xmlsoap.org/soap/encoding/') .
1326                          ':arrayType="' .
1327                          $this->getPrefixFromNamespace($this->getPrefix($typeDef['arrayType'])) .
1328                          ':' .
1329                          $this->getLocalPart($typeDef['arrayType'])."[0]\"/>";
1330                  }
1331                  $this->debug("in serializeType: returning: $xml");
1332                  return $xml;
1333              }
1334              if (isset($typeDef['multidimensional'])) {
1335                  $nv = array();
1336                  foreach($value as $v) {
1337                      $cols = ',' . sizeof($v);
1338                      $nv = array_merge($nv, $v);
1339                  } 
1340                  $value = $nv;
1341              } else {
1342                  $cols = '';
1343              } 
1344              if (is_array($value) && sizeof($value) >= 1) {
1345                  $rows = sizeof($value);
1346                  $contents = '';
1347                  foreach($value as $k => $v) {
1348                      $this->debug("serializing array element: $k, $v of type: $typeDef[arrayType]");
1349                      //if (strpos($typeDef['arrayType'], ':') ) {

1350                      if (!in_array($typeDef['arrayType'],$this->typemap['http://www.w3.org/2001/XMLSchema'])) {
1351                          $contents .= $this->serializeType('item', $typeDef['arrayType'], $v, $use);
1352                      } else {
1353                          $contents .= $this->serialize_val($v, 'item', $typeDef['arrayType'], null, $this->XMLSchemaVersion, false, $use);
1354                      } 
1355                  }
1356              } else {
1357                  $rows = 0;
1358                  $contents = null;
1359              }
1360              // TODO: for now, an empty value will be serialized as a zero element

1361              // array.  Revisit this when coding the handling of null/nil values.

1362              if ($use == 'literal') {
1363                  $xml = "<$name$elementNS>"
1364                      .$contents
1365                      ."</$name>";
1366              } else {
1367                  $xml = "<$name$elementNS xsi:type=\"".$this->getPrefixFromNamespace('http://schemas.xmlsoap.org/soap/encoding/').':Array" '.
1368                      $this->getPrefixFromNamespace('http://schemas.xmlsoap.org/soap/encoding/')
1369                      .':arrayType="'
1370                      .$this->getPrefixFromNamespace($this->getPrefix($typeDef['arrayType']))
1371                      .":".$this->getLocalPart($typeDef['arrayType'])."[$rows$cols]\">"
1372                      .$contents
1373                      ."</$name>";
1374              }
1375          } elseif ($phpType == 'scalar') {
1376              if (isset($typeDef['form']) && ($typeDef['form'] == 'qualified')) {
1377                  $elementNS = " xmlns=\"$ns\"";
1378              } else {
1379                  if ($unqualified) {
1380                      $elementNS = " xmlns=\"\"";
1381                  } else {
1382                      $elementNS = '';
1383                  }
1384              }
1385              if ($use == 'literal') {
1386                  if ($forceType) {
1387                      $xml = "<$name$elementNS xsi:type=\"" . $this->getPrefixFromNamespace($ns) . ":$uqType\">$value</$name>";
1388                  } else {
1389                      $xml = "<$name$elementNS>$value</$name>";
1390                  }
1391              } else {
1392                  $xml = "<$name$elementNS xsi:type=\"" . $this->getPrefixFromNamespace($ns) . ":$uqType\"$encodingStyle>$value</$name>";
1393              }
1394          }
1395          $this->debug("in serializeType: returning: $xml");
1396          return $xml;
1397      }
1398      
1399      /**

1400       * serializes the attributes for a complexType

1401       *

1402       * @param array $typeDef our internal representation of an XML schema type (or element)

1403       * @param mixed $value a native PHP value (parameter value)

1404       * @param string $ns the namespace of the type

1405       * @param string $uqType the local part of the type

1406       * @return string value serialized as an XML string

1407       * @access private

1408       */
1409  	function serializeComplexTypeAttributes($typeDef, $value, $ns, $uqType) {
1410          $xml = '';
1411          if (isset($typeDef['attrs']) && is_array($typeDef['attrs'])) {
1412              $this->debug("serialize attributes for XML Schema type $ns:$uqType");
1413              if (is_array($value)) {
1414                  $xvalue = $value;
1415              } elseif (is_object($value)) {
1416                  $xvalue = get_object_vars($value);
1417              } else {
1418                  $this->debug("value is neither an array nor an object for XML Schema type $ns:$uqType");
1419                  $xvalue = array();
1420              }
1421              foreach ($typeDef['attrs'] as $aName => $attrs) {
1422                  if (isset($xvalue['!' . $aName])) {
1423                      $xname = '!' . $aName;
1424                      $this->debug("value provided for attribute $aName with key $xname");
1425                  } elseif (isset($xvalue[$aName])) {
1426                      $xname = $aName;
1427                      $this->debug("value provided for attribute $aName with key $xname");
1428                  } elseif (isset($attrs['default'])) {
1429                      $xname = '!' . $aName;
1430                      $xvalue[$xname] = $attrs['default'];
1431                      $this->debug('use default value of ' . $xvalue[$aName] . ' for attribute ' . $aName);
1432                  } else {
1433                      $xname = '';
1434                      $this->debug("no value provided for attribute $aName");
1435                  }
1436                  if ($xname) {
1437                      $xml .=  " $aName=\"" . $this->expandEntities($xvalue[$xname]) . "\"";
1438                  }
1439              } 
1440          } else {
1441              $this->debug("no attributes to serialize for XML Schema type $ns:$uqType");
1442          }
1443          if (isset($typeDef['extensionBase'])) {
1444              $ns = $this->getPrefix($typeDef['extensionBase']);
1445              $uqType = $this->getLocalPart($typeDef['extensionBase']);
1446              if ($this->getNamespaceFromPrefix($ns)) {
1447                  $ns = $this->getNamespaceFromPrefix($ns);
1448              }
1449              if ($typeDef = $this->getTypeDef($uqType, $ns)) {
1450                  $this->debug("serialize attributes for extension base $ns:$uqType");
1451                  $xml .= $this->serializeComplexTypeAttributes($typeDef, $value, $ns, $uqType);
1452              } else {
1453                  $this->debug("extension base $ns:$uqType is not a supported type");
1454              }
1455          }
1456          return $xml;
1457      }
1458  
1459      /**

1460       * serializes the elements for a complexType

1461       *

1462       * @param array $typeDef our internal representation of an XML schema type (or element)

1463       * @param mixed $value a native PHP value (parameter value)

1464       * @param string $ns the namespace of the type

1465       * @param string $uqType the local part of the type

1466       * @param string $use use for part (encoded|literal)

1467       * @param string $encodingStyle SOAP encoding style for the value (if different than the enclosing style)

1468       * @return string value serialized as an XML string

1469       * @access private

1470       */
1471  	function serializeComplexTypeElements($typeDef, $value, $ns, $uqType, $use='encoded', $encodingStyle=false) {
1472          $xml = '';
1473          if (isset($typeDef['elements']) && is_array($typeDef['elements'])) {
1474              $this->debug("in serializeComplexTypeElements, serialize elements for XML Schema type $ns:$uqType");
1475              if (is_array($value)) {
1476                  $xvalue = $value;
1477              } elseif (is_object($value)) {
1478                  $xvalue = get_object_vars($value);
1479              } else {
1480                  $this->debug("value is neither an array nor an object for XML Schema type $ns:$uqType");
1481                  $xvalue = array();
1482              }
1483              // toggle whether all elements are present - ideally should validate against schema

1484              if (count($typeDef['elements']) != count($xvalue)){
1485                  $optionals = true;
1486              }
1487              foreach ($typeDef['elements'] as $eName => $attrs) {
1488                  if (!isset($xvalue[$eName])) {
1489                      if (isset($attrs['default'])) {
1490                          $xvalue[$eName] = $attrs['default'];
1491                          $this->debug('use default value of ' . $xvalue[$eName] . ' for element ' . $eName);
1492                      }
1493                  }
1494                  // if user took advantage of a minOccurs=0, then only serialize named parameters

1495                  if (isset($optionals)
1496                      && (!isset($xvalue[$eName])) 
1497                      && ( (!isset($attrs['nillable'])) || $attrs['nillable'] != 'true')
1498                      ){
1499                      if (isset($attrs['minOccurs']) && $attrs['minOccurs'] <> '0') {
1500                          $this->debug("apparent error: no value provided for element $eName with minOccurs=" . $attrs['minOccurs']);
1501                      }
1502                      // do nothing

1503                      $this->debug("no value provided for complexType element $eName and element is not nillable, so serialize nothing");
1504                  } else {
1505                      // get value

1506                      if (isset($xvalue[$eName])) {
1507                          $v = $xvalue[$eName];
1508                      } else {
1509                          $v = null;
1510                      }
1511                      if (isset($attrs['form'])) {
1512                          $unqualified = ($attrs['form'] == 'unqualified');
1513                      } else {
1514                          $unqualified = false;
1515                      }
1516                      if (isset($attrs['maxOccurs']) && ($attrs['maxOccurs'] == 'unbounded' || $attrs['maxOccurs'] > 1) && isset($v) && is_array($v) && $this->isArraySimpleOrStruct($v) == 'arraySimple') {
1517                          $vv = $v;
1518                          foreach ($vv as $k => $v) {
1519                              if (isset($attrs['type']) || isset($attrs['ref'])) {
1520                                  // serialize schema-defined type

1521                                  $xml .= $this->serializeType($eName, isset($attrs['type']) ? $attrs['type'] : $attrs['ref'], $v, $use, $encodingStyle, $unqualified);
1522                              } else {
1523                                  // serialize generic type (can this ever really happen?)

1524                                  $this->debug("calling serialize_val() for $v, $eName, false, false, false, false, $use");
1525                                  $xml .= $this->serialize_val($v, $eName, false, false, false, false, $use);
1526                              }
1527                          }
1528                      } else {
1529                          if (isset($attrs['type']) || isset($attrs['ref'])) {
1530                              // serialize schema-defined type

1531                              $xml .= $this->serializeType($eName, isset($attrs['type']) ? $attrs['type'] : $attrs['ref'], $v, $use, $encodingStyle, $unqualified);
1532                          } else {
1533                              // serialize generic type (can this ever really happen?)

1534                              $this->debug("calling serialize_val() for $v, $eName, false, false, false, false, $use");
1535                              $xml .= $this->serialize_val($v, $eName, false, false, false, false, $use);
1536                          }
1537                      }
1538                  }
1539              } 
1540          } else {
1541              $this->debug("no elements to serialize for XML Schema type $ns:$uqType");
1542          }
1543          if (isset($typeDef['extensionBase'])) {
1544              $ns = $this->getPrefix($typeDef['extensionBase']);
1545              $uqType = $this->getLocalPart($typeDef['extensionBase']);
1546              if ($this->getNamespaceFromPrefix($ns)) {
1547                  $ns = $this->getNamespaceFromPrefix($ns);
1548              }
1549              if ($typeDef = $this->getTypeDef($uqType, $ns)) {
1550                  $this->debug("serialize elements for extension base $ns:$uqType");
1551                  $xml .= $this->serializeComplexTypeElements($typeDef, $value, $ns, $uqType, $use, $encodingStyle);
1552              } else {
1553                  $this->debug("extension base $ns:$uqType is not a supported type");
1554              }
1555          }
1556          return $xml;
1557      }
1558  
1559      /**

1560      * adds an XML Schema complex type to the WSDL types

1561      *

1562      * @param string    name

1563      * @param string typeClass (complexType|simpleType|attribute)

1564      * @param string phpType: currently supported are array and struct (php assoc array)

1565      * @param string compositor (all|sequence|choice)

1566      * @param string restrictionBase namespace:name (http://schemas.xmlsoap.org/soap/encoding/:Array)

1567      * @param array elements = array ( name => array(name=>'',type=>'') )

1568      * @param array attrs =     array(array('ref'=>'SOAP-ENC:arrayType','wsdl:arrayType'=>'xsd:string[]'))

1569      * @param string arrayType: namespace:name (xsd:string)

1570      * @see xmlschema

1571      * @access public

1572      */
1573  	function addComplexType($name,$typeClass='complexType',$phpType='array',$compositor='',$restrictionBase='',$elements=array(),$attrs=array(),$arrayType='') {
1574          if (count($elements) > 0) {
1575              foreach($elements as $n => $e){
1576                  // expand each element

1577                  foreach ($e as $k => $v) {
1578                      $k = strpos($k,':') ? $this->expandQname($k) : $k;
1579                      $v = strpos($v,':') ? $this->expandQname($v) : $v;
1580                      $ee[$k] = $v;
1581                  }
1582                  $eElements[$n] = $ee;
1583              }
1584              $elements = $eElements;
1585          }
1586          
1587          if (count($attrs) > 0) {
1588              foreach($attrs as $n => $a){
1589                  // expand each attribute

1590                  foreach ($a as $k => $v) {
1591                      $k = strpos($k,':') ? $this->expandQname($k) : $k;
1592                      $v = strpos($v,':') ? $this->expandQname($v) : $v;
1593                      $aa[$k] = $v;
1594                  }
1595                  $eAttrs[$n] = $aa;
1596              }
1597              $attrs = $eAttrs;
1598          }
1599  
1600          $restrictionBase = strpos($restrictionBase,':') ? $this->expandQname($restrictionBase) : $restrictionBase;
1601          $arrayType = strpos($arrayType,':') ? $this->expandQname($arrayType) : $arrayType;
1602  
1603          $typens = isset($this->namespaces['types']) ? $this->namespaces['types'] : $this->namespaces['tns'];
1604          $this->schemas[$typens][0]->addComplexType($name,$typeClass,$phpType,$compositor,$restrictionBase,$elements,$attrs,$arrayType);
1605      }
1606  
1607      /**

1608      * adds an XML Schema simple type to the WSDL types

1609      *

1610      * @param string $name

1611      * @param string $restrictionBase namespace:name (http://schemas.xmlsoap.org/soap/encoding/:Array)

1612      * @param string $typeClass (should always be simpleType)

1613      * @param string $phpType (should always be scalar)

1614      * @param array $enumeration array of values

1615      * @see xmlschema

1616      * @access public

1617      */
1618  	function addSimpleType($name, $restrictionBase='', $typeClass='simpleType', $phpType='scalar', $enumeration=array()) {
1619          $restrictionBase = strpos($restrictionBase,':') ? $this->expandQname($restrictionBase) : $restrictionBase;
1620  
1621          $typens = isset($this->namespaces['types']) ? $this->namespaces['types'] : $this->namespaces['tns'];
1622          $this->schemas[$typens][0]->addSimpleType($name, $restrictionBase, $typeClass, $phpType, $enumeration);
1623      }
1624  
1625      /**

1626      * adds an element to the WSDL types

1627      *

1628      * @param array $attrs attributes that must include name and type

1629      * @see xmlschema

1630      * @access public

1631      */
1632  	function addElement($attrs) {
1633          $typens = isset($this->namespaces['types']) ? $this->namespaces['types'] : $this->namespaces['tns'];
1634          $this->schemas[$typens][0]->addElement($attrs);
1635      }
1636  
1637      /**

1638      * register an operation with the server

1639      * 

1640      * @param string $name operation (method) name

1641      * @param array $in assoc array of input values: key = param name, value = param type

1642      * @param array $out assoc array of output values: key = param name, value = param type

1643      * @param string $namespace optional The namespace for the operation

1644      * @param string $soapaction optional The soapaction for the operation

1645      * @param string $style (rpc|document) optional The style for the operation Note: when 'document' is specified, parameter and return wrappers are created for you automatically

1646      * @param string $use (encoded|literal) optional The use for the parameters (cannot mix right now)

1647      * @param string $documentation optional The description to include in the WSDL

1648      * @param string $encodingStyle optional (usually 'http://schemas.xmlsoap.org/soap/encoding/' for encoded)

1649      * @access public 

1650      */
1651  	function addOperation($name, $in = false, $out = false, $namespace = false, $soapaction = false, $style = 'rpc', $use = 'encoded', $documentation = '', $encodingStyle = ''){
1652          if ($use == 'encoded' && $encodingStyle == '') {
1653              $encodingStyle = 'http://schemas.xmlsoap.org/soap/encoding/';
1654          }
1655  
1656          if ($style == 'document') {
1657              $elements = array();
1658              foreach ($in as $n => $t) {
1659                  $elements[$n] = array('name' => $n, 'type' => $t);
1660              }
1661              $this->addComplexType($name . 'RequestType', 'complexType', 'struct', 'all', '', $elements);
1662              $this->addElement(array('name' => $name, 'type' => $name . 'RequestType'));
1663              $in = array('parameters' => 'tns:' . $name);
1664  
1665              $elements = array();
1666              foreach ($out as $n => $t) {
1667                  $elements[$n] = array('name' => $n, 'type' => $t);
1668              }
1669              $this->addComplexType($name . 'ResponseType', 'complexType', 'struct', 'all', '', $elements);
1670              $this->addElement(array('name' => $name . 'Response', 'type' => $name . 'ResponseType'));
1671              $out = array('parameters' => 'tns:' . $name . 'Response');
1672          }
1673  
1674          // get binding

1675          $this->bindings[ $this->serviceName . 'Binding' ]['operations'][$name] =
1676          array(
1677          'name' => $name,
1678          'binding' => $this->serviceName . 'Binding',
1679          'endpoint' => $this->endpoint,
1680          'soapAction' => $soapaction,
1681          'style' => $style,
1682          'input' => array(
1683              'use' => $use,
1684              'namespace' => $namespace,
1685              'encodingStyle' => $encodingStyle,
1686              'message' => $name . 'Request',
1687              'parts' => $in),
1688          'output' => array(
1689              'use' => $use,
1690              'namespace' => $namespace,
1691              'encodingStyle' => $encodingStyle,
1692              'message' => $name . 'Response',
1693              'parts' => $out),
1694          'namespace' => $namespace,
1695          'transport' => 'http://schemas.xmlsoap.org/soap/http',
1696          'documentation' => $documentation); 
1697          // add portTypes

1698          // add messages

1699          if($in)
1700          {
1701              foreach($in as $pName => $pType)
1702              {
1703                  if(strpos($pType,':')) {
1704                      $pType = $this->getNamespaceFromPrefix($this->getPrefix($pType)).":".$this->getLocalPart($pType);
1705                  }
1706                  $this->messages[$name.'Request'][$pName] = $pType;
1707              }
1708          } else {
1709              $this->messages[$name.'Request']= '0';
1710          }
1711          if($out)
1712          {
1713              foreach($out as $pName => $pType)
1714              {
1715                  if(strpos($pType,':')) {
1716                      $pType = $this->getNamespaceFromPrefix($this->getPrefix($pType)).":".$this->getLocalPart($pType);
1717                  }
1718                  $this->messages[$name.'Response'][$pName] = $pType;
1719              }
1720          } else {
1721              $this->messages[$name.'Response']= '0';
1722          }
1723          return true;
1724      } 
1725  }
1726  
1727  ?>


Généré le : Tue Apr 3 18:50:37 2007 par Balluche grâce à PHPXref 0.7