ILIAS  release_5-3 Revision v5.3.23-19-g915713cf615
nusoap.php
Go to the documentation of this file.
1 <?php
2 
3 /*
4 $Id$
5 
6 NuSOAP - Web Services Toolkit for PHP
7 
8 Copyright (c) 2002 NuSphere Corporation
9 
10 This library is free software; you can redistribute it and/or
11 modify it under the terms of the GNU Lesser General Public
12 License as published by the Free Software Foundation; either
13 version 2.1 of the License, or (at your option) any later version.
14 
15 This library is distributed in the hope that it will be useful,
16 but WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18 Lesser General Public License for more details.
19 
20 You should have received a copy of the GNU Lesser General Public
21 License along with this library; if not, write to the Free Software
22 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
23 
24 The NuSOAP project home is:
25 http://sourceforge.net/projects/nusoap/
26 
27 The primary support for NuSOAP is the mailing list:
28 nusoap-general@lists.sourceforge.net
29 
30 If you have any questions or comments, please email:
31 
32 Dietrich Ayala
33 dietrich@ganx4.com
34 http://dietrich.ganx4.com/nusoap
35 
36 NuSphere Corporation
37 http://www.nusphere.com
38 
39 */
40 
41 /*
42  * Some of the standards implmented in whole or part by NuSOAP:
43  *
44  * SOAP 1.1 (http://www.w3.org/TR/2000/NOTE-SOAP-20000508/)
45  * WSDL 1.1 (http://www.w3.org/TR/2001/NOTE-wsdl-20010315)
46  * SOAP Messages With Attachments (http://www.w3.org/TR/SOAP-attachments)
47  * XML 1.0 (http://www.w3.org/TR/2006/REC-xml-20060816/)
48  * Namespaces in XML 1.0 (http://www.w3.org/TR/2006/REC-xml-names-20060816/)
49  * XML Schema 1.0 (http://www.w3.org/TR/xmlschema-0/)
50  * RFC 2045 Multipurpose Internet Mail Extensions (MIME) Part One: Format of Internet Message Bodies
51  * RFC 2068 Hypertext Transfer Protocol -- HTTP/1.1
52  * RFC 2617 HTTP Authentication: Basic and Digest Access Authentication
53  */
54 
55 /* load classes
56 
57 // necessary classes
58 require_once('class.soapclient.php');
59 require_once('class.soap_val.php');
60 require_once('class.soap_parser.php');
61 require_once('class.soap_fault.php');
62 
63 // transport classes
64 require_once('class.soap_transport_http.php');
65 
66 // optional add-on classes
67 require_once('class.xmlschema.php');
68 require_once('class.wsdl.php');
69 
70 // server class
71 require_once('class.soap_server.php');*/
72 
73 // class variable emulation
74 // cf. http://www.webkreator.com/php/techniques/php-static-class-variables.html
75 
76 // alex patch: we need an object here, otherwise we will get a warning in php 5.4
77 if (!is_object($GLOBALS['_transient']['static']['nusoap_base']))
78 {
79  $GLOBALS['_transient']['static']['nusoap_base'] = new stdClass();
80 }
81 $GLOBALS['_transient']['static']['nusoap_base']->globalDebugLevel = 0;
82 
92 class nusoap_base {
99  var $title = 'NuSOAP';
106  var $version = '0.7.3';
113  var $revision = '$Revision$';
120  var $error_str = '';
127  var $debug_str = '';
135  var $charencoding = true;
143 
150  var $XMLSchemaVersion = 'http://www.w3.org/2001/XMLSchema';
151 
158  //var $soap_defencoding = 'ISO-8859-1';
159  var $soap_defencoding = 'UTF-8';
160 
169  var $namespaces = array(
170  'SOAP-ENV' => 'http://schemas.xmlsoap.org/soap/envelope/',
171  'xsd' => 'http://www.w3.org/2001/XMLSchema',
172  'xsi' => 'http://www.w3.org/2001/XMLSchema-instance',
173  'SOAP-ENC' => 'http://schemas.xmlsoap.org/soap/encoding/'
174  );
175 
182  var $usedNamespaces = array();
183 
191  var $typemap = array(
192  'http://www.w3.org/2001/XMLSchema' => array(
193  'string'=>'string','boolean'=>'boolean','float'=>'double','double'=>'double','decimal'=>'double',
194  'duration'=>'','dateTime'=>'string','time'=>'string','date'=>'string','gYearMonth'=>'',
195  'gYear'=>'','gMonthDay'=>'','gDay'=>'','gMonth'=>'','hexBinary'=>'string','base64Binary'=>'string',
196  // abstract "any" types
197  'anyType'=>'string','anySimpleType'=>'string',
198  // derived datatypes
199  'normalizedString'=>'string','token'=>'string','language'=>'','NMTOKEN'=>'','NMTOKENS'=>'','Name'=>'','NCName'=>'','ID'=>'',
200  'IDREF'=>'','IDREFS'=>'','ENTITY'=>'','ENTITIES'=>'','integer'=>'integer','nonPositiveInteger'=>'integer',
201  'negativeInteger'=>'integer','long'=>'integer','int'=>'integer','short'=>'integer','byte'=>'integer','nonNegativeInteger'=>'integer',
202  'unsignedLong'=>'','unsignedInt'=>'','unsignedShort'=>'','unsignedByte'=>'','positiveInteger'=>''),
203  'http://www.w3.org/2000/10/XMLSchema' => array(
204  'i4'=>'','int'=>'integer','boolean'=>'boolean','string'=>'string','double'=>'double',
205  'float'=>'double','dateTime'=>'string',
206  'timeInstant'=>'string','base64Binary'=>'string','base64'=>'string','ur-type'=>'array'),
207  'http://www.w3.org/1999/XMLSchema' => array(
208  'i4'=>'','int'=>'integer','boolean'=>'boolean','string'=>'string','double'=>'double',
209  'float'=>'double','dateTime'=>'string',
210  'timeInstant'=>'string','base64Binary'=>'string','base64'=>'string','ur-type'=>'array'),
211  'http://soapinterop.org/xsd' => array('SOAPStruct'=>'struct'),
212  'http://schemas.xmlsoap.org/soap/encoding/' => array('base64'=>'string','array'=>'array','Array'=>'array'),
213  'http://xml.apache.org/xml-soap' => array('Map')
214  );
215 
224  var $xmlEntities = array('quot' => '"','amp' => '&',
225  'lt' => '<','gt' => '>','apos' => "'");
226 
232  function __construct() {
233  $this->debugLevel = $GLOBALS['_transient']['static']['nusoap_base']->globalDebugLevel;
234  }
235 
242  function getGlobalDebugLevel() {
243  return $GLOBALS['_transient']['static']['nusoap_base']->globalDebugLevel;
244  }
245 
252  function setGlobalDebugLevel($level) {
253  $GLOBALS['_transient']['static']['nusoap_base']->globalDebugLevel = $level;
254  }
255 
262  function getDebugLevel() {
263  return $this->debugLevel;
264  }
265 
272  function setDebugLevel($level) {
273  $this->debugLevel = $level;
274  }
275 
282  function debug($string){
283  if ($this->debugLevel > 0) {
284  $this->appendDebug($this->getmicrotime().' '.get_class($this).": $string\n");
285  }
286  }
287 
294  function appendDebug($string){
295  if ($this->debugLevel > 0) {
296  // it would be nice to use a memory stream here to use
297  // memory more efficiently
298  $this->debug_str .= $string;
299  }
300  }
301 
307  function clearDebug() {
308  // it would be nice to use a memory stream here to use
309  // memory more efficiently
310  $this->debug_str = '';
311  }
312 
319  function &getDebug() {
320  // it would be nice to use a memory stream here to use
321  // memory more efficiently
322  return $this->debug_str;
323  }
324 
332  function &getDebugAsXMLComment() {
333  // it would be nice to use a memory stream here to use
334  // memory more efficiently
335  while (strpos($this->debug_str, '--')) {
336  $this->debug_str = str_replace('--', '- -', $this->debug_str);
337  }
338  $ret = "<!--\n" . $this->debug_str . "\n-->";
339  return $ret;
340  }
341 
348  function expandEntities($val) {
349  if ($this->charencoding) {
350  $val = str_replace('&', '&amp;', $val);
351  $val = str_replace("'", '&apos;', $val);
352  $val = str_replace('"', '&quot;', $val);
353  $val = str_replace('<', '&lt;', $val);
354  $val = str_replace('>', '&gt;', $val);
355  }
356  return $val;
357  }
358 
365  function getError(){
366  if($this->error_str != ''){
367  return $this->error_str;
368  }
369  return false;
370  }
371 
378  function setError($str){
379  $this->error_str = $str;
380  }
381 
389  function isArraySimpleOrStruct($val) {
390  $keyList = array_keys($val);
391  foreach ($keyList as $keyListValue) {
392  if (!is_int($keyListValue)) {
393  return 'arrayStruct';
394  }
395  }
396  return 'arraySimple';
397  }
398 
414  function serialize_val($val,$name=false,$type=false,$name_ns=false,$type_ns=false,$attributes=false,$use='encoded',$soapval=false) {
415  $this->debug("in serialize_val: name=$name, type=$type, name_ns=$name_ns, type_ns=$type_ns, use=$use, soapval=$soapval");
416  $this->appendDebug('value=' . $this->varDump($val));
417  $this->appendDebug('attributes=' . $this->varDump($attributes));
418 
419  if (is_object($val) && get_class($val) == 'soapval' && (! $soapval)) {
420  $this->debug("serialize_val: serialize soapval");
421  $xml = $val->serialize($use);
422  $this->appendDebug($val->getDebug());
423  $val->clearDebug();
424  $this->debug("serialize_val of soapval returning $xml");
425  return $xml;
426  }
427  // force valid name if necessary
428  if (is_numeric($name)) {
429  $name = '__numeric_' . $name;
430  } elseif (! $name) {
431  $name = 'noname';
432  }
433  // if name has ns, add ns prefix to name
434  $xmlns = '';
435  if($name_ns){
436  $prefix = 'nu'.rand(1000,9999);
437  $name = $prefix.':'.$name;
438  $xmlns .= " xmlns:$prefix=\"$name_ns\"";
439  }
440  // if type is prefixed, create type prefix
441  if($type_ns != '' && $type_ns == $this->namespaces['xsd']){
442  // need to fix this. shouldn't default to xsd if no ns specified
443  // w/o checking against typemap
444  $type_prefix = 'xsd';
445  } elseif($type_ns){
446  $type_prefix = 'ns'.rand(1000,9999);
447  $xmlns .= " xmlns:$type_prefix=\"$type_ns\"";
448  }
449  // serialize attributes if present
450  $atts = '';
451  if($attributes){
452  foreach($attributes as $k => $v){
453  $atts .= " $k=\"".$this->expandEntities($v).'"';
454  }
455  }
456  // serialize null value
457  if (is_null($val)) {
458  $this->debug("serialize_val: serialize null");
459  if ($use == 'literal') {
460  // TODO: depends on minOccurs
461  $xml = "<$name$xmlns$atts/>";
462  $this->debug("serialize_val returning $xml");
463  return $xml;
464  } else {
465  if (isset($type) && isset($type_prefix)) {
466  $type_str = " xsi:type=\"$type_prefix:$type\"";
467  } else {
468  $type_str = '';
469  }
470  $xml = "<$name$xmlns$type_str$atts xsi:nil=\"true\"/>";
471  $this->debug("serialize_val returning $xml");
472  return $xml;
473  }
474  }
475  // serialize if an xsd built-in primitive type
476  if($type != '' && isset($this->typemap[$this->XMLSchemaVersion][$type])){
477  $this->debug("serialize_val: serialize xsd built-in primitive type");
478  if (is_bool($val)) {
479  if ($type == 'boolean') {
480  $val = $val ? 'true' : 'false';
481  } elseif (! $val) {
482  $val = 0;
483  }
484  } else if (is_string($val)) {
485  $val = $this->expandEntities($val);
486  }
487  if ($use == 'literal') {
488  $xml = "<$name$xmlns$atts>$val</$name>";
489  $this->debug("serialize_val returning $xml");
490  return $xml;
491  } else {
492  $xml = "<$name$xmlns xsi:type=\"xsd:$type\"$atts>$val</$name>";
493  $this->debug("serialize_val returning $xml");
494  return $xml;
495  }
496  }
497  // detect type and serialize
498  $xml = '';
499  switch(true) {
500  case (is_bool($val) || $type == 'boolean'):
501  $this->debug("serialize_val: serialize boolean");
502  if ($type == 'boolean') {
503  $val = $val ? 'true' : 'false';
504  } elseif (! $val) {
505  $val = 0;
506  }
507  if ($use == 'literal') {
508  $xml .= "<$name$xmlns$atts>$val</$name>";
509  } else {
510  $xml .= "<$name$xmlns xsi:type=\"xsd:boolean\"$atts>$val</$name>";
511  }
512  break;
513  case (is_int($val) || is_long($val) || $type == 'int'):
514  $this->debug("serialize_val: serialize int");
515  if ($use == 'literal') {
516  $xml .= "<$name$xmlns$atts>$val</$name>";
517  } else {
518  $xml .= "<$name$xmlns xsi:type=\"xsd:int\"$atts>$val</$name>";
519  }
520  break;
521  case (is_float($val)|| is_double($val) || $type == 'float'):
522  $this->debug("serialize_val: serialize float");
523  if ($use == 'literal') {
524  $xml .= "<$name$xmlns$atts>$val</$name>";
525  } else {
526  $xml .= "<$name$xmlns xsi:type=\"xsd:float\"$atts>$val</$name>";
527  }
528  break;
529  case (is_string($val) || $type == 'string'):
530  $this->debug("serialize_val: serialize string");
531  $val = $this->expandEntities($val);
532  if ($use == 'literal') {
533  $xml .= "<$name$xmlns$atts>$val</$name>";
534  } else {
535  $xml .= "<$name$xmlns xsi:type=\"xsd:string\"$atts>$val</$name>";
536  }
537  break;
538  case is_object($val):
539  $this->debug("serialize_val: serialize object");
540  if (get_class($val) == 'soapval') {
541  $this->debug("serialize_val: serialize soapval object");
542  $pXml = $val->serialize($use);
543  $this->appendDebug($val->getDebug());
544  $val->clearDebug();
545  } else {
546  if (! $name) {
547  $name = get_class($val);
548  $this->debug("In serialize_val, used class name $name as element name");
549  } else {
550  $this->debug("In serialize_val, do not override name $name for element name for class " . get_class($val));
551  }
552  foreach(get_object_vars($val) as $k => $v){
553  $pXml = isset($pXml) ? $pXml.$this->serialize_val($v,$k,false,false,false,false,$use) : $this->serialize_val($v,$k,false,false,false,false,$use);
554  }
555  }
556  if(isset($type) && isset($type_prefix)){
557  $type_str = " xsi:type=\"$type_prefix:$type\"";
558  } else {
559  $type_str = '';
560  }
561  if ($use == 'literal') {
562  $xml .= "<$name$xmlns$atts>$pXml</$name>";
563  } else {
564  $xml .= "<$name$xmlns$type_str$atts>$pXml</$name>";
565  }
566  break;
567  break;
568  case (is_array($val) || $type):
569  // detect if struct or array
570  $valueType = $this->isArraySimpleOrStruct($val);
571  if($valueType=='arraySimple' || preg_match('/^ArrayOf/',$type)){
572  $this->debug("serialize_val: serialize array");
573  $i = 0;
574  if(is_array($val) && count($val)> 0){
575  foreach($val as $v){
576  if(is_object($v) && get_class($v) == 'soapval'){
577  $tt_ns = $v->type_ns;
578  $tt = $v->type;
579  } elseif (is_array($v)) {
580  $tt = $this->isArraySimpleOrStruct($v);
581  } else {
582  $tt = gettype($v);
583  }
584  $array_types[$tt] = 1;
585  // TODO: for literal, the name should be $name
586  $xml .= $this->serialize_val($v,'item',false,false,false,false,$use);
587  ++$i;
588  }
589  if(count($array_types) > 1){
590  $array_typename = 'xsd:anyType';
591  } elseif(isset($tt) && isset($this->typemap[$this->XMLSchemaVersion][$tt])) {
592  if ($tt == 'integer') {
593  $tt = 'int';
594  }
595  $array_typename = 'xsd:'.$tt;
596  } elseif(isset($tt) && $tt == 'arraySimple'){
597  $array_typename = 'SOAP-ENC:Array';
598  } elseif(isset($tt) && $tt == 'arrayStruct'){
599  $array_typename = 'unnamed_struct_use_soapval';
600  } else {
601  // if type is prefixed, create type prefix
602  if ($tt_ns != '' && $tt_ns == $this->namespaces['xsd']){
603  $array_typename = 'xsd:' . $tt;
604  } elseif ($tt_ns) {
605  $tt_prefix = 'ns' . rand(1000, 9999);
606  $array_typename = "$tt_prefix:$tt";
607  $xmlns .= " xmlns:$tt_prefix=\"$tt_ns\"";
608  } else {
609  $array_typename = $tt;
610  }
611  }
612  $array_type = $i;
613  if ($use == 'literal') {
614  $type_str = '';
615  } else if (isset($type) && isset($type_prefix)) {
616  $type_str = " xsi:type=\"$type_prefix:$type\"";
617  } else {
618  $type_str = " xsi:type=\"SOAP-ENC:Array\" SOAP-ENC:arrayType=\"".$array_typename."[$array_type]\"";
619  }
620  // empty array
621  } else {
622  if ($use == 'literal') {
623  $type_str = '';
624  } else if (isset($type) && isset($type_prefix)) {
625  $type_str = " xsi:type=\"$type_prefix:$type\"";
626  } else {
627  $type_str = " xsi:type=\"SOAP-ENC:Array\" SOAP-ENC:arrayType=\"xsd:anyType[0]\"";
628  }
629  }
630  // TODO: for array in literal, there is no wrapper here
631  $xml = "<$name$xmlns$type_str$atts>".$xml."</$name>";
632  } else {
633  // got a struct
634  $this->debug("serialize_val: serialize struct");
635  if(isset($type) && isset($type_prefix)){
636  $type_str = " xsi:type=\"$type_prefix:$type\"";
637  } else {
638  $type_str = '';
639  }
640  if ($use == 'literal') {
641  $xml .= "<$name$xmlns$atts>";
642  } else {
643  $xml .= "<$name$xmlns$type_str$atts>";
644  }
645  foreach($val as $k => $v){
646  // Apache Map
647  if ($type == 'Map' && $type_ns == 'http://xml.apache.org/xml-soap') {
648  $xml .= '<item>';
649  $xml .= $this->serialize_val($k,'key',false,false,false,false,$use);
650  $xml .= $this->serialize_val($v,'value',false,false,false,false,$use);
651  $xml .= '</item>';
652  } else {
653  $xml .= $this->serialize_val($v,$k,false,false,false,false,$use);
654  }
655  }
656  $xml .= "</$name>";
657  }
658  break;
659  default:
660  $this->debug("serialize_val: serialize unknown");
661  $xml .= 'not detected, got '.gettype($val).' for '.$val;
662  break;
663  }
664  $this->debug("serialize_val returning $xml");
665  return $xml;
666  }
667 
680  function serializeEnvelope($body,$headers=false,$namespaces=array(),$style='rpc',$use='encoded',$encodingStyle='http://schemas.xmlsoap.org/soap/encoding/'){
681  // TODO: add an option to automatically run utf8_encode on $body and $headers
682  // if $this->soap_defencoding is UTF-8. Not doing this automatically allows
683  // one to send arbitrary UTF-8 characters, not just characters that map to ISO-8859-1
684 
685  $this->debug("In serializeEnvelope length=" . strlen($body) . " body (max 1000 characters)=" . substr($body, 0, 1000) . " style=$style use=$use encodingStyle=$encodingStyle");
686  $this->debug("headers:");
687  $this->appendDebug($this->varDump($headers));
688  $this->debug("namespaces:");
689  $this->appendDebug($this->varDump($namespaces));
690 
691  // serialize namespaces
692  $ns_string = '';
693  foreach(array_merge($this->namespaces,$namespaces) as $k => $v){
694  $ns_string .= " xmlns:$k=\"$v\"";
695  }
696  if($encodingStyle) {
697  $ns_string = " SOAP-ENV:encodingStyle=\"$encodingStyle\"$ns_string";
698  }
699 
700  // serialize headers
701  if($headers){
702  if (is_array($headers)) {
703  $xml = '';
704  foreach ($headers as $k => $v) {
705  if (is_object($v) && get_class($v) == 'soapval') {
706  $xml .= $this->serialize_val($v, false, false, false, false, false, $use);
707  } else {
708  $xml .= $this->serialize_val($v, $k, false, false, false, false, $use);
709  }
710  }
711  $headers = $xml;
712  $this->debug("In serializeEnvelope, serialized array of headers to $headers");
713  }
714  $headers = "<SOAP-ENV:Header>".$headers."</SOAP-ENV:Header>";
715  }
716  // serialize envelope
717  return
718  '<?xml version="1.0" encoding="'.$this->soap_defencoding .'"?'.">".
719  '<SOAP-ENV:Envelope'.$ns_string.">".
720  $headers.
721  "<SOAP-ENV:Body>".
722  $body.
723  "</SOAP-ENV:Body>".
724  "</SOAP-ENV:Envelope>";
725  }
726 
735  function formatDump($str){
736  $str = htmlspecialchars($str);
737  return nl2br($str);
738  }
739 
747  function contractQname($qname){
748  // get element namespace
749  //$this->xdebug("Contract $qname");
750  if (strrpos($qname, ':')) {
751  // get unqualified name
752  $name = substr($qname, strrpos($qname, ':') + 1);
753  // get ns
754  $ns = substr($qname, 0, strrpos($qname, ':'));
755  $p = $this->getPrefixFromNamespace($ns);
756  if ($p) {
757  return $p . ':' . $name;
758  }
759  return $qname;
760  } else {
761  return $qname;
762  }
763  }
764 
772  function expandQname($qname){
773  // get element prefix
774  if(strpos($qname,':') && !preg_match('/^http:\/\//',$qname)){
775  // get unqualified name
776  $name = substr(strstr($qname,':'),1);
777  // get ns prefix
778  $prefix = substr($qname,0,strpos($qname,':'));
779  if(isset($this->namespaces[$prefix])){
780  return $this->namespaces[$prefix].':'.$name;
781  } else {
782  return $qname;
783  }
784  } else {
785  return $qname;
786  }
787  }
788 
797  function getLocalPart($str){
798  if($sstr = strrchr($str,':')){
799  // get unqualified name
800  return substr( $sstr, 1 );
801  } else {
802  return $str;
803  }
804  }
805 
814  function getPrefix($str){
815  if($pos = strrpos($str,':')){
816  // get prefix
817  return substr($str,0,$pos);
818  }
819  return false;
820  }
821 
829  function getNamespaceFromPrefix($prefix){
830  if (isset($this->namespaces[$prefix])) {
831  return $this->namespaces[$prefix];
832  }
833  //$this->setError("No namespace registered for prefix '$prefix'");
834  return false;
835  }
836 
845  function getPrefixFromNamespace($ns) {
846  foreach ($this->namespaces as $p => $n) {
847  if ($ns == $n || $ns == $p) {
848  $this->usedNamespaces[$p] = $n;
849  return $p;
850  }
851  }
852  return false;
853  }
854 
861  function getmicrotime() {
862  if (function_exists('gettimeofday')) {
863  $tod = gettimeofday();
864  $sec = $tod['sec'];
865  $usec = $tod['usec'];
866  } else {
867  $sec = time();
868  $usec = 0;
869  }
870  return strftime('%Y-%m-%d %H:%M:%S', $sec) . '.' . sprintf('%06d', $usec);
871  }
872 
880  function varDump($data) {
881  ob_start();
882  var_dump($data);
883  $ret_val = ob_get_contents();
884  ob_end_clean();
885  return $ret_val;
886  }
887 
894  function __toString() {
895  return $this->varDump($this);
896  }
897 }
898 
899 // XML Schema Datatype Helper Functions
900 
901 //xsd:dateTime helpers
902 
910 function timestamp_to_iso8601($timestamp,$utc=true){
911  $datestr = date('Y-m-d\TH:i:sO',$timestamp);
912  if($utc){
913  $pattern = '/'.
914  '([0-9]{4})-'. // centuries & years CCYY-
915  '([0-9]{2})-'. // months MM-
916  '([0-9]{2})'. // days DD
917  'T'. // separator T
918  '([0-9]{2}):'. // hours hh:
919  '([0-9]{2}):'. // minutes mm:
920  '([0-9]{2})(\.[0-9]*)?'. // seconds ss.ss...
921  '(Z|[+\-][0-9]{2}:?[0-9]{2})?'. // Z to indicate UTC, -/+HH:MM:SS.SS... for local tz's
922  '/';
923 
924  if(preg_match($pattern,$datestr,$regs)){
925  return sprintf('%04d-%02d-%02dT%02d:%02d:%02dZ',$regs[1],$regs[2],$regs[3],$regs[4],$regs[5],$regs[6]);
926  }
927  return false;
928  } else {
929  return $datestr;
930  }
931 }
932 
939 function iso8601_to_timestamp($datestr){
940  $pattern = '/'.
941  '([0-9]{4})-'. // centuries & years CCYY-
942  '([0-9]{2})-'. // months MM-
943  '([0-9]{2})'. // days DD
944  'T'. // separator T
945  '([0-9]{2}):'. // hours hh:
946  '([0-9]{2}):'. // minutes mm:
947  '([0-9]{2})(\.[0-9]+)?'. // seconds ss.ss...
948  '(Z|[+\-][0-9]{2}:?[0-9]{2})?'. // Z to indicate UTC, -/+HH:MM:SS.SS... for local tz's
949  '/';
950 
951  if(preg_match($pattern,$datestr,$regs)){
952  // not utc
953  if($regs[8] != 'Z'){
954  $op = substr($regs[8],0,1);
955  $h = substr($regs[8],1,2);
956  $m = substr($regs[8],strlen($regs[8])-2,2);
957  if($op == '-'){
958  $regs[4] = $regs[4] + $h;
959  $regs[5] = $regs[5] + $m;
960  } elseif($op == '+'){
961  $regs[4] = $regs[4] - $h;
962  $regs[5] = $regs[5] - $m;
963  }
964  }
965  return gmmktime($regs[4], $regs[5], $regs[6], $regs[2], $regs[3], $regs[1]);
966 // return strtotime("$regs[1]-$regs[2]-$regs[3] $regs[4]:$regs[5]:$regs[6]Z");
967  } else {
968  return false;
969  }
970 }
971 
979 function usleepWindows($usec)
980 {
981  $start = gettimeofday();
982 
983  do
984  {
985  $stop = gettimeofday();
986  $timePassed = 1000000 * ($stop['sec'] - $start['sec'])
987  + $stop['usec'] - $start['usec'];
988  }
989  while ($timePassed < $usec);
990 }
991 
992 ?><?php
993 
994 
995 
1004 class nusoap_fault extends nusoap_base {
1029 
1038  function __construct($faultcode,$faultactor='',$faultstring='',$faultdetail=''){
1039  parent::__construct();
1040  $this->faultcode = $faultcode;
1041  $this->faultactor = $faultactor;
1042  $this->faultstring = $faultstring;
1043  $this->faultdetail = $faultdetail;
1044  }
1045 
1052  function serialize(){
1053  $ns_string = '';
1054  foreach($this->namespaces as $k => $v){
1055  $ns_string .= "\n xmlns:$k=\"$v\"";
1056  }
1057  $return_msg =
1058  '<?xml version="1.0" encoding="'.$this->soap_defencoding.'"?>'.
1059  '<SOAP-ENV:Envelope SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"'.$ns_string.">\n".
1060  '<SOAP-ENV:Body>'.
1061  '<SOAP-ENV:Fault>'.
1062  $this->serialize_val($this->faultcode, 'faultcode').
1063  $this->serialize_val($this->faultstring, 'faultstring').
1064  $this->serialize_val($this->faultactor, 'faultactor').
1065  $this->serialize_val($this->faultdetail, 'detail').
1066  '</SOAP-ENV:Fault>'.
1067  '</SOAP-ENV:Body>'.
1068  '</SOAP-ENV:Envelope>';
1069  return $return_msg;
1070  }
1071 }
1072 
1076 class soap_fault extends nusoap_fault {
1077 }
1078 
1079 ?><?php
1080 
1081 
1082 
1093 
1094  // files
1095  var $schema = '';
1096  var $xml = '';
1097  // namespaces
1099  // schema info
1100  var $schemaInfo = array();
1101  var $schemaTargetNamespace = '';
1102  // types, elements, attributes defined by the schema
1104  var $complexTypes = array();
1105  var $complexTypeStack = array();
1106  var $currentComplexType = null;
1107  var $elements = array();
1108  var $elementStack = array();
1109  var $currentElement = null;
1110  var $simpleTypes = array();
1111  var $simpleTypeStack = array();
1112  var $currentSimpleType = null;
1113  // imports
1114  var $imports = array();
1115  // parser vars
1116  var $parser;
1117  var $position = 0;
1118  var $depth = 0;
1119  var $depth_array = array();
1120  var $message = array();
1121  var $defaultNamespace = array();
1122 
1131  function __construct($schema='',$xml='',$namespaces=array()){
1132  parent::__construct();
1133  $this->debug('nusoap_xmlschema class instantiated, inside constructor');
1134  // files
1135  $this->schema = $schema;
1136  $this->xml = $xml;
1137 
1138  // namespaces
1139  $this->enclosingNamespaces = $namespaces;
1140  $this->namespaces = array_merge($this->namespaces, $namespaces);
1141 
1142  // parse schema file
1143  if($schema != ''){
1144  $this->debug('initial schema file: '.$schema);
1145  $this->parseFile($schema, 'schema');
1146  }
1147 
1148  // parse xml file
1149  if($xml != ''){
1150  $this->debug('initial xml file: '.$xml);
1151  $this->parseFile($xml, 'xml');
1152  }
1153 
1154  }
1155 
1164  function parseFile($xml,$type){
1165  // parse xml file
1166  if($xml != ""){
1167  $xmlStr = @join("",@file($xml));
1168  if($xmlStr == ""){
1169  $msg = 'Error reading XML from '.$xml;
1170  $this->setError($msg);
1171  $this->debug($msg);
1172  return false;
1173  } else {
1174  $this->debug("parsing $xml");
1175  $this->parseString($xmlStr,$type);
1176  $this->debug("done parsing $xml");
1177  return true;
1178  }
1179  }
1180  return false;
1181  }
1182 
1190  function parseString($xml,$type){
1191  // parse xml string
1192  if($xml != ""){
1193 
1194  // Create an XML parser.
1195  $this->parser = xml_parser_create();
1196  // Set the options for parsing the XML data.
1197  xml_parser_set_option($this->parser, XML_OPTION_CASE_FOLDING, 0);
1198 
1199  // Set the object for the parser.
1200  xml_set_object($this->parser, $this);
1201 
1202  // Set the element handlers for the parser.
1203  if($type == "schema"){
1204  xml_set_element_handler($this->parser, 'schemaStartElement','schemaEndElement');
1205  xml_set_character_data_handler($this->parser,'schemaCharacterData');
1206  } elseif($type == "xml"){
1207  xml_set_element_handler($this->parser, 'xmlStartElement','xmlEndElement');
1208  xml_set_character_data_handler($this->parser,'xmlCharacterData');
1209  }
1210 
1211  // Parse the XML file.
1212  if(!xml_parse($this->parser,$xml,true)){
1213  // Display an error message.
1214  $errstr = sprintf('XML error parsing XML schema on line %d: %s',
1215  xml_get_current_line_number($this->parser),
1216  xml_error_string(xml_get_error_code($this->parser))
1217  );
1218  $this->debug($errstr);
1219  $this->debug("XML payload:\n" . $xml);
1220  $this->setError($errstr);
1221  }
1222 
1223  xml_parser_free($this->parser);
1224  } else{
1225  $this->debug('no xml passed to parseString()!!');
1226  $this->setError('no xml passed to parseString()!!');
1227  }
1228  }
1229 
1237  function CreateTypeName($ename) {
1238  $scope = '';
1239  for ($i = 0; $i < count($this->complexTypeStack); $i++) {
1240  $scope .= $this->complexTypeStack[$i] . '_';
1241  }
1242  return $scope . $ename . '_ContainedType';
1243  }
1244 
1253  function schemaStartElement($parser, $name, $attrs) {
1254 
1255  // position in the total number of elements, starting from 0
1256  $pos = $this->position++;
1257  $depth = $this->depth++;
1258  // set self as current value for this depth
1259  $this->depth_array[$depth] = $pos;
1260  $this->message[$pos] = array('cdata' => '');
1261  if ($depth > 0) {
1262  $this->defaultNamespace[$pos] = $this->defaultNamespace[$this->depth_array[$depth - 1]];
1263  } else {
1264  $this->defaultNamespace[$pos] = false;
1265  }
1266 
1267  // get element prefix
1268  if($prefix = $this->getPrefix($name)){
1269  // get unqualified name
1270  $name = $this->getLocalPart($name);
1271  } else {
1272  $prefix = '';
1273  }
1274 
1275  // loop thru attributes, expanding, and registering namespace declarations
1276  if(count($attrs) > 0){
1277  foreach($attrs as $k => $v){
1278  // if ns declarations, add to class level array of valid namespaces
1279  if(preg_match('/^xmlns/',$k)){
1280  //$this->xdebug("$k: $v");
1281  //$this->xdebug('ns_prefix: '.$this->getPrefix($k));
1282  if($ns_prefix = substr(strrchr($k,':'),1)){
1283  //$this->xdebug("Add namespace[$ns_prefix] = $v");
1284  $this->namespaces[$ns_prefix] = $v;
1285  } else {
1286  $this->defaultNamespace[$pos] = $v;
1287  if (! $this->getPrefixFromNamespace($v)) {
1288  $this->namespaces['ns'.(count($this->namespaces)+1)] = $v;
1289  }
1290  }
1291  if($v == 'http://www.w3.org/2001/XMLSchema' || $v == 'http://www.w3.org/1999/XMLSchema' || $v == 'http://www.w3.org/2000/10/XMLSchema'){
1292  $this->XMLSchemaVersion = $v;
1293  $this->namespaces['xsi'] = $v.'-instance';
1294  }
1295  }
1296  }
1297  foreach($attrs as $k => $v){
1298  // expand each attribute
1299  $k = strpos($k,':') ? $this->expandQname($k) : $k;
1300  $v = strpos($v,':') ? $this->expandQname($v) : $v;
1301  $eAttrs[$k] = $v;
1302  }
1303  $attrs = $eAttrs;
1304  } else {
1305  $attrs = array();
1306  }
1307  // find status, register data
1308  switch($name){
1309  case 'all': // (optional) compositor content for a complexType
1310  case 'choice':
1311  case 'group':
1312  case 'sequence':
1313  //$this->xdebug("compositor $name for currentComplexType: $this->currentComplexType and currentElement: $this->currentElement");
1314  $this->complexTypes[$this->currentComplexType]['compositor'] = $name;
1315  //if($name == 'all' || $name == 'sequence'){
1316  // $this->complexTypes[$this->currentComplexType]['phpType'] = 'struct';
1317  //}
1318  break;
1319  case 'attribute': // complexType attribute
1320  //$this->xdebug("parsing attribute $attrs[name] $attrs[ref] of value: ".$attrs['http://schemas.xmlsoap.org/wsdl/:arrayType']);
1321  $this->xdebug("parsing attribute:");
1322  $this->appendDebug($this->varDump($attrs));
1323  if (!isset($attrs['form'])) {
1324  $attrs['form'] = $this->schemaInfo['attributeFormDefault'];
1325  }
1326  if (isset($attrs['http://schemas.xmlsoap.org/wsdl/:arrayType'])) {
1327  $v = $attrs['http://schemas.xmlsoap.org/wsdl/:arrayType'];
1328  if (!strpos($v, ':')) {
1329  // no namespace in arrayType attribute value...
1330  if ($this->defaultNamespace[$pos]) {
1331  // ...so use the default
1332  $attrs['http://schemas.xmlsoap.org/wsdl/:arrayType'] = $this->defaultNamespace[$pos] . ':' . $attrs['http://schemas.xmlsoap.org/wsdl/:arrayType'];
1333  }
1334  }
1335  }
1336  if(isset($attrs['name'])){
1337  $this->attributes[$attrs['name']] = $attrs;
1338  $aname = $attrs['name'];
1339  } elseif(isset($attrs['ref']) && $attrs['ref'] == 'http://schemas.xmlsoap.org/soap/encoding/:arrayType'){
1340  if (isset($attrs['http://schemas.xmlsoap.org/wsdl/:arrayType'])) {
1341  $aname = $attrs['http://schemas.xmlsoap.org/wsdl/:arrayType'];
1342  } else {
1343  $aname = '';
1344  }
1345  } elseif(isset($attrs['ref'])){
1346  $aname = $attrs['ref'];
1347  $this->attributes[$attrs['ref']] = $attrs;
1348  }
1349 
1350  if($this->currentComplexType){ // This should *always* be
1351  $this->complexTypes[$this->currentComplexType]['attrs'][$aname] = $attrs;
1352  }
1353  // arrayType attribute
1354  if(isset($attrs['http://schemas.xmlsoap.org/wsdl/:arrayType']) || $this->getLocalPart($aname) == 'arrayType'){
1355  $this->complexTypes[$this->currentComplexType]['phpType'] = 'array';
1356  $prefix = $this->getPrefix($aname);
1357  if(isset($attrs['http://schemas.xmlsoap.org/wsdl/:arrayType'])){
1358  $v = $attrs['http://schemas.xmlsoap.org/wsdl/:arrayType'];
1359  } else {
1360  $v = '';
1361  }
1362  if(strpos($v,'[,]')){
1363  $this->complexTypes[$this->currentComplexType]['multidimensional'] = true;
1364  }
1365  $v = substr($v,0,strpos($v,'[')); // clip the []
1366  if(!strpos($v,':') && isset($this->typemap[$this->XMLSchemaVersion][$v])){
1367  $v = $this->XMLSchemaVersion.':'.$v;
1368  }
1369  $this->complexTypes[$this->currentComplexType]['arrayType'] = $v;
1370  }
1371  break;
1372  case 'complexContent': // (optional) content for a complexType
1373  break;
1374  case 'complexType':
1375  array_push($this->complexTypeStack, $this->currentComplexType);
1376  if(isset($attrs['name'])){
1377  // TODO: what is the scope of named complexTypes that appear
1378  // nested within other c complexTypes?
1379  $this->xdebug('processing named complexType '.$attrs['name']);
1380  //$this->currentElement = false;
1381  $this->currentComplexType = $attrs['name'];
1382  $this->complexTypes[$this->currentComplexType] = $attrs;
1383  $this->complexTypes[$this->currentComplexType]['typeClass'] = 'complexType';
1384  // This is for constructs like
1385  // <complexType name="ListOfString" base="soap:Array">
1386  // <sequence>
1387  // <element name="string" type="xsd:string"
1388  // minOccurs="0" maxOccurs="unbounded" />
1389  // </sequence>
1390  // </complexType>
1391  if(isset($attrs['base']) && preg_match('/:Array$/',$attrs['base'])){
1392  $this->xdebug('complexType is unusual array');
1393  $this->complexTypes[$this->currentComplexType]['phpType'] = 'array';
1394  } else {
1395  $this->complexTypes[$this->currentComplexType]['phpType'] = 'struct';
1396  }
1397  } else {
1398  $name = $this->CreateTypeName($this->currentElement);
1399  $this->xdebug('processing unnamed complexType for element ' . $this->currentElement . ' named ' . $name);
1400  $this->currentComplexType = $name;
1401  //$this->currentElement = false;
1402  $this->complexTypes[$this->currentComplexType] = $attrs;
1403  $this->complexTypes[$this->currentComplexType]['typeClass'] = 'complexType';
1404  // This is for constructs like
1405  // <complexType name="ListOfString" base="soap:Array">
1406  // <sequence>
1407  // <element name="string" type="xsd:string"
1408  // minOccurs="0" maxOccurs="unbounded" />
1409  // </sequence>
1410  // </complexType>
1411  if(isset($attrs['base']) && preg_match('/:Array$/',$attrs['base'])){
1412  $this->xdebug('complexType is unusual array');
1413  $this->complexTypes[$this->currentComplexType]['phpType'] = 'array';
1414  } else {
1415  $this->complexTypes[$this->currentComplexType]['phpType'] = 'struct';
1416  }
1417  }
1418  break;
1419  case 'element':
1420  array_push($this->elementStack, $this->currentElement);
1421  if (!isset($attrs['form'])) {
1422  $attrs['form'] = $this->schemaInfo['elementFormDefault'];
1423  }
1424  if(isset($attrs['type'])){
1425  $this->xdebug("processing typed element ".$attrs['name']." of type ".$attrs['type']);
1426  if (! $this->getPrefix($attrs['type'])) {
1427  if ($this->defaultNamespace[$pos]) {
1428  $attrs['type'] = $this->defaultNamespace[$pos] . ':' . $attrs['type'];
1429  $this->xdebug('used default namespace to make type ' . $attrs['type']);
1430  }
1431  }
1432  // This is for constructs like
1433  // <complexType name="ListOfString" base="soap:Array">
1434  // <sequence>
1435  // <element name="string" type="xsd:string"
1436  // minOccurs="0" maxOccurs="unbounded" />
1437  // </sequence>
1438  // </complexType>
1439  if ($this->currentComplexType && $this->complexTypes[$this->currentComplexType]['phpType'] == 'array') {
1440  $this->xdebug('arrayType for unusual array is ' . $attrs['type']);
1441  $this->complexTypes[$this->currentComplexType]['arrayType'] = $attrs['type'];
1442  }
1443  $this->currentElement = $attrs['name'];
1444  $ename = $attrs['name'];
1445  } elseif(isset($attrs['ref'])){
1446  $this->xdebug("processing element as ref to ".$attrs['ref']);
1447  $this->currentElement = "ref to ".$attrs['ref'];
1448  $ename = $this->getLocalPart($attrs['ref']);
1449  } else {
1450  $type = $this->CreateTypeName($this->currentComplexType . '_' . $attrs['name']);
1451  $this->xdebug("processing untyped element " . $attrs['name'] . ' type ' . $type);
1452  $this->currentElement = $attrs['name'];
1453  $attrs['type'] = $this->schemaTargetNamespace . ':' . $type;
1454  $ename = $attrs['name'];
1455  }
1456  if (isset($ename) && $this->currentComplexType) {
1457  $this->xdebug("add element $ename to complexType $this->currentComplexType");
1458  $this->complexTypes[$this->currentComplexType]['elements'][$ename] = $attrs;
1459  } elseif (!isset($attrs['ref'])) {
1460  $this->xdebug("add element $ename to elements array");
1461  $this->elements[ $attrs['name'] ] = $attrs;
1462  $this->elements[ $attrs['name'] ]['typeClass'] = 'element';
1463  }
1464  break;
1465  case 'enumeration': // restriction value list member
1466  $this->xdebug('enumeration ' . $attrs['value']);
1467  if ($this->currentSimpleType) {
1468  $this->simpleTypes[$this->currentSimpleType]['enumeration'][] = $attrs['value'];
1469  } elseif ($this->currentComplexType) {
1470  $this->complexTypes[$this->currentComplexType]['enumeration'][] = $attrs['value'];
1471  }
1472  break;
1473  case 'extension': // simpleContent or complexContent type extension
1474  $this->xdebug('extension ' . $attrs['base']);
1475  if ($this->currentComplexType) {
1476  $this->complexTypes[$this->currentComplexType]['extensionBase'] = $attrs['base'];
1477  }
1478  break;
1479  case 'import':
1480  if (isset($attrs['schemaLocation'])) {
1481  //$this->xdebug('import namespace ' . $attrs['namespace'] . ' from ' . $attrs['schemaLocation']);
1482  $this->imports[$attrs['namespace']][] = array('location' => $attrs['schemaLocation'], 'loaded' => false);
1483  } else {
1484  //$this->xdebug('import namespace ' . $attrs['namespace']);
1485  $this->imports[$attrs['namespace']][] = array('location' => '', 'loaded' => true);
1486  if (! $this->getPrefixFromNamespace($attrs['namespace'])) {
1487  $this->namespaces['ns'.(count($this->namespaces)+1)] = $attrs['namespace'];
1488  }
1489  }
1490  break;
1491  case 'list': // simpleType value list
1492  break;
1493  case 'restriction': // simpleType, simpleContent or complexContent value restriction
1494  $this->xdebug('restriction ' . $attrs['base']);
1495  if($this->currentSimpleType){
1496  $this->simpleTypes[$this->currentSimpleType]['type'] = $attrs['base'];
1497  } elseif($this->currentComplexType){
1498  $this->complexTypes[$this->currentComplexType]['restrictionBase'] = $attrs['base'];
1499  if(strstr($attrs['base'],':') == ':Array'){
1500  $this->complexTypes[$this->currentComplexType]['phpType'] = 'array';
1501  }
1502  }
1503  break;
1504  case 'schema':
1505  $this->schemaInfo = $attrs;
1506  $this->schemaInfo['schemaVersion'] = $this->getNamespaceFromPrefix($prefix);
1507  if (isset($attrs['targetNamespace'])) {
1508  $this->schemaTargetNamespace = $attrs['targetNamespace'];
1509  }
1510  if (!isset($attrs['elementFormDefault'])) {
1511  $this->schemaInfo['elementFormDefault'] = 'unqualified';
1512  }
1513  if (!isset($attrs['attributeFormDefault'])) {
1514  $this->schemaInfo['attributeFormDefault'] = 'unqualified';
1515  }
1516  break;
1517  case 'simpleContent': // (optional) content for a complexType
1518  break;
1519  case 'simpleType':
1520  array_push($this->simpleTypeStack, $this->currentSimpleType);
1521  if(isset($attrs['name'])){
1522  $this->xdebug("processing simpleType for name " . $attrs['name']);
1523  $this->currentSimpleType = $attrs['name'];
1524  $this->simpleTypes[ $attrs['name'] ] = $attrs;
1525  $this->simpleTypes[ $attrs['name'] ]['typeClass'] = 'simpleType';
1526  $this->simpleTypes[ $attrs['name'] ]['phpType'] = 'scalar';
1527  } else {
1528  $name = $this->CreateTypeName($this->currentComplexType . '_' . $this->currentElement);
1529  $this->xdebug('processing unnamed simpleType for element ' . $this->currentElement . ' named ' . $name);
1530  $this->currentSimpleType = $name;
1531  //$this->currentElement = false;
1532  $this->simpleTypes[$this->currentSimpleType] = $attrs;
1533  $this->simpleTypes[$this->currentSimpleType]['phpType'] = 'scalar';
1534  }
1535  break;
1536  case 'union': // simpleType type list
1537  break;
1538  default:
1539  //$this->xdebug("do not have anything to do for element $name");
1540  }
1541  }
1542 
1550  function schemaEndElement($parser, $name) {
1551  // bring depth down a notch
1552  $this->depth--;
1553  // position of current element is equal to the last value left in depth_array for my depth
1554  if(isset($this->depth_array[$this->depth])){
1555  $pos = $this->depth_array[$this->depth];
1556  }
1557  // get element prefix
1558  if ($prefix = $this->getPrefix($name)){
1559  // get unqualified name
1560  $name = $this->getLocalPart($name);
1561  } else {
1562  $prefix = '';
1563  }
1564  // move on...
1565  if($name == 'complexType'){
1566  $this->xdebug('done processing complexType ' . ($this->currentComplexType ? $this->currentComplexType : '(unknown)'));
1567  $this->currentComplexType = array_pop($this->complexTypeStack);
1568  //$this->currentElement = false;
1569  }
1570  if($name == 'element'){
1571  $this->xdebug('done processing element ' . ($this->currentElement ? $this->currentElement : '(unknown)'));
1572  $this->currentElement = array_pop($this->elementStack);
1573  }
1574  if($name == 'simpleType'){
1575  $this->xdebug('done processing simpleType ' . ($this->currentSimpleType ? $this->currentSimpleType : '(unknown)'));
1576  $this->currentSimpleType = array_pop($this->simpleTypeStack);
1577  }
1578  }
1579 
1587  function schemaCharacterData($parser, $data){
1588  $pos = $this->depth_array[$this->depth - 1];
1589  $this->message[$pos]['cdata'] .= $data;
1590  }
1591 
1597  function serializeSchema(){
1598 
1599  $schemaPrefix = $this->getPrefixFromNamespace($this->XMLSchemaVersion);
1600  $xml = '';
1601  // imports
1602  if (sizeof($this->imports) > 0) {
1603  foreach($this->imports as $ns => $list) {
1604  foreach ($list as $ii) {
1605  if ($ii['location'] != '') {
1606  $xml .= " <$schemaPrefix:import location=\"" . $ii['location'] . '" namespace="' . $ns . "\" />\n";
1607  } else {
1608  $xml .= " <$schemaPrefix:import namespace=\"" . $ns . "\" />\n";
1609  }
1610  }
1611  }
1612  }
1613  // complex types
1614  foreach($this->complexTypes as $typeName => $attrs){
1615  $contentStr = '';
1616  // serialize child elements
1617  if(isset($attrs['elements']) && (count($attrs['elements']) > 0)){
1618  foreach($attrs['elements'] as $element => $eParts){
1619  if(isset($eParts['ref'])){
1620  $contentStr .= " <$schemaPrefix:element ref=\"$element\"/>\n";
1621  } else {
1622  $contentStr .= " <$schemaPrefix:element name=\"$element\" type=\"" . $this->contractQName($eParts['type']) . "\"";
1623  foreach ($eParts as $aName => $aValue) {
1624  // handle, e.g., abstract, default, form, minOccurs, maxOccurs, nillable
1625  if ($aName != 'name' && $aName != 'type') {
1626  $contentStr .= " $aName=\"$aValue\"";
1627  }
1628  }
1629  $contentStr .= "/>\n";
1630  }
1631  }
1632  // compositor wraps elements
1633  if (isset($attrs['compositor']) && ($attrs['compositor'] != '')) {
1634  $contentStr = " <$schemaPrefix:$attrs[compositor]>\n".$contentStr." </$schemaPrefix:$attrs[compositor]>\n";
1635  }
1636  }
1637  // attributes
1638  if(isset($attrs['attrs']) && (count($attrs['attrs']) >= 1)){
1639  foreach($attrs['attrs'] as $attr => $aParts){
1640  $contentStr .= " <$schemaPrefix:attribute";
1641  foreach ($aParts as $a => $v) {
1642  if ($a == 'ref' || $a == 'type') {
1643  $contentStr .= " $a=\"".$this->contractQName($v).'"';
1644  } elseif ($a == 'http://schemas.xmlsoap.org/wsdl/:arrayType') {
1645  $this->usedNamespaces['wsdl'] = $this->namespaces['wsdl'];
1646  $contentStr .= ' wsdl:arrayType="'.$this->contractQName($v).'"';
1647  } else {
1648  $contentStr .= " $a=\"$v\"";
1649  }
1650  }
1651  $contentStr .= "/>\n";
1652  }
1653  }
1654  // if restriction
1655  if (isset($attrs['restrictionBase']) && $attrs['restrictionBase'] != ''){
1656  $contentStr = " <$schemaPrefix:restriction base=\"".$this->contractQName($attrs['restrictionBase'])."\">\n".$contentStr." </$schemaPrefix:restriction>\n";
1657  // complex or simple content
1658  if ((isset($attrs['elements']) && count($attrs['elements']) > 0) || (isset($attrs['attrs']) && count($attrs['attrs']) > 0)){
1659  $contentStr = " <$schemaPrefix:complexContent>\n".$contentStr." </$schemaPrefix:complexContent>\n";
1660  }
1661  }
1662  // finalize complex type
1663  if($contentStr != ''){
1664  $contentStr = " <$schemaPrefix:complexType name=\"$typeName\">\n".$contentStr." </$schemaPrefix:complexType>\n";
1665  } else {
1666  $contentStr = " <$schemaPrefix:complexType name=\"$typeName\"/>\n";
1667  }
1668  $xml .= $contentStr;
1669  }
1670  // simple types
1671  if(isset($this->simpleTypes) && count($this->simpleTypes) > 0){
1672  foreach($this->simpleTypes as $typeName => $eParts){
1673  $xml .= " <$schemaPrefix:simpleType name=\"$typeName\">\n <$schemaPrefix:restriction base=\"".$this->contractQName($eParts['type'])."\">\n";
1674  if (isset($eParts['enumeration'])) {
1675  foreach ($eParts['enumeration'] as $e) {
1676  $xml .= " <$schemaPrefix:enumeration value=\"$e\"/>\n";
1677  }
1678  }
1679  $xml .= " </$schemaPrefix:restriction>\n </$schemaPrefix:simpleType>";
1680  }
1681  }
1682  // elements
1683  if(isset($this->elements) && count($this->elements) > 0){
1684  foreach($this->elements as $element => $eParts){
1685  $xml .= " <$schemaPrefix:element name=\"$element\" type=\"".$this->contractQName($eParts['type'])."\"/>\n";
1686  }
1687  }
1688  // attributes
1689  if(isset($this->attributes) && count($this->attributes) > 0){
1690  foreach($this->attributes as $attr => $aParts){
1691  $xml .= " <$schemaPrefix:attribute name=\"$attr\" type=\"".$this->contractQName($aParts['type'])."\"\n/>";
1692  }
1693  }
1694  // finish 'er up
1695  $attr = '';
1696  foreach ($this->schemaInfo as $k => $v) {
1697  if ($k == 'elementFormDefault' || $k == 'attributeFormDefault') {
1698  $attr .= " $k=\"$v\"";
1699  }
1700  }
1701  $el = "<$schemaPrefix:schema$attr targetNamespace=\"$this->schemaTargetNamespace\"\n";
1702  foreach (array_diff($this->usedNamespaces, $this->enclosingNamespaces) as $nsp => $ns) {
1703  $el .= " xmlns:$nsp=\"$ns\"";
1704  }
1705  $xml = $el . ">\n".$xml."</$schemaPrefix:schema>\n";
1706  return $xml;
1707  }
1708 
1715  function xdebug($string){
1716  $this->debug('<' . $this->schemaTargetNamespace . '> '.$string);
1717  }
1718 
1731  function getPHPType($type,$ns){
1732  if(isset($this->typemap[$ns][$type])){
1733  //print "found type '$type' and ns $ns in typemap<br>";
1734  return $this->typemap[$ns][$type];
1735  } elseif(isset($this->complexTypes[$type])){
1736  //print "getting type '$type' and ns $ns from complexTypes array<br>";
1737  return $this->complexTypes[$type]['phpType'];
1738  }
1739  return false;
1740  }
1741 
1764  function getTypeDef($type){
1765  //$this->debug("in getTypeDef for type $type");
1766  if (substr($type, -1) == '^') {
1767  $is_element = 1;
1768  $type = substr($type, 0, -1);
1769  } else {
1770  $is_element = 0;
1771  }
1772 
1773  if((! $is_element) && isset($this->complexTypes[$type])){
1774  $this->xdebug("in getTypeDef, found complexType $type");
1775  return $this->complexTypes[$type];
1776  } elseif((! $is_element) && isset($this->simpleTypes[$type])){
1777  $this->xdebug("in getTypeDef, found simpleType $type");
1778  if (!isset($this->simpleTypes[$type]['phpType'])) {
1779  // get info for type to tack onto the simple type
1780  // TODO: can this ever really apply (i.e. what is a simpleType really?)
1781  $uqType = substr($this->simpleTypes[$type]['type'], strrpos($this->simpleTypes[$type]['type'], ':') + 1);
1782  $ns = substr($this->simpleTypes[$type]['type'], 0, strrpos($this->simpleTypes[$type]['type'], ':'));
1783  $etype = $this->getTypeDef($uqType);
1784  if ($etype) {
1785  $this->xdebug("in getTypeDef, found type for simpleType $type:");
1786  $this->xdebug($this->varDump($etype));
1787  if (isset($etype['phpType'])) {
1788  $this->simpleTypes[$type]['phpType'] = $etype['phpType'];
1789  }
1790  if (isset($etype['elements'])) {
1791  $this->simpleTypes[$type]['elements'] = $etype['elements'];
1792  }
1793  }
1794  }
1795  return $this->simpleTypes[$type];
1796  } elseif(isset($this->elements[$type])){
1797  $this->xdebug("in getTypeDef, found element $type");
1798  if (!isset($this->elements[$type]['phpType'])) {
1799  // get info for type to tack onto the element
1800  $uqType = substr($this->elements[$type]['type'], strrpos($this->elements[$type]['type'], ':') + 1);
1801  $ns = substr($this->elements[$type]['type'], 0, strrpos($this->elements[$type]['type'], ':'));
1802  $etype = $this->getTypeDef($uqType);
1803  if ($etype) {
1804  $this->xdebug("in getTypeDef, found type for element $type:");
1805  $this->xdebug($this->varDump($etype));
1806  if (isset($etype['phpType'])) {
1807  $this->elements[$type]['phpType'] = $etype['phpType'];
1808  }
1809  if (isset($etype['elements'])) {
1810  $this->elements[$type]['elements'] = $etype['elements'];
1811  }
1812  } elseif ($ns == 'http://www.w3.org/2001/XMLSchema') {
1813  $this->xdebug("in getTypeDef, element $type is an XSD type");
1814  $this->elements[$type]['phpType'] = 'scalar';
1815  }
1816  }
1817  return $this->elements[$type];
1818  } elseif(isset($this->attributes[$type])){
1819  $this->xdebug("in getTypeDef, found attribute $type");
1820  return $this->attributes[$type];
1821  } elseif (preg_match('/_ContainedType$/', $type)) {
1822  $this->xdebug("in getTypeDef, have an untyped element $type");
1823  $typeDef['typeClass'] = 'simpleType';
1824  $typeDef['phpType'] = 'scalar';
1825  $typeDef['type'] = 'http://www.w3.org/2001/XMLSchema:string';
1826  return $typeDef;
1827  }
1828  $this->xdebug("in getTypeDef, did not find $type");
1829  return false;
1830  }
1831 
1841  //print "in sTD() for type $type<br>";
1842  if($typeDef = $this->getTypeDef($type)){
1843  $str .= '<'.$type;
1844  if(is_array($typeDef['attrs'])){
1845  foreach($typeDef['attrs'] as $attName => $data){
1846  $str .= " $attName=\"{type = ".$data['type']."}\"";
1847  }
1848  }
1849  $str .= " xmlns=\"".$this->schema['targetNamespace']."\"";
1850  if(count($typeDef['elements']) > 0){
1851  $str .= ">";
1852  foreach($typeDef['elements'] as $element => $eData){
1853  $str .= $this->serializeTypeDef($element);
1854  }
1855  $str .= "</$type>";
1856  } elseif($typeDef['typeClass'] == 'element') {
1857  $str .= "></$type>";
1858  } else {
1859  $str .= "/>";
1860  }
1861  return $str;
1862  }
1863  return false;
1864  }
1865 
1877  // get typedef
1878  if($typeDef = $this->getTypeDef($type)){
1879  // if struct
1880  if($typeDef['phpType'] == 'struct'){
1881  $buffer .= '<table>';
1882  foreach($typeDef['elements'] as $child => $childDef){
1883  $buffer .= "
1884  <tr><td align='right'>$childDef[name] (type: ".$this->getLocalPart($childDef['type'])."):</td>
1885  <td><input type='text' name='parameters[".$name."][$childDef[name]]'></td></tr>";
1886  }
1887  $buffer .= '</table>';
1888  // if array
1889  } elseif($typeDef['phpType'] == 'array'){
1890  $buffer .= '<table>';
1891  for($i=0;$i < 3; $i++){
1892  $buffer .= "
1893  <tr><td align='right'>array item (type: $typeDef[arrayType]):</td>
1894  <td><input type='text' name='parameters[".$name."][]'></td></tr>";
1895  }
1896  $buffer .= '</table>';
1897  // if scalar
1898  } else {
1899  $buffer .= "<input type='text' name='parameters[$name]'>";
1900  }
1901  } else {
1902  $buffer .= "<input type='text' name='parameters[$name]'>";
1903  }
1904  return $buffer;
1905  }
1906 
1948  function addComplexType($name,$typeClass='complexType',$phpType='array',$compositor='',$restrictionBase='',$elements=array(),$attrs=array(),$arrayType=''){
1949  $this->complexTypes[$name] = array(
1950  'name' => $name,
1951  'typeClass' => $typeClass,
1952  'phpType' => $phpType,
1953  'compositor'=> $compositor,
1954  'restrictionBase' => $restrictionBase,
1955  'elements' => $elements,
1956  'attrs' => $attrs,
1957  'arrayType' => $arrayType
1958  );
1959 
1960  $this->xdebug("addComplexType $name:");
1961  $this->appendDebug($this->varDump($this->complexTypes[$name]));
1962  }
1963 
1976  function addSimpleType($name, $restrictionBase='', $typeClass='simpleType', $phpType='scalar', $enumeration=array()) {
1977  $this->simpleTypes[$name] = array(
1978  'name' => $name,
1979  'typeClass' => $typeClass,
1980  'phpType' => $phpType,
1981  'type' => $restrictionBase,
1982  'enumeration' => $enumeration
1983  );
1984 
1985  $this->xdebug("addSimpleType $name:");
1986  $this->appendDebug($this->varDump($this->simpleTypes[$name]));
1987  }
1988 
1996  function addElement($attrs) {
1997  if (! $this->getPrefix($attrs['type'])) {
1998  $attrs['type'] = $this->schemaTargetNamespace . ':' . $attrs['type'];
1999  }
2000  $this->elements[ $attrs['name'] ] = $attrs;
2001  $this->elements[ $attrs['name'] ]['typeClass'] = 'element';
2002 
2003  $this->xdebug("addElement " . $attrs['name']);
2004  $this->appendDebug($this->varDump($this->elements[ $attrs['name'] ]));
2005  }
2006 }
2007 
2011 class XMLSchema extends nusoap_xmlschema {
2012 }
2013 
2014 ?><?php
2015 
2016 
2017 
2029 class soapval extends nusoap_base {
2036  var $name;
2043  var $type;
2050  var $value;
2072 
2084  function __construct($name='soapval',$type=false,$value=-1,$element_ns=false,$type_ns=false,$attributes=false) {
2085  parent::__construct();
2086  $this->name = $name;
2087  $this->type = $type;
2088  $this->value = $value;
2089  $this->element_ns = $element_ns;
2090  $this->type_ns = $type_ns;
2091  $this->attributes = $attributes;
2092  }
2093 
2101  function serialize($use='encoded') {
2102  return $this->serialize_val($this->value, $this->name, $this->type, $this->element_ns, $this->type_ns, $this->attributes, $use, true);
2103  }
2104 
2111  function decode(){
2112  return $this->value;
2113  }
2114 }
2115 
2116 
2117 
2118 ?><?php
2119 
2120 
2121 
2131 class soap_transport_http extends nusoap_base {
2132 
2133  var $url = '';
2134  var $uri = '';
2135  var $digest_uri = '';
2136  var $scheme = '';
2137  var $host = '';
2138  var $port = '';
2139  var $path = '';
2140  var $request_method = 'POST';
2141  var $protocol_version = '1.0';
2142  var $encoding = '';
2143  var $outgoing_headers = array();
2144  var $incoming_headers = array();
2145  var $incoming_cookies = array();
2146  var $outgoing_payload = '';
2147  var $incoming_payload = '';
2148  var $response_status_line; // HTTP response status line
2149  var $useSOAPAction = true;
2150  var $persistentConnection = false;
2151  var $ch = false; // cURL handle
2152  var $ch_options = array(); // cURL custom options
2153  var $use_curl = false; // force cURL use
2154  var $proxy = null; // proxy information (associative array)
2155  var $username = '';
2156  var $password = '';
2157  var $authtype = '';
2158  var $digestRequest = array();
2159  var $certRequest = array(); // keys must be cainfofile (optional), sslcertfile, sslkeyfile, passphrase, certpassword (optional), verifypeer (optional), verifyhost (optional)
2160  // cainfofile: certificate authority file, e.g. '$pathToPemFiles/rootca.pem'
2161  // sslcertfile: SSL certificate file, e.g. '$pathToPemFiles/mycert.pem'
2162  // sslkeyfile: SSL key file, e.g. '$pathToPemFiles/mykey.pem'
2163  // passphrase: SSL key password/passphrase
2164  // certpassword: SSL certificate password
2165  // verifypeer: default is 1
2166  // verifyhost: default is 1
2167 
2176  function __construct($url, $curl_options = NULL, $use_curl = false){
2177  parent::__construct();
2178  $this->debug("ctor url=$url use_curl=$use_curl curl_options:");
2179  $this->appendDebug($this->varDump($curl_options));
2180  $this->setURL($url);
2181  if (is_array($curl_options)) {
2182  $this->ch_options = $curl_options;
2183  }
2184  $this->use_curl = $use_curl;
2185  preg_match('/\$Revisio' . 'n: ([^ ]+)/', $this->revision, $rev);
2186  $this->setHeader('User-Agent', $this->title.'/'.$this->version.' ('.$rev[1].')');
2187  }
2188 
2196  function setCurlOption($option, $value) {
2197  $this->debug("setCurlOption option=$option, value=");
2198  $this->appendDebug($this->varDump($value));
2199  curl_setopt($this->ch, $option, $value);
2200  }
2201 
2209  function setHeader($name, $value) {
2210  $this->outgoing_headers[$name] = $value;
2211  $this->debug("set header $name: $value");
2212  }
2213 
2220  function unsetHeader($name) {
2221  if (isset($this->outgoing_headers[$name])) {
2222  $this->debug("unset header $name");
2223  unset($this->outgoing_headers[$name]);
2224  }
2225  }
2226 
2233  function setURL($url) {
2234  $this->url = $url;
2235 
2236  $u = parse_url($url);
2237  foreach($u as $k => $v){
2238  $this->debug("parsed URL $k = $v");
2239  $this->$k = $v;
2240  }
2241 
2242  // add any GET params to path
2243  if(isset($u['query']) && $u['query'] != ''){
2244  $this->path .= '?' . $u['query'];
2245  }
2246 
2247  // set default port
2248  if(!isset($u['port'])){
2249  if($u['scheme'] == 'https'){
2250  $this->port = 443;
2251  } else {
2252  $this->port = 80;
2253  }
2254  }
2255 
2256  $this->uri = $this->path;
2257  $this->digest_uri = $this->uri;
2258 
2259  // build headers
2260  if (!isset($u['port'])) {
2261  $this->setHeader('Host', $this->host);
2262  } else {
2263  $this->setHeader('Host', $this->host.':'.$this->port);
2264  }
2265 
2266  if (isset($u['user']) && $u['user'] != '') {
2267  $this->setCredentials(urldecode($u['user']), isset($u['pass']) ? urldecode($u['pass']) : '');
2268  }
2269  }
2270 
2277  function io_method() {
2278  if ($this->use_curl || ($this->scheme == 'https') || ($this->scheme == 'http' && $this->authtype == 'ntlm') || ($this->scheme == 'http' && is_array($this->proxy) && $this->proxy['authtype'] == 'ntlm'))
2279  return 'curl';
2280  if (($this->scheme == 'http' || $this->scheme == 'ssl') && $this->authtype != 'ntlm' && (!is_array($this->proxy) || $this->proxy['authtype'] != 'ntlm'))
2281  return 'socket';
2282  return 'unknown';
2283  }
2284 
2293  function connect($connection_timeout=0,$response_timeout=30){
2294  // For PHP 4.3 with OpenSSL, change https scheme to ssl, then treat like
2295  // "regular" socket.
2296  // TODO: disabled for now because OpenSSL must be *compiled* in (not just
2297  // loaded), and until PHP5 stream_get_wrappers is not available.
2298 // if ($this->scheme == 'https') {
2299 // if (version_compare(phpversion(), '4.3.0') >= 0) {
2300 // if (extension_loaded('openssl')) {
2301 // $this->scheme = 'ssl';
2302 // $this->debug('Using SSL over OpenSSL');
2303 // }
2304 // }
2305 // }
2306  $this->debug("connect connection_timeout $connection_timeout, response_timeout $response_timeout, scheme $this->scheme, host $this->host, port $this->port");
2307  if ($this->io_method() == 'socket') {
2308  if (!is_array($this->proxy)) {
2309  $host = $this->host;
2310  $port = $this->port;
2311  } else {
2312  $host = $this->proxy['host'];
2313  $port = $this->proxy['port'];
2314  }
2315 
2316  // use persistent connection
2317  if($this->persistentConnection && isset($this->fp) && is_resource($this->fp)){
2318  if (!feof($this->fp)) {
2319  $this->debug('Re-use persistent connection');
2320  return true;
2321  }
2322  fclose($this->fp);
2323  $this->debug('Closed persistent connection at EOF');
2324  }
2325 
2326  // munge host if using OpenSSL
2327  if ($this->scheme == 'ssl') {
2328  $host = 'ssl://' . $host;
2329  }
2330  $this->debug('calling fsockopen with host ' . $host . ' connection_timeout ' . $connection_timeout);
2331 
2332  // open socket
2333  if($connection_timeout > 0){
2334  $this->fp = @fsockopen( $host, $this->port, $this->errno, $this->error_str, $connection_timeout);
2335  } else {
2336  $this->fp = @fsockopen( $host, $this->port, $this->errno, $this->error_str);
2337  }
2338 
2339  // test pointer
2340  if(!$this->fp) {
2341  $msg = 'Couldn\'t open socket connection to server ' . $this->url;
2342  if ($this->errno) {
2343  $msg .= ', Error ('.$this->errno.'): '.$this->error_str;
2344  } else {
2345  $msg .= ' prior to connect(). This is often a problem looking up the host name.';
2346  }
2347  $this->debug($msg);
2348  $this->setError($msg);
2349  return false;
2350  }
2351 
2352  // set response timeout
2353  $this->debug('set response timeout to ' . $response_timeout);
2354  socket_set_timeout( $this->fp, $response_timeout);
2355 
2356  $this->debug('socket connected');
2357  return true;
2358  } else if ($this->io_method() == 'curl') {
2359  if (!extension_loaded('curl')) {
2360 // $this->setError('cURL Extension, or OpenSSL extension w/ PHP version >= 4.3 is required for HTTPS');
2361  $this->setError('The PHP cURL Extension is required for HTTPS or NLTM. You will need to re-build or update your PHP to included cURL.');
2362  return false;
2363  }
2364  // Avoid warnings when PHP does not have these options
2365  if (defined('CURLOPT_CONNECTIONTIMEOUT'))
2366  $CURLOPT_CONNECTIONTIMEOUT = CURLOPT_CONNECTIONTIMEOUT;
2367  else
2368  $CURLOPT_CONNECTIONTIMEOUT = 78;
2369  if (defined('CURLOPT_HTTPAUTH'))
2370  $CURLOPT_HTTPAUTH = CURLOPT_HTTPAUTH;
2371  else
2372  $CURLOPT_HTTPAUTH = 107;
2373  if (defined('CURLOPT_PROXYAUTH'))
2374  $CURLOPT_PROXYAUTH = CURLOPT_PROXYAUTH;
2375  else
2376  $CURLOPT_PROXYAUTH = 111;
2377  if (defined('CURLAUTH_BASIC'))
2378  $CURLAUTH_BASIC = CURLAUTH_BASIC;
2379  else
2380  $CURLAUTH_BASIC = 1;
2381  if (defined('CURLAUTH_DIGEST'))
2382  $CURLAUTH_DIGEST = CURLAUTH_DIGEST;
2383  else
2384  $CURLAUTH_DIGEST = 2;
2385  if (defined('CURLAUTH_NTLM'))
2386  $CURLAUTH_NTLM = CURLAUTH_NTLM;
2387  else
2388  $CURLAUTH_NTLM = 8;
2389 
2390  $this->debug('connect using cURL');
2391  // init CURL
2392  $this->ch = curl_init();
2393  // set url
2394  $hostURL = ($this->port != '') ? "$this->scheme://$this->host:$this->port" : "$this->scheme://$this->host";
2395  // add path
2396  $hostURL .= $this->path;
2397  $this->setCurlOption(CURLOPT_URL, $hostURL);
2398  // follow location headers (re-directs)
2399  if (ini_get('safe_mode') || ini_get('open_basedir')) {
2400  $this->debug('safe_mode or open_basedir set, so do not set CURLOPT_FOLLOWLOCATION');
2401  $this->debug('safe_mode = ');
2402  $this->appendDebug($this->varDump(ini_get('safe_mode')));
2403  $this->debug('open_basedir = ');
2404  $this->appendDebug($this->varDump(ini_get('open_basedir')));
2405  } else {
2406  $this->setCurlOption(CURLOPT_FOLLOWLOCATION, 1);
2407  }
2408  // ask for headers in the response output
2409  $this->setCurlOption(CURLOPT_HEADER, 1);
2410  // ask for the response output as the return value
2411  $this->setCurlOption(CURLOPT_RETURNTRANSFER, 1);
2412  // encode
2413  // We manage this ourselves through headers and encoding
2414 // if(function_exists('gzuncompress')){
2415 // $this->setCurlOption(CURLOPT_ENCODING, 'deflate');
2416 // }
2417  // persistent connection
2418  if ($this->persistentConnection) {
2419  // I believe the following comment is now bogus, having applied to
2420  // the code when it used CURLOPT_CUSTOMREQUEST to send the request.
2421  // The way we send data, we cannot use persistent connections, since
2422  // there will be some "junk" at the end of our request.
2423  //$this->setCurlOption(CURL_HTTP_VERSION_1_1, true);
2424  $this->persistentConnection = false;
2425  $this->setHeader('Connection', 'close');
2426  }
2427  // set timeouts
2428  if ($connection_timeout != 0) {
2429  $this->setCurlOption($CURLOPT_CONNECTIONTIMEOUT, $connection_timeout);
2430  }
2431  if ($response_timeout != 0) {
2432  $this->setCurlOption(CURLOPT_TIMEOUT, $response_timeout);
2433  }
2434 
2435  if ($this->scheme == 'https') {
2436  $this->debug('set cURL SSL verify options');
2437  // recent versions of cURL turn on peer/host checking by default,
2438  // while PHP binaries are not compiled with a default location for the
2439  // CA cert bundle, so disable peer/host checking.
2440  //$this->setCurlOption(CURLOPT_CAINFO, 'f:\php-4.3.2-win32\extensions\curl-ca-bundle.crt');
2441  $this->setCurlOption(CURLOPT_SSL_VERIFYPEER, 0);
2442  $this->setCurlOption(CURLOPT_SSL_VERIFYHOST, 0);
2443 
2444  // support client certificates (thanks Tobias Boes, Doug Anarino, Eryan Ariobowo)
2445  if ($this->authtype == 'certificate') {
2446  $this->debug('set cURL certificate options');
2447  if (isset($this->certRequest['cainfofile'])) {
2448  $this->setCurlOption(CURLOPT_CAINFO, $this->certRequest['cainfofile']);
2449  }
2450  if (isset($this->certRequest['verifypeer'])) {
2451  $this->setCurlOption(CURLOPT_SSL_VERIFYPEER, $this->certRequest['verifypeer']);
2452  } else {
2453  $this->setCurlOption(CURLOPT_SSL_VERIFYPEER, 1);
2454  }
2455  if (isset($this->certRequest['verifyhost'])) {
2456  $this->setCurlOption(CURLOPT_SSL_VERIFYHOST, $this->certRequest['verifyhost']);
2457  } else {
2458  $this->setCurlOption(CURLOPT_SSL_VERIFYHOST, 1);
2459  }
2460  if (isset($this->certRequest['sslcertfile'])) {
2461  $this->setCurlOption(CURLOPT_SSLCERT, $this->certRequest['sslcertfile']);
2462  }
2463  if (isset($this->certRequest['sslkeyfile'])) {
2464  $this->setCurlOption(CURLOPT_SSLKEY, $this->certRequest['sslkeyfile']);
2465  }
2466  if (isset($this->certRequest['passphrase'])) {
2467  $this->setCurlOption(CURLOPT_SSLKEYPASSWD, $this->certRequest['passphrase']);
2468  }
2469  if (isset($this->certRequest['certpassword'])) {
2470  $this->setCurlOption(CURLOPT_SSLCERTPASSWD, $this->certRequest['certpassword']);
2471  }
2472  }
2473  }
2474  if ($this->authtype && ($this->authtype != 'certificate')) {
2475  if ($this->username) {
2476  $this->debug('set cURL username/password');
2477  $this->setCurlOption(CURLOPT_USERPWD, "$this->username:$this->password");
2478  }
2479  if ($this->authtype == 'basic') {
2480  $this->debug('set cURL for Basic authentication');
2481  $this->setCurlOption($CURLOPT_HTTPAUTH, $CURLAUTH_BASIC);
2482  }
2483  if ($this->authtype == 'digest') {
2484  $this->debug('set cURL for digest authentication');
2485  $this->setCurlOption($CURLOPT_HTTPAUTH, $CURLAUTH_DIGEST);
2486  }
2487  if ($this->authtype == 'ntlm') {
2488  $this->debug('set cURL for NTLM authentication');
2489  $this->setCurlOption($CURLOPT_HTTPAUTH, $CURLAUTH_NTLM);
2490  }
2491  }
2492  if (is_array($this->proxy)) {
2493  $this->debug('set cURL proxy options');
2494  if ($this->proxy['port'] != '') {
2495  $this->setCurlOption(CURLOPT_PROXY, $this->proxy['host'].':'.$this->proxy['port']);
2496  } else {
2497  $this->setCurlOption(CURLOPT_PROXY, $this->proxy['host']);
2498  }
2499  if ($this->proxy['username'] || $this->proxy['password']) {
2500  $this->debug('set cURL proxy authentication options');
2501  $this->setCurlOption(CURLOPT_PROXYUSERPWD, $this->proxy['username'].':'.$this->proxy['password']);
2502  if ($this->proxy['authtype'] == 'basic') {
2503  $this->setCurlOption($CURLOPT_PROXYAUTH, $CURLAUTH_BASIC);
2504  }
2505  if ($this->proxy['authtype'] == 'ntlm') {
2506  $this->setCurlOption($CURLOPT_PROXYAUTH, $CURLAUTH_NTLM);
2507  }
2508  }
2509  }
2510  $this->debug('cURL connection set up');
2511  return true;
2512  } else {
2513  $this->setError('Unknown scheme ' . $this->scheme);
2514  $this->debug('Unknown scheme ' . $this->scheme);
2515  return false;
2516  }
2517  }
2518 
2529  function send($data, $timeout=0, $response_timeout=30, $cookies=NULL) {
2530 
2531  $this->debug('entered send() with data of length: '.strlen($data));
2532 
2533  $this->tryagain = true;
2534  $tries = 0;
2535  while ($this->tryagain) {
2536  $this->tryagain = false;
2537  if ($tries++ < 2) {
2538  // make connnection
2539  if (!$this->connect($timeout, $response_timeout)){
2540  return false;
2541  }
2542 
2543  // send request
2544  if (!$this->sendRequest($data, $cookies)){
2545  return false;
2546  }
2547 
2548  // get response
2549  $respdata = $this->getResponse();
2550  } else {
2551  $this->setError("Too many tries to get an OK response ($this->response_status_line)");
2552  }
2553  }
2554  $this->debug('end of send()');
2555  return $respdata;
2556  }
2557 
2558 
2570  function sendHTTPS($data, $timeout=0, $response_timeout=30, $cookies) {
2571  return $this->send($data, $timeout, $response_timeout, $cookies);
2572  }
2573 
2584  function setCredentials($username, $password, $authtype = 'basic', $digestRequest = array(), $certRequest = array()) {
2585  $this->debug("setCredentials username=$username authtype=$authtype digestRequest=");
2586  $this->appendDebug($this->varDump($digestRequest));
2587  $this->debug("certRequest=");
2588  $this->appendDebug($this->varDump($certRequest));
2589  // cf. RFC 2617
2590  if ($authtype == 'basic') {
2591  $this->setHeader('Authorization', 'Basic '.base64_encode(str_replace(':','',$username).':'.$password));
2592  } elseif ($authtype == 'digest') {
2593  if (isset($digestRequest['nonce'])) {
2594  $digestRequest['nc'] = isset($digestRequest['nc']) ? $digestRequest['nc']++ : 1;
2595 
2596  // calculate the Digest hashes (calculate code based on digest implementation found at: http://www.rassoc.com/gregr/weblog/stories/2002/07/09/webServicesSecurityHttpDigestAuthenticationWithoutActiveDirectory.html)
2597 
2598  // A1 = unq(username-value) ":" unq(realm-value) ":" passwd
2599  $A1 = $username. ':' . (isset($digestRequest['realm']) ? $digestRequest['realm'] : '') . ':' . $password;
2600 
2601  // H(A1) = MD5(A1)
2602  $HA1 = md5($A1);
2603 
2604  // A2 = Method ":" digest-uri-value
2605  $A2 = $this->request_method . ':' . $this->digest_uri;
2606 
2607  // H(A2)
2608  $HA2 = md5($A2);
2609 
2610  // KD(secret, data) = H(concat(secret, ":", data))
2611  // if qop == auth:
2612  // request-digest = <"> < KD ( H(A1), unq(nonce-value)
2613  // ":" nc-value
2614  // ":" unq(cnonce-value)
2615  // ":" unq(qop-value)
2616  // ":" H(A2)
2617  // ) <">
2618  // if qop is missing,
2619  // request-digest = <"> < KD ( H(A1), unq(nonce-value) ":" H(A2) ) > <">
2620 
2621  $unhashedDigest = '';
2622  $nonce = isset($digestRequest['nonce']) ? $digestRequest['nonce'] : '';
2623  $cnonce = $nonce;
2624  if ($digestRequest['qop'] != '') {
2625  $unhashedDigest = $HA1 . ':' . $nonce . ':' . sprintf("%08d", $digestRequest['nc']) . ':' . $cnonce . ':' . $digestRequest['qop'] . ':' . $HA2;
2626  } else {
2627  $unhashedDigest = $HA1 . ':' . $nonce . ':' . $HA2;
2628  }
2629 
2630  $hashedDigest = md5($unhashedDigest);
2631 
2632  $opaque = '';
2633  if (isset($digestRequest['opaque'])) {
2634  $opaque = ', opaque="' . $digestRequest['opaque'] . '"';
2635  }
2636 
2637  $this->setHeader('Authorization', 'Digest username="' . $username . '", realm="' . $digestRequest['realm'] . '", nonce="' . $nonce . '", uri="' . $this->digest_uri . $opaque . '", cnonce="' . $cnonce . '", nc=' . sprintf("%08x", $digestRequest['nc']) . ', qop="' . $digestRequest['qop'] . '", response="' . $hashedDigest . '"');
2638  }
2639  } elseif ($authtype == 'certificate') {
2640  $this->certRequest = $certRequest;
2641  $this->debug('Authorization header not set for certificate');
2642  } elseif ($authtype == 'ntlm') {
2643  // do nothing
2644  $this->debug('Authorization header not set for ntlm');
2645  }
2646  $this->username = $username;
2647  $this->password = $password;
2648  $this->authtype = $authtype;
2649  $this->digestRequest = $digestRequest;
2650  }
2651 
2658  function setSOAPAction($soapaction) {
2659  $this->setHeader('SOAPAction', '"' . $soapaction . '"');
2660  }
2661 
2668  function setEncoding($enc='gzip, deflate') {
2669  if (function_exists('gzdeflate')) {
2670  $this->protocol_version = '1.1';
2671  $this->setHeader('Accept-Encoding', $enc);
2672  if (!isset($this->outgoing_headers['Connection'])) {
2673  $this->setHeader('Connection', 'close');
2674  $this->persistentConnection = false;
2675  }
2676  #set_magic_quotes_runtime(0);
2677  // deprecated
2678  $this->encoding = $enc;
2679  }
2680  }
2681 
2692  function setProxy($proxyhost, $proxyport, $proxyusername = '', $proxypassword = '', $proxyauthtype = 'basic') {
2693  if ($proxyhost) {
2694  $this->proxy = array(
2695  'host' => $proxyhost,
2696  'port' => $proxyport,
2697  'username' => $proxyusername,
2698  'password' => $proxypassword,
2699  'authtype' => $proxyauthtype
2700  );
2701  if ($proxyusername != '' && $proxypassword != '' && $proxyauthtype = 'basic') {
2702  $this->setHeader('Proxy-Authorization', ' Basic '.base64_encode($proxyusername.':'.$proxypassword));
2703  }
2704  } else {
2705  $this->debug('remove proxy');
2706  $proxy = null;
2707  unsetHeader('Proxy-Authorization');
2708  }
2709  }
2710 
2711 
2721  $skipHeaders = array( 'HTTP/1.1 100',
2722  'HTTP/1.0 301',
2723  'HTTP/1.1 301',
2724  'HTTP/1.0 302',
2725  'HTTP/1.1 302',
2726  'HTTP/1.0 401',
2727  'HTTP/1.1 401',
2728  'HTTP/1.0 200 Connection established');
2729  foreach ($skipHeaders as $hd) {
2730  $prefix = substr($data, 0, strlen($hd));
2731  if ($prefix == $hd) return true;
2732  }
2733 
2734  return false;
2735  }
2736 
2747  function decodeChunked($buffer, $lb){
2748  // length := 0
2749  $length = 0;
2750  $new = '';
2751 
2752  // read chunk-size, chunk-extension (if any) and CRLF
2753  // get the position of the linebreak
2754  $chunkend = strpos($buffer, $lb);
2755  if ($chunkend == FALSE) {
2756  $this->debug('no linebreak found in decodeChunked');
2757  return $new;
2758  }
2759  $temp = substr($buffer,0,$chunkend);
2760  $chunk_size = hexdec( trim($temp) );
2761  $chunkstart = $chunkend + strlen($lb);
2762  // while (chunk-size > 0) {
2763  while ($chunk_size > 0) {
2764  $this->debug("chunkstart: $chunkstart chunk_size: $chunk_size");
2765  $chunkend = strpos( $buffer, $lb, $chunkstart + $chunk_size);
2766 
2767  // Just in case we got a broken connection
2768  if ($chunkend == FALSE) {
2769  $chunk = substr($buffer,$chunkstart);
2770  // append chunk-data to entity-body
2771  $new .= $chunk;
2772  $length += strlen($chunk);
2773  break;
2774  }
2775 
2776  // read chunk-data and CRLF
2777  $chunk = substr($buffer,$chunkstart,$chunkend-$chunkstart);
2778  // append chunk-data to entity-body
2779  $new .= $chunk;
2780  // length := length + chunk-size
2781  $length += strlen($chunk);
2782  // read chunk-size and CRLF
2783  $chunkstart = $chunkend + strlen($lb);
2784 
2785  $chunkend = strpos($buffer, $lb, $chunkstart) + strlen($lb);
2786  if ($chunkend == FALSE) {
2787  break; //Just in case we got a broken connection
2788  }
2789  $temp = substr($buffer,$chunkstart,$chunkend-$chunkstart);
2790  $chunk_size = hexdec( trim($temp) );
2791  $chunkstart = $chunkend;
2792  }
2793  return $new;
2794  }
2795 
2804  function buildPayload($data, $cookie_str = '') {
2805  // Note: for cURL connections, $this->outgoing_payload is ignored,
2806  // as is the Content-Length header, but these are still created as
2807  // debugging guides.
2808 
2809  // add content-length header
2810  $this->setHeader('Content-Length', strlen($data));
2811 
2812  // start building outgoing payload:
2813  if ($this->proxy) {
2814  $uri = $this->url;
2815  } else {
2816  $uri = $this->uri;
2817  }
2818  $req = "$this->request_method $uri HTTP/$this->protocol_version";
2819  $this->debug("HTTP request: $req");
2820  $this->outgoing_payload = "$req\r\n";
2821 
2822  // loop thru headers, serializing
2823  foreach($this->outgoing_headers as $k => $v){
2824  $hdr = $k.': '.$v;
2825  $this->debug("HTTP header: $hdr");
2826  $this->outgoing_payload .= "$hdr\r\n";
2827  }
2828 
2829  // add any cookies
2830  if ($cookie_str != '') {
2831  $hdr = 'Cookie: '.$cookie_str;
2832  $this->debug("HTTP header: $hdr");
2833  $this->outgoing_payload .= "$hdr\r\n";
2834  }
2835 
2836  // header/body separator
2837  $this->outgoing_payload .= "\r\n";
2838 
2839  // add data
2840  $this->outgoing_payload .= $data;
2841  }
2842 
2851  function sendRequest($data, $cookies = NULL) {
2852  // build cookie string
2853  $cookie_str = $this->getCookiesForRequest($cookies, (($this->scheme == 'ssl') || ($this->scheme == 'https')));
2854 
2855  // build payload
2856  $this->buildPayload($data, $cookie_str);
2857 
2858  if ($this->io_method() == 'socket') {
2859  // send payload
2860  if(!fputs($this->fp, $this->outgoing_payload, strlen($this->outgoing_payload))) {
2861  $this->setError('couldn\'t write message data to socket');
2862  $this->debug('couldn\'t write message data to socket');
2863  return false;
2864  }
2865  $this->debug('wrote data to socket, length = ' . strlen($this->outgoing_payload));
2866  return true;
2867  } else if ($this->io_method() == 'curl') {
2868  // set payload
2869  // cURL does say this should only be the verb, and in fact it
2870  // turns out that the URI and HTTP version are appended to this, which
2871  // some servers refuse to work with (so we no longer use this method!)
2872  //$this->setCurlOption(CURLOPT_CUSTOMREQUEST, $this->outgoing_payload);
2873  $curl_headers = array();
2874  foreach($this->outgoing_headers as $k => $v){
2875  if ($k == 'Connection' || $k == 'Content-Length' || $k == 'Host' || $k == 'Authorization' || $k == 'Proxy-Authorization') {
2876  $this->debug("Skip cURL header $k: $v");
2877  } else {
2878  $curl_headers[] = "$k: $v";
2879  }
2880  }
2881  if ($cookie_str != '') {
2882  $curl_headers[] = 'Cookie: ' . $cookie_str;
2883  }
2884  $this->setCurlOption(CURLOPT_HTTPHEADER, $curl_headers);
2885  $this->debug('set cURL HTTP headers');
2886  if ($this->request_method == "POST") {
2887  $this->setCurlOption(CURLOPT_POST, 1);
2888  $this->setCurlOption(CURLOPT_POSTFIELDS, $data);
2889  $this->debug('set cURL POST data');
2890  } else {
2891  }
2892  // insert custom user-set cURL options
2893  foreach ($this->ch_options as $key => $val) {
2894  $this->setCurlOption($key, $val);
2895  }
2896 
2897  $this->debug('set cURL payload');
2898  return true;
2899  }
2900  }
2901 
2908  function getResponse(){
2909  $this->incoming_payload = '';
2910 
2911  if ($this->io_method() == 'socket') {
2912  // loop until headers have been retrieved
2913  $data = '';
2914  while (!isset($lb)){
2915 
2916  // We might EOF during header read.
2917  if(feof($this->fp)) {
2918  $this->incoming_payload = $data;
2919  $this->debug('found no headers before EOF after length ' . strlen($data));
2920  $this->debug("received before EOF:\n" . $data);
2921  $this->setError('server failed to send headers');
2922  return false;
2923  }
2924 
2925  $tmp = fgets($this->fp, 256);
2926  $tmplen = strlen($tmp);
2927  $this->debug("read line of $tmplen bytes: " . trim($tmp));
2928 
2929  if ($tmplen == 0) {
2930  $this->incoming_payload = $data;
2931  $this->debug('socket read of headers timed out after length ' . strlen($data));
2932  $this->debug("read before timeout: " . $data);
2933  $this->setError('socket read of headers timed out');
2934  return false;
2935  }
2936 
2937  $data .= $tmp;
2938  $pos = strpos($data,"\r\n\r\n");
2939  if($pos > 1){
2940  $lb = "\r\n";
2941  } else {
2942  $pos = strpos($data,"\n\n");
2943  if($pos > 1){
2944  $lb = "\n";
2945  }
2946  }
2947  // remove 100 headers
2948  if (isset($lb) && preg_match('/^HTTP\/1.1 100/',$data)) {
2949  unset($lb);
2950  $data = '';
2951  }//
2952  }
2953  // store header data
2954  $this->incoming_payload .= $data;
2955  $this->debug('found end of headers after length ' . strlen($data));
2956  // process headers
2957  $header_data = trim(substr($data,0,$pos));
2958  $header_array = explode($lb,$header_data);
2959  $this->incoming_headers = array();
2960  $this->incoming_cookies = array();
2961  foreach($header_array as $header_line){
2962  $arr = explode(':',$header_line, 2);
2963  if(count($arr) > 1){
2964  $header_name = strtolower(trim($arr[0]));
2965  $this->incoming_headers[$header_name] = trim($arr[1]);
2966  if ($header_name == 'set-cookie') {
2967  // TODO: allow multiple cookies from parseCookie
2968  $cookie = $this->parseCookie(trim($arr[1]));
2969  if ($cookie) {
2970  $this->incoming_cookies[] = $cookie;
2971  $this->debug('found cookie: ' . $cookie['name'] . ' = ' . $cookie['value']);
2972  } else {
2973  $this->debug('did not find cookie in ' . trim($arr[1]));
2974  }
2975  }
2976  } else if (isset($header_name)) {
2977  // append continuation line to previous header
2978  $this->incoming_headers[$header_name] .= $lb . ' ' . $header_line;
2979  }
2980  }
2981 
2982  // loop until msg has been received
2983  if (isset($this->incoming_headers['transfer-encoding']) && strtolower($this->incoming_headers['transfer-encoding']) == 'chunked') {
2984  $content_length = 2147483647; // ignore any content-length header
2985  $chunked = true;
2986  $this->debug("want to read chunked content");
2987  } elseif (isset($this->incoming_headers['content-length'])) {
2988  $content_length = $this->incoming_headers['content-length'];
2989  $chunked = false;
2990  $this->debug("want to read content of length $content_length");
2991  } else {
2992  $content_length = 2147483647;
2993  $chunked = false;
2994  $this->debug("want to read content to EOF");
2995  }
2996  $data = '';
2997  do {
2998  if ($chunked) {
2999  $tmp = fgets($this->fp, 256);
3000  $tmplen = strlen($tmp);
3001  $this->debug("read chunk line of $tmplen bytes");
3002  if ($tmplen == 0) {
3003  $this->incoming_payload = $data;
3004  $this->debug('socket read of chunk length timed out after length ' . strlen($data));
3005  $this->debug("read before timeout:\n" . $data);
3006  $this->setError('socket read of chunk length timed out');
3007  return false;
3008  }
3009  $content_length = hexdec(trim($tmp));
3010  $this->debug("chunk length $content_length");
3011  }
3012  $strlen = 0;
3013  while (($strlen < $content_length) && (!feof($this->fp))) {
3014  $readlen = min(8192, $content_length - $strlen);
3015  $tmp = fread($this->fp, $readlen);
3016  $tmplen = strlen($tmp);
3017  $this->debug("read buffer of $tmplen bytes");
3018  if (($tmplen == 0) && (!feof($this->fp))) {
3019  $this->incoming_payload = $data;
3020  $this->debug('socket read of body timed out after length ' . strlen($data));
3021  $this->debug("read before timeout:\n" . $data);
3022  $this->setError('socket read of body timed out');
3023  return false;
3024  }
3025  $strlen += $tmplen;
3026  $data .= $tmp;
3027  }
3028  if ($chunked && ($content_length > 0)) {
3029  $tmp = fgets($this->fp, 256);
3030  $tmplen = strlen($tmp);
3031  $this->debug("read chunk terminator of $tmplen bytes");
3032  if ($tmplen == 0) {
3033  $this->incoming_payload = $data;
3034  $this->debug('socket read of chunk terminator timed out after length ' . strlen($data));
3035  $this->debug("read before timeout:\n" . $data);
3036  $this->setError('socket read of chunk terminator timed out');
3037  return false;
3038  }
3039  }
3040  } while ($chunked && ($content_length > 0) && (!feof($this->fp)));
3041  if (feof($this->fp)) {
3042  $this->debug('read to EOF');
3043  }
3044  $this->debug('read body of length ' . strlen($data));
3045  $this->incoming_payload .= $data;
3046  $this->debug('received a total of '.strlen($this->incoming_payload).' bytes of data from server');
3047 
3048  // close filepointer
3049  if(
3050  (isset($this->incoming_headers['connection']) && strtolower($this->incoming_headers['connection']) == 'close') ||
3051  (! $this->persistentConnection) || feof($this->fp)){
3052  fclose($this->fp);
3053  $this->fp = false;
3054  $this->debug('closed socket');
3055  }
3056 
3057  // connection was closed unexpectedly
3058  if($this->incoming_payload == ''){
3059  $this->setError('no response from server');
3060  return false;
3061  }
3062 
3063  // decode transfer-encoding
3064 // if(isset($this->incoming_headers['transfer-encoding']) && strtolower($this->incoming_headers['transfer-encoding']) == 'chunked'){
3065 // if(!$data = $this->decodeChunked($data, $lb)){
3066 // $this->setError('Decoding of chunked data failed');
3067 // return false;
3068 // }
3069  //print "<pre>\nde-chunked:\n---------------\n$data\n\n---------------\n</pre>";
3070  // set decoded payload
3071 // $this->incoming_payload = $header_data.$lb.$lb.$data;
3072 // }
3073 
3074  } else if ($this->io_method() == 'curl') {
3075  // send and receive
3076  $this->debug('send and receive with cURL');
3077  $this->incoming_payload = curl_exec($this->ch);
3078  $data = $this->incoming_payload;
3079 
3080  $cErr = curl_error($this->ch);
3081  if ($cErr != '') {
3082  $err = 'cURL ERROR: '.curl_errno($this->ch).': '.$cErr.'<br>';
3083  // TODO: there is a PHP bug that can cause this to SEGV for CURLINFO_CONTENT_TYPE
3084  foreach(curl_getinfo($this->ch) as $k => $v){
3085  $err .= "$k: $v<br>";
3086  }
3087  $this->debug($err);
3088  $this->setError($err);
3089  curl_close($this->ch);
3090  return false;
3091  } else {
3092  //echo '<pre>';
3093  //var_dump(curl_getinfo($this->ch));
3094  //echo '</pre>';
3095  }
3096  // close curl
3097  $this->debug('No cURL error, closing cURL');
3098  curl_close($this->ch);
3099 
3100  // try removing skippable headers
3101  $savedata = $data;
3102  while ($this->isSkippableCurlHeader($data)) {
3103  $this->debug("Found HTTP header to skip");
3104  if ($pos = strpos($data,"\r\n\r\n")) {
3105  $data = ltrim(substr($data,$pos));
3106  } elseif($pos = strpos($data,"\n\n") ) {
3107  $data = ltrim(substr($data,$pos));
3108  }
3109  }
3110 
3111  if ($data == '') {
3112  // have nothing left; just remove 100 header(s)
3113  $data = $savedata;
3114  while (preg_match('/^HTTP\/1.1 100/',$data)) {
3115  if ($pos = strpos($data,"\r\n\r\n")) {
3116  $data = ltrim(substr($data,$pos));
3117  } elseif($pos = strpos($data,"\n\n") ) {
3118  $data = ltrim(substr($data,$pos));
3119  }
3120  }
3121  }
3122 
3123  // separate content from HTTP headers
3124  if ($pos = strpos($data,"\r\n\r\n")) {
3125  $lb = "\r\n";
3126  } elseif( $pos = strpos($data,"\n\n")) {
3127  $lb = "\n";
3128  } else {
3129  $this->debug('no proper separation of headers and document');
3130  $this->setError('no proper separation of headers and document');
3131  return false;
3132  }
3133  $header_data = trim(substr($data,0,$pos));
3134  $header_array = explode($lb,$header_data);
3135  $data = ltrim(substr($data,$pos));
3136  $this->debug('found proper separation of headers and document');
3137  $this->debug('cleaned data, stringlen: '.strlen($data));
3138  // clean headers
3139  foreach ($header_array as $header_line) {
3140  $arr = explode(':',$header_line,2);
3141  if(count($arr) > 1){
3142  $header_name = strtolower(trim($arr[0]));
3143  $this->incoming_headers[$header_name] = trim($arr[1]);
3144  if ($header_name == 'set-cookie') {
3145  // TODO: allow multiple cookies from parseCookie
3146  $cookie = $this->parseCookie(trim($arr[1]));
3147  if ($cookie) {
3148  $this->incoming_cookies[] = $cookie;
3149  $this->debug('found cookie: ' . $cookie['name'] . ' = ' . $cookie['value']);
3150  } else {
3151  $this->debug('did not find cookie in ' . trim($arr[1]));
3152  }
3153  }
3154  } else if (isset($header_name)) {
3155  // append continuation line to previous header
3156  $this->incoming_headers[$header_name] .= $lb . ' ' . $header_line;
3157  }
3158  }
3159  }
3160 
3161  $this->response_status_line = $header_array[0];
3162  $arr = explode(' ', $this->response_status_line, 3);
3163  $http_version = $arr[0];
3164  $http_status = intval($arr[1]);
3165  $http_reason = count($arr) > 2 ? $arr[2] : '';
3166 
3167  // see if we need to resend the request with http digest authentication
3168  if (isset($this->incoming_headers['location']) && ($http_status == 301 || $http_status == 302)) {
3169  $this->debug("Got $http_status $http_reason with Location: " . $this->incoming_headers['location']);
3170  $this->setURL($this->incoming_headers['location']);
3171  $this->tryagain = true;
3172  return false;
3173  }
3174 
3175  // see if we need to resend the request with http digest authentication
3176  if (isset($this->incoming_headers['www-authenticate']) && $http_status == 401) {
3177  $this->debug("Got 401 $http_reason with WWW-Authenticate: " . $this->incoming_headers['www-authenticate']);
3178  if (strstr($this->incoming_headers['www-authenticate'], "Digest ")) {
3179  $this->debug('Server wants digest authentication');
3180  // remove "Digest " from our elements
3181  $digestString = str_replace('Digest ', '', $this->incoming_headers['www-authenticate']);
3182 
3183  // parse elements into array
3184  $digestElements = explode(',', $digestString);
3185  foreach ($digestElements as $val) {
3186  $tempElement = explode('=', trim($val), 2);
3187  $digestRequest[$tempElement[0]] = str_replace("\"", '', $tempElement[1]);
3188  }
3189 
3190  // should have (at least) qop, realm, nonce
3191  if (isset($digestRequest['nonce'])) {
3192  $this->setCredentials($this->username, $this->password, 'digest', $digestRequest);
3193  $this->tryagain = true;
3194  return false;
3195  }
3196  }
3197  $this->debug('HTTP authentication failed');
3198  $this->setError('HTTP authentication failed');
3199  return false;
3200  }
3201 
3202  if (
3203  ($http_status >= 300 && $http_status <= 307) ||
3204  ($http_status >= 400 && $http_status <= 417) ||
3205  ($http_status >= 501 && $http_status <= 505)
3206  ) {
3207  $this->setError("Unsupported HTTP response status $http_status $http_reason (soapclient->response has contents of the response)");
3208  return false;
3209  }
3210 
3211  // decode content-encoding
3212  if(isset($this->incoming_headers['content-encoding']) && $this->incoming_headers['content-encoding'] != ''){
3213  if(strtolower($this->incoming_headers['content-encoding']) == 'deflate' || strtolower($this->incoming_headers['content-encoding']) == 'gzip'){
3214  // if decoding works, use it. else assume data wasn't gzencoded
3215  if(function_exists('gzinflate')){
3216  //$timer->setMarker('starting decoding of gzip/deflated content');
3217  // IIS 5 requires gzinflate instead of gzuncompress (similar to IE 5 and gzdeflate v. gzcompress)
3218  // this means there are no Zlib headers, although there should be
3219  $this->debug('The gzinflate function exists');
3220  $datalen = strlen($data);
3221  if ($this->incoming_headers['content-encoding'] == 'deflate') {
3222  if ($degzdata = @gzinflate($data)) {
3223  $data = $degzdata;
3224  $this->debug('The payload has been inflated to ' . strlen($data) . ' bytes');
3225  if (strlen($data) < $datalen) {
3226  // test for the case that the payload has been compressed twice
3227  $this->debug('The inflated payload is smaller than the gzipped one; try again');
3228  if ($degzdata = @gzinflate($data)) {
3229  $data = $degzdata;
3230  $this->debug('The payload has been inflated again to ' . strlen($data) . ' bytes');
3231  }
3232  }
3233  } else {
3234  $this->debug('Error using gzinflate to inflate the payload');
3235  $this->setError('Error using gzinflate to inflate the payload');
3236  }
3237  } elseif ($this->incoming_headers['content-encoding'] == 'gzip') {
3238  if ($degzdata = @gzinflate(substr($data, 10))) { // do our best
3239  $data = $degzdata;
3240  $this->debug('The payload has been un-gzipped to ' . strlen($data) . ' bytes');
3241  if (strlen($data) < $datalen) {
3242  // test for the case that the payload has been compressed twice
3243  $this->debug('The un-gzipped payload is smaller than the gzipped one; try again');
3244  if ($degzdata = @gzinflate(substr($data, 10))) {
3245  $data = $degzdata;
3246  $this->debug('The payload has been un-gzipped again to ' . strlen($data) . ' bytes');
3247  }
3248  }
3249  } else {
3250  $this->debug('Error using gzinflate to un-gzip the payload');
3251  $this->setError('Error using gzinflate to un-gzip the payload');
3252  }
3253  }
3254  //$timer->setMarker('finished decoding of gzip/deflated content');
3255  //print "<xmp>\nde-inflated:\n---------------\n$data\n-------------\n</xmp>";
3256  // set decoded payload
3257  $this->incoming_payload = $header_data.$lb.$lb.$data;
3258  } else {
3259  $this->debug('The server sent compressed data. Your php install must have the Zlib extension compiled in to support this.');
3260  $this->setError('The server sent compressed data. Your php install must have the Zlib extension compiled in to support this.');
3261  }
3262  } else {
3263  $this->debug('Unsupported Content-Encoding ' . $this->incoming_headers['content-encoding']);
3264  $this->setError('Unsupported Content-Encoding ' . $this->incoming_headers['content-encoding']);
3265  }
3266  } else {
3267  $this->debug('No Content-Encoding header');
3268  }
3269 
3270  if(strlen($data) == 0){
3271  $this->debug('no data after headers!');
3272  $this->setError('no data present after HTTP headers');
3273  return false;
3274  }
3275 
3276  return $data;
3277  }
3278 
3286  function setContentType($type, $charset = false) {
3287  $this->setHeader('Content-Type', $type . ($charset ? '; charset=' . $charset : ''));
3288  }
3289 
3297  if (isset($this->outgoing_headers['Accept-Encoding'])) {
3298  return false;
3299  }
3300  $this->protocol_version = '1.1';
3301  $this->persistentConnection = true;
3302  $this->setHeader('Connection', 'Keep-Alive');
3303  return true;
3304  }
3305 
3313  /*
3314  * TODO: allow a Set-Cookie string to be parsed into multiple cookies
3315  */
3316  function parseCookie($cookie_str) {
3317  $cookie_str = str_replace('; ', ';', $cookie_str) . ';';
3318  $data = split(';', $cookie_str);
3319  $value_str = $data[0];
3320 
3321  $cookie_param = 'domain=';
3322  $start = strpos($cookie_str, $cookie_param);
3323  if ($start > 0) {
3324  $domain = substr($cookie_str, $start + strlen($cookie_param));
3325  $domain = substr($domain, 0, strpos($domain, ';'));
3326  } else {
3327  $domain = '';
3328  }
3329 
3330  $cookie_param = 'expires=';
3331  $start = strpos($cookie_str, $cookie_param);
3332  if ($start > 0) {
3333  $expires = substr($cookie_str, $start + strlen($cookie_param));
3334  $expires = substr($expires, 0, strpos($expires, ';'));
3335  } else {
3336  $expires = '';
3337  }
3338 
3339  $cookie_param = 'path=';
3340  $start = strpos($cookie_str, $cookie_param);
3341  if ( $start > 0 ) {
3342  $path = substr($cookie_str, $start + strlen($cookie_param));
3343  $path = substr($path, 0, strpos($path, ';'));
3344  } else {
3345  $path = '/';
3346  }
3347 
3348  $cookie_param = ';secure;';
3349  if (strpos($cookie_str, $cookie_param) !== FALSE) {
3350  $secure = true;
3351  } else {
3352  $secure = false;
3353  }
3354 
3355  $sep_pos = strpos($value_str, '=');
3356 
3357  if ($sep_pos) {
3358  $name = substr($value_str, 0, $sep_pos);
3359  $value = substr($value_str, $sep_pos + 1);
3360  $cookie= array( 'name' => $name,
3361  'value' => $value,
3362  'domain' => $domain,
3363  'path' => $path,
3364  'expires' => $expires,
3365  'secure' => $secure
3366  );
3367  return $cookie;
3368  }
3369  return false;
3370  }
3371 
3380  function getCookiesForRequest($cookies, $secure=false) {
3381  $cookie_str = '';
3382  if ((! is_null($cookies)) && (is_array($cookies))) {
3383  foreach ($cookies as $cookie) {
3384  if (! is_array($cookie)) {
3385  continue;
3386  }
3387  $this->debug("check cookie for validity: ".$cookie['name'].'='.$cookie['value']);
3388  if ((isset($cookie['expires'])) && (! empty($cookie['expires']))) {
3389  if (strtotime($cookie['expires']) <= time()) {
3390  $this->debug('cookie has expired');
3391  continue;
3392  }
3393  }
3394  if ((isset($cookie['domain'])) && (! empty($cookie['domain']))) {
3395  $domain = preg_quote($cookie['domain']);
3396  if (! preg_match("'.*$domain$'i", $this->host)) {
3397  $this->debug('cookie has different domain');
3398  continue;
3399  }
3400  }
3401  if ((isset($cookie['path'])) && (! empty($cookie['path']))) {
3402  $path = preg_quote($cookie['path']);
3403  if (! preg_match("'^$path.*'i", $this->path)) {
3404  $this->debug('cookie is for a different path');
3405  continue;
3406  }
3407  }
3408  if ((! $secure) && (isset($cookie['secure'])) && ($cookie['secure'])) {
3409  $this->debug('cookie is secure, transport is not');
3410  continue;
3411  }
3412  $cookie_str .= $cookie['name'] . '=' . $cookie['value'] . '; ';
3413  $this->debug('add cookie to Cookie-String: ' . $cookie['name'] . '=' . $cookie['value']);
3414  }
3415  }
3416  return $cookie_str;
3417  }
3418 }
3419 
3420 ?><?php
3421 
3422 
3423 
3440  var $headers = array();
3446  var $request = '';
3452  var $requestHeaders = '';
3458  var $requestHeader = NULL;
3464  var $document = '';
3470  var $requestSOAP = '';
3476  var $methodURI = '';
3482  var $methodname = '';
3488  var $methodparams = array();
3494  var $SOAPAction = '';
3500  var $xml_encoding = '';
3506  var $decode_utf8 = true;
3507 
3513  var $outgoing_headers = array();
3519  var $response = '';
3525  var $responseHeaders = '';
3531  var $responseSOAP = '';
3537  var $methodreturn = false;
3543  var $methodreturnisliteralxml = false;
3549  var $fault = false;
3555  var $result = 'successful';
3556 
3563  var $operations = array();
3569  var $wsdl = false;
3575  var $externalWSDLURL = false;
3581  var $debug_flag = false;
3582 
3583 
3591  function __construct($wsdl=false){
3592  parent::__construct();
3593  // turn on debugging?
3594  global $debug;
3595  global $HTTP_SERVER_VARS;
3596 
3597  if (isset($_SERVER)) {
3598  $this->debug("_SERVER is defined:");
3599  $this->appendDebug($this->varDump($_SERVER));
3600  } elseif (isset($HTTP_SERVER_VARS)) {
3601  $this->debug("HTTP_SERVER_VARS is defined:");
3602  $this->appendDebug($this->varDump($HTTP_SERVER_VARS));
3603  } else {
3604  $this->debug("Neither _SERVER nor HTTP_SERVER_VARS is defined.");
3605  }
3606 
3607  if (isset($debug)) {
3608  $this->debug("In nusoap_server, set debug_flag=$debug based on global flag");
3609  $this->debug_flag = $debug;
3610  } elseif (isset($_SERVER['QUERY_STRING'])) {
3611  $qs = explode('&', $_SERVER['QUERY_STRING']);
3612  foreach ($qs as $v) {
3613  if (substr($v, 0, 6) == 'debug=') {
3614  $this->debug("In nusoap_server, set debug_flag=" . substr($v, 6) . " based on query string #1");
3615  $this->debug_flag = substr($v, 6);
3616  }
3617  }
3618  } elseif (isset($HTTP_SERVER_VARS['QUERY_STRING'])) {
3619  $qs = explode('&', $HTTP_SERVER_VARS['QUERY_STRING']);
3620  foreach ($qs as $v) {
3621  if (substr($v, 0, 6) == 'debug=') {
3622  $this->debug("In nusoap_server, set debug_flag=" . substr($v, 6) . " based on query string #2");
3623  $this->debug_flag = substr($v, 6);
3624  }
3625  }
3626  }
3627 
3628  // wsdl
3629  if($wsdl){
3630  $this->debug("In nusoap_server, WSDL is specified");
3631  if (is_object($wsdl) && (get_class($wsdl) == 'wsdl')) {
3632  $this->wsdl = $wsdl;
3633  $this->externalWSDLURL = $this->wsdl->wsdl;
3634  $this->debug('Use existing wsdl instance from ' . $this->externalWSDLURL);
3635  } else {
3636  $this->debug('Create wsdl from ' . $wsdl);
3637  $this->wsdl = new wsdl($wsdl);
3638  $this->externalWSDLURL = $wsdl;
3639  }
3640  $this->appendDebug($this->wsdl->getDebug());
3641  $this->wsdl->clearDebug();
3642  if($err = $this->wsdl->getError()){
3643  die('WSDL ERROR: '.$err);
3644  }
3645  }
3646  }
3647 
3654  function service($data){
3655  global $HTTP_SERVER_VARS;
3656 
3657  if (isset($_SERVER['QUERY_STRING'])) {
3658  $qs = $_SERVER['QUERY_STRING'];
3659  } elseif (isset($HTTP_SERVER_VARS['QUERY_STRING'])) {
3660  $qs = $HTTP_SERVER_VARS['QUERY_STRING'];
3661  } else {
3662  $qs = '';
3663  }
3664  $this->debug("In service, query string=$qs");
3665 
3666  if (preg_match('/wsdl/', $qs) ){
3667  $this->debug("In service, this is a request for WSDL");
3668  if($this->externalWSDLURL){
3669  if (strpos($this->externalWSDLURL,"://")!==false) { // assume URL
3670  header('Location: '.$this->externalWSDLURL);
3671  } else { // assume file
3672  header("Content-Type: text/xml\r\n");
3673  $fp = fopen($this->externalWSDLURL, 'r');
3674  fpassthru($fp);
3675  }
3676  } elseif ($this->wsdl) {
3677  header("Content-Type: text/xml; charset=ISO-8859-1\r\n");
3678  print $this->wsdl->serialize($this->debug_flag);
3679  if ($this->debug_flag) {
3680  $this->debug('wsdl:');
3681  $this->appendDebug($this->varDump($this->wsdl));
3682  print $this->getDebugAsXMLComment();
3683  }
3684  } else {
3685  header("Content-Type: text/html; charset=ISO-8859-1\r\n");
3686  print "This service does not provide WSDL";
3687  }
3688  } elseif ($data == '' && $this->wsdl) {
3689  $this->debug("In service, there is no data, so return Web description");
3690  print $this->wsdl->webDescription();
3691  } else {
3692  $this->debug("In service, invoke the request");
3693  $this->parse_request($data);
3694  if (! $this->fault) {
3695  $this->invoke_method();
3696  }
3697  if (! $this->fault) {
3698  $this->serialize_return();
3699  }
3700  $this->send_response();
3701  }
3702  }
3703 
3716  function parse_http_headers() {
3717  global $HTTP_SERVER_VARS;
3718 
3719  $this->request = '';
3720  $this->SOAPAction = '';
3721  if(function_exists('getallheaders')){
3722  $this->debug("In parse_http_headers, use getallheaders");
3723  $headers = getallheaders();
3724  foreach($headers as $k=>$v){
3725  $k = strtolower($k);
3726  $this->headers[$k] = $v;
3727  $this->request .= "$k: $v\r\n";
3728  $this->debug("$k: $v");
3729  }
3730  // get SOAPAction header
3731  if(isset($this->headers['soapaction'])){
3732  $this->SOAPAction = str_replace('"','',$this->headers['soapaction']);
3733  }
3734  // get the character encoding of the incoming request
3735  if(isset($this->headers['content-type']) && strpos($this->headers['content-type'],'=')){
3736  $enc = str_replace('"','',substr(strstr($this->headers["content-type"],'='),1));
3737  if(preg_match('/^(ISO-8859-1|US-ASCII|UTF-8)$/i',$enc)){
3738  $this->xml_encoding = strtoupper($enc);
3739  } else {
3740  $this->xml_encoding = 'US-ASCII';
3741  }
3742  } else {
3743  // should be US-ASCII for HTTP 1.0 or ISO-8859-1 for HTTP 1.1
3744  $this->xml_encoding = 'ISO-8859-1';
3745  }
3746  } elseif(isset($_SERVER) && is_array($_SERVER)){
3747  $this->debug("In parse_http_headers, use _SERVER");
3748  foreach ($_SERVER as $k => $v) {
3749  if (substr($k, 0, 5) == 'HTTP_') {
3750  $k = str_replace(' ', '-', strtolower(str_replace('_', ' ', substr($k, 5))));
3751  } else {
3752  $k = str_replace(' ', '-', strtolower(str_replace('_', ' ', $k)));
3753  }
3754  if ($k == 'soapaction') {
3755  // get SOAPAction header
3756  $k = 'SOAPAction';
3757  $v = str_replace('"', '', $v);
3758  $v = str_replace('\\', '', $v);
3759  $this->SOAPAction = $v;
3760  } else if ($k == 'content-type') {
3761  // get the character encoding of the incoming request
3762  if (strpos($v, '=')) {
3763  $enc = substr(strstr($v, '='), 1);
3764  $enc = str_replace('"', '', $enc);
3765  $enc = str_replace('\\', '', $enc);
3766  if (preg_match('/^(ISO-8859-1|US-ASCII|UTF-8)$/i',$enc)) {
3767  $this->xml_encoding = strtoupper($enc);
3768  } else {
3769  $this->xml_encoding = 'US-ASCII';
3770  }
3771  } else {
3772  // should be US-ASCII for HTTP 1.0 or ISO-8859-1 for HTTP 1.1
3773  $this->xml_encoding = 'ISO-8859-1';
3774  }
3775  }
3776  $this->headers[$k] = $v;
3777  $this->request .= "$k: $v\r\n";
3778  $this->debug("$k: $v");
3779  }
3780  } elseif (is_array($HTTP_SERVER_VARS)) {
3781  $this->debug("In parse_http_headers, use HTTP_SERVER_VARS");
3782  foreach ($HTTP_SERVER_VARS as $k => $v) {
3783  if (substr($k, 0, 5) == 'HTTP_') {
3784  $k = str_replace(' ', '-', strtolower(str_replace('_', ' ', substr($k, 5)))); $k = strtolower(substr($k, 5));
3785  } else {
3786  $k = str_replace(' ', '-', strtolower(str_replace('_', ' ', $k))); $k = strtolower($k);
3787  }
3788  if ($k == 'soapaction') {
3789  // get SOAPAction header
3790  $k = 'SOAPAction';
3791  $v = str_replace('"', '', $v);
3792  $v = str_replace('\\', '', $v);
3793  $this->SOAPAction = $v;
3794  } else if ($k == 'content-type') {
3795  // get the character encoding of the incoming request
3796  if (strpos($v, '=')) {
3797  $enc = substr(strstr($v, '='), 1);
3798  $enc = str_replace('"', '', $enc);
3799  $enc = str_replace('\\', '', $enc);
3800  if (preg_match('/^(ISO-8859-1|US-ASCII|UTF-8)$/i',$enc)) {
3801  $this->xml_encoding = strtoupper($enc);
3802  } else {
3803  $this->xml_encoding = 'US-ASCII';
3804  }
3805  } else {
3806  // should be US-ASCII for HTTP 1.0 or ISO-8859-1 for HTTP 1.1
3807  $this->xml_encoding = 'ISO-8859-1';
3808  }
3809  }
3810  $this->headers[$k] = $v;
3811  $this->request .= "$k: $v\r\n";
3812  $this->debug("$k: $v");
3813  }
3814  } else {
3815  $this->debug("In parse_http_headers, HTTP headers not accessible");
3816  $this->setError("HTTP headers not accessible");
3817  }
3818  }
3819 
3842  function parse_request($data='') {
3843  $this->debug('entering parse_request()');
3844  $this->parse_http_headers();
3845  $this->debug('got character encoding: '.$this->xml_encoding);
3846  // uncompress if necessary
3847  if (isset($this->headers['content-encoding']) && $this->headers['content-encoding'] != '') {
3848  $this->debug('got content encoding: ' . $this->headers['content-encoding']);
3849  if ($this->headers['content-encoding'] == 'deflate' || $this->headers['content-encoding'] == 'gzip') {
3850  // if decoding works, use it. else assume data wasn't gzencoded
3851  if (function_exists('gzuncompress')) {
3852  if ($this->headers['content-encoding'] == 'deflate' && $degzdata = @gzuncompress($data)) {
3853  $data = $degzdata;
3854  } elseif ($this->headers['content-encoding'] == 'gzip' && $degzdata = gzinflate(substr($data, 10))) {
3855  $data = $degzdata;
3856  } else {
3857  $this->fault('SOAP-ENV:Client', 'Errors occurred when trying to decode the data');
3858  return;
3859  }
3860  } else {
3861  $this->fault('SOAP-ENV:Client', 'This Server does not support compressed data');
3862  return;
3863  }
3864  }
3865  }
3866  $this->request .= "\r\n".$data;
3867  $data = $this->parseRequest($this->headers, $data);
3868  $this->requestSOAP = $data;
3869  $this->debug('leaving parse_request');
3870  }
3871 
3889  function invoke_method() {
3890  $this->debug('in invoke_method, methodname=' . $this->methodname . ' methodURI=' . $this->methodURI . ' SOAPAction=' . $this->SOAPAction);
3891 
3892  if ($this->wsdl) {
3893  if ($this->opData = $this->wsdl->getOperationData($this->methodname)) {
3894  $this->debug('in invoke_method, found WSDL operation=' . $this->methodname);
3895  $this->appendDebug('opData=' . $this->varDump($this->opData));
3896  } elseif ($this->opData = $this->wsdl->getOperationDataForSoapAction($this->SOAPAction)) {
3897  // Note: hopefully this case will only be used for doc/lit, since rpc services should have wrapper element
3898  $this->debug('in invoke_method, found WSDL soapAction=' . $this->SOAPAction . ' for operation=' . $this->opData['name']);
3899  $this->appendDebug('opData=' . $this->varDump($this->opData));
3900  $this->methodname = $this->opData['name'];
3901  } else {
3902  $this->debug('in invoke_method, no WSDL for operation=' . $this->methodname);
3903  $this->fault('SOAP-ENV:Client', "Operation '" . $this->methodname . "' is not defined in the WSDL for this service");
3904  return;
3905  }
3906  } else {
3907  $this->debug('in invoke_method, no WSDL to validate method');
3908  }
3909 
3910  // if a . is present in $this->methodname, we see if there is a class in scope,
3911  // which could be referred to. We will also distinguish between two deliminators,
3912  // to allow methods to be called a the class or an instance
3913  $class = '';
3914  $method = '';
3915  if (strpos($this->methodname, '..') > 0) {
3916  $delim = '..';
3917  } else if (strpos($this->methodname, '.') > 0) {
3918  $delim = '.';
3919  } else {
3920  $delim = '';
3921  }
3922 
3923  if (strlen($delim) > 0 && substr_count($this->methodname, $delim) == 1 &&
3924  class_exists(substr($this->methodname, 0, strpos($this->methodname, $delim)))) {
3925  // get the class and method name
3926  $class = substr($this->methodname, 0, strpos($this->methodname, $delim));
3927  $method = substr($this->methodname, strpos($this->methodname, $delim) + strlen($delim));
3928  $this->debug("in invoke_method, class=$class method=$method delim=$delim");
3929  }
3930  // set class handler
3931  // added to support single operations
3932  if ($class == '' && $this->class !='')
3933  {
3934  $class = $this->class;
3935  $delim = "..";
3936  $method = $this->methodname;
3937  }
3938 
3939  // does method exist?
3940  if ($class == '') {
3941  if (!function_exists($this->methodname)) {
3942  $this->debug("in invoke_method, function '$this->methodname' not found!");
3943  $this->result = 'fault: method not found';
3944  $this->fault('SOAP-ENV:Client',"method '$this->methodname' not defined in service");
3945  return;
3946  }
3947  } else {
3948  $method_to_compare = (substr(phpversion(), 0, 2) == '4.') ? strtolower($method) : $method;
3949  if (!in_array($method_to_compare, get_class_methods($class))) {
3950  $this->debug("in invoke_method, method '$this->methodname' not found in class '$class'!");
3951  $this->result = 'fault: method not found';
3952  $this->fault('SOAP-ENV:Client',"method '$this->methodname' not defined in service");
3953  return;
3954  }
3955  }
3956 
3957  // evaluate message, getting back parameters
3958  // verify that request parameters match the method's signature
3959  if(! $this->verify_method($this->methodname,$this->methodparams)){
3960  // debug
3961  $this->debug('ERROR: request not verified against method signature');
3962  $this->result = 'fault: request failed validation against method signature';
3963  // return fault
3964  $this->fault('SOAP-ENV:Client',"Operation '$this->methodname' not defined in service.");
3965  return;
3966  }
3967 
3968  // if there are parameters to pass
3969  $this->debug('in invoke_method, params:');
3970  $this->appendDebug($this->varDump($this->methodparams));
3971  $this->debug("in invoke_method, calling '$this->methodname'");
3972  if (!function_exists('call_user_func_array')) {
3973  if ($class == '') {
3974  $this->debug('in invoke_method, calling function using eval()');
3975  $funcCall = "\$this->methodreturn = $this->methodname(";
3976  } else {
3977  if ($delim == '..') {
3978  $this->debug('in invoke_method, calling class method using eval()');
3979  $funcCall = "\$this->methodreturn = ".$class."::".$method."(";
3980  } else {
3981  $this->debug('in invoke_method, calling instance method using eval()');
3982  // generate unique instance name
3983  $instname = "\$inst_".time();
3984  $funcCall = $instname." = new ".$class."(); ";
3985  $funcCall .= "\$this->methodreturn = ".$instname."->".$method."(";
3986  }
3987  }
3988  if ($this->methodparams) {
3989  foreach ($this->methodparams as $param) {
3990  if (is_array($param) || is_object($param)) {
3991  $this->fault('SOAP-ENV:Client', 'NuSOAP does not handle complexType parameters correctly when using eval; call_user_func_array must be available');
3992  return;
3993  }
3994  $funcCall .= "\"$param\",";
3995  }
3996  $funcCall = substr($funcCall, 0, -1);
3997  }
3998  $funcCall .= ');';
3999  $this->debug('in invoke_method, function call: '.$funcCall);
4000  @eval($funcCall);
4001  } else {
4002  if ($class == '') {
4003  $this->debug('in invoke_method, calling function using call_user_func_array()');
4004  $call_arg = "$this->methodname"; // straight assignment changes $this->methodname to lower case after call_user_func_array()
4005  } elseif ($delim == '..') {
4006  $this->debug('in invoke_method, calling class method using call_user_func_array()');
4007  $call_arg = array ($class, $method);
4008  } else {
4009  $this->debug('in invoke_method, calling instance method using call_user_func_array()');
4010  $instance = new $class ();
4011  $call_arg = array(&$instance, $method);
4012  }
4013  if (is_array($this->methodparams)) {
4014  $this->methodreturn = call_user_func_array($call_arg, array_values($this->methodparams));
4015  } else {
4016  $this->methodreturn = call_user_func_array($call_arg, array());
4017  }
4018  }
4019  $this->debug('in invoke_method, methodreturn:');
4020  $this->appendDebug($this->varDump($this->methodreturn));
4021  $this->debug("in invoke_method, called method $this->methodname, received data of type ".gettype($this->methodreturn));
4022  }
4023 
4035  function serialize_return() {
4036  $this->debug('Entering serialize_return methodname: ' . $this->methodname . ' methodURI: ' . $this->methodURI);
4037  // if fault
4038  if (isset($this->methodreturn) && ((get_class((object)$this->methodreturn) == 'soap_fault') || (get_class((object)$this->methodreturn) == 'nusoap_fault'))) {
4039  $this->debug('got a fault object from method');
4040  $this->fault = $this->methodreturn;
4041  return;
4042  } elseif ($this->methodreturnisliteralxml) {
4043  $return_val = $this->methodreturn;
4044  // returned value(s)
4045  } else {
4046  $this->debug('got a(n) '.gettype($this->methodreturn).' from method');
4047  $this->debug('serializing return value');
4048  if($this->wsdl){
4049  if (sizeof($this->opData['output']['parts']) > 1) {
4050  $this->debug('more than one output part, so use the method return unchanged');
4051  $opParams = $this->methodreturn;
4052  } elseif (sizeof($this->opData['output']['parts']) == 1) {
4053  $this->debug('exactly one output part, so wrap the method return in a simple array');
4054  // TODO: verify that it is not already wrapped!
4055  //foreach ($this->opData['output']['parts'] as $name => $type) {
4056  // $this->debug('wrap in element named ' . $name);
4057  //}
4058  $opParams = array($this->methodreturn);
4059  }
4060  $return_val = $this->wsdl->serializeRPCParameters($this->methodname,'output',$opParams);
4061  $this->appendDebug($this->wsdl->getDebug());
4062  $this->wsdl->clearDebug();
4063  if($errstr = $this->wsdl->getError()){
4064  $this->debug('got wsdl error: '.$errstr);
4065  $this->fault('SOAP-ENV:Server', 'unable to serialize result');
4066  return;
4067  }
4068  } else {
4069  if (isset($this->methodreturn)) {
4070  $return_val = $this->serialize_val($this->methodreturn, 'return');
4071  } else {
4072  $return_val = '';
4073  $this->debug('in absence of WSDL, assume void return for backward compatibility');
4074  }
4075  }
4076  }
4077  $this->debug('return value:');
4078  $this->appendDebug($this->varDump($return_val));
4079 
4080  $this->debug('serializing response');
4081  if ($this->wsdl) {
4082  $this->debug('have WSDL for serialization: style is ' . $this->opData['style']);
4083  if ($this->opData['style'] == 'rpc') {
4084  $this->debug('style is rpc for serialization: use is ' . $this->opData['output']['use']);
4085  if ($this->opData['output']['use'] == 'literal') {
4086  // http://www.ws-i.org/Profiles/BasicProfile-1.1-2004-08-24.html R2735 says rpc/literal accessor elements should not be in a namespace
4087  $payload = '<ns1:'.$this->methodname.'Response xmlns:ns1="'.$this->methodURI.'">'.$return_val.'</ns1:'.$this->methodname."Response>";
4088  } else {
4089  $payload = '<ns1:'.$this->methodname.'Response xmlns:ns1="'.$this->methodURI.'">'.$return_val.'</ns1:'.$this->methodname."Response>";
4090  }
4091  } else {
4092  $this->debug('style is not rpc for serialization: assume document');
4093  $payload = $return_val;
4094  }
4095  } else {
4096  $this->debug('do not have WSDL for serialization: assume rpc/encoded');
4097  $payload = '<ns1:'.$this->methodname.'Response xmlns:ns1="'.$this->methodURI.'">'.$return_val.'</ns1:'.$this->methodname."Response>";
4098  }
4099  $this->result = 'successful';
4100  if($this->wsdl){
4101  //if($this->debug_flag){
4102  $this->appendDebug($this->wsdl->getDebug());
4103  // }
4104  if (isset($opData['output']['encodingStyle'])) {
4105  $encodingStyle = $opData['output']['encodingStyle'];
4106  } else {
4107  $encodingStyle = '';
4108  }
4109  // Added: In case we use a WSDL, return a serialized env. WITH the usedNamespaces.
4110  $this->responseSOAP = $this->serializeEnvelope($payload,$this->responseHeaders,$this->wsdl->usedNamespaces,$this->opData['style'],$this->opData['output']['use'],$encodingStyle);
4111  } else {
4112  $this->responseSOAP = $this->serializeEnvelope($payload,$this->responseHeaders);
4113  }
4114  $this->debug("Leaving serialize_return");
4115  }
4116 
4127  function send_response() {
4128  $this->debug('Enter send_response');
4129  if ($this->fault) {
4130  $payload = $this->fault->serialize();
4131  $this->outgoing_headers[] = "HTTP/1.0 500 Internal Server Error";
4132  $this->outgoing_headers[] = "Status: 500 Internal Server Error";
4133  } else {
4134  $payload = $this->responseSOAP;
4135  // Some combinations of PHP+Web server allow the Status
4136  // to come through as a header. Since OK is the default
4137  // just do nothing.
4138  // $this->outgoing_headers[] = "HTTP/1.0 200 OK";
4139  // $this->outgoing_headers[] = "Status: 200 OK";
4140  }
4141  // add debug data if in debug mode
4142  if(isset($this->debug_flag) && $this->debug_flag){
4143  $payload .= $this->getDebugAsXMLComment();
4144  }
4145  $this->outgoing_headers[] = "Server: $this->title Server v$this->version";
4146  preg_match('/\$Revisio' . 'n: ([^ ]+)/', $this->revision, $rev);
4147  $this->outgoing_headers[] = "X-SOAP-Server: $this->title/$this->version (".$rev[1].")";
4148  // Let the Web server decide about this
4149  //$this->outgoing_headers[] = "Connection: Close\r\n";
4150  $payload = $this->getHTTPBody($payload);
4151  $type = $this->getHTTPContentType();
4152  $charset = $this->getHTTPContentTypeCharset();
4153  $this->outgoing_headers[] = "Content-Type: $type" . ($charset ? '; charset=' . $charset : '');
4154  //begin code to compress payload - by John
4155  // NOTE: there is no way to know whether the Web server will also compress
4156  // this data.
4157  if (strlen($payload) > 1024 && isset($this->headers) && isset($this->headers['accept-encoding'])) {
4158  if (strstr($this->headers['accept-encoding'], 'gzip')) {
4159  if (function_exists('gzencode')) {
4160  if (isset($this->debug_flag) && $this->debug_flag) {
4161  $payload .= "<!-- Content being gzipped -->";
4162  }
4163  $this->outgoing_headers[] = "Content-Encoding: gzip";
4164  $payload = gzencode($payload);
4165  } else {
4166  if (isset($this->debug_flag) && $this->debug_flag) {
4167  $payload .= "<!-- Content will not be gzipped: no gzencode -->";
4168  }
4169  }
4170  } elseif (strstr($this->headers['accept-encoding'], 'deflate')) {
4171  // Note: MSIE requires gzdeflate output (no Zlib header and checksum),
4172  // instead of gzcompress output,
4173  // which conflicts with HTTP 1.1 spec (http://www.w3.org/Protocols/rfc2616/rfc2616-sec3.html#sec3.5)
4174  if (function_exists('gzdeflate')) {
4175  if (isset($this->debug_flag) && $this->debug_flag) {
4176  $payload .= "<!-- Content being deflated -->";
4177  }
4178  $this->outgoing_headers[] = "Content-Encoding: deflate";
4179  $payload = gzdeflate($payload);
4180  } else {
4181  if (isset($this->debug_flag) && $this->debug_flag) {
4182  $payload .= "<!-- Content will not be deflated: no gzcompress -->";
4183  }
4184  }
4185  }
4186  }
4187  //end code
4188  $this->outgoing_headers[] = "Content-Length: ".strlen($payload);
4189  reset($this->outgoing_headers);
4190  foreach($this->outgoing_headers as $hdr){
4191  header($hdr, false);
4192  }
4193  print $payload;
4194  $this->response = join("\r\n",$this->outgoing_headers)."\r\n\r\n".$payload;
4195  }
4196 
4206  function verify_method($operation,$request){
4207  if(isset($this->wsdl) && is_object($this->wsdl)){
4208  if($this->wsdl->getOperationData($operation)){
4209  return true;
4210  }
4211  } elseif(isset($this->operations[$operation])){
4212  return true;
4213  }
4214  return false;
4215  }
4216 
4225  function parseRequest($headers, $data) {
4226  $this->debug('Entering parseRequest() for data of length ' . strlen($data) . ' and type ' . $headers['content-type']);
4227  if (!strstr($headers['content-type'], 'text/xml')) {
4228  $this->setError('Request not of type text/xml');
4229  return false;
4230  }
4231  if (strpos($headers['content-type'], '=')) {
4232  $enc = str_replace('"', '', substr(strstr($headers["content-type"], '='), 1));
4233  $this->debug('Got response encoding: ' . $enc);
4234  if(preg_match('/^(ISO-8859-1|US-ASCII|UTF-8)$/i',$enc)){
4235  $this->xml_encoding = strtoupper($enc);
4236  } else {
4237  $this->xml_encoding = 'US-ASCII';
4238  }
4239  } else {
4240  // should be US-ASCII for HTTP 1.0 or ISO-8859-1 for HTTP 1.1
4241  $this->xml_encoding = 'ISO-8859-1';
4242  }
4243  $this->debug('Use encoding: ' . $this->xml_encoding . ' when creating nusoap_parser');
4244  // parse response, get soap parser obj
4245  $parser = new nusoap_parser($data,$this->xml_encoding,'',$this->decode_utf8);
4246  // parser debug
4247  $this->debug("parser debug: \n".$parser->getDebug());
4248  // if fault occurred during message parsing
4249  if($err = $parser->getError()){
4250  $this->result = 'fault: error in msg parsing: '.$err;
4251  $this->fault('SOAP-ENV:Client',"error in msg parsing:\n".$err);
4252  // else successfully parsed request into soapval object
4253  } else {
4254  // get/set methodname
4255  $this->methodURI = $parser->root_struct_namespace;
4256  $this->methodname = $parser->root_struct_name;
4257  $this->debug('methodname: '.$this->methodname.' methodURI: '.$this->methodURI);
4258  $this->debug('calling parser->get_soapbody()');
4259  $this->methodparams = $parser->get_soapbody();
4260  // get SOAP headers
4261  $this->requestHeaders = $parser->getHeaders();
4262  // get SOAP Header
4263  $this->requestHeader = $parser->get_soapheader();
4264  // add document for doclit support
4265  $this->document = $parser->document;
4266  }
4267  }
4268 
4276  function getHTTPBody($soapmsg) {
4277  return $soapmsg;
4278  }
4279 
4288  function getHTTPContentType() {
4289  return 'text/xml';
4290  }
4291 
4302  return $this->soap_defencoding;
4303  }
4304 
4314  function add_to_map($methodname,$in,$out){
4315  $this->operations[$methodname] = array('name' => $methodname,'in' => $in,'out' => $out);
4316  }
4317 
4332  function register($name,$in=array(),$out=array(),$namespace=false,$soapaction=false,$style=false,$use=false,$documentation='',$encodingStyle=''){
4333  global $HTTP_SERVER_VARS;
4334 
4335  if($this->externalWSDLURL){
4336  die('You cannot bind to an external WSDL file, and register methods outside of it! Please choose either WSDL or no WSDL.');
4337  }
4338  if (! $name) {
4339  die('You must specify a name when you register an operation');
4340  }
4341  if (!is_array($in)) {
4342  die('You must provide an array for operation inputs');
4343  }
4344  if (!is_array($out)) {
4345  die('You must provide an array for operation outputs');
4346  }
4347  if(false == $namespace) {
4348  }
4349  if(false == $soapaction) {
4350  if (isset($_SERVER)) {
4351  $SERVER_NAME = $_SERVER['SERVER_NAME'];
4352  $SCRIPT_NAME = isset($_SERVER['PHP_SELF']) ? $_SERVER['PHP_SELF'] : $_SERVER['SCRIPT_NAME'];
4353  $HTTPS = isset($_SERVER['HTTPS']) ? $_SERVER['HTTPS'] : (isset($HTTP_SERVER_VARS['HTTPS']) ? $HTTP_SERVER_VARS['HTTPS'] : 'off');
4354  } elseif (isset($HTTP_SERVER_VARS)) {
4355  $SERVER_NAME = $HTTP_SERVER_VARS['SERVER_NAME'];
4356  $SCRIPT_NAME = isset($HTTP_SERVER_VARS['PHP_SELF']) ? $HTTP_SERVER_VARS['PHP_SELF'] : $HTTP_SERVER_VARS['SCRIPT_NAME'];
4357  $HTTPS = isset($HTTP_SERVER_VARS['HTTPS']) ? $HTTP_SERVER_VARS['HTTPS'] : 'off';
4358  } else {
4359  $this->setError("Neither _SERVER nor HTTP_SERVER_VARS is available");
4360  }
4361  if ($HTTPS == '1' || $HTTPS == 'on') {
4362  $SCHEME = 'https';
4363  } else {
4364  $SCHEME = 'http';
4365  }
4366  $soapaction = "$SCHEME://$SERVER_NAME$SCRIPT_NAME/$name";
4367  }
4368  if(false == $style) {
4369  $style = "rpc";
4370  }
4371  if(false == $use) {
4372  $use = "encoded";
4373  }
4374  if ($use == 'encoded' && $encodingStyle = '') {
4375  $encodingStyle = 'http://schemas.xmlsoap.org/soap/encoding/';
4376  }
4377 
4378  $this->operations[$name] = array(
4379  'name' => $name,
4380  'in' => $in,
4381  'out' => $out,
4382  'namespace' => $namespace,
4383  'soapaction' => $soapaction,
4384  'style' => $style);
4385  if($this->wsdl){
4386  $this->wsdl->addOperation($name,$in,$out,$namespace,$soapaction,$style,$use,$documentation,$encodingStyle);
4387  }
4388  return true;
4389  }
4390 
4401  function fault($faultcode,$faultstring,$faultactor='',$faultdetail=''){
4402  if ($faultdetail == '' && $this->debug_flag) {
4403  $faultdetail = $this->getDebug();
4404  }
4405  $this->fault = new nusoap_fault($faultcode,$faultactor,$faultstring,$faultdetail);
4406  $this->fault->soap_defencoding = $this->soap_defencoding;
4407  }
4408 
4420  function configureWSDL($serviceName,$namespace = false,$endpoint = false,$style='rpc', $transport = 'http://schemas.xmlsoap.org/soap/http', $schemaTargetNamespace = false)
4421  {
4422  global $HTTP_SERVER_VARS;
4423 
4424  if (isset($_SERVER)) {
4425  $SERVER_NAME = $_SERVER['SERVER_NAME'];
4426  $SERVER_PORT = $_SERVER['SERVER_PORT'];
4427  $SCRIPT_NAME = isset($_SERVER['PHP_SELF']) ? $_SERVER['PHP_SELF'] : $_SERVER['SCRIPT_NAME'];
4428  $HTTPS = isset($_SERVER['HTTPS']) ? $_SERVER['HTTPS'] : (isset($HTTP_SERVER_VARS['HTTPS']) ? $HTTP_SERVER_VARS['HTTPS'] : 'off');
4429  } elseif (isset($HTTP_SERVER_VARS)) {
4430  $SERVER_NAME = $HTTP_SERVER_VARS['SERVER_NAME'];
4431  $SERVER_PORT = $HTTP_SERVER_VARS['SERVER_PORT'];
4432  $SCRIPT_NAME = isset($HTTP_SERVER_VARS['PHP_SELF']) ? $HTTP_SERVER_VARS['PHP_SELF'] : $HTTP_SERVER_VARS['SCRIPT_NAME'];
4433  $HTTPS = isset($HTTP_SERVER_VARS['HTTPS']) ? $HTTP_SERVER_VARS['HTTPS'] : 'off';
4434  } else {
4435  $this->setError("Neither _SERVER nor HTTP_SERVER_VARS is available");
4436  }
4437  // If server name has port number attached then strip it (else port number gets duplicated in WSDL output) (occurred using lighttpd and FastCGI)
4438  $colon = strpos($SERVER_NAME,":");
4439  if ($colon) {
4440  $SERVER_NAME = substr($SERVER_NAME, 0, $colon);
4441  }
4442  if ($SERVER_PORT == 80) {
4443  $SERVER_PORT = '';
4444  } else {
4445  $SERVER_PORT = ':' . $SERVER_PORT;
4446  }
4447  if(false == $namespace) {
4448  $namespace = "http://$SERVER_NAME/soap/$serviceName";
4449  }
4450 
4451  if(false == $endpoint) {
4452  if ($HTTPS == '1' || $HTTPS == 'on') {
4453  $SCHEME = 'https';
4454  } else {
4455  $SCHEME = 'http';
4456  }
4457  $endpoint = "$SCHEME://$SERVER_NAME$SERVER_PORT$SCRIPT_NAME";
4458  }
4459 
4460  if(false == $schemaTargetNamespace) {
4461  $schemaTargetNamespace = $namespace;
4462  }
4463 
4464  $this->wsdl = new wsdl;
4465  $this->wsdl->serviceName = $serviceName;
4466  $this->wsdl->endpoint = $endpoint;
4467  $this->wsdl->namespaces['tns'] = $namespace;
4468  $this->wsdl->namespaces['soap'] = 'http://schemas.xmlsoap.org/wsdl/soap/';
4469  $this->wsdl->namespaces['wsdl'] = 'http://schemas.xmlsoap.org/wsdl/';
4470  if ($schemaTargetNamespace != $namespace) {
4471  $this->wsdl->namespaces['types'] = $schemaTargetNamespace;
4472  }
4473  $this->wsdl->schemas[$schemaTargetNamespace][0] = new nusoap_xmlschema('', '', $this->wsdl->namespaces);
4474  if ($style == 'document') {
4475  $this->wsdl->schemas[$schemaTargetNamespace][0]->schemaInfo['elementFormDefault'] = 'qualified';
4476  }
4477  $this->wsdl->schemas[$schemaTargetNamespace][0]->schemaTargetNamespace = $schemaTargetNamespace;
4478  $this->wsdl->schemas[$schemaTargetNamespace][0]->imports['http://schemas.xmlsoap.org/soap/encoding/'][0] = array('location' => '', 'loaded' => true);
4479  $this->wsdl->schemas[$schemaTargetNamespace][0]->imports['http://schemas.xmlsoap.org/wsdl/'][0] = array('location' => '', 'loaded' => true);
4480  $this->wsdl->bindings[$serviceName.'Binding'] = array(
4481  'name'=>$serviceName.'Binding',
4482  'style'=>$style,
4483  'transport'=>$transport,
4484  'portType'=>$serviceName.'PortType');
4485  $this->wsdl->ports[$serviceName.'Port'] = array(
4486  'binding'=>$serviceName.'Binding',
4487  'location'=>$endpoint,
4488  'bindingType'=>'http://schemas.xmlsoap.org/wsdl/soap/');
4489  }
4490 }
4491 
4495 class soap_server extends nusoap_server {
4496 }
4497 
4498 ?><?php
4499 
4500 
4501 
4511 class wsdl extends nusoap_base {
4512  // URL or filename of the root of this WSDL
4513  var $wsdl;
4514  // define internal arrays of bindings, ports, operations, messages, etc.
4515  var $schemas = array();
4516  var $currentSchema;
4517  var $message = array();
4518  var $complexTypes = array();
4519  var $messages = array();
4520  var $currentMessage;
4521  var $currentOperation;
4522  var $portTypes = array();
4523  var $currentPortType;
4524  var $bindings = array();
4525  var $currentBinding;
4526  var $ports = array();
4527  var $currentPort;
4528  var $opData = array();
4529  var $status = '';
4530  var $documentation = false;
4531  var $endpoint = '';
4532  // array of wsdl docs to import
4533  var $import = array();
4534  // parser vars
4535  var $parser;
4536  var $position = 0;
4537  var $depth = 0;
4538  var $depth_array = array();
4539  // for getting wsdl
4540  var $proxyhost = '';
4541  var $proxyport = '';
4542  var $proxyusername = '';
4543  var $proxypassword = '';
4544  var $timeout = 0;
4545  var $response_timeout = 30;
4546  var $curl_options = array(); // User-specified cURL options
4547  var $use_curl = false; // whether to always try to use cURL
4548  // for HTTP authentication
4549  var $username = ''; // Username for HTTP authentication
4550  var $password = ''; // Password for HTTP authentication
4551  var $authtype = ''; // Type of HTTP authentication
4552  var $certRequest = array(); // Certificate for HTTP SSL authentication
4553 
4568  function __construct($wsdl = '',$proxyhost=false,$proxyport=false,$proxyusername=false,$proxypassword=false,$timeout=0,$response_timeout=30,$curl_options=null,$use_curl=false){
4569  parent::__construct();
4570  $this->debug("ctor wsdl=$wsdl timeout=$timeout response_timeout=$response_timeout");
4571  $this->proxyhost = $proxyhost;
4572  $this->proxyport = $proxyport;
4573  $this->proxyusername = $proxyusername;
4574  $this->proxypassword = $proxypassword;
4575  $this->timeout = $timeout;
4576  $this->response_timeout = $response_timeout;
4577  if (is_array($curl_options))
4578  $this->curl_options = $curl_options;
4579  $this->use_curl = $use_curl;
4580  $this->fetchWSDL($wsdl);
4581  }
4582 
4588  function fetchWSDL($wsdl) {
4589  $this->debug("parse and process WSDL path=$wsdl");
4590  $this->wsdl = $wsdl;
4591  // parse wsdl file
4592  if ($this->wsdl != "") {
4593  $this->parseWSDL($this->wsdl);
4594  }
4595  // imports
4596  // TODO: handle imports more properly, grabbing them in-line and nesting them
4597  $imported_urls = array();
4598  $imported = 1;
4599  while ($imported > 0) {
4600  $imported = 0;
4601  // Schema imports
4602  foreach ($this->schemas as $ns => $list) {
4603  foreach ($list as $xs) {
4604  $wsdlparts = parse_url($this->wsdl); // this is bogusly simple!
4605  foreach ($xs->imports as $ns2 => $list2) {
4606  for ($ii = 0; $ii < count($list2); $ii++) {
4607  if (! $list2[$ii]['loaded']) {
4608  $this->schemas[$ns]->imports[$ns2][$ii]['loaded'] = true;
4609  $url = $list2[$ii]['location'];
4610  if ($url != '') {
4611  $urlparts = parse_url($url);
4612  if (!isset($urlparts['host'])) {
4613  $url = $wsdlparts['scheme'] . '://' . $wsdlparts['host'] . (isset($wsdlparts['port']) ? ':' .$wsdlparts['port'] : '') .
4614  substr($wsdlparts['path'],0,strrpos($wsdlparts['path'],'/') + 1) .$urlparts['path'];
4615  }
4616  if (! in_array($url, $imported_urls)) {
4617  $this->parseWSDL($url);
4618  $imported++;
4619  $imported_urls[] = $url;
4620  }
4621  } else {
4622  $this->debug("Unexpected scenario: empty URL for unloaded import");
4623  }
4624  }
4625  }
4626  }
4627  }
4628  }
4629  // WSDL imports
4630  $wsdlparts = parse_url($this->wsdl); // this is bogusly simple!
4631  foreach ($this->import as $ns => $list) {
4632  for ($ii = 0; $ii < count($list); $ii++) {
4633  if (! $list[$ii]['loaded']) {
4634  $this->import[$ns][$ii]['loaded'] = true;
4635  $url = $list[$ii]['location'];
4636  if ($url != '') {
4637  $urlparts = parse_url($url);
4638  if (!isset($urlparts['host'])) {
4639  $url = $wsdlparts['scheme'] . '://' . $wsdlparts['host'] . (isset($wsdlparts['port']) ? ':' . $wsdlparts['port'] : '') .
4640  substr($wsdlparts['path'],0,strrpos($wsdlparts['path'],'/') + 1) .$urlparts['path'];
4641  }
4642  if (! in_array($url, $imported_urls)) {
4643  $this->parseWSDL($url);
4644  $imported++;
4645  $imported_urls[] = $url;
4646  }
4647  } else {
4648  $this->debug("Unexpected scenario: empty URL for unloaded import");
4649  }
4650  }
4651  }
4652  }
4653  }
4654  // add new data to operation data
4655  foreach($this->bindings as $binding => $bindingData) {
4656  if (isset($bindingData['operations']) && is_array($bindingData['operations'])) {
4657  foreach($bindingData['operations'] as $operation => $data) {
4658  $this->debug('post-parse data gathering for ' . $operation);
4659  $this->bindings[$binding]['operations'][$operation]['input'] =
4660  isset($this->bindings[$binding]['operations'][$operation]['input']) ?
4661  array_merge($this->bindings[$binding]['operations'][$operation]['input'], $this->portTypes[ $bindingData['portType'] ][$operation]['input']) :
4662  $this->portTypes[ $bindingData['portType'] ][$operation]['input'];
4663  $this->bindings[$binding]['operations'][$operation]['output'] =
4664  isset($this->bindings[$binding]['operations'][$operation]['output']) ?
4665  array_merge($this->bindings[$binding]['operations'][$operation]['output'], $this->portTypes[ $bindingData['portType'] ][$operation]['output']) :
4666  $this->portTypes[ $bindingData['portType'] ][$operation]['output'];
4667  if(isset($this->messages[ $this->bindings[$binding]['operations'][$operation]['input']['message'] ])){
4668  $this->bindings[$binding]['operations'][$operation]['input']['parts'] = $this->messages[ $this->bindings[$binding]['operations'][$operation]['input']['message'] ];
4669  }
4670  if(isset($this->messages[ $this->bindings[$binding]['operations'][$operation]['output']['message'] ])){
4671  $this->bindings[$binding]['operations'][$operation]['output']['parts'] = $this->messages[ $this->bindings[$binding]['operations'][$operation]['output']['message'] ];
4672  }
4673  // Set operation style if necessary, but do not override one already provided
4674  if (isset($bindingData['style']) && !isset($this->bindings[$binding]['operations'][$operation]['style'])) {
4675  $this->bindings[$binding]['operations'][$operation]['style'] = $bindingData['style'];
4676  }
4677  $this->bindings[$binding]['operations'][$operation]['transport'] = isset($bindingData['transport']) ? $bindingData['transport'] : '';
4678  $this->bindings[$binding]['operations'][$operation]['documentation'] = isset($this->portTypes[ $bindingData['portType'] ][$operation]['documentation']) ? $this->portTypes[ $bindingData['portType'] ][$operation]['documentation'] : '';
4679  $this->bindings[$binding]['operations'][$operation]['endpoint'] = isset($bindingData['endpoint']) ? $bindingData['endpoint'] : '';
4680  }
4681  }
4682  }
4683  }
4684 
4691  function parseWSDL($wsdl = '') {
4692  $this->debug("parse WSDL at path=$wsdl");
4693 
4694  if ($wsdl == '') {
4695  $this->debug('no wsdl passed to parseWSDL()!!');
4696  $this->setError('no wsdl passed to parseWSDL()!!');
4697  return false;
4698  }
4699 
4700  // parse $wsdl for url format
4701  $wsdl_props = parse_url($wsdl);
4702 
4703  if (isset($wsdl_props['scheme']) && ($wsdl_props['scheme'] == 'http' || $wsdl_props['scheme'] == 'https')) {
4704  $this->debug('getting WSDL http(s) URL ' . $wsdl);
4705  // get wsdl
4706  $tr = new soap_transport_http($wsdl, $this->curl_options, $this->use_curl);
4707  $tr->request_method = 'GET';
4708  $tr->useSOAPAction = false;
4709  if($this->proxyhost && $this->proxyport){
4710  $tr->setProxy($this->proxyhost,$this->proxyport,$this->proxyusername,$this->proxypassword);
4711  }
4712  if ($this->authtype != '') {
4713  $tr->setCredentials($this->username, $this->password, $this->authtype, array(), $this->certRequest);
4714  }
4715  $tr->setEncoding('gzip, deflate');
4716  $wsdl_string = $tr->send('', $this->timeout, $this->response_timeout);
4717  //$this->debug("WSDL request\n" . $tr->outgoing_payload);
4718  //$this->debug("WSDL response\n" . $tr->incoming_payload);
4719  $this->appendDebug($tr->getDebug());
4720  // catch errors
4721  if($err = $tr->getError() ){
4722  $errstr = 'HTTP ERROR: '.$err;
4723  $this->debug($errstr);
4724  $this->setError($errstr);
4725  unset($tr);
4726  return false;
4727  }
4728  unset($tr);
4729  $this->debug("got WSDL URL");
4730  } else {
4731  // $wsdl is not http(s), so treat it as a file URL or plain file path
4732  if (isset($wsdl_props['scheme']) && ($wsdl_props['scheme'] == 'file') && isset($wsdl_props['path'])) {
4733  $path = isset($wsdl_props['host']) ? ($wsdl_props['host'] . ':' . $wsdl_props['path']) : $wsdl_props['path'];
4734  } else {
4735  $path = $wsdl;
4736  }
4737  $this->debug('getting WSDL file ' . $path);
4738  if ($fp = @fopen($path, 'r')) {
4739  $wsdl_string = '';
4740  while ($data = fread($fp, 32768)) {
4741  $wsdl_string .= $data;
4742  }
4743  fclose($fp);
4744  } else {
4745  $errstr = "Bad path to WSDL file $path";
4746  $this->debug($errstr);
4747  $this->setError($errstr);
4748  return false;
4749  }
4750  }
4751  $this->debug('Parse WSDL');
4752  // end new code added
4753  // Create an XML parser.
4754  $this->parser = xml_parser_create();
4755  // Set the options for parsing the XML data.
4756  // xml_parser_set_option($parser, XML_OPTION_SKIP_WHITE, 1);
4757  xml_parser_set_option($this->parser, XML_OPTION_CASE_FOLDING, 0);
4758  // Set the object for the parser.
4759  xml_set_object($this->parser, $this);
4760  // Set the element handlers for the parser.
4761  xml_set_element_handler($this->parser, 'start_element', 'end_element');
4762  xml_set_character_data_handler($this->parser, 'character_data');
4763  // Parse the XML file.
4764  if (!xml_parse($this->parser, $wsdl_string, true)) {
4765  // Display an error message.
4766  $errstr = sprintf(
4767  'XML error parsing WSDL from %s on line %d: %s',
4768  $wsdl,
4769  xml_get_current_line_number($this->parser),
4770  xml_error_string(xml_get_error_code($this->parser))
4771  );
4772  $this->debug($errstr);
4773  $this->debug("XML payload:\n" . $wsdl_string);
4774  $this->setError($errstr);
4775  return false;
4776  }
4777  // free the parser
4778  xml_parser_free($this->parser);
4779  $this->debug('Parsing WSDL done');
4780  // catch wsdl parse errors
4781  if($this->getError()){
4782  return false;
4783  }
4784  return true;
4785  }
4786 
4795  function start_element($parser, $name, $attrs)
4796  {
4797  if ($this->status == 'schema') {
4798  $this->currentSchema->schemaStartElement($parser, $name, $attrs);
4799  $this->appendDebug($this->currentSchema->getDebug());
4800  $this->currentSchema->clearDebug();
4801  } elseif (preg_match('/schema$/', $name)) {
4802  $this->debug('Parsing WSDL schema');
4803  // $this->debug("startElement for $name ($attrs[name]). status = $this->status (".$this->getLocalPart($name).")");
4804  $this->status = 'schema';
4805  $this->currentSchema = new nusoap_xmlschema('', '', $this->namespaces);
4806  $this->currentSchema->schemaStartElement($parser, $name, $attrs);
4807  $this->appendDebug($this->currentSchema->getDebug());
4808  $this->currentSchema->clearDebug();
4809  } else {
4810  // position in the total number of elements, starting from 0
4811  $pos = $this->position++;
4812  $depth = $this->depth++;
4813  // set self as current value for this depth
4814  $this->depth_array[$depth] = $pos;
4815  $this->message[$pos] = array('cdata' => '');
4816  // process attributes
4817  if (count($attrs) > 0) {
4818  // register namespace declarations
4819  foreach($attrs as $k => $v) {
4820  if (preg_match('/^xmlns/',$k)) {
4821  if ($ns_prefix = substr(strrchr($k, ':'), 1)) {
4822  $this->namespaces[$ns_prefix] = $v;
4823  } else {
4824  $this->namespaces['ns' . (count($this->namespaces) + 1)] = $v;
4825  }
4826  if ($v == 'http://www.w3.org/2001/XMLSchema' || $v == 'http://www.w3.org/1999/XMLSchema' || $v == 'http://www.w3.org/2000/10/XMLSchema') {
4827  $this->XMLSchemaVersion = $v;
4828  $this->namespaces['xsi'] = $v . '-instance';
4829  }
4830  }
4831  }
4832  // expand each attribute prefix to its namespace
4833  foreach($attrs as $k => $v) {
4834  $k = strpos($k, ':') ? $this->expandQname($k) : $k;
4835  if ($k != 'location' && $k != 'soapAction' && $k != 'namespace') {
4836  $v = strpos($v, ':') ? $this->expandQname($v) : $v;
4837  }
4838  $eAttrs[$k] = $v;
4839  }
4840  $attrs = $eAttrs;
4841  } else {
4842  $attrs = array();
4843  }
4844  // get element prefix, namespace and name
4845  if (preg_match('/:/', $name)) {
4846  // get ns prefix
4847  $prefix = substr($name, 0, strpos($name, ':'));
4848  // get ns
4849  $namespace = isset($this->namespaces[$prefix]) ? $this->namespaces[$prefix] : '';
4850  // get unqualified name
4851  $name = substr(strstr($name, ':'), 1);
4852  }
4853  // process attributes, expanding any prefixes to namespaces
4854  // find status, register data
4855  switch ($this->status) {
4856  case 'message':
4857  if ($name == 'part') {
4858  if (isset($attrs['type'])) {
4859  $this->debug("msg " . $this->currentMessage . ": found part (with type) $attrs[name]: " . implode(',', $attrs));
4860  $this->messages[$this->currentMessage][$attrs['name']] = $attrs['type'];
4861  }
4862  if (isset($attrs['element'])) {
4863  $this->debug("msg " . $this->currentMessage . ": found part (with element) $attrs[name]: " . implode(',', $attrs));
4864  $this->messages[$this->currentMessage][$attrs['name']] = $attrs['element'] . '^';
4865  }
4866  }
4867  break;
4868  case 'portType':
4869  switch ($name) {
4870  case 'operation':
4871  $this->currentPortOperation = $attrs['name'];
4872  $this->debug("portType $this->currentPortType operation: $this->currentPortOperation");
4873  if (isset($attrs['parameterOrder'])) {
4874  $this->portTypes[$this->currentPortType][$attrs['name']]['parameterOrder'] = $attrs['parameterOrder'];
4875  }
4876  break;
4877  case 'documentation':
4878  $this->documentation = true;
4879  break;
4880  // merge input/output data
4881  default:
4882  $m = isset($attrs['message']) ? $this->getLocalPart($attrs['message']) : '';
4883  $this->portTypes[$this->currentPortType][$this->currentPortOperation][$name]['message'] = $m;
4884  break;
4885  }
4886  break;
4887  case 'binding':
4888  switch ($name) {
4889  case 'binding':
4890  // get ns prefix
4891  if (isset($attrs['style'])) {
4892  $this->bindings[$this->currentBinding]['prefix'] = $prefix;
4893  }
4894  $this->bindings[$this->currentBinding] = array_merge($this->bindings[$this->currentBinding], $attrs);
4895  break;
4896  case 'header':
4897  $this->bindings[$this->currentBinding]['operations'][$this->currentOperation][$this->opStatus]['headers'][] = $attrs;
4898  break;
4899  case 'operation':
4900  if (isset($attrs['soapAction'])) {
4901  $this->bindings[$this->currentBinding]['operations'][$this->currentOperation]['soapAction'] = $attrs['soapAction'];
4902  }
4903  if (isset($attrs['style'])) {
4904  $this->bindings[$this->currentBinding]['operations'][$this->currentOperation]['style'] = $attrs['style'];
4905  }
4906  if (isset($attrs['name'])) {
4907  $this->currentOperation = $attrs['name'];
4908  $this->debug("current binding operation: $this->currentOperation");
4909  $this->bindings[$this->currentBinding]['operations'][$this->currentOperation]['name'] = $attrs['name'];
4910  $this->bindings[$this->currentBinding]['operations'][$this->currentOperation]['binding'] = $this->currentBinding;
4911  $this->bindings[$this->currentBinding]['operations'][$this->currentOperation]['endpoint'] = isset($this->bindings[$this->currentBinding]['endpoint']) ? $this->bindings[$this->currentBinding]['endpoint'] : '';
4912  }
4913  break;
4914  case 'input':
4915  $this->opStatus = 'input';
4916  break;
4917  case 'output':
4918  $this->opStatus = 'output';
4919  break;
4920  case 'body':
4921  if (isset($this->bindings[$this->currentBinding]['operations'][$this->currentOperation][$this->opStatus])) {
4922  $this->bindings[$this->currentBinding]['operations'][$this->currentOperation][$this->opStatus] = array_merge($this->bindings[$this->currentBinding]['operations'][$this->currentOperation][$this->opStatus], $attrs);
4923  } else {
4924  $this->bindings[$this->currentBinding]['operations'][$this->currentOperation][$this->opStatus] = $attrs;
4925  }
4926  break;
4927  }
4928  break;
4929  case 'service':
4930  switch ($name) {
4931  case 'port':
4932  $this->currentPort = $attrs['name'];
4933  $this->debug('current port: ' . $this->currentPort);
4934  $this->ports[$this->currentPort]['binding'] = $this->getLocalPart($attrs['binding']);
4935 
4936  break;
4937  case 'address':
4938  $this->ports[$this->currentPort]['location'] = $attrs['location'];
4939  $this->ports[$this->currentPort]['bindingType'] = $namespace;
4940  $this->bindings[ $this->ports[$this->currentPort]['binding'] ]['bindingType'] = $namespace;
4941  $this->bindings[ $this->ports[$this->currentPort]['binding'] ]['endpoint'] = $attrs['location'];
4942  break;
4943  }
4944  break;
4945  }
4946  // set status
4947  switch ($name) {
4948  case 'import':
4949  if (isset($attrs['location'])) {
4950  $this->import[$attrs['namespace']][] = array('location' => $attrs['location'], 'loaded' => false);
4951  $this->debug('parsing import ' . $attrs['namespace']. ' - ' . $attrs['location'] . ' (' . count($this->import[$attrs['namespace']]).')');
4952  } else {
4953  $this->import[$attrs['namespace']][] = array('location' => '', 'loaded' => true);
4954  if (! $this->getPrefixFromNamespace($attrs['namespace'])) {
4955  $this->namespaces['ns'.(count($this->namespaces)+1)] = $attrs['namespace'];
4956  }
4957  $this->debug('parsing import ' . $attrs['namespace']. ' - [no location] (' . count($this->import[$attrs['namespace']]).')');
4958  }
4959  break;
4960  //wait for schema
4961  //case 'types':
4962  // $this->status = 'schema';
4963  // break;
4964  case 'message':
4965  $this->status = 'message';
4966  $this->messages[$attrs['name']] = array();
4967  $this->currentMessage = $attrs['name'];
4968  break;
4969  case 'portType':
4970  $this->status = 'portType';
4971  $this->portTypes[$attrs['name']] = array();
4972  $this->currentPortType = $attrs['name'];
4973  break;
4974  case "binding":
4975  if (isset($attrs['name'])) {
4976  // get binding name
4977  if (strpos($attrs['name'], ':')) {
4978  $this->currentBinding = $this->getLocalPart($attrs['name']);
4979  } else {
4980  $this->currentBinding = $attrs['name'];
4981  }
4982  $this->status = 'binding';
4983  $this->bindings[$this->currentBinding]['portType'] = $this->getLocalPart($attrs['type']);
4984  $this->debug("current binding: $this->currentBinding of portType: " . $attrs['type']);
4985  }
4986  break;
4987  case 'service':
4988  $this->serviceName = $attrs['name'];
4989  $this->status = 'service';
4990  $this->debug('current service: ' . $this->serviceName);
4991  break;
4992  case 'definitions':
4993  foreach ($attrs as $name => $value) {
4994  $this->wsdl_info[$name] = $value;
4995  }
4996  break;
4997  }
4998  }
4999  }
5000 
5008  function end_element($parser, $name){
5009  // unset schema status
5010  if (/*preg_match('/types$/', $name) ||*/ preg_match('/schema$/', $name)) {
5011  $this->status = "";
5012  $this->appendDebug($this->currentSchema->getDebug());
5013  $this->currentSchema->clearDebug();
5014  $this->schemas[$this->currentSchema->schemaTargetNamespace][] = $this->currentSchema;
5015  $this->debug('Parsing WSDL schema done');
5016  }
5017  if ($this->status == 'schema') {
5018  $this->currentSchema->schemaEndElement($parser, $name);
5019  } else {
5020  // bring depth down a notch
5021  $this->depth--;
5022  }
5023  // end documentation
5024  if ($this->documentation) {
5025  //TODO: track the node to which documentation should be assigned; it can be a part, message, etc.
5026  //$this->portTypes[$this->currentPortType][$this->currentPortOperation]['documentation'] = $this->documentation;
5027  $this->documentation = false;
5028  }
5029  }
5030 
5038  function character_data($parser, $data)
5039  {
5040  $pos = isset($this->depth_array[$this->depth]) ? $this->depth_array[$this->depth] : 0;
5041  if (isset($this->message[$pos]['cdata'])) {
5042  $this->message[$pos]['cdata'] .= $data;
5043  }
5044  if ($this->documentation) {
5045  $this->documentation .= $data;
5046  }
5047  }
5048 
5058  function setCredentials($username, $password, $authtype = 'basic', $certRequest = array()) {
5059  $this->debug("setCredentials username=$username authtype=$authtype certRequest=");
5060  $this->appendDebug($this->varDump($certRequest));
5061  $this->username = $username;
5062  $this->password = $password;
5063  $this->authtype = $authtype;
5064  $this->certRequest = $certRequest;
5065  }
5066 
5068  {
5069  if (is_array($this->bindings[$binding])) {
5070  return $this->bindings[$binding];
5071  }
5072  }
5073 
5081  function getOperations($bindingType = 'soap') {
5082  $ops = array();
5083  if ($bindingType == 'soap') {
5084  $bindingType = 'http://schemas.xmlsoap.org/wsdl/soap/';
5085  } elseif ($bindingType == 'soap12') {
5086  $bindingType = 'http://schemas.xmlsoap.org/wsdl/soap12/';
5087  }
5088  // loop thru ports
5089  foreach($this->ports as $port => $portData) {
5090  // binding type of port matches parameter
5091  if ($portData['bindingType'] == $bindingType) {
5092  //$this->debug("getOperations for port $port");
5093  //$this->debug("port data: " . $this->varDump($portData));
5094  //$this->debug("bindings: " . $this->varDump($this->bindings[ $portData['binding'] ]));
5095  // merge bindings
5096  if (isset($this->bindings[ $portData['binding'] ]['operations'])) {
5097  $ops = array_merge ($ops, $this->bindings[ $portData['binding'] ]['operations']);
5098  }
5099  }
5100  }
5101  return $ops;
5102  }
5103 
5112  function getOperationData($operation, $bindingType = 'soap')
5113  {
5114  if ($bindingType == 'soap') {
5115  $bindingType = 'http://schemas.xmlsoap.org/wsdl/soap/';
5116  } elseif ($bindingType == 'soap12') {
5117  $bindingType = 'http://schemas.xmlsoap.org/wsdl/soap12/';
5118  }
5119  // loop thru ports
5120  foreach($this->ports as $port => $portData) {
5121  // binding type of port matches parameter
5122  if ($portData['bindingType'] == $bindingType) {
5123  // get binding
5124  //foreach($this->bindings[ $portData['binding'] ]['operations'] as $bOperation => $opData) {
5125  foreach(array_keys($this->bindings[ $portData['binding'] ]['operations']) as $bOperation) {
5126  // note that we could/should also check the namespace here
5127  if ($operation == $bOperation) {
5128  $opData = $this->bindings[ $portData['binding'] ]['operations'][$operation];
5129  return $opData;
5130  }
5131  }
5132  }
5133  }
5134  }
5135 
5144  function getOperationDataForSoapAction($soapAction, $bindingType = 'soap') {
5145  if ($bindingType == 'soap') {
5146  $bindingType = 'http://schemas.xmlsoap.org/wsdl/soap/';
5147  } elseif ($bindingType == 'soap12') {
5148  $bindingType = 'http://schemas.xmlsoap.org/wsdl/soap12/';
5149  }
5150  // loop thru ports
5151  foreach($this->ports as $port => $portData) {
5152  // binding type of port matches parameter
5153  if ($portData['bindingType'] == $bindingType) {
5154  // loop through operations for the binding
5155  foreach ($this->bindings[ $portData['binding'] ]['operations'] as $bOperation => $opData) {
5156  if ($opData['soapAction'] == $soapAction) {
5157  return $opData;
5158  }
5159  }
5160  }
5161  }
5162  }
5163 
5182  function getTypeDef($type, $ns) {
5183  $this->debug("in getTypeDef: type=$type, ns=$ns");
5184  if ((! $ns) && isset($this->namespaces['tns'])) {
5185  $ns = $this->namespaces['tns'];
5186  $this->debug("in getTypeDef: type namespace forced to $ns");
5187  }
5188  if (!isset($this->schemas[$ns])) {
5189  foreach ($this->schemas as $ns0 => $schema0) {
5190  if (strcasecmp($ns, $ns0) == 0) {
5191  $this->debug("in getTypeDef: replacing schema namespace $ns with $ns0");
5192  $ns = $ns0;
5193  break;
5194  }
5195  }
5196  }
5197  if (isset($this->schemas[$ns])) {
5198  $this->debug("in getTypeDef: have schema for namespace $ns");
5199  for ($i = 0; $i < count($this->schemas[$ns]); $i++) {
5200  $xs = &$this->schemas[$ns][$i];
5201  $t = $xs->getTypeDef($type);
5202  //$this->appendDebug($xs->getDebug());
5203  //$xs->clearDebug();
5204  if ($t) {
5205  if (!isset($t['phpType'])) {
5206  // get info for type to tack onto the element
5207  $uqType = substr($t['type'], strrpos($t['type'], ':') + 1);
5208  $ns = substr($t['type'], 0, strrpos($t['type'], ':'));
5209  $etype = $this->getTypeDef($uqType, $ns);
5210  if ($etype) {
5211  $this->debug("found type for [element] $type:");
5212  $this->debug($this->varDump($etype));
5213  if (isset($etype['phpType'])) {
5214  $t['phpType'] = $etype['phpType'];
5215  }
5216  if (isset($etype['elements'])) {
5217  $t['elements'] = $etype['elements'];
5218  }
5219  if (isset($etype['attrs'])) {
5220  $t['attrs'] = $etype['attrs'];
5221  }
5222  }
5223  }
5224  return $t;
5225  }
5226  }
5227  } else {
5228  $this->debug("in getTypeDef: do not have schema for namespace $ns");
5229  }
5230  return false;
5231  }
5232 
5238  function webDescription(){
5239  global $HTTP_SERVER_VARS;
5240 
5241  if (isset($_SERVER)) {
5242  $PHP_SELF = $_SERVER['PHP_SELF'];
5243  } elseif (isset($HTTP_SERVER_VARS)) {
5244  $PHP_SELF = $HTTP_SERVER_VARS['PHP_SELF'];
5245  } else {
5246  $this->setError("Neither _SERVER nor HTTP_SERVER_VARS is available");
5247  }
5248 
5249  $b = '
5250  <html><head><title>NuSOAP: '.$this->serviceName.'</title>
5251  <style type="text/css">
5252  body { font-family: arial; color: #000000; background-color: #ffffff; margin: 0px 0px 0px 0px; }
5253  p { font-family: arial; color: #000000; margin-top: 0px; margin-bottom: 12px; }
5254  pre { background-color: silver; padding: 5px; font-family: Courier New; font-size: x-small; color: #000000;}
5255  ul { margin-top: 10px; margin-left: 20px; }
5256  li { list-style-type: none; margin-top: 10px; color: #000000; }
5257  .content{
5258  margin-left: 0px; padding-bottom: 2em; }
5259  .nav {
5260  padding-top: 10px; padding-bottom: 10px; padding-left: 15px; font-size: .70em;
5261  margin-top: 10px; margin-left: 0px; color: #000000;
5262  background-color: #ccccff; width: 20%; margin-left: 20px; margin-top: 20px; }
5263  .title {
5264  font-family: arial; font-size: 26px; color: #ffffff;
5265  background-color: #999999; width: 105%; margin-left: 0px;
5266  padding-top: 10px; padding-bottom: 10px; padding-left: 15px;}
5267  .hidden {
5268  position: absolute; visibility: hidden; z-index: 200; left: 250px; top: 100px;
5269  font-family: arial; overflow: hidden; width: 600;
5270  padding: 20px; font-size: 10px; background-color: #999999;
5271  layer-background-color:#FFFFFF; }
5272  a,a:active { color: charcoal; font-weight: bold; }
5273  a:visited { color: #666666; font-weight: bold; }
5274  a:hover { color: cc3300; font-weight: bold; }
5275  </style>
5276  <script language="JavaScript" type="text/javascript">
5277  <!--
5278  // POP-UP CAPTIONS...
5279  function lib_bwcheck(){ //Browsercheck (needed)
5280  this.ver=navigator.appVersion
5281  this.agent=navigator.userAgent
5282  this.dom=document.getElementById?1:0
5283  this.opera5=this.agent.indexOf("Opera 5")>-1
5284  this.ie5=(this.ver.indexOf("MSIE 5")>-1 && this.dom && !this.opera5)?1:0;
5285  this.ie6=(this.ver.indexOf("MSIE 6")>-1 && this.dom && !this.opera5)?1:0;
5286  this.ie4=(document.all && !this.dom && !this.opera5)?1:0;
5287  this.ie=this.ie4||this.ie5||this.ie6
5288  this.mac=this.agent.indexOf("Mac")>-1
5289  this.ns6=(this.dom && parseInt(this.ver) >= 5) ?1:0;
5290  this.ns4=(document.layers && !this.dom)?1:0;
5291  this.bw=(this.ie6 || this.ie5 || this.ie4 || this.ns4 || this.ns6 || this.opera5)
5292  return this
5293  }
5294  var bw = new lib_bwcheck()
5295  //Makes crossbrowser object.
5296  function makeObj(obj){
5297  this.evnt=bw.dom? document.getElementById(obj):bw.ie4?document.all[obj]:bw.ns4?document.layers[obj]:0;
5298  if(!this.evnt) return false
5299  this.css=bw.dom||bw.ie4?this.evnt.style:bw.ns4?this.evnt:0;
5300  this.wref=bw.dom||bw.ie4?this.evnt:bw.ns4?this.css.document:0;
5301  this.writeIt=b_writeIt;
5302  return this
5303  }
5304  // A unit of measure that will be added when setting the position of a layer.
5305  //var px = bw.ns4||window.opera?"":"px";
5306  function b_writeIt(text){
5307  if (bw.ns4){this.wref.write(text);this.wref.close()}
5308  else this.wref.innerHTML = text
5309  }
5310  //Shows the messages
5311  var oDesc;
5312  function popup(divid){
5313  if(oDesc = new makeObj(divid)){
5314  oDesc.css.visibility = "visible"
5315  }
5316  }
5317  function popout(){ // Hides message
5318  if(oDesc) oDesc.css.visibility = "hidden"
5319  }
5320  //-->
5321  </script>
5322  </head>
5323  <body>
5324  <div class=content>
5325  <br><br>
5326  <div class=title>'.$this->serviceName.'</div>
5327  <div class=nav>
5328  <p>View the <a href="'.$PHP_SELF.'?wsdl">WSDL</a> for the service.
5329  Click on an operation name to view it&apos;s details.</p>
5330  <ul>';
5331  foreach($this->getOperations() as $op => $data){
5332  $b .= "<li><a href='#' onclick=\"popout();popup('$op')\">$op</a></li>";
5333  // create hidden div
5334  $b .= "<div id='$op' class='hidden'>
5335  <a href='#' onclick='popout()'><font color='#ffffff'>Close</font></a><br><br>";
5336  foreach($data as $donnie => $marie){ // loop through opdata
5337  if($donnie == 'input' || $donnie == 'output'){ // show input/output data
5338  $b .= "<font color='white'>".ucfirst($donnie).':</font><br>';
5339  foreach($marie as $captain => $tenille){ // loop through data
5340  if($captain == 'parts'){ // loop thru parts
5341  $b .= "&nbsp;&nbsp;$captain:<br>";
5342  //if(is_array($tenille)){
5343  foreach($tenille as $joanie => $chachi){
5344  $b .= "&nbsp;&nbsp;&nbsp;&nbsp;$joanie: $chachi<br>";
5345  }
5346  //}
5347  } else {
5348  $b .= "&nbsp;&nbsp;$captain: $tenille<br>";
5349  }
5350  }
5351  } else {
5352  $b .= "<font color='white'>".ucfirst($donnie).":</font> $marie<br>";
5353  }
5354  }
5355  $b .= '</div>';
5356  }
5357  $b .= '
5358  <ul>
5359  </div>
5360  </div></body></html>';
5361  return $b;
5362  }
5363 
5371  function serialize($debug = 0)
5372  {
5373  $xml = '<?xml version="1.0" encoding="ISO-8859-1"?>';
5374  $xml .= "\n<definitions";
5375  foreach($this->namespaces as $k => $v) {
5376  $xml .= " xmlns:$k=\"$v\"";
5377  }
5378  // 10.9.02 - add poulter fix for wsdl and tns declarations
5379  if (isset($this->namespaces['wsdl'])) {
5380  $xml .= " xmlns=\"" . $this->namespaces['wsdl'] . "\"";
5381  }
5382  if (isset($this->namespaces['tns'])) {
5383  $xml .= " targetNamespace=\"" . $this->namespaces['tns'] . "\"";
5384  }
5385  $xml .= '>';
5386  // imports
5387  if (sizeof($this->import) > 0) {
5388  foreach($this->import as $ns => $list) {
5389  foreach ($list as $ii) {
5390  if ($ii['location'] != '') {
5391  $xml .= '<import location="' . $ii['location'] . '" namespace="' . $ns . '" />';
5392  } else {
5393  $xml .= '<import namespace="' . $ns . '" />';
5394  }
5395  }
5396  }
5397  }
5398  // types
5399  if (count($this->schemas)>=1) {
5400  $xml .= "\n<types>\n";
5401  foreach ($this->schemas as $ns => $list) {
5402  foreach ($list as $xs) {
5403  $xml .= $xs->serializeSchema();
5404  }
5405  }
5406  $xml .= '</types>';
5407  }
5408  // messages
5409  if (count($this->messages) >= 1) {
5410  foreach($this->messages as $msgName => $msgParts) {
5411  $xml .= "\n<message name=\"" . $msgName . '">';
5412  if(is_array($msgParts)){
5413  foreach($msgParts as $partName => $partType) {
5414  // print 'serializing '.$partType.', sv: '.$this->XMLSchemaVersion.'<br>';
5415  if (strpos($partType, ':')) {
5416  $typePrefix = $this->getPrefixFromNamespace($this->getPrefix($partType));
5417  } elseif (isset($this->typemap[$this->namespaces['xsd']][$partType])) {
5418  // print 'checking typemap: '.$this->XMLSchemaVersion.'<br>';
5419  $typePrefix = 'xsd';
5420  } else {
5421  foreach($this->typemap as $ns => $types) {
5422  if (isset($types[$partType])) {
5423  $typePrefix = $this->getPrefixFromNamespace($ns);
5424  }
5425  }
5426  if (!isset($typePrefix)) {
5427  die("$partType has no namespace!");
5428  }
5429  }
5430  $ns = $this->getNamespaceFromPrefix($typePrefix);
5431  $localPart = $this->getLocalPart($partType);
5432  $typeDef = $this->getTypeDef($localPart, $ns);
5433  if ($typeDef['typeClass'] == 'element') {
5434  $elementortype = 'element';
5435  if (substr($localPart, -1) == '^') {
5436  $localPart = substr($localPart, 0, -1);
5437  }
5438  } else {
5439  $elementortype = 'type';
5440  }
5441  $xml .= "\n" . ' <part name="' . $partName . '" ' . $elementortype . '="' . $typePrefix . ':' . $localPart . '" />';
5442  }
5443  }
5444  $xml .= '</message>';
5445  }
5446  }
5447  // bindings & porttypes
5448  if (count($this->bindings) >= 1) {
5449  $binding_xml = '';
5450  $portType_xml = '';
5451  foreach($this->bindings as $bindingName => $attrs) {
5452  $binding_xml .= "\n<binding name=\"" . $bindingName . '" type="tns:' . $attrs['portType'] . '">';
5453  $binding_xml .= "\n" . ' <soap:binding style="' . $attrs['style'] . '" transport="' . $attrs['transport'] . '"/>';
5454  $portType_xml .= "\n<portType name=\"" . $attrs['portType'] . '">';
5455  foreach($attrs['operations'] as $opName => $opParts) {
5456  $binding_xml .= "\n" . ' <operation name="' . $opName . '">';
5457  $binding_xml .= "\n" . ' <soap:operation soapAction="' . $opParts['soapAction'] . '" style="'. $opParts['style'] . '"/>';
5458  if (isset($opParts['input']['encodingStyle']) && $opParts['input']['encodingStyle'] != '') {
5459  $enc_style = ' encodingStyle="' . $opParts['input']['encodingStyle'] . '"';
5460  } else {
5461  $enc_style = '';
5462  }
5463  $binding_xml .= "\n" . ' <input><soap:body use="' . $opParts['input']['use'] . '" namespace="' . $opParts['input']['namespace'] . '"' . $enc_style . '/></input>';
5464  if (isset($opParts['output']['encodingStyle']) && $opParts['output']['encodingStyle'] != '') {
5465  $enc_style = ' encodingStyle="' . $opParts['output']['encodingStyle'] . '"';
5466  } else {
5467  $enc_style = '';
5468  }
5469  $binding_xml .= "\n" . ' <output><soap:body use="' . $opParts['output']['use'] . '" namespace="' . $opParts['output']['namespace'] . '"' . $enc_style . '/></output>';
5470  $binding_xml .= "\n" . ' </operation>';
5471  $portType_xml .= "\n" . ' <operation name="' . $opParts['name'] . '"';
5472  if (isset($opParts['parameterOrder'])) {
5473  $portType_xml .= ' parameterOrder="' . $opParts['parameterOrder'] . '"';
5474  }
5475  $portType_xml .= '>';
5476  if(isset($opParts['documentation']) && $opParts['documentation'] != '') {
5477  $portType_xml .= "\n" . ' <documentation>' . htmlspecialchars($opParts['documentation']) . '</documentation>';
5478  }
5479  $portType_xml .= "\n" . ' <input message="tns:' . $opParts['input']['message'] . '"/>';
5480  $portType_xml .= "\n" . ' <output message="tns:' . $opParts['output']['message'] . '"/>';
5481  $portType_xml .= "\n" . ' </operation>';
5482  }
5483  $portType_xml .= "\n" . '</portType>';
5484  $binding_xml .= "\n" . '</binding>';
5485  }
5486  $xml .= $portType_xml . $binding_xml;
5487  }
5488  // services
5489  $xml .= "\n<service name=\"" . $this->serviceName . '">';
5490  $has_client = isset($_GET['client_id']);
5491  if (count($this->ports) >= 1) {
5492  foreach($this->ports as $pName => $attrs) {
5493  $xml .= "\n" . ' <port name="' . $pName . '" binding="tns:' . $attrs['binding'] . '">';
5494  $address = $attrs['location'] . ($debug || $has_client ? "?" : "")
5495  . ($debug ? 'debug=1' : '') . ($debug && $has_client ? "&amp;" : "")
5496  . ($has_client ? 'client_id=' . $_GET['client_id'] : '');
5497  $xml .= "\n" . ' <soap:address location="' . $address. '"/>';
5498  $xml .= "\n" . ' </port>';
5499  }
5500  }
5501 
5502  $xml .= "\n" . '</service>';
5503  return $xml . "\n</definitions>";
5504  }
5505 
5515  function parametersMatchWrapped($type, &$parameters) {
5516  $this->debug("in parametersMatchWrapped type=$type, parameters=");
5517  $this->appendDebug($this->varDump($parameters));
5518 
5519  // split type into namespace:unqualified-type
5520  if (strpos($type, ':')) {
5521  $uqType = substr($type, strrpos($type, ':') + 1);
5522  $ns = substr($type, 0, strrpos($type, ':'));
5523  $this->debug("in parametersMatchWrapped: got a prefixed type: $uqType, $ns");
5524  if ($this->getNamespaceFromPrefix($ns)) {
5525  $ns = $this->getNamespaceFromPrefix($ns);
5526  $this->debug("in parametersMatchWrapped: expanded prefixed type: $uqType, $ns");
5527  }
5528  } else {
5529  // TODO: should the type be compared to types in XSD, and the namespace
5530  // set to XSD if the type matches?
5531  $this->debug("in parametersMatchWrapped: No namespace for type $type");
5532  $ns = '';
5533  $uqType = $type;
5534  }
5535 
5536  // get the type information
5537  if (!$typeDef = $this->getTypeDef($uqType, $ns)) {
5538  $this->debug("in parametersMatchWrapped: $type ($uqType) is not a supported type.");
5539  return false;
5540  }
5541  $this->debug("in parametersMatchWrapped: found typeDef=");
5542  $this->appendDebug($this->varDump($typeDef));
5543  if (substr($uqType, -1) == '^') {
5544  $uqType = substr($uqType, 0, -1);
5545  }
5546  $phpType = $typeDef['phpType'];
5547  $arrayType = (isset($typeDef['arrayType']) ? $typeDef['arrayType'] : '');
5548  $this->debug("in parametersMatchWrapped: uqType: $uqType, ns: $ns, phptype: $phpType, arrayType: $arrayType");
5549 
5550  // we expect a complexType or element of complexType
5551  if ($phpType != 'struct') {
5552  $this->debug("in parametersMatchWrapped: not a struct");
5553  return false;
5554  }
5555 
5556  // see whether the parameter names match the elements
5557  if (isset($typeDef['elements']) && is_array($typeDef['elements'])) {
5558  $elements = 0;
5559  $matches = 0;
5560  $change = false;
5561  if ($this->isArraySimpleOrStruct($parameters) == 'arraySimple' && count($parameters) == count($typeDef['elements'])) {
5562  $this->debug("in parametersMatchWrapped: (wrapped return value kludge) correct number of elements in simple array, so change array and wrap");
5563  $change = true;
5564  }
5565  foreach ($typeDef['elements'] as $name => $attrs) {
5566  if ($change) {
5567  $this->debug("in parametersMatchWrapped: change parameter $element to name $name");
5568  $parameters[$name] = $parameters[$elements];
5569  unset($parameters[$elements]);
5570  $matches++;
5571  } elseif (isset($parameters[$name])) {
5572  $this->debug("in parametersMatchWrapped: have parameter named $name");
5573  $matches++;
5574  } else {
5575  $this->debug("in parametersMatchWrapped: do not have parameter named $name");
5576  }
5577  $elements++;
5578  }
5579 
5580  $this->debug("in parametersMatchWrapped: $matches parameter names match $elements wrapped parameter names");
5581  if ($matches == 0) {
5582  return false;
5583  }
5584  return true;
5585  }
5586 
5587  // since there are no elements for the type, if the user passed no
5588  // parameters, the parameters match wrapped.
5589  $this->debug("in parametersMatchWrapped: no elements type $ns:$uqType");
5590  return count($parameters) == 0;
5591  }
5592 
5608  function serializeRPCParameters($operation, $direction, $parameters, $bindingType = 'soap') {
5609  $this->debug("in serializeRPCParameters: operation=$operation, direction=$direction, XMLSchemaVersion=$this->XMLSchemaVersion, bindingType=$bindingType");
5610  $this->appendDebug('parameters=' . $this->varDump($parameters));
5611 
5612  if ($direction != 'input' && $direction != 'output') {
5613  $this->debug('The value of the \$direction argument needs to be either "input" or "output"');
5614  $this->setError('The value of the \$direction argument needs to be either "input" or "output"');
5615  return false;
5616  }
5617  if (!$opData = $this->getOperationData($operation, $bindingType)) {
5618  $this->debug('Unable to retrieve WSDL data for operation: ' . $operation . ' bindingType: ' . $bindingType);
5619  $this->setError('Unable to retrieve WSDL data for operation: ' . $operation . ' bindingType: ' . $bindingType);
5620  return false;
5621  }
5622  $this->debug('in serializeRPCParameters: opData:');
5623  $this->appendDebug($this->varDump($opData));
5624 
5625  // Get encoding style for output and set to current
5626  $encodingStyle = 'http://schemas.xmlsoap.org/soap/encoding/';
5627  if(($direction == 'input') && isset($opData['output']['encodingStyle']) && ($opData['output']['encodingStyle'] != $encodingStyle)) {
5628  $encodingStyle = $opData['output']['encodingStyle'];
5629  $enc_style = $encodingStyle;
5630  }
5631 
5632  // set input params
5633  $xml = '';
5634  if (isset($opData[$direction]['parts']) && sizeof($opData[$direction]['parts']) > 0) {
5635  $parts = &$opData[$direction]['parts'];
5636  $part_count = sizeof($parts);
5637  $style = $opData['style'];
5638  $use = $opData[$direction]['use'];
5639  $this->debug("have $part_count part(s) to serialize using $style/$use");
5640  if (is_array($parameters)) {
5641  $parametersArrayType = $this->isArraySimpleOrStruct($parameters);
5642  $parameter_count = count($parameters);
5643  $this->debug("have $parameter_count parameter(s) provided as $parametersArrayType to serialize");
5644  // check for Microsoft-style wrapped parameters
5645  if ($style == 'document' && $use == 'literal' && $part_count == 1 && isset($parts['parameters'])) {
5646  $this->debug('check whether the caller has wrapped the parameters');
5647  if ((($parametersArrayType == 'arrayStruct' || $parameter_count == 0) && !isset($parameters['parameters'])) || ($direction == 'output' && $parametersArrayType == 'arraySimple' && $parameter_count == 1)) {
5648  $this->debug('check whether caller\'s parameters match the wrapped ones');
5649  if ($this->parametersMatchWrapped($parts['parameters'], $parameters)) {
5650  $this->debug('wrap the parameters for the caller');
5651  $parameters = array('parameters' => $parameters);
5652  $parameter_count = 1;
5653  }
5654  }
5655  }
5656  foreach ($parts as $name => $type) {
5657  $this->debug("serializing part $name of type $type");
5658  // Track encoding style
5659  if (isset($opData[$direction]['encodingStyle']) && $encodingStyle != $opData[$direction]['encodingStyle']) {
5660  $encodingStyle = $opData[$direction]['encodingStyle'];
5661  $enc_style = $encodingStyle;
5662  } else {
5663  $enc_style = false;
5664  }
5665  // NOTE: add error handling here
5666  // if serializeType returns false, then catch global error and fault
5667  if ($parametersArrayType == 'arraySimple') {
5668  $p = array_shift($parameters);
5669  $this->debug('calling serializeType w/indexed param');
5670  $xml .= $this->serializeType($name, $type, $p, $use, $enc_style);
5671  } elseif (isset($parameters[$name])) {
5672  $this->debug('calling serializeType w/named param');
5673  $xml .= $this->serializeType($name, $type, $parameters[$name], $use, $enc_style);
5674  } else {
5675  // TODO: only send nillable
5676  $this->debug('calling serializeType w/null param');
5677  $xml .= $this->serializeType($name, $type, null, $use, $enc_style);
5678  }
5679  }
5680  } else {
5681  $this->debug('no parameters passed.');
5682  }
5683  }
5684  $this->debug("serializeRPCParameters returning: $xml");
5685  return $xml;
5686  }
5687 
5702  function serializeParameters($operation, $direction, $parameters)
5703  {
5704  $this->debug("in serializeParameters: operation=$operation, direction=$direction, XMLSchemaVersion=$this->XMLSchemaVersion");
5705  $this->appendDebug('parameters=' . $this->varDump($parameters));
5706 
5707  if ($direction != 'input' && $direction != 'output') {
5708  $this->debug('The value of the \$direction argument needs to be either "input" or "output"');
5709  $this->setError('The value of the \$direction argument needs to be either "input" or "output"');
5710  return false;
5711  }
5712  if (!$opData = $this->getOperationData($operation)) {
5713  $this->debug('Unable to retrieve WSDL data for operation: ' . $operation);
5714  $this->setError('Unable to retrieve WSDL data for operation: ' . $operation);
5715  return false;
5716  }
5717  $this->debug('opData:');
5718  $this->appendDebug($this->varDump($opData));
5719 
5720  // Get encoding style for output and set to current
5721  $encodingStyle = 'http://schemas.xmlsoap.org/soap/encoding/';
5722  if(($direction == 'input') && isset($opData['output']['encodingStyle']) && ($opData['output']['encodingStyle'] != $encodingStyle)) {
5723  $encodingStyle = $opData['output']['encodingStyle'];
5724  $enc_style = $encodingStyle;
5725  }
5726 
5727  // set input params
5728  $xml = '';
5729  if (isset($opData[$direction]['parts']) && sizeof($opData[$direction]['parts']) > 0) {
5730 
5731  $use = $opData[$direction]['use'];
5732  $this->debug("use=$use");
5733  $this->debug('got ' . count($opData[$direction]['parts']) . ' part(s)');
5734  if (is_array($parameters)) {
5735  $parametersArrayType = $this->isArraySimpleOrStruct($parameters);
5736  $this->debug('have ' . $parametersArrayType . ' parameters');
5737  foreach($opData[$direction]['parts'] as $name => $type) {
5738  $this->debug('serializing part "'.$name.'" of type "'.$type.'"');
5739  // Track encoding style
5740  if(isset($opData[$direction]['encodingStyle']) && $encodingStyle != $opData[$direction]['encodingStyle']) {
5741  $encodingStyle = $opData[$direction]['encodingStyle'];
5742  $enc_style = $encodingStyle;
5743  } else {
5744  $enc_style = false;
5745  }
5746  // NOTE: add error handling here
5747  // if serializeType returns false, then catch global error and fault
5748  if ($parametersArrayType == 'arraySimple') {
5749  $p = array_shift($parameters);
5750  $this->debug('calling serializeType w/indexed param');
5751  $xml .= $this->serializeType($name, $type, $p, $use, $enc_style);
5752  } elseif (isset($parameters[$name])) {
5753  $this->debug('calling serializeType w/named param');
5754  $xml .= $this->serializeType($name, $type, $parameters[$name], $use, $enc_style);
5755  } else {
5756  // TODO: only send nillable
5757  $this->debug('calling serializeType w/null param');
5758  $xml .= $this->serializeType($name, $type, null, $use, $enc_style);
5759  }
5760  }
5761  } else {
5762  $this->debug('no parameters passed.');
5763  }
5764  }
5765  $this->debug("serializeParameters returning: $xml");
5766  return $xml;
5767  }
5768 
5781  function serializeType($name, $type, $value, $use='encoded', $encodingStyle=false, $unqualified=false)
5782  {
5783  $this->debug("in serializeType: name=$name, type=$type, use=$use, encodingStyle=$encodingStyle, unqualified=" . ($unqualified ? "unqualified" : "qualified"));
5784  $this->appendDebug("value=" . $this->varDump($value));
5785  if($use == 'encoded' && $encodingStyle) {
5786  $encodingStyle = ' SOAP-ENV:encodingStyle="' . $encodingStyle . '"';
5787  }
5788 
5789  // if a soapval has been supplied, let its type override the WSDL
5790  if (is_object($value) && get_class($value) == 'soapval') {
5791  if ($value->type_ns) {
5792  $type = $value->type_ns . ':' . $value->type;
5793  $forceType = true;
5794  $this->debug("in serializeType: soapval overrides type to $type");
5795  } elseif ($value->type) {
5796  $type = $value->type;
5797  $forceType = true;
5798  $this->debug("in serializeType: soapval overrides type to $type");
5799  } else {
5800  $forceType = false;
5801  $this->debug("in serializeType: soapval does not override type");
5802  }
5803  $attrs = $value->attributes;
5804  $value = $value->value;
5805  $this->debug("in serializeType: soapval overrides value to $value");
5806  if ($attrs) {
5807  if (!is_array($value)) {
5808  $value['!'] = $value;
5809  }
5810  foreach ($attrs as $n => $v) {
5811  $value['!' . $n] = $v;
5812  }
5813  $this->debug("in serializeType: soapval provides attributes");
5814  }
5815  } else {
5816  $forceType = false;
5817  }
5818 
5819  $xml = '';
5820  if (strpos($type, ':')) {
5821  $uqType = substr($type, strrpos($type, ':') + 1);
5822  $ns = substr($type, 0, strrpos($type, ':'));
5823  $this->debug("in serializeType: got a prefixed type: $uqType, $ns");
5824  if ($this->getNamespaceFromPrefix($ns)) {
5825  $ns = $this->getNamespaceFromPrefix($ns);
5826  $this->debug("in serializeType: expanded prefixed type: $uqType, $ns");
5827  }
5828 
5829  if($ns == $this->XMLSchemaVersion || $ns == 'http://schemas.xmlsoap.org/soap/encoding/'){
5830  $this->debug('in serializeType: type namespace indicates XML Schema or SOAP Encoding type');
5831  if ($unqualified && $use == 'literal') {
5832  $elementNS = " xmlns=\"\"";
5833  } else {
5834  $elementNS = '';
5835  }
5836  if (is_null($value)) {
5837  if ($use == 'literal') {
5838  // TODO: depends on minOccurs
5839  $xml = "<$name$elementNS/>";
5840  } else {
5841  // TODO: depends on nillable, which should be checked before calling this method
5842  $xml = "<$name$elementNS xsi:nil=\"true\" xsi:type=\"" . $this->getPrefixFromNamespace($ns) . ":$uqType\"/>";
5843  }
5844  $this->debug("in serializeType: returning: $xml");
5845  return $xml;
5846  }
5847  if ($uqType == 'Array') {
5848  // JBoss/Axis does this sometimes
5849  return $this->serialize_val($value, $name, false, false, false, false, $use);
5850  }
5851  if ($uqType == 'boolean') {
5852  if ((is_string($value) && $value == 'false') || (! $value)) {
5853  $value = 'false';
5854  } else {
5855  $value = 'true';
5856  }
5857  }
5858  if ($uqType == 'string' && gettype($value) == 'string') {
5859  $value = $this->expandEntities($value);
5860  }
5861  if (($uqType == 'long' || $uqType == 'unsignedLong') && gettype($value) == 'double') {
5862  $value = sprintf("%.0lf", $value);
5863  }
5864  // it's a scalar
5865  // TODO: what about null/nil values?
5866  // check type isn't a custom type extending xmlschema namespace
5867  if (!$this->getTypeDef($uqType, $ns)) {
5868  if ($use == 'literal') {
5869  if ($forceType) {
5870  $xml = "<$name$elementNS xsi:type=\"" . $this->getPrefixFromNamespace($ns) . ":$uqType\">$value</$name>";
5871  } else {
5872  $xml = "<$name$elementNS>$value</$name>";
5873  }
5874  } else {
5875  $xml = "<$name$elementNS xsi:type=\"" . $this->getPrefixFromNamespace($ns) . ":$uqType\"$encodingStyle>$value</$name>";
5876  }
5877  $this->debug("in serializeType: returning: $xml");
5878  return $xml;
5879  }
5880  $this->debug('custom type extends XML Schema or SOAP Encoding namespace (yuck)');
5881  } else if ($ns == 'http://xml.apache.org/xml-soap') {
5882  $this->debug('in serializeType: appears to be Apache SOAP type');
5883  if ($uqType == 'Map') {
5884  $tt_prefix = $this->getPrefixFromNamespace('http://xml.apache.org/xml-soap');
5885  if (! $tt_prefix) {
5886  $this->debug('in serializeType: Add namespace for Apache SOAP type');
5887  $tt_prefix = 'ns' . rand(1000, 9999);
5888  $this->namespaces[$tt_prefix] = 'http://xml.apache.org/xml-soap';
5889  // force this to be added to usedNamespaces
5890  $tt_prefix = $this->getPrefixFromNamespace('http://xml.apache.org/xml-soap');
5891  }
5892  $contents = '';
5893  foreach($value as $k => $v) {
5894  $this->debug("serializing map element: key $k, value $v");
5895  $contents .= '<item>';
5896  $contents .= $this->serialize_val($k,'key',false,false,false,false,$use);
5897  $contents .= $this->serialize_val($v,'value',false,false,false,false,$use);
5898  $contents .= '</item>';
5899  }
5900  if ($use == 'literal') {
5901  if ($forceType) {
5902  $xml = "<$name xsi:type=\"" . $tt_prefix . ":$uqType\">$contents</$name>";
5903  } else {
5904  $xml = "<$name>$contents</$name>";
5905  }
5906  } else {
5907  $xml = "<$name xsi:type=\"" . $tt_prefix . ":$uqType\"$encodingStyle>$contents</$name>";
5908  }
5909  $this->debug("in serializeType: returning: $xml");
5910  return $xml;
5911  }
5912  $this->debug('in serializeType: Apache SOAP type, but only support Map');
5913  }
5914  } else {
5915  // TODO: should the type be compared to types in XSD, and the namespace
5916  // set to XSD if the type matches?
5917  $this->debug("in serializeType: No namespace for type $type");
5918  $ns = '';
5919  $uqType = $type;
5920  }
5921  if(!$typeDef = $this->getTypeDef($uqType, $ns)){
5922  $this->setError("$type ($uqType) is not a supported type.");
5923  $this->debug("in serializeType: $type ($uqType) is not a supported type.");
5924  return false;
5925  } else {
5926  $this->debug("in serializeType: found typeDef");
5927  $this->appendDebug('typeDef=' . $this->varDump($typeDef));
5928  if (substr($uqType, -1) == '^') {
5929  $uqType = substr($uqType, 0, -1);
5930  }
5931  }
5932  $phpType = $typeDef['phpType'];
5933  $this->debug("in serializeType: uqType: $uqType, ns: $ns, phptype: $phpType, arrayType: " . (isset($typeDef['arrayType']) ? $typeDef['arrayType'] : '') );
5934  // if php type == struct, map value to the <all> element names
5935  if ($phpType == 'struct') {
5936  if (isset($typeDef['typeClass']) && $typeDef['typeClass'] == 'element') {
5937  $elementName = $uqType;
5938  if (isset($typeDef['form']) && ($typeDef['form'] == 'qualified')) {
5939  $elementNS = " xmlns=\"$ns\"";
5940  } else {
5941  $elementNS = " xmlns=\"\"";
5942  }
5943  } else {
5944  $elementName = $name;
5945  if ($unqualified) {
5946  $elementNS = " xmlns=\"\"";
5947  } else {
5948  $elementNS = '';
5949  }
5950  }
5951  if (is_null($value)) {
5952  if ($use == 'literal') {
5953  // TODO: depends on minOccurs
5954  $xml = "<$elementName$elementNS/>";
5955  } else {
5956  $xml = "<$elementName$elementNS xsi:nil=\"true\" xsi:type=\"" . $this->getPrefixFromNamespace($ns) . ":$uqType\"/>";
5957  }
5958  $this->debug("in serializeType: returning: $xml");
5959  return $xml;
5960  }
5961  if (is_object($value)) {
5962  $value = get_object_vars($value);
5963  }
5964  if (is_array($value)) {
5965  $elementAttrs = $this->serializeComplexTypeAttributes($typeDef, $value, $ns, $uqType);
5966  if ($use == 'literal') {
5967  if ($forceType) {
5968  $xml = "<$elementName$elementNS$elementAttrs xsi:type=\"" . $this->getPrefixFromNamespace($ns) . ":$uqType\">";
5969  } else {
5970  $xml = "<$elementName$elementNS$elementAttrs>";
5971  }
5972  } else {
5973  $xml = "<$elementName$elementNS$elementAttrs xsi:type=\"" . $this->getPrefixFromNamespace($ns) . ":$uqType\"$encodingStyle>";
5974  }
5975 
5976  $xml .= $this->serializeComplexTypeElements($typeDef, $value, $ns, $uqType, $use, $encodingStyle);
5977  $xml .= "</$elementName>";
5978  } else {
5979  $this->debug("in serializeType: phpType is struct, but value is not an array");
5980  $this->setError("phpType is struct, but value is not an array: see debug output for details");
5981  $xml = '';
5982  }
5983  } elseif ($phpType == 'array') {
5984  if (isset($typeDef['form']) && ($typeDef['form'] == 'qualified')) {
5985  $elementNS = " xmlns=\"$ns\"";
5986  } else {
5987  if ($unqualified) {
5988  $elementNS = " xmlns=\"\"";
5989  } else {
5990  $elementNS = '';
5991  }
5992  }
5993  if (is_null($value)) {
5994  if ($use == 'literal') {
5995  // TODO: depends on minOccurs
5996  $xml = "<$name$elementNS/>";
5997  } else {
5998  $xml = "<$name$elementNS xsi:nil=\"true\" xsi:type=\"" .
5999  $this->getPrefixFromNamespace('http://schemas.xmlsoap.org/soap/encoding/') .
6000  ":Array\" " .
6001  $this->getPrefixFromNamespace('http://schemas.xmlsoap.org/soap/encoding/') .
6002  ':arrayType="' .
6003  $this->getPrefixFromNamespace($this->getPrefix($typeDef['arrayType'])) .
6004  ':' .
6005  $this->getLocalPart($typeDef['arrayType'])."[0]\"/>";
6006  }
6007  $this->debug("in serializeType: returning: $xml");
6008  return $xml;
6009  }
6010  if (isset($typeDef['multidimensional'])) {
6011  $nv = array();
6012  foreach($value as $v) {
6013  $cols = ',' . sizeof($v);
6014  $nv = array_merge($nv, $v);
6015  }
6016  $value = $nv;
6017  } else {
6018  $cols = '';
6019  }
6020  if (is_array($value) && sizeof($value) >= 1) {
6021  $rows = sizeof($value);
6022  $contents = '';
6023  foreach($value as $k => $v) {
6024  $this->debug("serializing array element: $k, $v of type: $typeDef[arrayType]");
6025  //if (strpos($typeDef['arrayType'], ':') ) {
6026  if (!in_array($typeDef['arrayType'],$this->typemap['http://www.w3.org/2001/XMLSchema'])) {
6027  $contents .= $this->serializeType('item', $typeDef['arrayType'], $v, $use);
6028  } else {
6029  $contents .= $this->serialize_val($v, 'item', $typeDef['arrayType'], null, $this->XMLSchemaVersion, false, $use);
6030  }
6031  }
6032  } else {
6033  $rows = 0;
6034  $contents = null;
6035  }
6036  // TODO: for now, an empty value will be serialized as a zero element
6037  // array. Revisit this when coding the handling of null/nil values.
6038  if ($use == 'literal') {
6039  $xml = "<$name$elementNS>"
6040  .$contents
6041  ."</$name>";
6042  } else {
6043  $xml = "<$name$elementNS xsi:type=\"".$this->getPrefixFromNamespace('http://schemas.xmlsoap.org/soap/encoding/').':Array" '.
6044  $this->getPrefixFromNamespace('http://schemas.xmlsoap.org/soap/encoding/')
6045  .':arrayType="'
6046  .$this->getPrefixFromNamespace($this->getPrefix($typeDef['arrayType']))
6047  .":".$this->getLocalPart($typeDef['arrayType'])."[$rows$cols]\">"
6048  .$contents
6049  ."</$name>";
6050  }
6051  } elseif ($phpType == 'scalar') {
6052  if (isset($typeDef['form']) && ($typeDef['form'] == 'qualified')) {
6053  $elementNS = " xmlns=\"$ns\"";
6054  } else {
6055  if ($unqualified) {
6056  $elementNS = " xmlns=\"\"";
6057  } else {
6058  $elementNS = '';
6059  }
6060  }
6061  if ($use == 'literal') {
6062  if ($forceType) {
6063  $xml = "<$name$elementNS xsi:type=\"" . $this->getPrefixFromNamespace($ns) . ":$uqType\">$value</$name>";
6064  } else {
6065  $xml = "<$name$elementNS>$value</$name>";
6066  }
6067  } else {
6068  $xml = "<$name$elementNS xsi:type=\"" . $this->getPrefixFromNamespace($ns) . ":$uqType\"$encodingStyle>$value</$name>";
6069  }
6070  }
6071  $this->debug("in serializeType: returning: $xml");
6072  return $xml;
6073  }
6074 
6085  function serializeComplexTypeAttributes($typeDef, $value, $ns, $uqType) {
6086  $xml = '';
6087  if (isset($typeDef['attrs']) && is_array($typeDef['attrs'])) {
6088  $this->debug("serialize attributes for XML Schema type $ns:$uqType");
6089  if (is_array($value)) {
6090  $xvalue = $value;
6091  } elseif (is_object($value)) {
6092  $xvalue = get_object_vars($value);
6093  } else {
6094  $this->debug("value is neither an array nor an object for XML Schema type $ns:$uqType");
6095  $xvalue = array();
6096  }
6097  foreach ($typeDef['attrs'] as $aName => $attrs) {
6098  if (isset($xvalue['!' . $aName])) {
6099  $xname = '!' . $aName;
6100  $this->debug("value provided for attribute $aName with key $xname");
6101  } elseif (isset($xvalue[$aName])) {
6102  $xname = $aName;
6103  $this->debug("value provided for attribute $aName with key $xname");
6104  } elseif (isset($attrs['default'])) {
6105  $xname = '!' . $aName;
6106  $xvalue[$xname] = $attrs['default'];
6107  $this->debug('use default value of ' . $xvalue[$aName] . ' for attribute ' . $aName);
6108  } else {
6109  $xname = '';
6110  $this->debug("no value provided for attribute $aName");
6111  }
6112  if ($xname) {
6113  $xml .= " $aName=\"" . $this->expandEntities($xvalue[$xname]) . "\"";
6114  }
6115  }
6116  } else {
6117  $this->debug("no attributes to serialize for XML Schema type $ns:$uqType");
6118  }
6119  if (isset($typeDef['extensionBase'])) {
6120  $ns = $this->getPrefix($typeDef['extensionBase']);
6121  $uqType = $this->getLocalPart($typeDef['extensionBase']);
6122  if ($this->getNamespaceFromPrefix($ns)) {
6123  $ns = $this->getNamespaceFromPrefix($ns);
6124  }
6125  if ($typeDef = $this->getTypeDef($uqType, $ns)) {
6126  $this->debug("serialize attributes for extension base $ns:$uqType");
6127  $xml .= $this->serializeComplexTypeAttributes($typeDef, $value, $ns, $uqType);
6128  } else {
6129  $this->debug("extension base $ns:$uqType is not a supported type");
6130  }
6131  }
6132  return $xml;
6133  }
6134 
6147  function serializeComplexTypeElements($typeDef, $value, $ns, $uqType, $use='encoded', $encodingStyle=false) {
6148  $xml = '';
6149  if (isset($typeDef['elements']) && is_array($typeDef['elements'])) {
6150  $this->debug("in serializeComplexTypeElements, serialize elements for XML Schema type $ns:$uqType");
6151  if (is_array($value)) {
6152  $xvalue = $value;
6153  } elseif (is_object($value)) {
6154  $xvalue = get_object_vars($value);
6155  } else {
6156  $this->debug("value is neither an array nor an object for XML Schema type $ns:$uqType");
6157  $xvalue = array();
6158  }
6159  // toggle whether all elements are present - ideally should validate against schema
6160  if (count($typeDef['elements']) != count($xvalue)){
6161  $optionals = true;
6162  }
6163  foreach ($typeDef['elements'] as $eName => $attrs) {
6164  if (!isset($xvalue[$eName])) {
6165  if (isset($attrs['default'])) {
6166  $xvalue[$eName] = $attrs['default'];
6167  $this->debug('use default value of ' . $xvalue[$eName] . ' for element ' . $eName);
6168  }
6169  }
6170  // if user took advantage of a minOccurs=0, then only serialize named parameters
6171  if (isset($optionals)
6172  && (!isset($xvalue[$eName]))
6173  && ( (!isset($attrs['nillable'])) || $attrs['nillable'] != 'true')
6174  ){
6175  if (isset($attrs['minOccurs']) && $attrs['minOccurs'] <> '0') {
6176  $this->debug("apparent error: no value provided for element $eName with minOccurs=" . $attrs['minOccurs']);
6177  }
6178  // do nothing
6179  $this->debug("no value provided for complexType element $eName and element is not nillable, so serialize nothing");
6180  } else {
6181  // get value
6182  if (isset($xvalue[$eName])) {
6183  $v = $xvalue[$eName];
6184  } else {
6185  $v = null;
6186  }
6187  if (isset($attrs['form'])) {
6188  $unqualified = ($attrs['form'] == 'unqualified');
6189  } else {
6190  $unqualified = false;
6191  }
6192  if (isset($attrs['maxOccurs']) && ($attrs['maxOccurs'] == 'unbounded' || $attrs['maxOccurs'] > 1) && isset($v) && is_array($v) && $this->isArraySimpleOrStruct($v) == 'arraySimple') {
6193  $vv = $v;
6194  foreach ($vv as $k => $v) {
6195  if (isset($attrs['type']) || isset($attrs['ref'])) {
6196  // serialize schema-defined type
6197  $xml .= $this->serializeType($eName, isset($attrs['type']) ? $attrs['type'] : $attrs['ref'], $v, $use, $encodingStyle, $unqualified);
6198  } else {
6199  // serialize generic type (can this ever really happen?)
6200  $this->debug("calling serialize_val() for $v, $eName, false, false, false, false, $use");
6201  $xml .= $this->serialize_val($v, $eName, false, false, false, false, $use);
6202  }
6203  }
6204  } else {
6205  if (isset($attrs['type']) || isset($attrs['ref'])) {
6206  // serialize schema-defined type
6207  $xml .= $this->serializeType($eName, isset($attrs['type']) ? $attrs['type'] : $attrs['ref'], $v, $use, $encodingStyle, $unqualified);
6208  } else {
6209  // serialize generic type (can this ever really happen?)
6210  $this->debug("calling serialize_val() for $v, $eName, false, false, false, false, $use");
6211  $xml .= $this->serialize_val($v, $eName, false, false, false, false, $use);
6212  }
6213  }
6214  }
6215  }
6216  } else {
6217  $this->debug("no elements to serialize for XML Schema type $ns:$uqType");
6218  }
6219  if (isset($typeDef['extensionBase'])) {
6220  $ns = $this->getPrefix($typeDef['extensionBase']);
6221  $uqType = $this->getLocalPart($typeDef['extensionBase']);
6222  if ($this->getNamespaceFromPrefix($ns)) {
6223  $ns = $this->getNamespaceFromPrefix($ns);
6224  }
6225  if ($typeDef = $this->getTypeDef($uqType, $ns)) {
6226  $this->debug("serialize elements for extension base $ns:$uqType");
6227  $xml .= $this->serializeComplexTypeElements($typeDef, $value, $ns, $uqType, $use, $encodingStyle);
6228  } else {
6229  $this->debug("extension base $ns:$uqType is not a supported type");
6230  }
6231  }
6232  return $xml;
6233  }
6234 
6249  function addComplexType($name,$typeClass='complexType',$phpType='array',$compositor='',$restrictionBase='',$elements=array(),$attrs=array(),$arrayType='') {
6250  if (count($elements) > 0) {
6251  $eElements = array();
6252  foreach($elements as $n => $e){
6253  // expand each element
6254  $ee = array();
6255  foreach ($e as $k => $v) {
6256  $k = strpos($k,':') ? $this->expandQname($k) : $k;
6257  $v = strpos($v,':') ? $this->expandQname($v) : $v;
6258  $ee[$k] = $v;
6259  }
6260  $eElements[$n] = $ee;
6261  }
6262  $elements = $eElements;
6263  }
6264 
6265  if (count($attrs) > 0) {
6266  foreach($attrs as $n => $a){
6267  // expand each attribute
6268  foreach ($a as $k => $v) {
6269  $k = strpos($k,':') ? $this->expandQname($k) : $k;
6270  $v = strpos($v,':') ? $this->expandQname($v) : $v;
6271  $aa[$k] = $v;
6272  }
6273  $eAttrs[$n] = $aa;
6274  }
6275  $attrs = $eAttrs;
6276  }
6277 
6278  $restrictionBase = strpos($restrictionBase,':') ? $this->expandQname($restrictionBase) : $restrictionBase;
6279  $arrayType = strpos($arrayType,':') ? $this->expandQname($arrayType) : $arrayType;
6280 
6281  $typens = isset($this->namespaces['types']) ? $this->namespaces['types'] : $this->namespaces['tns'];
6282  $this->schemas[$typens][0]->addComplexType($name,$typeClass,$phpType,$compositor,$restrictionBase,$elements,$attrs,$arrayType);
6283  }
6284 
6296  function addSimpleType($name, $restrictionBase='', $typeClass='simpleType', $phpType='scalar', $enumeration=array()) {
6297  $restrictionBase = strpos($restrictionBase,':') ? $this->expandQname($restrictionBase) : $restrictionBase;
6298 
6299  $typens = isset($this->namespaces['types']) ? $this->namespaces['types'] : $this->namespaces['tns'];
6300  $this->schemas[$typens][0]->addSimpleType($name, $restrictionBase, $typeClass, $phpType, $enumeration);
6301  }
6302 
6310  function addElement($attrs) {
6311  $typens = isset($this->namespaces['types']) ? $this->namespaces['types'] : $this->namespaces['tns'];
6312  $this->schemas[$typens][0]->addElement($attrs);
6313  }
6314 
6329  function addOperation($name, $in = false, $out = false, $namespace = false, $soapaction = false, $style = 'rpc', $use = 'encoded', $documentation = '', $encodingStyle = ''){
6330  if ($use == 'encoded' && $encodingStyle == '') {
6331  $encodingStyle = 'http://schemas.xmlsoap.org/soap/encoding/';
6332  }
6333 
6334  if ($style == 'document') {
6335  $elements = array();
6336  foreach ($in as $n => $t) {
6337  $elements[$n] = array('name' => $n, 'type' => $t);
6338  }
6339  $this->addComplexType($name . 'RequestType', 'complexType', 'struct', 'all', '', $elements);
6340  $this->addElement(array('name' => $name, 'type' => $name . 'RequestType'));
6341  $in = array('parameters' => 'tns:' . $name . '^');
6342 
6343  $elements = array();
6344  foreach ($out as $n => $t) {
6345  $elements[$n] = array('name' => $n, 'type' => $t);
6346  }
6347  $this->addComplexType($name . 'ResponseType', 'complexType', 'struct', 'all', '', $elements);
6348  $this->addElement(array('name' => $name . 'Response', 'type' => $name . 'ResponseType', 'form' => 'qualified'));
6349  $out = array('parameters' => 'tns:' . $name . 'Response' . '^');
6350  }
6351 
6352  // get binding
6353  $this->bindings[ $this->serviceName . 'Binding' ]['operations'][$name] =
6354  array(
6355  'name' => $name,
6356  'binding' => $this->serviceName . 'Binding',
6357  'endpoint' => $this->endpoint,
6358  'soapAction' => $soapaction,
6359  'style' => $style,
6360  'input' => array(
6361  'use' => $use,
6362  'namespace' => $namespace,
6363  'encodingStyle' => $encodingStyle,
6364  'message' => $name . 'Request',
6365  'parts' => $in),
6366  'output' => array(
6367  'use' => $use,
6368  'namespace' => $namespace,
6369  'encodingStyle' => $encodingStyle,
6370  'message' => $name . 'Response',
6371  'parts' => $out),
6372  'namespace' => $namespace,
6373  'transport' => 'http://schemas.xmlsoap.org/soap/http',
6374  'documentation' => $documentation);
6375  // add portTypes
6376  // add messages
6377  if($in)
6378  {
6379  foreach($in as $pName => $pType)
6380  {
6381  if(strpos($pType,':')) {
6382  $pType = $this->getNamespaceFromPrefix($this->getPrefix($pType)).":".$this->getLocalPart($pType);
6383  }
6384  $this->messages[$name.'Request'][$pName] = $pType;
6385  }
6386  } else {
6387  $this->messages[$name.'Request']= '0';
6388  }
6389  if($out)
6390  {
6391  foreach($out as $pName => $pType)
6392  {
6393  if(strpos($pType,':')) {
6394  $pType = $this->getNamespaceFromPrefix($this->getPrefix($pType)).":".$this->getLocalPart($pType);
6395  }
6396  $this->messages[$name.'Response'][$pName] = $pType;
6397  }
6398  } else {
6399  $this->messages[$name.'Response']= '0';
6400  }
6401  return true;
6402  }
6403 }
6404 ?><?php
6405 
6406 
6407 
6418 
6419  var $xml = '';
6420  var $xml_encoding = '';
6421  var $method = '';
6422  var $root_struct = '';
6423  var $root_struct_name = '';
6424  var $root_struct_namespace = '';
6425  var $root_header = '';
6426  var $document = ''; // incoming SOAP body (text)
6427  // determines where in the message we are (envelope,header,body,method)
6428  var $status = '';
6429  var $position = 0;
6430  var $depth = 0;
6431  var $default_namespace = '';
6432  var $namespaces = array();
6433  var $message = array();
6434  var $parent = '';
6435  var $fault = false;
6436  var $fault_code = '';
6437  var $fault_str = '';
6438  var $fault_detail = '';
6439  var $depth_array = array();
6440  var $debug_flag = true;
6441  var $soapresponse = NULL; // parsed SOAP Body
6442  var $soapheader = NULL; // parsed SOAP Header
6443  var $responseHeaders = ''; // incoming SOAP headers (text)
6444  var $body_position = 0;
6445  // for multiref parsing:
6446  // array of id => pos
6447  var $ids = array();
6448  // array of id => hrefs => pos
6449  var $multirefs = array();
6450  // toggle for auto-decoding element content
6451  var $decode_utf8 = true;
6452 
6462  function __construct($xml,$encoding='UTF-8',$method='',$decode_utf8=true){
6463  parent::__construct();
6464  $this->xml = $xml;
6465  $this->xml_encoding = $encoding;
6466  $this->method = $method;
6467  $this->decode_utf8 = $decode_utf8;
6468 
6469  // Check whether content has been read.
6470  if(!empty($xml)){
6471  // Check XML encoding
6472  $pos_xml = strpos($xml, '<?xml');
6473  if ($pos_xml !== FALSE) {
6474  $xml_decl = substr($xml, $pos_xml, strpos($xml, '?>', $pos_xml + 2) - $pos_xml + 1);
6475  if (preg_match("/encoding=[\"']([^\"']*)[\"']/", $xml_decl, $res)) {
6476  $xml_encoding = $res[1];
6477  if (strtoupper($xml_encoding) != $encoding) {
6478  $err = "Charset from HTTP Content-Type '" . $encoding . "' does not match encoding from XML declaration '" . $xml_encoding . "'";
6479  $this->debug($err);
6480  if ($encoding != 'ISO-8859-1' || strtoupper($xml_encoding) != 'UTF-8') {
6481  $this->setError($err);
6482  return;
6483  }
6484  // when HTTP says ISO-8859-1 (the default) and XML says UTF-8 (the typical), assume the other endpoint is just sloppy and proceed
6485  } else {
6486  $this->debug('Charset from HTTP Content-Type matches encoding from XML declaration');
6487  }
6488  } else {
6489  $this->debug('No encoding specified in XML declaration');
6490  }
6491  } else {
6492  $this->debug('No XML declaration');
6493  }
6494  $this->debug('Entering nusoap_parser(), length='.strlen($xml).', encoding='.$encoding);
6495  // Create an XML parser - why not xml_parser_create_ns?
6496  $this->parser = xml_parser_create($this->xml_encoding);
6497  // Set the options for parsing the XML data.
6498  //xml_parser_set_option($parser, XML_OPTION_SKIP_WHITE, 1);
6499  xml_parser_set_option($this->parser, XML_OPTION_CASE_FOLDING, 0);
6500  xml_parser_set_option($this->parser, XML_OPTION_TARGET_ENCODING, $this->xml_encoding);
6501  // Set the object for the parser.
6502  xml_set_object($this->parser, $this);
6503  // Set the element handlers for the parser.
6504  xml_set_element_handler($this->parser, 'start_element','end_element');
6505  xml_set_character_data_handler($this->parser,'character_data');
6506 
6507  // Parse the XML file.
6508  if(!xml_parse($this->parser,$xml,true)){
6509  // Display an error message.
6510  $err = sprintf('XML error parsing SOAP payload on line %d: %s',
6511  xml_get_current_line_number($this->parser),
6512  xml_error_string(xml_get_error_code($this->parser)));
6513  $this->debug($err);
6514  $this->debug("XML payload:\n" . $xml);
6515  $this->setError($err);
6516  } else {
6517  $this->debug('parsed successfully, found root struct: '.$this->root_struct.' of name '.$this->root_struct_name);
6518  // get final value
6519  $this->soapresponse = $this->message[$this->root_struct]['result'];
6520  // get header value
6521  if($this->root_header != '' && isset($this->message[$this->root_header]['result'])){
6522  $this->soapheader = $this->message[$this->root_header]['result'];
6523  }
6524  // resolve hrefs/ids
6525  if(sizeof($this->multirefs) > 0){
6526  foreach($this->multirefs as $id => $hrefs){
6527  $this->debug('resolving multirefs for id: '.$id);
6528  $idVal = $this->buildVal($this->ids[$id]);
6529  if (is_array($idVal) && isset($idVal['!id'])) {
6530  unset($idVal['!id']);
6531  }
6532  foreach($hrefs as $refPos => $ref){
6533  $this->debug('resolving href at pos '.$refPos);
6534  $this->multirefs[$id][$refPos] = $idVal;
6535  }
6536  }
6537  }
6538  }
6539  xml_parser_free($this->parser);
6540  } else {
6541  $this->debug('xml was empty, didn\'t parse!');
6542  $this->setError('xml was empty, didn\'t parse!');
6543  }
6544  }
6545 
6554  function start_element($parser, $name, $attrs) {
6555  // position in a total number of elements, starting from 0
6556  // update class level pos
6557  $pos = $this->position++;
6558  // and set mine
6559  $this->message[$pos] = array('pos' => $pos,'children'=>'','cdata'=>'');
6560  // depth = how many levels removed from root?
6561  // set mine as current global depth and increment global depth value
6562  $this->message[$pos]['depth'] = $this->depth++;
6563 
6564  // else add self as child to whoever the current parent is
6565  if($pos != 0){
6566  $this->message[$this->parent]['children'] .= '|'.$pos;
6567  }
6568  // set my parent
6569  $this->message[$pos]['parent'] = $this->parent;
6570  // set self as current parent
6571  $this->parent = $pos;
6572  // set self as current value for this depth
6573  $this->depth_array[$this->depth] = $pos;
6574  // get element prefix
6575  if(strpos($name,':')){
6576  // get ns prefix
6577  $prefix = substr($name,0,strpos($name,':'));
6578  // get unqualified name
6579  $name = substr(strstr($name,':'),1);
6580  }
6581  // set status
6582  if($name == 'Envelope'){
6583  $this->status = 'envelope';
6584  } elseif($name == 'Header' && $this->status = 'envelope'){
6585  $this->root_header = $pos;
6586  $this->status = 'header';
6587  } elseif($name == 'Body' && $this->status = 'envelope'){
6588  $this->status = 'body';
6589  $this->body_position = $pos;
6590  // set method
6591  } elseif($this->status == 'body' && $pos == ($this->body_position+1)){
6592  $this->status = 'method';
6593  $this->root_struct_name = $name;
6594  $this->root_struct = $pos;
6595  $this->message[$pos]['type'] = 'struct';
6596  $this->debug("found root struct $this->root_struct_name, pos $this->root_struct");
6597  }
6598  // set my status
6599  $this->message[$pos]['status'] = $this->status;
6600  // set name
6601  $this->message[$pos]['name'] = htmlspecialchars($name);
6602  // set attrs
6603  $this->message[$pos]['attrs'] = $attrs;
6604 
6605  // loop through atts, logging ns and type declarations
6606  $attstr = '';
6607  foreach($attrs as $key => $value){
6608  $key_prefix = $this->getPrefix($key);
6609  $key_localpart = $this->getLocalPart($key);
6610  // if ns declarations, add to class level array of valid namespaces
6611  if($key_prefix == 'xmlns'){
6612  if(preg_match('/^http:\/\/www.w3.org\/[0-9]{4}\/XMLSchema$/',$value)){
6613  $this->XMLSchemaVersion = $value;
6614  $this->namespaces['xsd'] = $this->XMLSchemaVersion;
6615  $this->namespaces['xsi'] = $this->XMLSchemaVersion.'-instance';
6616  }
6617  $this->namespaces[$key_localpart] = $value;
6618  // set method namespace
6619  if($name == $this->root_struct_name){
6620  $this->methodNamespace = $value;
6621  }
6622  // if it's a type declaration, set type
6623  } elseif($key_localpart == 'type'){
6624  if (isset($this->message[$pos]['type']) && $this->message[$pos]['type'] == 'array') {
6625  // do nothing: already processed arrayType
6626  } else {
6627  $value_prefix = $this->getPrefix($value);
6628  $value_localpart = $this->getLocalPart($value);
6629  $this->message[$pos]['type'] = $value_localpart;
6630  $this->message[$pos]['typePrefix'] = $value_prefix;
6631  if(isset($this->namespaces[$value_prefix])){
6632  $this->message[$pos]['type_namespace'] = $this->namespaces[$value_prefix];
6633  } else if(isset($attrs['xmlns:'.$value_prefix])) {
6634  $this->message[$pos]['type_namespace'] = $attrs['xmlns:'.$value_prefix];
6635  }
6636  // should do something here with the namespace of specified type?
6637  }
6638  } elseif($key_localpart == 'arrayType'){
6639  $this->message[$pos]['type'] = 'array';
6640  /* do arrayType ereg here
6641  [1] arrayTypeValue ::= atype asize
6642  [2] atype ::= QName rank*
6643  [3] rank ::= '[' (',')* ']'
6644  [4] asize ::= '[' length~ ']'
6645  [5] length ::= nextDimension* Digit+
6646  [6] nextDimension ::= Digit+ ','
6647  */
6648  $expr = '/([A-Za-z0-9_]+):([A-Za-z]+[A-Za-z0-9_]+)\[([0-9]+),?([0-9]*)\]/';
6649  if(preg_match($expr,$value,$regs)){
6650  $this->message[$pos]['typePrefix'] = $regs[1];
6651  $this->message[$pos]['arrayTypePrefix'] = $regs[1];
6652  if (isset($this->namespaces[$regs[1]])) {
6653  $this->message[$pos]['arrayTypeNamespace'] = $this->namespaces[$regs[1]];
6654  } else if (isset($attrs['xmlns:'.$regs[1]])) {
6655  $this->message[$pos]['arrayTypeNamespace'] = $attrs['xmlns:'.$regs[1]];
6656  }
6657  $this->message[$pos]['arrayType'] = $regs[2];
6658  $this->message[$pos]['arraySize'] = $regs[3];
6659  $this->message[$pos]['arrayCols'] = $regs[4];
6660  }
6661  // specifies nil value (or not)
6662  } elseif ($key_localpart == 'nil'){
6663  $this->message[$pos]['nil'] = ($value == 'true' || $value == '1');
6664  // some other attribute
6665  } elseif ($key != 'href' && $key != 'xmlns' && $key_localpart != 'encodingStyle' && $key_localpart != 'root') {
6666  $this->message[$pos]['xattrs']['!' . $key] = $value;
6667  }
6668 
6669  if ($key == 'xmlns') {
6670  $this->default_namespace = $value;
6671  }
6672  // log id
6673  if($key == 'id'){
6674  $this->ids[$value] = $pos;
6675  }
6676  // root
6677  if($key_localpart == 'root' && $value == 1){
6678  $this->status = 'method';
6679  $this->root_struct_name = $name;
6680  $this->root_struct = $pos;
6681  $this->debug("found root struct $this->root_struct_name, pos $pos");
6682  }
6683  // for doclit
6684  $attstr .= " $key=\"$value\"";
6685  }
6686  // get namespace - must be done after namespace atts are processed
6687  if(isset($prefix)){
6688  $this->message[$pos]['namespace'] = $this->namespaces[$prefix];
6689  $this->default_namespace = $this->namespaces[$prefix];
6690  } else {
6691  $this->message[$pos]['namespace'] = $this->default_namespace;
6692  }
6693  if($this->status == 'header'){
6694  if ($this->root_header != $pos) {
6695  $this->responseHeaders .= "<" . (isset($prefix) ? $prefix . ':' : '') . "$name$attstr>";
6696  }
6697  } elseif($this->root_struct_name != ''){
6698  $this->document .= "<" . (isset($prefix) ? $prefix . ':' : '') . "$name$attstr>";
6699  }
6700  }
6701 
6709  function end_element($parser, $name) {
6710  // position of current element is equal to the last value left in depth_array for my depth
6711  $pos = $this->depth_array[$this->depth--];
6712 
6713  // get element prefix
6714  if(strpos($name,':')){
6715  // get ns prefix
6716  $prefix = substr($name,0,strpos($name,':'));
6717  // get unqualified name
6718  $name = substr(strstr($name,':'),1);
6719  }
6720 
6721  // build to native type
6722  if(isset($this->body_position) && $pos > $this->body_position){
6723  // deal w/ multirefs
6724  if(isset($this->message[$pos]['attrs']['href'])){
6725  // get id
6726  $id = substr($this->message[$pos]['attrs']['href'],1);
6727  // add placeholder to href array
6728  $this->multirefs[$id][$pos] = 'placeholder';
6729  // add set a reference to it as the result value
6730  $this->message[$pos]['result'] =& $this->multirefs[$id][$pos];
6731  // build complexType values
6732  } elseif($this->message[$pos]['children'] != ''){
6733  // if result has already been generated (struct/array)
6734  if(!isset($this->message[$pos]['result'])){
6735  $this->message[$pos]['result'] = $this->buildVal($pos);
6736  }
6737  // build complexType values of attributes and possibly simpleContent
6738  } elseif (isset($this->message[$pos]['xattrs'])) {
6739  if (isset($this->message[$pos]['nil']) && $this->message[$pos]['nil']) {
6740  $this->message[$pos]['xattrs']['!'] = null;
6741  } elseif (isset($this->message[$pos]['cdata']) && trim($this->message[$pos]['cdata']) != '') {
6742  if (isset($this->message[$pos]['type'])) {
6743  $this->message[$pos]['xattrs']['!'] = $this->decodeSimple($this->message[$pos]['cdata'], $this->message[$pos]['type'], isset($this->message[$pos]['type_namespace']) ? $this->message[$pos]['type_namespace'] : '');
6744  } else {
6745  $parent = $this->message[$pos]['parent'];
6746  if (isset($this->message[$parent]['type']) && ($this->message[$parent]['type'] == 'array') && isset($this->message[$parent]['arrayType'])) {
6747  $this->message[$pos]['xattrs']['!'] = $this->decodeSimple($this->message[$pos]['cdata'], $this->message[$parent]['arrayType'], isset($this->message[$parent]['arrayTypeNamespace']) ? $this->message[$parent]['arrayTypeNamespace'] : '');
6748  } else {
6749  $this->message[$pos]['xattrs']['!'] = $this->message[$pos]['cdata'];
6750  }
6751  }
6752  }
6753  $this->message[$pos]['result'] = $this->message[$pos]['xattrs'];
6754  // set value of simpleType (or nil complexType)
6755  } else {
6756  //$this->debug('adding data for scalar value '.$this->message[$pos]['name'].' of value '.$this->message[$pos]['cdata']);
6757  if (isset($this->message[$pos]['nil']) && $this->message[$pos]['nil']) {
6758  $this->message[$pos]['xattrs']['!'] = null;
6759  } elseif (isset($this->message[$pos]['type'])) {
6760  $this->message[$pos]['result'] = $this->decodeSimple($this->message[$pos]['cdata'], $this->message[$pos]['type'], isset($this->message[$pos]['type_namespace']) ? $this->message[$pos]['type_namespace'] : '');
6761  } else {
6762  $parent = $this->message[$pos]['parent'];
6763  if (isset($this->message[$parent]['type']) && ($this->message[$parent]['type'] == 'array') && isset($this->message[$parent]['arrayType'])) {
6764  $this->message[$pos]['result'] = $this->decodeSimple($this->message[$pos]['cdata'], $this->message[$parent]['arrayType'], isset($this->message[$parent]['arrayTypeNamespace']) ? $this->message[$parent]['arrayTypeNamespace'] : '');
6765  } else {
6766  $this->message[$pos]['result'] = $this->message[$pos]['cdata'];
6767  }
6768  }
6769 
6770  /* add value to parent's result, if parent is struct/array
6771  $parent = $this->message[$pos]['parent'];
6772  if($this->message[$parent]['type'] != 'map'){
6773  if(strtolower($this->message[$parent]['type']) == 'array'){
6774  $this->message[$parent]['result'][] = $this->message[$pos]['result'];
6775  } else {
6776  $this->message[$parent]['result'][$this->message[$pos]['name']] = $this->message[$pos]['result'];
6777  }
6778  }
6779  */
6780  }
6781  }
6782 
6783  // for doclit
6784  if($this->status == 'header'){
6785  if ($this->root_header != $pos) {
6786  $this->responseHeaders .= "</" . (isset($prefix) ? $prefix . ':' : '') . "$name>";
6787  }
6788  } elseif($pos >= $this->root_struct){
6789  $this->document .= "</" . (isset($prefix) ? $prefix . ':' : '') . "$name>";
6790  }
6791  // switch status
6792  if($pos == $this->root_struct){
6793  $this->status = 'body';
6794  $this->root_struct_namespace = $this->message[$pos]['namespace'];
6795  } elseif($name == 'Body'){
6796  $this->status = 'envelope';
6797  } elseif($name == 'Header'){
6798  $this->status = 'envelope';
6799  } elseif($name == 'Envelope'){
6800  //
6801  }
6802  // set parent back to my parent
6803  $this->parent = $this->message[$pos]['parent'];
6804  }
6805 
6813  function character_data($parser, $data){
6814  $pos = $this->depth_array[$this->depth];
6815  if ($this->xml_encoding=='UTF-8'){
6816  // TODO: add an option to disable this for folks who want
6817  // raw UTF-8 that, e.g., might not map to iso-8859-1
6818  // TODO: this can also be handled with xml_parser_set_option($this->parser, XML_OPTION_TARGET_ENCODING, "ISO-8859-1");
6819  if($this->decode_utf8){
6820  $data = utf8_decode($data);
6821  }
6822  }
6823  $this->message[$pos]['cdata'] .= $data;
6824  // for doclit
6825  if($this->status == 'header'){
6826  $this->responseHeaders .= $data;
6827  } else {
6828  $this->document .= $data;
6829  }
6830  }
6831 
6839  function get_response(){
6840  return $this->soapresponse;
6841  }
6842 
6849  function get_soapbody(){
6850  return $this->soapresponse;
6851  }
6852 
6859  function get_soapheader(){
6860  return $this->soapheader;
6861  }
6862 
6869  function getHeaders(){
6870  return $this->responseHeaders;
6871  }
6872 
6882  function decodeSimple($value, $type, $typens) {
6883  // TODO: use the namespace!
6884  if ((!isset($type)) || $type == 'string' || $type == 'long' || $type == 'unsignedLong') {
6885  return (string) $value;
6886  }
6887  if ($type == 'int' || $type == 'integer' || $type == 'short' || $type == 'byte') {
6888  return (int) $value;
6889  }
6890  if ($type == 'float' || $type == 'double' || $type == 'decimal') {
6891  return (double) $value;
6892  }
6893  if ($type == 'boolean') {
6894  if (strtolower($value) == 'false' || strtolower($value) == 'f') {
6895  return false;
6896  }
6897  return (boolean) $value;
6898  }
6899  if ($type == 'base64' || $type == 'base64Binary') {
6900  $this->debug('Decode base64 value');
6901  return base64_decode($value);
6902  }
6903  // obscure numeric types
6904  if ($type == 'nonPositiveInteger' || $type == 'negativeInteger'
6905  || $type == 'nonNegativeInteger' || $type == 'positiveInteger'
6906  || $type == 'unsignedInt'
6907  || $type == 'unsignedShort' || $type == 'unsignedByte') {
6908  return (int) $value;
6909  }
6910  // bogus: parser treats array with no elements as a simple type
6911  if ($type == 'array') {
6912  return array();
6913  }
6914  // everything else
6915  return (string) $value;
6916  }
6917 
6926  function buildVal($pos){
6927  if(!isset($this->message[$pos]['type'])){
6928  $this->message[$pos]['type'] = '';
6929  }
6930  $this->debug('in buildVal() for '.$this->message[$pos]['name']."(pos $pos) of type ".$this->message[$pos]['type']);
6931  // if there are children...
6932  if($this->message[$pos]['children'] != ''){
6933  $this->debug('in buildVal, there are children');
6934  $children = explode('|',$this->message[$pos]['children']);
6935  array_shift($children); // knock off empty
6936  // md array
6937  if(isset($this->message[$pos]['arrayCols']) && $this->message[$pos]['arrayCols'] != ''){
6938  $r=0; // rowcount
6939  $c=0; // colcount
6940  foreach($children as $child_pos){
6941  $this->debug("in buildVal, got an MD array element: $r, $c");
6942  $params[$r][] = $this->message[$child_pos]['result'];
6943  $c++;
6944  if($c == $this->message[$pos]['arrayCols']){
6945  $c = 0;
6946  $r++;
6947  }
6948  }
6949  // array
6950  } elseif($this->message[$pos]['type'] == 'array' || $this->message[$pos]['type'] == 'Array'){
6951  $this->debug('in buildVal, adding array '.$this->message[$pos]['name']);
6952  foreach($children as $child_pos){
6953  $params[] = &$this->message[$child_pos]['result'];
6954  }
6955  // apache Map type: java hashtable
6956  } elseif($this->message[$pos]['type'] == 'Map' && $this->message[$pos]['type_namespace'] == 'http://xml.apache.org/xml-soap'){
6957  $this->debug('in buildVal, Java Map '.$this->message[$pos]['name']);
6958  foreach($children as $child_pos){
6959  $kv = explode("|",$this->message[$child_pos]['children']);
6960  $params[$this->message[$kv[1]]['result']] = &$this->message[$kv[2]]['result'];
6961  }
6962  // generic compound type
6963  //} elseif($this->message[$pos]['type'] == 'SOAPStruct' || $this->message[$pos]['type'] == 'struct') {
6964  } else {
6965  // Apache Vector type: treat as an array
6966  $this->debug('in buildVal, adding Java Vector or generic compound type '.$this->message[$pos]['name']);
6967  if ($this->message[$pos]['type'] == 'Vector' && $this->message[$pos]['type_namespace'] == 'http://xml.apache.org/xml-soap') {
6968  $notstruct = 1;
6969  } else {
6970  $notstruct = 0;
6971  }
6972  //
6973  foreach($children as $child_pos){
6974  if($notstruct){
6975  $params[] = &$this->message[$child_pos]['result'];
6976  } else {
6977  if (isset($params[$this->message[$child_pos]['name']])) {
6978  // de-serialize repeated element name into an array
6979  if ((!is_array($params[$this->message[$child_pos]['name']])) || (!isset($params[$this->message[$child_pos]['name']][0]))) {
6980  $params[$this->message[$child_pos]['name']] = array($params[$this->message[$child_pos]['name']]);
6981  }
6982  $params[$this->message[$child_pos]['name']][] = &$this->message[$child_pos]['result'];
6983  } else {
6984  $params[$this->message[$child_pos]['name']] = &$this->message[$child_pos]['result'];
6985  }
6986  }
6987  }
6988  }
6989  if (isset($this->message[$pos]['xattrs'])) {
6990  $this->debug('in buildVal, handling attributes');
6991  foreach ($this->message[$pos]['xattrs'] as $n => $v) {
6992  $params[$n] = $v;
6993  }
6994  }
6995  // handle simpleContent
6996  if (isset($this->message[$pos]['cdata']) && trim($this->message[$pos]['cdata']) != '') {
6997  $this->debug('in buildVal, handling simpleContent');
6998  if (isset($this->message[$pos]['type'])) {
6999  $params['!'] = $this->decodeSimple($this->message[$pos]['cdata'], $this->message[$pos]['type'], isset($this->message[$pos]['type_namespace']) ? $this->message[$pos]['type_namespace'] : '');
7000  } else {
7001  $parent = $this->message[$pos]['parent'];
7002  if (isset($this->message[$parent]['type']) && ($this->message[$parent]['type'] == 'array') && isset($this->message[$parent]['arrayType'])) {
7003  $params['!'] = $this->decodeSimple($this->message[$pos]['cdata'], $this->message[$parent]['arrayType'], isset($this->message[$parent]['arrayTypeNamespace']) ? $this->message[$parent]['arrayTypeNamespace'] : '');
7004  } else {
7005  $params['!'] = $this->message[$pos]['cdata'];
7006  }
7007  }
7008  }
7009  $ret = is_array($params) ? $params : array();
7010  $this->debug('in buildVal, return:');
7011  $this->appendDebug($this->varDump($ret));
7012  return $ret;
7013  } else {
7014  $this->debug('in buildVal, no children, building scalar');
7015  $cdata = isset($this->message[$pos]['cdata']) ? $this->message[$pos]['cdata'] : '';
7016  if (isset($this->message[$pos]['type'])) {
7017  $ret = $this->decodeSimple($cdata, $this->message[$pos]['type'], isset($this->message[$pos]['type_namespace']) ? $this->message[$pos]['type_namespace'] : '');
7018  $this->debug("in buildVal, return: $ret");
7019  return $ret;
7020  }
7021  $parent = $this->message[$pos]['parent'];
7022  if (isset($this->message[$parent]['type']) && ($this->message[$parent]['type'] == 'array') && isset($this->message[$parent]['arrayType'])) {
7023  $ret = $this->decodeSimple($cdata, $this->message[$parent]['arrayType'], isset($this->message[$parent]['arrayTypeNamespace']) ? $this->message[$parent]['arrayTypeNamespace'] : '');
7024  $this->debug("in buildVal, return: $ret");
7025  return $ret;
7026  }
7027  $ret = $this->message[$pos]['cdata'];
7028  $this->debug("in buildVal, return: $ret");
7029  return $ret;
7030  }
7031  }
7032 }
7033 
7037 class soap_parser extends nusoap_parser {
7038 }
7039 
7040 ?><?php
7041 
7042 
7043 
7065 
7066  var $username = ''; // Username for HTTP authentication
7067  var $password = ''; // Password for HTTP authentication
7068  var $authtype = ''; // Type of HTTP authentication
7069  var $certRequest = array(); // Certificate for HTTP SSL authentication
7070  var $requestHeaders = false; // SOAP headers in request (text)
7071  var $responseHeaders = ''; // SOAP headers from response (incomplete namespace resolution) (text)
7072  var $responseHeader = NULL; // SOAP Header from response (parsed)
7073  var $document = ''; // SOAP body response portion (incomplete namespace resolution) (text)
7075  var $forceEndpoint = ''; // overrides WSDL endpoint
7076  var $proxyhost = '';
7077  var $proxyport = '';
7078  var $proxyusername = '';
7079  var $proxypassword = '';
7080  var $xml_encoding = ''; // character set encoding of incoming (response) messages
7081  var $http_encoding = false;
7082  var $timeout = 0; // HTTP connection timeout
7083  var $response_timeout = 30; // HTTP response timeout
7084  var $endpointType = ''; // soap|wsdl, empty for WSDL initialization error
7085  var $persistentConnection = false;
7086  var $defaultRpcParams = false; // This is no longer used
7087  var $request = ''; // HTTP request
7088  var $response = ''; // HTTP response
7089  var $responseData = ''; // SOAP payload of response
7090  var $cookies = array(); // Cookies from response or for request
7091  var $decode_utf8 = true; // toggles whether the parser decodes element content w/ utf8_decode()
7092  var $operations = array(); // WSDL operations, empty for WSDL initialization error
7093  var $curl_options = array(); // User-specified cURL options
7094  var $bindingType = ''; // WSDL operation binding type
7095  var $use_curl = false; // whether to always try to use cURL
7096 
7097  /*
7098  * fault related variables
7099  */
7104  var $fault;
7120 
7135  function __construct($endpoint,$wsdl = false,$proxyhost = false,$proxyport = false,$proxyusername = false, $proxypassword = false, $timeout = 0, $response_timeout = 30){
7136  parent::__construct();
7137  $this->endpoint = $endpoint;
7138  $this->proxyhost = $proxyhost;
7139  $this->proxyport = $proxyport;
7140  $this->proxyusername = $proxyusername;
7141  $this->proxypassword = $proxypassword;
7142  $this->timeout = $timeout;
7143  $this->response_timeout = $response_timeout;
7144 
7145  $this->debug("ctor wsdl=$wsdl timeout=$timeout response_timeout=$response_timeout");
7146  $this->appendDebug('endpoint=' . $this->varDump($endpoint));
7147 
7148  // make values
7149  if($wsdl){
7150  if (is_object($endpoint) && (get_class($endpoint) == 'wsdl')) {
7151  $this->wsdl = $endpoint;
7152  $this->endpoint = $this->wsdl->wsdl;
7153  $this->wsdlFile = $this->endpoint;
7154  $this->debug('existing wsdl instance created from ' . $this->endpoint);
7155  $this->checkWSDL();
7156  } else {
7157  $this->wsdlFile = $this->endpoint;
7158  $this->wsdl = null;
7159  $this->debug('will use lazy evaluation of wsdl from ' . $this->endpoint);
7160  }
7161  $this->endpointType = 'wsdl';
7162  } else {
7163  $this->debug("instantiate SOAP with endpoint at $endpoint");
7164  $this->endpointType = 'soap';
7165  }
7166  }
7167 
7193  function call($operation,$params=array(),$namespace='http://tempuri.org',$soapAction='',$headers=false,$rpcParams=null,$style='rpc',$use='encoded'){
7194  $this->operation = $operation;
7195  $this->fault = false;
7196  $this->setError('');
7197  $this->request = '';
7198  $this->response = '';
7199  $this->responseData = '';
7200  $this->faultstring = '';
7201  $this->faultcode = '';
7202  $this->opData = array();
7203 
7204  $this->debug("call: operation=$operation, namespace=$namespace, soapAction=$soapAction, rpcParams=$rpcParams, style=$style, use=$use, endpointType=$this->endpointType");
7205  $this->appendDebug('params=' . $this->varDump($params));
7206  $this->appendDebug('headers=' . $this->varDump($headers));
7207  if ($headers) {
7208  $this->requestHeaders = $headers;
7209  }
7210  if ($this->endpointType == 'wsdl' && is_null($this->wsdl)) {
7211  $this->loadWSDL();
7212  if ($this->getError())
7213  return false;
7214  }
7215  // serialize parameters
7216  if($this->endpointType == 'wsdl' && $opData = $this->getOperationData($operation)){
7217  // use WSDL for operation
7218  $this->opData = $opData;
7219  $this->debug("found operation");
7220  $this->appendDebug('opData=' . $this->varDump($opData));
7221  if (isset($opData['soapAction'])) {
7222  $soapAction = $opData['soapAction'];
7223  }
7224  if (! $this->forceEndpoint) {
7225  $this->endpoint = $opData['endpoint'];
7226  } else {
7227  $this->endpoint = $this->forceEndpoint;
7228  }
7229  $namespace = isset($opData['input']['namespace']) ? $opData['input']['namespace'] : $namespace;
7230  $style = $opData['style'];
7231  $use = $opData['input']['use'];
7232  // add ns to ns array
7233  if($namespace != '' && !isset($this->wsdl->namespaces[$namespace])){
7234  $nsPrefix = 'ns' . rand(1000, 9999);
7235  $this->wsdl->namespaces[$nsPrefix] = $namespace;
7236  }
7237  $nsPrefix = $this->wsdl->getPrefixFromNamespace($namespace);
7238  // serialize payload
7239  if (is_string($params)) {
7240  $this->debug("serializing param string for WSDL operation $operation");
7241  $payload = $params;
7242  } elseif (is_array($params)) {
7243  $this->debug("serializing param array for WSDL operation $operation");
7244  $payload = $this->wsdl->serializeRPCParameters($operation,'input',$params,$this->bindingType);
7245  } else {
7246  $this->debug('params must be array or string');
7247  $this->setError('params must be array or string');
7248  return false;
7249  }
7250  $usedNamespaces = $this->wsdl->usedNamespaces;
7251  if (isset($opData['input']['encodingStyle'])) {
7252  $encodingStyle = $opData['input']['encodingStyle'];
7253  } else {
7254  $encodingStyle = '';
7255  }
7256  $this->appendDebug($this->wsdl->getDebug());
7257  $this->wsdl->clearDebug();
7258  if ($errstr = $this->wsdl->getError()) {
7259  $this->debug('got wsdl error: '.$errstr);
7260  $this->setError('wsdl error: '.$errstr);
7261  return false;
7262  }
7263  } elseif($this->endpointType == 'wsdl') {
7264  // operation not in WSDL
7265  $this->appendDebug($this->wsdl->getDebug());
7266  $this->wsdl->clearDebug();
7267  $this->setError( 'operation '.$operation.' not present.');
7268  $this->debug("operation '$operation' not present.");
7269  return false;
7270  } else {
7271  // no WSDL
7272  //$this->namespaces['ns1'] = $namespace;
7273  $nsPrefix = 'ns' . rand(1000, 9999);
7274  // serialize
7275  $payload = '';
7276  if (is_string($params)) {
7277  $this->debug("serializing param string for operation $operation");
7278  $payload = $params;
7279  } elseif (is_array($params)) {
7280  $this->debug("serializing param array for operation $operation");
7281  foreach($params as $k => $v){
7282  $payload .= $this->serialize_val($v,$k,false,false,false,false,$use);
7283  }
7284  } else {
7285  $this->debug('params must be array or string');
7286  $this->setError('params must be array or string');
7287  return false;
7288  }
7289  $usedNamespaces = array();
7290  if ($use == 'encoded') {
7291  $encodingStyle = 'http://schemas.xmlsoap.org/soap/encoding/';
7292  } else {
7293  $encodingStyle = '';
7294  }
7295  }
7296  // wrap RPC calls with method element
7297  if ($style == 'rpc') {
7298  if ($use == 'literal') {
7299  $this->debug("wrapping RPC request with literal method element");
7300  if ($namespace) {
7301  // http://www.ws-i.org/Profiles/BasicProfile-1.1-2004-08-24.html R2735 says rpc/literal accessor elements should not be in a namespace
7302  $payload = "<$nsPrefix:$operation xmlns:$nsPrefix=\"$namespace\">" .
7303  $payload .
7304  "</$nsPrefix:$operation>";
7305  } else {
7306  $payload = "<$operation>" . $payload . "</$operation>";
7307  }
7308  } else {
7309  $this->debug("wrapping RPC request with encoded method element");
7310  if ($namespace) {
7311  $payload = "<$nsPrefix:$operation xmlns:$nsPrefix=\"$namespace\">" .
7312  $payload .
7313  "</$nsPrefix:$operation>";
7314  } else {
7315  $payload = "<$operation>" .
7316  $payload .
7317  "</$operation>";
7318  }
7319  }
7320  }
7321  // serialize envelope
7322  $soapmsg = $this->serializeEnvelope($payload,$this->requestHeaders,$usedNamespaces,$style,$use,$encodingStyle);
7323  $this->debug("endpoint=$this->endpoint, soapAction=$soapAction, namespace=$namespace, style=$style, use=$use, encodingStyle=$encodingStyle");
7324  $this->debug('SOAP message length=' . strlen($soapmsg) . ' contents (max 1000 bytes)=' . substr($soapmsg, 0, 1000));
7325  // send
7326  $return = $this->send($this->getHTTPBody($soapmsg),$soapAction,$this->timeout,$this->response_timeout);
7327  if($errstr = $this->getError()){
7328  $this->debug('Error: '.$errstr);
7329  return false;
7330  } else {
7331  $this->return = $return;
7332  $this->debug('sent message successfully and got a(n) '.gettype($return));
7333  $this->appendDebug('return=' . $this->varDump($return));
7334 
7335  // fault?
7336  if(is_array($return) && isset($return['faultcode'])){
7337  $this->debug('got fault');
7338  $this->setError($return['faultcode'].': '.$return['faultstring']);
7339  $this->fault = true;
7340  foreach($return as $k => $v){
7341  $this->$k = $v;
7342  $this->debug("$k = $v<br>");
7343  }
7344  return $return;
7345  } elseif ($style == 'document') {
7346  // NOTE: if the response is defined to have multiple parts (i.e. unwrapped),
7347  // we are only going to return the first part here...sorry about that
7348  return $return;
7349  } else {
7350  // array of return values
7351  if(is_array($return)){
7352  // multiple 'out' parameters, which we return wrapped up
7353  // in the array
7354  if(sizeof($return) > 1){
7355  return $return;
7356  }
7357  // single 'out' parameter (normally the return value)
7358  $return = array_shift($return);
7359  $this->debug('return shifted value: ');
7360  $this->appendDebug($this->varDump($return));
7361  return $return;
7362  // nothing returned (ie, echoVoid)
7363  } else {
7364  return "";
7365  }
7366  }
7367  }
7368  }
7369 
7375  function checkWSDL() {
7376  $this->appendDebug($this->wsdl->getDebug());
7377  $this->wsdl->clearDebug();
7378  $this->debug('checkWSDL');
7379  // catch errors
7380  if ($errstr = $this->wsdl->getError()) {
7381  $this->debug('got wsdl error: '.$errstr);
7382  $this->setError('wsdl error: '.$errstr);
7383  } elseif ($this->operations = $this->wsdl->getOperations('soap')) {
7384  $this->bindingType = 'soap';
7385  $this->debug('got '.count($this->operations).' operations from wsdl '.$this->wsdlFile.' for binding type '.$this->bindingType);
7386  } elseif ($this->operations = $this->wsdl->getOperations('soap12')) {
7387  $this->bindingType = 'soap12';
7388  $this->debug('got '.count($this->operations).' operations from wsdl '.$this->wsdlFile.' for binding type '.$this->bindingType);
7389  $this->debug('**************** WARNING: SOAP 1.2 BINDING *****************');
7390  } else {
7391  $this->debug('getOperations returned false');
7392  $this->setError('no operations defined in the WSDL document!');
7393  }
7394  }
7395 
7401  function loadWSDL() {
7402  $this->debug('instantiating wsdl class with doc: '.$this->wsdlFile);
7403  $this->wsdl = new wsdl('',$this->proxyhost,$this->proxyport,$this->proxyusername,$this->proxypassword,$this->timeout,$this->response_timeout,$this->curl_options,$this->use_curl);
7404  $this->wsdl->setCredentials($this->username, $this->password, $this->authtype, $this->certRequest);
7405  $this->wsdl->fetchWSDL($this->wsdlFile);
7406  $this->checkWSDL();
7407  }
7408 
7416  function getOperationData($operation){
7417  if ($this->endpointType == 'wsdl' && is_null($this->wsdl)) {
7418  $this->loadWSDL();
7419  if ($this->getError())
7420  return false;
7421  }
7422  if(isset($this->operations[$operation])){
7423  return $this->operations[$operation];
7424  }
7425  $this->debug("No data for operation: $operation");
7426  }
7427 
7442  function send($msg, $soapaction = '', $timeout=0, $response_timeout=30) {
7443  $this->checkCookies();
7444  // detect transport
7445  switch(true){
7446  // http(s)
7447  case preg_match('/^http/',$this->endpoint):
7448  $this->debug('transporting via HTTP');
7449  if($this->persistentConnection == true && is_object($this->persistentConnection)){
7450  $http =& $this->persistentConnection;
7451  } else {
7452  $http = new soap_transport_http($this->endpoint, $this->curl_options, $this->use_curl);
7453  if ($this->persistentConnection) {
7454  $http->usePersistentConnection();
7455  }
7456  }
7457  $http->setContentType($this->getHTTPContentType(), $this->getHTTPContentTypeCharset());
7458  $http->setSOAPAction($soapaction);
7459  if($this->proxyhost && $this->proxyport){
7460  $http->setProxy($this->proxyhost,$this->proxyport,$this->proxyusername,$this->proxypassword);
7461  }
7462  if($this->authtype != '') {
7463  $http->setCredentials($this->username, $this->password, $this->authtype, array(), $this->certRequest);
7464  }
7465  if($this->http_encoding != ''){
7466  $http->setEncoding($this->http_encoding);
7467  }
7468  $this->debug('sending message, length='.strlen($msg));
7469  if(preg_match('/^http:/',$this->endpoint)){
7470  //if(strpos($this->endpoint,'http:')){
7471  $this->responseData = $http->send($msg,$timeout,$response_timeout,$this->cookies);
7472  } elseif(preg_match('/^https/',$this->endpoint)){
7473  //} elseif(strpos($this->endpoint,'https:')){
7474  //if(phpversion() == '4.3.0-dev'){
7475  //$response = $http->send($msg,$timeout,$response_timeout);
7476  //$this->request = $http->outgoing_payload;
7477  //$this->response = $http->incoming_payload;
7478  //} else
7479  $this->responseData = $http->sendHTTPS($msg,$timeout,$response_timeout,$this->cookies);
7480  } else {
7481  $this->setError('no http/s in endpoint url');
7482  }
7483  $this->request = $http->outgoing_payload;
7484  $this->response = $http->incoming_payload;
7485  $this->appendDebug($http->getDebug());
7486  $this->UpdateCookies($http->incoming_cookies);
7487 
7488  // save transport object if using persistent connections
7489  if ($this->persistentConnection) {
7490  $http->clearDebug();
7491  if (!is_object($this->persistentConnection)) {
7492  $this->persistentConnection = $http;
7493  }
7494  }
7495 
7496  if($err = $http->getError()){
7497  $this->setError('HTTP Error: '.$err);
7498  return false;
7499  } elseif($this->getError()){
7500  return false;
7501  } else {
7502  $this->debug('got response, length='. strlen($this->responseData).' type='.$http->incoming_headers['content-type']);
7503  return $this->parseResponse($http->incoming_headers, $this->responseData);
7504  }
7505  break;
7506  default:
7507  $this->setError('no transport found, or selected transport is not yet supported!');
7508  return false;
7509  break;
7510  }
7511  }
7512 
7521  function parseResponse($headers, $data) {
7522  $this->debug('Entering parseResponse() for data of length ' . strlen($data) . ' headers:');
7523  $this->appendDebug($this->varDump($headers));
7524  if (!strstr($headers['content-type'], 'text/xml')) {
7525  $this->setError('Response not of type text/xml: ' . $headers['content-type']);
7526  return false;
7527  }
7528  if (strpos($headers['content-type'], '=')) {
7529  $enc = str_replace('"', '', substr(strstr($headers["content-type"], '='), 1));
7530  $this->debug('Got response encoding: ' . $enc);
7531  if(preg_match('/^(ISO-8859-1|US-ASCII|UTF-8)$/i',$enc)){
7532  $this->xml_encoding = strtoupper($enc);
7533  } else {
7534  $this->xml_encoding = 'US-ASCII';
7535  }
7536  } else {
7537  // should be US-ASCII for HTTP 1.0 or ISO-8859-1 for HTTP 1.1
7538  $this->xml_encoding = 'ISO-8859-1';
7539  }
7540  $this->debug('Use encoding: ' . $this->xml_encoding . ' when creating nusoap_parser');
7541  $parser = new nusoap_parser($data,$this->xml_encoding,$this->operation,$this->decode_utf8);
7542  // add parser debug data to our debug
7543  $this->appendDebug($parser->getDebug());
7544  // if parse errors
7545  if($errstr = $parser->getError()){
7546  $this->setError( $errstr);
7547  // destroy the parser object
7548  unset($parser);
7549  return false;
7550  } else {
7551  // get SOAP headers
7552  $this->responseHeaders = $parser->getHeaders();
7553  // get SOAP headers
7554  $this->responseHeader = $parser->get_soapheader();
7555  // get decoded message
7556  $return = $parser->get_soapbody();
7557  // add document for doclit support
7558  $this->document = $parser->document;
7559  // destroy the parser object
7560  unset($parser);
7561  // return decode message
7562  return $return;
7563  }
7564  }
7565 
7573  function setCurlOption($option, $value) {
7574  $this->debug("setCurlOption option=$option, value=");
7575  $this->appendDebug($this->varDump($value));
7576  $this->curl_options[$option] = $value;
7577  }
7578 
7585  function setEndpoint($endpoint) {
7586  $this->debug("setEndpoint(\"$endpoint\")");
7587  $this->forceEndpoint = $endpoint;
7588  }
7589 
7596  function setHeaders($headers){
7597  $this->debug("setHeaders headers=");
7598  $this->appendDebug($this->varDump($headers));
7599  $this->requestHeaders = $headers;
7600  }
7601 
7608  function getHeaders(){
7609  return $this->responseHeaders;
7610  }
7611 
7618  function getHeader(){
7619  return $this->responseHeader;
7620  }
7621 
7631  function setHTTPProxy($proxyhost, $proxyport, $proxyusername = '', $proxypassword = '') {
7632  $this->proxyhost = $proxyhost;
7633  $this->proxyport = $proxyport;
7634  $this->proxyusername = $proxyusername;
7635  $this->proxypassword = $proxypassword;
7636  }
7637 
7647  function setCredentials($username, $password, $authtype = 'basic', $certRequest = array()) {
7648  $this->debug("setCredentials username=$username authtype=$authtype certRequest=");
7649  $this->appendDebug($this->varDump($certRequest));
7650  $this->username = $username;
7651  $this->password = $password;
7652  $this->authtype = $authtype;
7653  $this->certRequest = $certRequest;
7654  }
7655 
7662  function setHTTPEncoding($enc='gzip, deflate'){
7663  $this->debug("setHTTPEncoding(\"$enc\")");
7664  $this->http_encoding = $enc;
7665  }
7666 
7673  function setUseCURL($use) {
7674  $this->debug("setUseCURL($use)");
7675  $this->use_curl = $use;
7676  }
7677 
7684  $this->debug("useHTTPPersistentConnection");
7685  $this->persistentConnection = true;
7686  }
7687 
7699  function getDefaultRpcParams() {
7700  return $this->defaultRpcParams;
7701  }
7702 
7714  function setDefaultRpcParams($rpcParams) {
7715  $this->defaultRpcParams = $rpcParams;
7716  }
7717 
7725  function getProxy() {
7726  $r = rand();
7727  $evalStr = $this->_getProxyClassCode($r);
7728  //$this->debug("proxy class: $evalStr");
7729  if ($this->getError()) {
7730  $this->debug("Error from _getProxyClassCode, so return NULL");
7731  return null;
7732  }
7733  // eval the class
7734  eval($evalStr);
7735  // instantiate proxy object
7736  eval("\$proxy = new nusoap_proxy_$r('');");
7737  // transfer current wsdl data to the proxy thereby avoiding parsing the wsdl twice
7738  $proxy->endpointType = 'wsdl';
7739  $proxy->wsdlFile = $this->wsdlFile;
7740  $proxy->wsdl = $this->wsdl;
7741  $proxy->operations = $this->operations;
7742  $proxy->defaultRpcParams = $this->defaultRpcParams;
7743  // transfer other state
7744  $proxy->soap_defencoding = $this->soap_defencoding;
7745  $proxy->username = $this->username;
7746  $proxy->password = $this->password;
7747  $proxy->authtype = $this->authtype;
7748  $proxy->certRequest = $this->certRequest;
7749  $proxy->requestHeaders = $this->requestHeaders;
7750  $proxy->endpoint = $this->endpoint;
7751  $proxy->forceEndpoint = $this->forceEndpoint;
7752  $proxy->proxyhost = $this->proxyhost;
7753  $proxy->proxyport = $this->proxyport;
7754  $proxy->proxyusername = $this->proxyusername;
7755  $proxy->proxypassword = $this->proxypassword;
7756  $proxy->http_encoding = $this->http_encoding;
7757  $proxy->timeout = $this->timeout;
7758  $proxy->response_timeout = $this->response_timeout;
7759  $proxy->persistentConnection = &$this->persistentConnection;
7760  $proxy->decode_utf8 = $this->decode_utf8;
7761  $proxy->curl_options = $this->curl_options;
7762  $proxy->bindingType = $this->bindingType;
7763  $proxy->use_curl = $this->use_curl;
7764  return $proxy;
7765  }
7766 
7774  $this->debug("in getProxy endpointType=$this->endpointType");
7775  $this->appendDebug("wsdl=" . $this->varDump($this->wsdl));
7776  if ($this->endpointType != 'wsdl') {
7777  $evalStr = 'A proxy can only be created for a WSDL client';
7778  $this->setError($evalStr);
7779  $evalStr = "echo \"$evalStr\";";
7780  return $evalStr;
7781  }
7782  if ($this->endpointType == 'wsdl' && is_null($this->wsdl)) {
7783  $this->loadWSDL();
7784  if ($this->getError()) {
7785  return "echo \"" . $this->getError() . "\";";
7786  }
7787  }
7788  $evalStr = '';
7789  foreach ($this->operations as $operation => $opData) {
7790  if ($operation != '') {
7791  // create param string and param comment string
7792  if (sizeof($opData['input']['parts']) > 0) {
7793  $paramStr = '';
7794  $paramArrayStr = '';
7795  $paramCommentStr = '';
7796  foreach ($opData['input']['parts'] as $name => $type) {
7797  $paramStr .= "\$$name, ";
7798  $paramArrayStr .= "'$name' => \$$name, ";
7799  $paramCommentStr .= "$type \$$name, ";
7800  }
7801  $paramStr = substr($paramStr, 0, strlen($paramStr)-2);
7802  $paramArrayStr = substr($paramArrayStr, 0, strlen($paramArrayStr)-2);
7803  $paramCommentStr = substr($paramCommentStr, 0, strlen($paramCommentStr)-2);
7804  } else {
7805  $paramStr = '';
7806  $paramArrayStr = '';
7807  $paramCommentStr = 'void';
7808  }
7809  $opData['namespace'] = !isset($opData['namespace']) ? 'http://testuri.com' : $opData['namespace'];
7810  $evalStr .= "// $paramCommentStr
7811  function " . str_replace('.', '__', $operation) . "($paramStr) {
7812  \$params = array($paramArrayStr);
7813  return \$this->call('$operation', \$params, '".$opData['namespace']."', '".(isset($opData['soapAction']) ? $opData['soapAction'] : '')."');
7814  }
7815  ";
7816  unset($paramStr);
7817  unset($paramCommentStr);
7818  }
7819  }
7820  $evalStr = 'class nusoap_proxy_'.$r.' extends nusoap_client {
7821  '.$evalStr.'
7822 }';
7823  return $evalStr;
7824  }
7825 
7832  function getProxyClassCode() {
7833  $r = rand();
7834  return $this->_getProxyClassCode($r);
7835  }
7836 
7844  function getHTTPBody($soapmsg) {
7845  return $soapmsg;
7846  }
7847 
7856  function getHTTPContentType() {
7857  return 'text/xml';
7858  }
7859 
7870  return $this->soap_defencoding;
7871  }
7872 
7873  /*
7874  * whether or not parser should decode utf8 element content
7875  *
7876  * @return always returns true
7877  * @access public
7878  */
7879  function decodeUTF8($bool){
7880  $this->decode_utf8 = $bool;
7881  return true;
7882  }
7883 
7892  function setCookie($name, $value) {
7893  if (strlen($name) == 0) {
7894  return false;
7895  }
7896  $this->cookies[] = array('name' => $name, 'value' => $value);
7897  return true;
7898  }
7899 
7906  function getCookies() {
7907  return $this->cookies;
7908  }
7909 
7916  function checkCookies() {
7917  if (sizeof($this->cookies) == 0) {
7918  return true;
7919  }
7920  $this->debug('checkCookie: check ' . sizeof($this->cookies) . ' cookies');
7921  $curr_cookies = $this->cookies;
7922  $this->cookies = array();
7923  foreach ($curr_cookies as $cookie) {
7924  if (! is_array($cookie)) {
7925  $this->debug('Remove cookie that is not an array');
7926  continue;
7927  }
7928  if ((isset($cookie['expires'])) && (! empty($cookie['expires']))) {
7929  if (strtotime($cookie['expires']) > time()) {
7930  $this->cookies[] = $cookie;
7931  } else {
7932  $this->debug('Remove expired cookie ' . $cookie['name']);
7933  }
7934  } else {
7935  $this->cookies[] = $cookie;
7936  }
7937  }
7938  $this->debug('checkCookie: '.sizeof($this->cookies).' cookies left in array');
7939  return true;
7940  }
7941 
7949  function UpdateCookies($cookies) {
7950  if (sizeof($this->cookies) == 0) {
7951  // no existing cookies: take whatever is new
7952  if (sizeof($cookies) > 0) {
7953  $this->debug('Setting new cookie(s)');
7954  $this->cookies = $cookies;
7955  }
7956  return true;
7957  }
7958  if (sizeof($cookies) == 0) {
7959  // no new cookies: keep what we've got
7960  return true;
7961  }
7962  // merge
7963  foreach ($cookies as $newCookie) {
7964  if (!is_array($newCookie)) {
7965  continue;
7966  }
7967  if ((!isset($newCookie['name'])) || (!isset($newCookie['value']))) {
7968  continue;
7969  }
7970  $newName = $newCookie['name'];
7971 
7972  $found = false;
7973  for ($i = 0; $i < count($this->cookies); $i++) {
7974  $cookie = $this->cookies[$i];
7975  if (!is_array($cookie)) {
7976  continue;
7977  }
7978  if (!isset($cookie['name'])) {
7979  continue;
7980  }
7981  if ($newName != $cookie['name']) {
7982  continue;
7983  }
7984  $newDomain = isset($newCookie['domain']) ? $newCookie['domain'] : 'NODOMAIN';
7985  $domain = isset($cookie['domain']) ? $cookie['domain'] : 'NODOMAIN';
7986  if ($newDomain != $domain) {
7987  continue;
7988  }
7989  $newPath = isset($newCookie['path']) ? $newCookie['path'] : 'NOPATH';
7990  $path = isset($cookie['path']) ? $cookie['path'] : 'NOPATH';
7991  if ($newPath != $path) {
7992  continue;
7993  }
7994  $this->cookies[$i] = $newCookie;
7995  $found = true;
7996  $this->debug('Update cookie ' . $newName . '=' . $newCookie['value']);
7997  break;
7998  }
7999  if (! $found) {
8000  $this->debug('Add cookie ' . $newName . '=' . $newCookie['value']);
8001  $this->cookies[] = $newCookie;
8002  }
8003  }
8004  return true;
8005  }
8006 }
8007 
8008 if (!extension_loaded('soap')) {
8012  class soapclient extends nusoap_client {
8013  }
8014 }
8015 ?>
timestamp_to_iso8601($timestamp, $utc=true)
convert unix timestamp to ISO 8601 compliant date string
Definition: nusoap.php:586
serialize($use='encoded')
return serialized value
Definition: nusoap.php:2101
$params
Definition: disable.php:11
connect($connection_timeout=0, $response_timeout=30)
establish an HTTP connection
Definition: nusoap.php:2293
if($err=$client->getError()) $namespace
addSimpleType($name, $restrictionBase='', $typeClass='simpleType', $phpType='scalar', $enumeration=array())
adds an XML Schema simple type to the WSDL types
Definition: nusoap.php:6296
appendDebug($string)
adds debug data to the instance debug string without formatting
Definition: nusoap.php:294
soap_server allows the user to create a SOAP server that is capable of receiving messages and returni...
Definition: nusoap.php:2313
setDebugLevel($level)
sets the debug level for this instance
Definition: nusoap.php:272
setHeader($name, $value)
sets an HTTP header
Definition: nusoap.php:2209
setCredentials($username, $password, $authtype='basic', $digestRequest=array(), $certRequest=array())
if authenticating, set user credentials here
Definition: nusoap.php:2584
setDefaultRpcParams($rpcParams)
sets the default RPC parameter setting.
Definition: nusoap.php:7714
& getDebugAsXMLComment()
gets the current debug data for this instance as an XML comment this may change the contents of the d...
Definition: nusoap.php:332
serializeEnvelope($body, $headers=false, $namespaces=array(), $style='rpc', $use='encoded')
serialize message
Definition: nusoap.php:417
getmicrotime()
returns the time in ODBC canonical form with microseconds
Definition: nusoap.php:861
setError($str)
sets error string
Definition: nusoap.php:378
if(isset($_REQUEST['delete'])) $list
Definition: registry.php:41
parseString($xml, $type)
parse an XML string
Definition: nusoap.php:1190
getTypeDef($type, $ns)
returns an array of information about a given type returns false if no type exists by the given name ...
Definition: nusoap.php:5182
decodeChunked($buffer, $lb)
decode a string that is encoded w/ "chunked&#39; transfer encoding as defined in RFC2068 19...
Definition: nusoap.php:2747
$style
Definition: example_012.php:70
Contains information for a SOAP fault.
Definition: nusoap.php:1004
decodeSimple($value, $type, $typens)
decodes simple types into PHP variables
Definition: nusoap.php:6882
end_element($parser, $name)
end-element handler
Definition: nusoap.php:6709
__construct($url, $curl_options=NULL, $use_curl=false)
constructor
Definition: nusoap.php:2176
if((!isset($_SERVER['DOCUMENT_ROOT'])) OR(empty($_SERVER['DOCUMENT_ROOT']))) $_SERVER['DOCUMENT_ROOT']
getHTTPBody($soapmsg)
gets the HTTP body for the current response.
Definition: nusoap.php:4276
transport class for sending/receiving data via HTTP and HTTPS NOTE: PHP must be compiled with the CUR...
Definition: nusoap.php:1552
& getDebug()
gets the current debug data for this instance
Definition: nusoap.php:319
__construct($schema='', $xml='', $namespaces=array())
constructor
Definition: nusoap.php:1131
decodeUTF8($bool)
Definition: nusoap.php:7879
start_element($parser, $name, $attrs)
start-element handler
Definition: nusoap.php:6554
addComplexType($name, $typeClass='complexType', $phpType='array', $compositor='', $restrictionBase='', $elements=array(), $attrs=array(), $arrayType='')
adds an XML Schema complex type to the WSDL types
Definition: nusoap.php:6249
$result
getDebugLevel()
gets the debug level for this instance
Definition: nusoap.php:262
addSimpleType($name, $restrictionBase='', $typeClass='simpleType', $phpType='scalar', $enumeration=array())
adds a simple type to the schema
Definition: nusoap.php:1976
isArraySimpleOrStruct($val)
detect if array is a simple array or a struct (associative array)
Definition: nusoap.php:389
getProxyClassCode()
dynamically creates proxy class code
Definition: nusoap.php:7832
configureWSDL($serviceName, $namespace=false, $endpoint=false, $style='rpc', $transport='http://schemas.xmlsoap.org/soap/http', $schemaTargetNamespace=false)
Sets up wsdl object.
Definition: nusoap.php:4420
parses a WSDL file, allows access to it&#39;s data, other utility methods
Definition: nusoap.php:3133
get_soapbody()
get the parsed SOAP Body (NULL if there was none)
Definition: nusoap.php:6849
$type
character_data($parser, $data)
element content handler
Definition: nusoap.php:5038
setProxy($proxyhost, $proxyport, $proxyusername='', $proxypassword='', $proxyauthtype='basic')
set proxy info here
Definition: nusoap.php:2692
setEncoding($enc='gzip, deflate')
use http encoding
Definition: nusoap.php:2668
typeToForm($name, $type)
returns HTML form elements that allow a user to enter values for creating an instance of the given ty...
Definition: nusoap.php:1876
$_GET["client_id"]
parseFile($xml, $type)
parse an XML file
Definition: nusoap.php:1164
getCookies()
gets all Cookies
Definition: nusoap.php:7906
addComplexType($name, $typeClass='complexType', $phpType='array', $compositor='', $restrictionBase='', $elements=array(), $attrs=array(), $arrayType='')
adds a complex type to the schema
Definition: nusoap.php:1948
$h
parseWSDL($wsdl='')
parses the wsdl document
Definition: nusoap.php:4691
buildVal($pos)
builds response structures for compound values (arrays/structs) and scalars
Definition: nusoap.php:6926
$endpoint
getOperationDataForSoapAction($soapAction, $bindingType='soap')
returns an associative array of data necessary for calling an operation
Definition: nusoap.php:5144
setCookie($name, $value)
adds a new Cookie into $this->cookies array
Definition: nusoap.php:7892
getGlobalDebugLevel()
gets the global debug level, which applies to future instances
Definition: nusoap.php:242
useHTTPPersistentConnection()
use HTTP persistent connections if possible
Definition: nusoap.php:7683
parseResponse($headers, $data)
processes SOAP message returned from server
Definition: nusoap.php:7521
send_response()
sends an HTTP response
Definition: nusoap.php:4127
checkWSDL()
check WSDL passed as an instance or pulled from an endpoint
Definition: nusoap.php:7375
$GLOBALS['loaded']
Global hash that tracks already loaded includes.
$XMLSchemaVersion
Definition: nusoap.php:78
soap_fault class, allows for creation of faults mainly used for returning faults from deployed functi...
Definition: nusoap.php:669
if(!array_key_exists('StateId', $_REQUEST)) $id
nusoap_server allows the user to create a SOAP server that is capable of receiving messages and retur...
Definition: nusoap.php:3434
send($msg, $soapaction='', $timeout=0, $response_timeout=30)
send the SOAP message
Definition: nusoap.php:7442
serialize()
serialize the parsed wsdl
Definition: nusoap.php:3741
addOperation($name, $in=false, $out=false, $namespace=false, $soapaction=false, $style='rpc', $use='encoded', $documentation='')
register a service with the server
Definition: nusoap.php:4362
$attributes
sendHTTPS($data, $timeout=0, $response_timeout=30, $cookies)
sends the SOAP request and gets the SOAP response via HTTPS using CURL
Definition: nusoap.php:2570
parse_request($data='')
parses a request
Definition: nusoap.php:3842
getDefaultRpcParams()
gets the default RPC parameter setting.
Definition: nusoap.php:7699
buildPayload($data, $cookie_str='')
Writes the payload, including HTTP headers, to $this->outgoing_payload.
Definition: nusoap.php:2804
usleepWindows($usec)
Definition: nusoap.php:644
sendRequest($data, $cookies=NULL)
sends the SOAP request via HTTP[S]
Definition: nusoap.php:2851
serializeComplexTypeElements($typeDef, $value, $ns, $uqType, $use='encoded', $encodingStyle=false)
serializes the elements for a complexType
Definition: nusoap.php:6147
getLocalPart($str)
returns the local part of a prefixed string returns the original string, if not prefixed ...
Definition: nusoap.php:797
fault($faultcode, $faultstring, $faultactor='', $faultdetail='')
Specify a fault to be returned to the client.
Definition: nusoap.php:4401
get_response()
get the parsed message (SOAP Body)
Definition: nusoap.php:6839
getTypeDef($type)
returns an associative array of information about a given type returns false if no type exists by the...
Definition: nusoap.php:1764
setContentType($type, $charset=false)
sets the content-type for the SOAP message to be sent
Definition: nusoap.php:3286
serialize_return()
serializes the return value from a PHP function into a full SOAP Envelope
Definition: nusoap.php:4035
serialize($debug=0)
serialize the parsed wsdl
Definition: nusoap.php:5371
__construct($wsdl=false)
constructor the optional parameter is a path to a WSDL file that you&#39;d like to bind the server insta...
Definition: nusoap.php:3591
setURL($url)
sets the URL to which to connect
Definition: nusoap.php:2233
$req
Definition: getUserInfo.php:20
schemaStartElement($parser, $name, $attrs)
start-element handler
Definition: nusoap.php:1253
__construct()
constructor
Definition: nusoap.php:232
decode()
decodes a soapval object into a PHP native type
Definition: nusoap.php:2111
end_element($parser, $name)
end-element handler
Definition: nusoap.php:5008
parses an XML Schema, allows access to it&#39;s data, other utility methods no validation...
Definition: nusoap.php:734
getHTTPContentTypeCharset()
gets the HTTP content type charset for the current request.
Definition: nusoap.php:7869
xdebug($string)
adds debug data to the clas level debug string
Definition: nusoap.php:1715
for creating serializable abstractions of native PHP types NOTE: this is only really used when WSDL i...
Definition: nusoap.php:1495
addElement($attrs)
adds an element to the WSDL types
Definition: nusoap.php:6310
__construct($endpoint, $wsdl=false, $proxyhost=false, $proxyport=false, $proxyusername=false, $proxypassword=false, $timeout=0, $response_timeout=30)
constructor
Definition: nusoap.php:7135
getError()
returns error string if present
Definition: nusoap.php:365
$bindings
debug($string)
adds debug data to the instance debug string with formatting
Definition: nusoap.php:282
$element_ns
Definition: nusoap.php:2057
iso8601_to_timestamp($datestr)
convert ISO 8601 compliant date string to unix timestamp
Definition: nusoap.php:614
setHeaders($headers)
set the SOAP headers
Definition: nusoap.php:7596
setCurlOption($option, $value)
sets a cURL option
Definition: nusoap.php:2196
addElement($attrs)
adds an element to the schema
Definition: nusoap.php:1996
__construct($xml, $encoding='UTF-8', $method='', $decode_utf8=true)
constructor that actually does the parsing
Definition: nusoap.php:6462
getPHPType($type, $ns)
get the PHP type of a user defined type in the schema PHP type is kind of a misnomer since it actuall...
Definition: nusoap.php:1731
$password
Definition: pwgen.php:17
add_to_map($methodname, $in, $out)
add a method to the dispatch map (this has been replaced by the register method)
Definition: nusoap.php:4314
$xml
Definition: metadata.php:240
soap_parser class parses SOAP XML messages into native PHP values
Definition: nusoap.php:4431
setEndpoint($endpoint)
sets the SOAP endpoint, which can override WSDL
Definition: nusoap.php:7585
invoke_method()
invokes a PHP function for the requested SOAP method
Definition: nusoap.php:3889
if($format !==null) $name
Definition: metadata.php:146
serializeParameters($operation, $direction, $parameters)
serialize a PHP value according to a WSDL message definition
Definition: nusoap.php:5702
checkCookies()
checks all Cookies and delete those which are expired
Definition: nusoap.php:7916
setHTTPProxy($proxyhost, $proxyport, $proxyusername='', $proxypassword='')
set proxy info here
Definition: nusoap.php:7631
$r
Definition: example_031.php:79
catch(Exception $e) $message
__toString()
represents the object as a string
Definition: nusoap.php:894
serializeRPCParameters($operation, $direction, $parameters, $bindingType='soap')
serialize PHP values according to a WSDL message definition contrary to the method name...
Definition: nusoap.php:5608
foreach($_POST as $key=> $value) $res
getPrefixFromNamespace($ns)
returns the prefix for a given namespace (or prefix) or false if no prefixes registered for the given...
Definition: nusoap.php:557
getHTTPContentType()
gets the HTTP content type for the current response.
Definition: nusoap.php:4288
getHTTPContentType()
gets the HTTP content type for the current request.
Definition: nusoap.php:7856
setGlobalDebugLevel($level)
sets the global debug level, which applies to future instances
Definition: nusoap.php:252
expandQname($qname)
expands (changes prefix to namespace) a qualified name
Definition: nusoap.php:772
parses an XML Schema, allows access to it&#39;s data, other utility methods.
Definition: nusoap.php:1092
setCredentials($username, $password, $authtype='basic', $certRequest=array())
if authenticating, set user credentials here
Definition: nusoap.php:5058
setSOAPAction($soapaction)
set the soapaction value
Definition: nusoap.php:2658
verify_method($operation, $request)
takes the value that was created by parsing the request and compares to the method&#39;s signature...
Definition: nusoap.php:4206
nusoap_base
Definition: nusoap.php:61
_getProxyClassCode($r)
dynamically creates proxy class code
Definition: nusoap.php:7773
getHeaders()
get the SOAP response headers (namespace resolution incomplete)
Definition: nusoap.php:7608
webDescription()
prints html description of services
Definition: nusoap.php:5238
parseRequest($headers, $data)
processes SOAP message received from client
Definition: nusoap.php:4225
date( 'd-M-Y', $objPHPExcel->getProperties() ->getCreated())
isSkippableCurlHeader(&$data)
Test if the given string starts with a header that is to be skipped.
Definition: nusoap.php:2720
getCookiesForRequest($cookies, $secure=false)
sort out cookies for the current request
Definition: nusoap.php:3380
[nu]soapclient higher level class for easy usage.
Definition: nusoap.php:7064
__construct($wsdl='', $proxyhost=false, $proxyport=false, $proxyusername=false, $proxypassword=false, $timeout=0, $response_timeout=30, $curl_options=null, $use_curl=false)
constructor
Definition: nusoap.php:4568
serialize_val($val, $name=false, $type=false, $name_ns=false, $type_ns=false, $attributes=false, $use='encoded')
serializes PHP values in accordance w/ section 5.
Definition: nusoap.php:212
Reload workbook from saved file
wsdl($wsdl='', $proxyhost=false, $proxyport=false, $proxyusername=false, $proxypassword=false, $timeout=0, $response_timeout=30)
constructor
Definition: nusoap.php:3181
__construct($faultcode, $faultactor='', $faultstring='', $faultdetail='')
constructor
Definition: nusoap.php:1038
serializeEnvelope($body, $headers=false, $namespaces=array(), $style='rpc', $use='encoded', $encodingStyle='http://schemas.xmlsoap.org/soap/encoding/')
serializes a message
Definition: nusoap.php:680
serializeType($name, $type, $value, $use='encoded', $encodingStyle=false, $unqualified=false)
serializes a PHP value according a given type definition
Definition: nusoap.php:5781
Add a drawing to the header
Definition: 04printing.php:69
getHeader()
get the SOAP response Header (parsed)
Definition: nusoap.php:7618
getOperationData($operation)
get available data pertaining to an operation
Definition: nusoap.php:7416
$n
Definition: RandomTest.php:85
getHTTPBody($soapmsg)
gets the HTTP body for the current request.
Definition: nusoap.php:7844
$http
Definition: raiseError.php:7
setHTTPEncoding($enc='gzip, deflate')
use HTTP encoding
Definition: nusoap.php:7662
start_element($parser, $name, $attrs)
start-element handler
Definition: nusoap.php:4795
Create styles array
The data for the language used.
varDump($data)
Definition: nusoap.php:567
getResponse()
gets the SOAP response via HTTP[S]
Definition: nusoap.php:2908
getHeaders()
get the unparsed SOAP Header
Definition: nusoap.php:6869
getPrefix($str)
returns the prefix part of a prefixed string returns false, if not prefixed
Definition: nusoap.php:814
parse_http_headers()
parses HTTP request headers.
Definition: nusoap.php:3716
getOperations($bindingType='soap')
returns an assoc array of operation names => operation data
Definition: nusoap.php:5081
if(php_sapi_name() !='cli') $in
Definition: Utf8Test.php:37
$rows
Definition: xhr_table.php:10
contractQname($qname)
contracts (changes namespace to prefix) a qualified name
Definition: nusoap.php:747
schemaCharacterData($parser, $data)
element content handler
Definition: nusoap.php:1587
setUseCURL($use)
Set whether to try to use cURL connections if possible.
Definition: nusoap.php:7673
foreach($mandatory_scripts as $file) $timestamp
Definition: buildRTE.php:81
$debug
Definition: loganalyzer.php:16
character_data($parser, $data)
element content handler
Definition: nusoap.php:6813
formatDump($str)
formats a string to be inserted into an HTML stream
Definition: nusoap.php:735
$attributes
Definition: nusoap.php:2071
serialize()
serialize a fault
Definition: nusoap.php:1052
send($data, $timeout=0, $response_timeout=30, $cookies=NULL)
sends the SOAP request and gets the SOAP response via HTTP[S]
Definition: nusoap.php:2529
$parser
Definition: BPMN2Parser.php:23
$messages
Definition: en-x-test.php:7
unsetHeader($name)
unsets an HTTP header
Definition: nusoap.php:2220
$soap_defencoding
Definition: nusoap.php:86
CreateTypeName($ename)
gets a type name for an unnamed type
Definition: nusoap.php:1237
usePersistentConnection()
specifies that an HTTP persistent connection should be used
Definition: nusoap.php:3296
expandEntities($val)
expands entities, e.g.
Definition: nusoap.php:348
serializeRPCParameters($operation, $direction, $parameters)
serialize a PHP value according to a WSDL message definition
Definition: nusoap.php:3870
parseCookie($cookie_str)
parse an incoming Cookie into it&#39;s parts
Definition: nusoap.php:3316
$ret
Definition: parser.php:6
schemaEndElement($parser, $name)
end-element handler
Definition: nusoap.php:1550
serializeComplexTypeAttributes($typeDef, $value, $ns, $uqType)
serializes the attributes for a complexType
Definition: nusoap.php:6085
$i
Definition: disco.tpl.php:19
__construct($name='soapval', $type=false, $value=-1, $element_ns=false, $type_ns=false, $attributes=false)
constructor
Definition: nusoap.php:2084
parse_request($message)
Parses a request message string into a request object.
Definition: functions.php:463
getNamespaceFromPrefix($prefix)
pass it a prefix, it returns a namespace
Definition: nusoap.php:829
nusoap_parser class parses SOAP XML messages into native PHP values
Definition: nusoap.php:6417
setCredentials($username, $password, $authtype='basic', $certRequest=array())
if authenticating, set user credentials here
Definition: nusoap.php:7647
serializeSchema()
serialize the schema
Definition: nusoap.php:1597
addOperation($name, $in=false, $out=false, $namespace=false, $soapaction=false, $style='rpc', $use='encoded', $documentation='', $encodingStyle='')
register an operation with the server
Definition: nusoap.php:6329
getOperationData($operation, $bindingType='soap')
returns an associative array of data necessary for calling an operation
Definition: nusoap.php:3679
$url
serializeTypeDef($type)
returns a sample serialization of a given type, or false if no type by the given name ...
Definition: nusoap.php:1840
Add data(end) time
Method that wraps PHPs time in order to allow simulations with the workflow.
get_soapheader()
get the parsed SOAP Header (NULL if there was none)
Definition: nusoap.php:6859
io_method()
gets the I/O method to use
Definition: nusoap.php:2277
loadWSDL()
instantiate wsdl object and parse wsdl file
Definition: nusoap.php:7401
if(!array_key_exists('domain', $_REQUEST)) $domain
Definition: resume.php:8
getProxy()
dynamically creates an instance of a proxy class, allowing user to directly call methods from wsdl ...
Definition: nusoap.php:7725
defined( 'APPLICATION_ENV')||define( 'APPLICATION_ENV'
Definition: bootstrap.php:27
call($operation, $params=array(), $namespace='http://tempuri.org', $soapAction='', $headers=false, $rpcParams=null, $style='rpc', $use='encoded')
calls method, returns PHP native type
Definition: nusoap.php:7193
getHTTPContentTypeCharset()
gets the HTTP content type charset for the current response.
Definition: nusoap.php:4301
clearDebug()
clears the current debug data for this instance
Definition: nusoap.php:307
UpdateCookies($cookies)
updates the current cookies with a new set
Definition: nusoap.php:7949
$response
getBindingData($binding)
Definition: nusoap.php:5067
setCurlOption($option, $value)
sets user-specified cURL options
Definition: nusoap.php:7573
$binding
$key
Definition: croninfo.php:18
fetchWSDL($wsdl)
fetches the WSDL document and parses it
Definition: nusoap.php:4588
$cols
Definition: xhr_table.php:11
parametersMatchWrapped($type, &$parameters)
determine whether a set of parameters are unwrapped when they are expect to be wrapped, Microsoft-style.
Definition: nusoap.php:5515
serialize_val($val, $name=false, $type=false, $name_ns=false, $type_ns=false, $attributes=false, $use='encoded', $soapval=false)
serializes PHP values in accordance w/ section 5.
Definition: nusoap.php:414
service($data)
processes request and returns response
Definition: nusoap.php:3654