1: <?php
2:
3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31: 32: 33: 34: 35: 36: 37: 38:
39:
40: 41: 42: 43: 44: 45: 46: 47: 48: 49: 50: 51: 52:
53:
54: 55: 56: 57: 58: 59: 60: 61: 62: 63: 64: 65: 66: 67: 68: 69: 70:
71:
72:
73:
74: $GLOBALS['_transient']['static']['nusoap_base']['globalDebugLevel'] = 9;
75:
76: 77: 78: 79: 80: 81: 82: 83: 84:
85: class nusoap_base {
86: 87: 88: 89: 90: 91:
92: var $title = 'NuSOAP';
93: 94: 95: 96: 97: 98:
99: var $version = '0.9.5';
100: 101: 102: 103: 104: 105:
106: var $revision = '$Revision: 1.123 $';
107: 108: 109: 110: 111: 112:
113: var $error_str = '';
114: 115: 116: 117: 118: 119:
120: var $debug_str = '';
121: 122: 123: 124: 125: 126: 127:
128: var $charencoding = true;
129: 130: 131: 132: 133: 134:
135: var $debugLevel;
136:
137: 138: 139: 140: 141: 142:
143: var $XMLSchemaVersion = 'http://www.w3.org/2001/XMLSchema';
144:
145: 146: 147: 148: 149: 150:
151: var $soap_defencoding = 'ISO-8859-1';
152:
153:
154: 155: 156: 157: 158: 159: 160: 161:
162: var $namespaces = array(
163: 'SOAP-ENV' => 'http://schemas.xmlsoap.org/soap/envelope/',
164: 'xsd' => 'http://www.w3.org/2001/XMLSchema',
165: 'xsi' => 'http://www.w3.org/2001/XMLSchema-instance',
166: 'SOAP-ENC' => 'http://schemas.xmlsoap.org/soap/encoding/'
167: );
168:
169: 170: 171: 172: 173: 174:
175: var $usedNamespaces = array();
176:
177: 178: 179: 180: 181: 182: 183:
184: var $typemap = array(
185: 'http://www.w3.org/2001/XMLSchema' => array(
186: 'string'=>'string','boolean'=>'boolean','float'=>'double','double'=>'double','decimal'=>'double',
187: 'duration'=>'','dateTime'=>'string','time'=>'string','date'=>'string','gYearMonth'=>'',
188: 'gYear'=>'','gMonthDay'=>'','gDay'=>'','gMonth'=>'','hexBinary'=>'string','base64Binary'=>'string',
189:
190: 'anyType'=>'string','anySimpleType'=>'string',
191:
192: 'normalizedString'=>'string','token'=>'string','language'=>'','NMTOKEN'=>'','NMTOKENS'=>'','Name'=>'','NCName'=>'','ID'=>'',
193: 'IDREF'=>'','IDREFS'=>'','ENTITY'=>'','ENTITIES'=>'','integer'=>'integer','nonPositiveInteger'=>'integer',
194: 'negativeInteger'=>'integer','long'=>'integer','int'=>'integer','short'=>'integer','byte'=>'integer','nonNegativeInteger'=>'integer',
195: 'unsignedLong'=>'','unsignedInt'=>'','unsignedShort'=>'','unsignedByte'=>'','positiveInteger'=>''),
196: 'http://www.w3.org/2000/10/XMLSchema' => array(
197: 'i4'=>'','int'=>'integer','boolean'=>'boolean','string'=>'string','double'=>'double',
198: 'float'=>'double','dateTime'=>'string',
199: 'timeInstant'=>'string','base64Binary'=>'string','base64'=>'string','ur-type'=>'array'),
200: 'http://www.w3.org/1999/XMLSchema' => array(
201: 'i4'=>'','int'=>'integer','boolean'=>'boolean','string'=>'string','double'=>'double',
202: 'float'=>'double','dateTime'=>'string',
203: 'timeInstant'=>'string','base64Binary'=>'string','base64'=>'string','ur-type'=>'array'),
204: 'http://soapinterop.org/xsd' => array('SOAPStruct'=>'struct'),
205: 'http://schemas.xmlsoap.org/soap/encoding/' => array('base64'=>'string','array'=>'array','Array'=>'array'),
206: 'http://xml.apache.org/xml-soap' => array('Map')
207: );
208:
209: 210: 211: 212: 213: 214: 215: 216:
217: var $xmlEntities = array('quot' => '"','amp' => '&',
218: 'lt' => '<','gt' => '>','apos' => "'");
219:
220: 221: 222: 223: 224:
225: function nusoap_base() {
226: $this->debugLevel = $GLOBALS['_transient']['static']['nusoap_base']['globalDebugLevel'];
227: }
228:
229: 230: 231: 232: 233: 234:
235: function getGlobalDebugLevel() {
236: return $GLOBALS['_transient']['static']['nusoap_base']['globalDebugLevel'];
237: }
238:
239: 240: 241: 242: 243: 244:
245: function setGlobalDebugLevel($level) {
246: $GLOBALS['_transient']['static']['nusoap_base']['globalDebugLevel'] = $level;
247: }
248:
249: 250: 251: 252: 253: 254:
255: function getDebugLevel() {
256: return $this->debugLevel;
257: }
258:
259: 260: 261: 262: 263: 264:
265: function setDebugLevel($level) {
266: $this->debugLevel = $level;
267: }
268:
269: 270: 271: 272: 273: 274:
275: function debug($string){
276: if ($this->debugLevel > 0) {
277: $this->appendDebug($this->getmicrotime().' '.get_class($this).": $string\n");
278: }
279: }
280:
281: 282: 283: 284: 285: 286:
287: function appendDebug($string){
288: if ($this->debugLevel > 0) {
289:
290:
291: $this->debug_str .= $string;
292: }
293: }
294:
295: 296: 297: 298: 299:
300: function clearDebug() {
301:
302:
303: $this->debug_str = '';
304: }
305:
306: 307: 308: 309: 310: 311:
312: function &getDebug() {
313:
314:
315: return $this->debug_str;
316: }
317:
318: 319: 320: 321: 322: 323: 324:
325: function &getDebugAsXMLComment() {
326:
327:
328: while (strpos($this->debug_str, '--')) {
329: $this->debug_str = str_replace('--', '- -', $this->debug_str);
330: }
331: $ret = "<!--\n" . $this->debug_str . "\n-->";
332: return $ret;
333: }
334:
335: 336: 337: 338: 339: 340:
341: function expandEntities($val) {
342: if ($this->charencoding) {
343: $val = str_replace('&', '&', $val);
344: $val = str_replace("'", ''', $val);
345: $val = str_replace('"', '"', $val);
346: $val = str_replace('<', '<', $val);
347: $val = str_replace('>', '>', $val);
348: }
349: return $val;
350: }
351:
352: 353: 354: 355: 356: 357:
358: function getError(){
359: if($this->error_str != ''){
360: return $this->error_str;
361: }
362: return false;
363: }
364:
365: 366: 367: 368: 369: 370:
371: function setError($str){
372: $this->error_str = $str;
373: }
374:
375: 376: 377: 378: 379: 380: 381:
382: function isArraySimpleOrStruct($val) {
383: $keyList = array_keys($val);
384: foreach ($keyList as $keyListValue) {
385: if (!is_int($keyListValue)) {
386: return 'arrayStruct';
387: }
388: }
389: return 'arraySimple';
390: }
391:
392: 393: 394: 395: 396: 397: 398: 399: 400: 401: 402: 403: 404: 405: 406:
407: function serialize_val($val,$name=false,$type=false,$name_ns=false,$type_ns=false,$attributes=false,$use='encoded',$soapval=false) {
408: $this->debug("in serialize_val: name=$name, type=$type, name_ns=$name_ns, type_ns=$type_ns, use=$use, soapval=$soapval");
409: $this->appendDebug('value=' . $this->varDump($val));
410: $this->appendDebug('attributes=' . $this->varDump($attributes));
411:
412: if (is_object($val) && get_class($val) == 'soapval' && (! $soapval)) {
413: $this->debug("serialize_val: serialize soapval");
414: $xml = $val->serialize($use);
415: $this->appendDebug($val->getDebug());
416: $val->clearDebug();
417: $this->debug("serialize_val of soapval returning $xml");
418: return $xml;
419: }
420:
421: if (is_numeric($name)) {
422: $name = '__numeric_' . $name;
423: } elseif (! $name) {
424: $name = 'noname';
425: }
426:
427: $xmlns = '';
428: if($name_ns){
429: $prefix = 'nu'.rand(1000,9999);
430: $name = $prefix.':'.$name;
431: $xmlns .= " xmlns:$prefix=\"$name_ns\"";
432: }
433:
434: if($type_ns != '' && $type_ns == $this->namespaces['xsd']){
435:
436:
437: $type_prefix = 'xsd';
438: } elseif($type_ns){
439: $type_prefix = 'ns'.rand(1000,9999);
440: $xmlns .= " xmlns:$type_prefix=\"$type_ns\"";
441: }
442:
443: $atts = '';
444: if($attributes){
445: foreach($attributes as $k => $v){
446: $atts .= " $k=\"".$this->expandEntities($v).'"';
447: }
448: }
449:
450: if (is_null($val)) {
451: $this->debug("serialize_val: serialize null");
452: if ($use == 'literal') {
453:
454: $xml = "<$name$xmlns$atts/>";
455: $this->debug("serialize_val returning $xml");
456: return $xml;
457: } else {
458: if (isset($type) && isset($type_prefix)) {
459: $type_str = " xsi:type=\"$type_prefix:$type\"";
460: } else {
461: $type_str = '';
462: }
463: $xml = "<$name$xmlns$type_str$atts xsi:nil=\"true\"/>";
464: $this->debug("serialize_val returning $xml");
465: return $xml;
466: }
467: }
468:
469: if($type != '' && isset($this->typemap[$this->XMLSchemaVersion][$type])){
470: $this->debug("serialize_val: serialize xsd built-in primitive type");
471: if (is_bool($val)) {
472: if ($type == 'boolean') {
473: $val = $val ? 'true' : 'false';
474: } elseif (! $val) {
475: $val = 0;
476: }
477: } else if (is_string($val)) {
478: $val = $this->expandEntities($val);
479: }
480: if ($use == 'literal') {
481: $xml = "<$name$xmlns$atts>$val</$name>";
482: $this->debug("serialize_val returning $xml");
483: return $xml;
484: } else {
485: $xml = "<$name$xmlns xsi:type=\"xsd:$type\"$atts>$val</$name>";
486: $this->debug("serialize_val returning $xml");
487: return $xml;
488: }
489: }
490:
491: $xml = '';
492: switch(true) {
493: case (is_bool($val) || $type == 'boolean'):
494: $this->debug("serialize_val: serialize boolean");
495: if ($type == 'boolean') {
496: $val = $val ? 'true' : 'false';
497: } elseif (! $val) {
498: $val = 0;
499: }
500: if ($use == 'literal') {
501: $xml .= "<$name$xmlns$atts>$val</$name>";
502: } else {
503: $xml .= "<$name$xmlns xsi:type=\"xsd:boolean\"$atts>$val</$name>";
504: }
505: break;
506: case (is_int($val) || is_long($val) || $type == 'int'):
507: $this->debug("serialize_val: serialize int");
508: if ($use == 'literal') {
509: $xml .= "<$name$xmlns$atts>$val</$name>";
510: } else {
511: $xml .= "<$name$xmlns xsi:type=\"xsd:int\"$atts>$val</$name>";
512: }
513: break;
514: case (is_float($val)|| is_double($val) || $type == 'float'):
515: $this->debug("serialize_val: serialize float");
516: if ($use == 'literal') {
517: $xml .= "<$name$xmlns$atts>$val</$name>";
518: } else {
519: $xml .= "<$name$xmlns xsi:type=\"xsd:float\"$atts>$val</$name>";
520: }
521: break;
522: case (is_string($val) || $type == 'string'):
523: $this->debug("serialize_val: serialize string");
524: $val = $this->expandEntities($val);
525: if ($use == 'literal') {
526: $xml .= "<$name$xmlns$atts>$val</$name>";
527: } else {
528: $xml .= "<$name$xmlns xsi:type=\"xsd:string\"$atts>$val</$name>";
529: }
530: break;
531: case is_object($val):
532: $this->debug("serialize_val: serialize object");
533: if (get_class($val) == 'soapval') {
534: $this->debug("serialize_val: serialize soapval object");
535: $pXml = $val->serialize($use);
536: $this->appendDebug($val->getDebug());
537: $val->clearDebug();
538: } else {
539: if (! $name) {
540: $name = get_class($val);
541: $this->debug("In serialize_val, used class name $name as element name");
542: } else {
543: $this->debug("In serialize_val, do not override name $name for element name for class " . get_class($val));
544: }
545: foreach(get_object_vars($val) as $k => $v){
546: $pXml = isset($pXml) ? $pXml.$this->serialize_val($v,$k,false,false,false,false,$use) : $this->serialize_val($v,$k,false,false,false,false,$use);
547: }
548: }
549: if(isset($type) && isset($type_prefix)){
550: $type_str = " xsi:type=\"$type_prefix:$type\"";
551: } else {
552: $type_str = '';
553: }
554: if ($use == 'literal') {
555: $xml .= "<$name$xmlns$atts>$pXml</$name>";
556: } else {
557: $xml .= "<$name$xmlns$type_str$atts>$pXml</$name>";
558: }
559: break;
560: break;
561: case (is_array($val) || $type):
562:
563: $valueType = $this->isArraySimpleOrStruct($val);
564: if($valueType=='arraySimple' || preg_match('/^ArrayOf/',$type)){
565: $this->debug("serialize_val: serialize array");
566: $i = 0;
567: if(is_array($val) && count($val)> 0){
568: foreach($val as $v){
569: if(is_object($v) && get_class($v) == 'soapval'){
570: $tt_ns = $v->type_ns;
571: $tt = $v->type;
572: } elseif (is_array($v)) {
573: $tt = $this->isArraySimpleOrStruct($v);
574: } else {
575: $tt = gettype($v);
576: }
577: $array_types[$tt] = 1;
578:
579: $xml .= $this->serialize_val($v,'item',false,false,false,false,$use);
580: ++$i;
581: }
582: if(count($array_types) > 1){
583: $array_typename = 'xsd:anyType';
584: } elseif(isset($tt) && isset($this->typemap[$this->XMLSchemaVersion][$tt])) {
585: if ($tt == 'integer') {
586: $tt = 'int';
587: }
588: $array_typename = 'xsd:'.$tt;
589: } elseif(isset($tt) && $tt == 'arraySimple'){
590: $array_typename = 'SOAP-ENC:Array';
591: } elseif(isset($tt) && $tt == 'arrayStruct'){
592: $array_typename = 'unnamed_struct_use_soapval';
593: } else {
594:
595: if ($tt_ns != '' && $tt_ns == $this->namespaces['xsd']){
596: $array_typename = 'xsd:' . $tt;
597: } elseif ($tt_ns) {
598: $tt_prefix = 'ns' . rand(1000, 9999);
599: $array_typename = "$tt_prefix:$tt";
600: $xmlns .= " xmlns:$tt_prefix=\"$tt_ns\"";
601: } else {
602: $array_typename = $tt;
603: }
604: }
605: $array_type = $i;
606: if ($use == 'literal') {
607: $type_str = '';
608: } else if (isset($type) && isset($type_prefix)) {
609: $type_str = " xsi:type=\"$type_prefix:$type\"";
610: } else {
611: $type_str = " xsi:type=\"SOAP-ENC:Array\" SOAP-ENC:arrayType=\"".$array_typename."[$array_type]\"";
612: }
613:
614: } else {
615: if ($use == 'literal') {
616: $type_str = '';
617: } else if (isset($type) && isset($type_prefix)) {
618: $type_str = " xsi:type=\"$type_prefix:$type\"";
619: } else {
620: $type_str = " xsi:type=\"SOAP-ENC:Array\" SOAP-ENC:arrayType=\"xsd:anyType[0]\"";
621: }
622: }
623:
624: $xml = "<$name$xmlns$type_str$atts>".$xml."</$name>";
625: } else {
626:
627: $this->debug("serialize_val: serialize struct");
628: if(isset($type) && isset($type_prefix)){
629: $type_str = " xsi:type=\"$type_prefix:$type\"";
630: } else {
631: $type_str = '';
632: }
633: if ($use == 'literal') {
634: $xml .= "<$name$xmlns$atts>";
635: } else {
636: $xml .= "<$name$xmlns$type_str$atts>";
637: }
638: foreach($val as $k => $v){
639:
640: if ($type == 'Map' && $type_ns == 'http://xml.apache.org/xml-soap') {
641: $xml .= '<item>';
642: $xml .= $this->serialize_val($k,'key',false,false,false,false,$use);
643: $xml .= $this->serialize_val($v,'value',false,false,false,false,$use);
644: $xml .= '</item>';
645: } else {
646: $xml .= $this->serialize_val($v,$k,false,false,false,false,$use);
647: }
648: }
649: $xml .= "</$name>";
650: }
651: break;
652: default:
653: $this->debug("serialize_val: serialize unknown");
654: $xml .= 'not detected, got '.gettype($val).' for '.$val;
655: break;
656: }
657: $this->debug("serialize_val returning $xml");
658: return $xml;
659: }
660:
661: 662: 663: 664: 665: 666: 667: 668: 669: 670: 671: 672:
673: function serializeEnvelope($body,$headers=false,$namespaces=array(),$style='rpc',$use='encoded',$encodingStyle='http://schemas.xmlsoap.org/soap/encoding/'){
674:
675:
676:
677:
678: $this->debug("In serializeEnvelope length=" . strlen($body) . " body (max 1000 characters)=" . substr($body, 0, 1000) . " style=$style use=$use encodingStyle=$encodingStyle");
679: $this->debug("headers:");
680: $this->appendDebug($this->varDump($headers));
681: $this->debug("namespaces:");
682: $this->appendDebug($this->varDump($namespaces));
683:
684:
685: $ns_string = '';
686: foreach(array_merge($this->namespaces,$namespaces) as $k => $v){
687: $ns_string .= " xmlns:$k=\"$v\"";
688: }
689: if($encodingStyle) {
690: $ns_string = " SOAP-ENV:encodingStyle=\"$encodingStyle\"$ns_string";
691: }
692:
693:
694: if($headers){
695: if (is_array($headers)) {
696: $xml = '';
697: foreach ($headers as $k => $v) {
698: if (is_object($v) && get_class($v) == 'soapval') {
699: $xml .= $this->serialize_val($v, false, false, false, false, false, $use);
700: } else {
701: $xml .= $this->serialize_val($v, $k, false, false, false, false, $use);
702: }
703: }
704: $headers = $xml;
705: $this->debug("In serializeEnvelope, serialized array of headers to $headers");
706: }
707: $headers = "<SOAP-ENV:Header>".$headers."</SOAP-ENV:Header>";
708: }
709:
710: return
711: '<?xml version="1.0" encoding="'.$this->soap_defencoding .'"?'.">".
712: '<SOAP-ENV:Envelope'.$ns_string.">".
713: $headers.
714: "<SOAP-ENV:Body>".
715: $body.
716: "</SOAP-ENV:Body>".
717: "</SOAP-ENV:Envelope>";
718: }
719:
720: 721: 722: 723: 724: 725: 726: 727:
728: function formatDump($str){
729: $str = htmlspecialchars($str);
730: return nl2br($str);
731: }
732:
733: 734: 735: 736: 737: 738: 739:
740: function contractQname($qname){
741:
742:
743: if (strrpos($qname, ':')) {
744:
745: $name = substr($qname, strrpos($qname, ':') + 1);
746:
747: $ns = substr($qname, 0, strrpos($qname, ':'));
748: $p = $this->getPrefixFromNamespace($ns);
749: if ($p) {
750: return $p . ':' . $name;
751: }
752: return $qname;
753: } else {
754: return $qname;
755: }
756: }
757:
758: 759: 760: 761: 762: 763: 764:
765: function expandQname($qname){
766:
767: if(strpos($qname,':') && !preg_match('/^http:\/\//',$qname)){
768:
769: $name = substr(strstr($qname,':'),1);
770:
771: $prefix = substr($qname,0,strpos($qname,':'));
772: if(isset($this->namespaces[$prefix])){
773: return $this->namespaces[$prefix].':'.$name;
774: } else {
775: return $qname;
776: }
777: } else {
778: return $qname;
779: }
780: }
781:
782: 783: 784: 785: 786: 787: 788: 789:
790: function getLocalPart($str){
791: if($sstr = strrchr($str,':')){
792:
793: return substr( $sstr, 1 );
794: } else {
795: return $str;
796: }
797: }
798:
799: 800: 801: 802: 803: 804: 805: 806:
807: function getPrefix($str){
808: if($pos = strrpos($str,':')){
809:
810: return substr($str,0,$pos);
811: }
812: return false;
813: }
814:
815: 816: 817: 818: 819: 820: 821:
822: function getNamespaceFromPrefix($prefix){
823: if (isset($this->namespaces[$prefix])) {
824: return $this->namespaces[$prefix];
825: }
826:
827: return false;
828: }
829:
830: 831: 832: 833: 834: 835: 836: 837:
838: function getPrefixFromNamespace($ns) {
839: foreach ($this->namespaces as $p => $n) {
840: if ($ns == $n || $ns == $p) {
841: $this->usedNamespaces[$p] = $n;
842: return $p;
843: }
844: }
845: return false;
846: }
847:
848: 849: 850: 851: 852: 853:
854: function getmicrotime() {
855: if (function_exists('gettimeofday')) {
856: $tod = gettimeofday();
857: $sec = $tod['sec'];
858: $usec = $tod['usec'];
859: } else {
860: $sec = time();
861: $usec = 0;
862: }
863: return strftime('%Y-%m-%d %H:%M:%S', $sec) . '.' . sprintf('%06d', $usec);
864: }
865:
866: 867: 868: 869: 870: 871: 872:
873: function varDump($data) {
874: ob_start();
875: var_dump($data);
876: $ret_val = ob_get_contents();
877: ob_end_clean();
878: return $ret_val;
879: }
880:
881: 882: 883: 884: 885: 886:
887: function __toString() {
888: return $this->varDump($this);
889: }
890: }
891:
892:
893:
894:
895:
896: 897: 898: 899: 900: 901: 902: 903:
904: function timestamp_to_iso8601($timestamp,$utc=true){
905: $datestr = date('Y-m-d\TH:i:sO',$timestamp);
906: $pos = strrpos($datestr, "+");
907: if ($pos === FALSE) {
908: $pos = strrpos($datestr, "-");
909: }
910: if ($pos !== FALSE) {
911: if (strlen($datestr) == $pos + 5) {
912: $datestr = substr($datestr, 0, $pos + 3) . ':' . substr($datestr, -2);
913: }
914: }
915: if($utc){
916: $pattern = '/'.
917: '([0-9]{4})-'.
918: '([0-9]{2})-'.
919: '([0-9]{2})'.
920: 'T'.
921: '([0-9]{2}):'.
922: '([0-9]{2}):'.
923: '([0-9]{2})(\.[0-9]*)?'.
924: '(Z|[+\-][0-9]{2}:?[0-9]{2})?'.
925: '/';
926:
927: if(preg_match($pattern,$datestr,$regs)){
928: return sprintf('%04d-%02d-%02dT%02d:%02d:%02dZ',$regs[1],$regs[2],$regs[3],$regs[4],$regs[5],$regs[6]);
929: }
930: return false;
931: } else {
932: return $datestr;
933: }
934: }
935:
936: 937: 938: 939: 940: 941: 942:
943: function iso8601_to_timestamp($datestr){
944: $pattern = '/'.
945: '([0-9]{4})-'.
946: '([0-9]{2})-'.
947: '([0-9]{2})'.
948: 'T'.
949: '([0-9]{2}):'.
950: '([0-9]{2}):'.
951: '([0-9]{2})(\.[0-9]+)?'.
952: '(Z|[+\-][0-9]{2}:?[0-9]{2})?'.
953: '/';
954: if(preg_match($pattern,$datestr,$regs)){
955:
956: if($regs[8] != 'Z'){
957: $op = substr($regs[8],0,1);
958: $h = substr($regs[8],1,2);
959: $m = substr($regs[8],strlen($regs[8])-2,2);
960: if($op == '-'){
961: $regs[4] = $regs[4] + $h;
962: $regs[5] = $regs[5] + $m;
963: } elseif($op == '+'){
964: $regs[4] = $regs[4] - $h;
965: $regs[5] = $regs[5] - $m;
966: }
967: }
968: return gmmktime($regs[4], $regs[5], $regs[6], $regs[2], $regs[3], $regs[1]);
969:
970: } else {
971: return false;
972: }
973: }
974:
975: 976: 977: 978: 979: 980: 981:
982: function usleepWindows($usec)
983: {
984: $start = gettimeofday();
985:
986: do
987: {
988: $stop = gettimeofday();
989: $timePassed = 1000000 * ($stop['sec'] - $start['sec'])
990: + $stop['usec'] - $start['usec'];
991: }
992: while ($timePassed < $usec);
993: }
994:
995: ?><?php
996:
997:
998:
999: 1000: 1001: 1002: 1003: 1004: 1005: 1006:
1007: class nusoap_fault extends nusoap_base {
1008: 1009: 1010: 1011: 1012:
1013: var $faultcode;
1014: 1015: 1016: 1017: 1018:
1019: var $faultactor;
1020: 1021: 1022: 1023: 1024:
1025: var $faultstring;
1026: 1027: 1028: 1029: 1030:
1031: var $faultdetail;
1032:
1033: 1034: 1035: 1036: 1037: 1038: 1039: 1040:
1041: function nusoap_fault($faultcode,$faultactor='',$faultstring='',$faultdetail=''){
1042: parent::nusoap_base();
1043: $this->faultcode = $faultcode;
1044: $this->faultactor = $faultactor;
1045: $this->faultstring = $faultstring;
1046: $this->faultdetail = $faultdetail;
1047: }
1048:
1049: 1050: 1051: 1052: 1053: 1054:
1055: function serialize(){
1056: $ns_string = '';
1057: foreach($this->namespaces as $k => $v){
1058: $ns_string .= "\n xmlns:$k=\"$v\"";
1059: }
1060: $return_msg =
1061: '<?xml version="1.0" encoding="'.$this->soap_defencoding.'"?>'.
1062: '<SOAP-ENV:Envelope SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"'.$ns_string.">\n".
1063: '<SOAP-ENV:Body>'.
1064: '<SOAP-ENV:Fault>'.
1065: $this->serialize_val($this->faultcode, 'faultcode').
1066: $this->serialize_val($this->faultactor, 'faultactor').
1067: $this->serialize_val($this->faultstring, 'faultstring').
1068: $this->serialize_val($this->faultdetail, 'detail').
1069: '</SOAP-ENV:Fault>'.
1070: '</SOAP-ENV:Body>'.
1071: '</SOAP-ENV:Envelope>';
1072: return $return_msg;
1073: }
1074: }
1075:
1076: 1077: 1078:
1079: class soap_fault extends nusoap_fault {
1080: }
1081:
1082: ?><?php
1083:
1084:
1085:
1086: 1087: 1088: 1089: 1090: 1091: 1092: 1093: 1094:
1095: class nusoap_xmlschema extends nusoap_base {
1096:
1097:
1098: var $schema = '';
1099: var $xml = '';
1100:
1101: var $enclosingNamespaces;
1102:
1103: var $schemaInfo = array();
1104: var $schemaTargetNamespace = '';
1105:
1106: var $attributes = array();
1107: var $complexTypes = array();
1108: var $complexTypeStack = array();
1109: var $currentComplexType = null;
1110: var $elements = array();
1111: var $elementStack = array();
1112: var $currentElement = null;
1113: var $simpleTypes = array();
1114: var $simpleTypeStack = array();
1115: var $currentSimpleType = null;
1116:
1117: var $imports = array();
1118:
1119: var $parser;
1120: var $position = 0;
1121: var $depth = 0;
1122: var $depth_array = array();
1123: var $message = array();
1124: var $defaultNamespace = array();
1125:
1126: 1127: 1128: 1129: 1130: 1131: 1132: 1133:
1134: function nusoap_xmlschema($schema='',$xml='',$namespaces=array()){
1135: parent::nusoap_base();
1136: $this->debug('nusoap_xmlschema class instantiated, inside constructor');
1137:
1138: $this->schema = $schema;
1139: $this->xml = $xml;
1140:
1141:
1142: $this->enclosingNamespaces = $namespaces;
1143: $this->namespaces = array_merge($this->namespaces, $namespaces);
1144:
1145:
1146: if($schema != ''){
1147: $this->debug('initial schema file: '.$schema);
1148: $this->parseFile($schema, 'schema');
1149: }
1150:
1151:
1152: if($xml != ''){
1153: $this->debug('initial xml file: '.$xml);
1154: $this->parseFile($xml, 'xml');
1155: }
1156:
1157: }
1158:
1159: 1160: 1161: 1162: 1163: 1164: 1165: 1166:
1167: function parseFile($xml,$type){
1168:
1169: if($xml != ""){
1170: $xmlStr = @join("",@file($xml));
1171: if($xmlStr == ""){
1172: $msg = 'Error reading XML from '.$xml;
1173: $this->setError($msg);
1174: $this->debug($msg);
1175: return false;
1176: } else {
1177: $this->debug("parsing $xml");
1178: $this->parseString($xmlStr,$type);
1179: $this->debug("done parsing $xml");
1180: return true;
1181: }
1182: }
1183: return false;
1184: }
1185:
1186: 1187: 1188: 1189: 1190: 1191: 1192:
1193: function parseString($xml,$type){
1194:
1195: if($xml != ""){
1196:
1197:
1198: $this->parser = xml_parser_create();
1199:
1200: xml_parser_set_option($this->parser, XML_OPTION_CASE_FOLDING, 0);
1201:
1202:
1203: xml_set_object($this->parser, $this);
1204:
1205:
1206: if($type == "schema"){
1207: xml_set_element_handler($this->parser, 'schemaStartElement','schemaEndElement');
1208: xml_set_character_data_handler($this->parser,'schemaCharacterData');
1209: } elseif($type == "xml"){
1210: xml_set_element_handler($this->parser, 'xmlStartElement','xmlEndElement');
1211: xml_set_character_data_handler($this->parser,'xmlCharacterData');
1212: }
1213:
1214:
1215: if(!xml_parse($this->parser,$xml,true)){
1216:
1217: $errstr = sprintf('XML error parsing XML schema on line %d: %s',
1218: xml_get_current_line_number($this->parser),
1219: xml_error_string(xml_get_error_code($this->parser))
1220: );
1221: $this->debug($errstr);
1222: $this->debug("XML payload:\n" . $xml);
1223: $this->setError($errstr);
1224: }
1225:
1226: xml_parser_free($this->parser);
1227: } else{
1228: $this->debug('no xml passed to parseString()!!');
1229: $this->setError('no xml passed to parseString()!!');
1230: }
1231: }
1232:
1233: 1234: 1235: 1236: 1237: 1238: 1239:
1240: function CreateTypeName($ename) {
1241: $scope = '';
1242: for ($i = 0; $i < count($this->complexTypeStack); $i++) {
1243: $scope .= $this->complexTypeStack[$i] . '_';
1244: }
1245: return $scope . $ename . '_ContainedType';
1246: }
1247:
1248: 1249: 1250: 1251: 1252: 1253: 1254: 1255:
1256: function schemaStartElement($parser, $name, $attrs) {
1257:
1258:
1259: $pos = $this->position++;
1260: $depth = $this->depth++;
1261:
1262: $this->depth_array[$depth] = $pos;
1263: $this->message[$pos] = array('cdata' => '');
1264: if ($depth > 0) {
1265: $this->defaultNamespace[$pos] = $this->defaultNamespace[$this->depth_array[$depth - 1]];
1266: } else {
1267: $this->defaultNamespace[$pos] = false;
1268: }
1269:
1270:
1271: if($prefix = $this->getPrefix($name)){
1272:
1273: $name = $this->getLocalPart($name);
1274: } else {
1275: $prefix = '';
1276: }
1277:
1278:
1279: if(count($attrs) > 0){
1280: foreach($attrs as $k => $v){
1281:
1282: if(preg_match('/^xmlns/',$k)){
1283:
1284:
1285: if($ns_prefix = substr(strrchr($k,':'),1)){
1286:
1287: $this->namespaces[$ns_prefix] = $v;
1288: } else {
1289: $this->defaultNamespace[$pos] = $v;
1290: if (! $this->getPrefixFromNamespace($v)) {
1291: $this->namespaces['ns'.(count($this->namespaces)+1)] = $v;
1292: }
1293: }
1294: if($v == 'http://www.w3.org/2001/XMLSchema' || $v == 'http://www.w3.org/1999/XMLSchema' || $v == 'http://www.w3.org/2000/10/XMLSchema'){
1295: $this->XMLSchemaVersion = $v;
1296: $this->namespaces['xsi'] = $v.'-instance';
1297: }
1298: }
1299: }
1300: foreach($attrs as $k => $v){
1301:
1302: $k = strpos($k,':') ? $this->expandQname($k) : $k;
1303: $v = strpos($v,':') ? $this->expandQname($v) : $v;
1304: $eAttrs[$k] = $v;
1305: }
1306: $attrs = $eAttrs;
1307: } else {
1308: $attrs = array();
1309: }
1310:
1311: switch($name){
1312: case 'all':
1313: case 'choice':
1314: case 'group':
1315: case 'sequence':
1316:
1317: $this->complexTypes[$this->currentComplexType]['compositor'] = $name;
1318:
1319:
1320:
1321: break;
1322: case 'attribute':
1323:
1324: $this->xdebug("parsing attribute:");
1325: $this->appendDebug($this->varDump($attrs));
1326: if (!isset($attrs['form'])) {
1327:
1328: $attrs['form'] = $this->schemaInfo['attributeFormDefault'];
1329: }
1330: if (isset($attrs['http://schemas.xmlsoap.org/wsdl/:arrayType'])) {
1331: $v = $attrs['http://schemas.xmlsoap.org/wsdl/:arrayType'];
1332: if (!strpos($v, ':')) {
1333:
1334: if ($this->defaultNamespace[$pos]) {
1335:
1336: $attrs['http://schemas.xmlsoap.org/wsdl/:arrayType'] = $this->defaultNamespace[$pos] . ':' . $attrs['http://schemas.xmlsoap.org/wsdl/:arrayType'];
1337: }
1338: }
1339: }
1340: if(isset($attrs['name'])){
1341: $this->attributes[$attrs['name']] = $attrs;
1342: $aname = $attrs['name'];
1343: } elseif(isset($attrs['ref']) && $attrs['ref'] == 'http://schemas.xmlsoap.org/soap/encoding/:arrayType'){
1344: if (isset($attrs['http://schemas.xmlsoap.org/wsdl/:arrayType'])) {
1345: $aname = $attrs['http://schemas.xmlsoap.org/wsdl/:arrayType'];
1346: } else {
1347: $aname = '';
1348: }
1349: } elseif(isset($attrs['ref'])){
1350: $aname = $attrs['ref'];
1351: $this->attributes[$attrs['ref']] = $attrs;
1352: }
1353:
1354: if($this->currentComplexType){
1355: $this->complexTypes[$this->currentComplexType]['attrs'][$aname] = $attrs;
1356: }
1357:
1358: if(isset($attrs['http://schemas.xmlsoap.org/wsdl/:arrayType']) || $this->getLocalPart($aname) == 'arrayType'){
1359: $this->complexTypes[$this->currentComplexType]['phpType'] = 'array';
1360: $prefix = $this->getPrefix($aname);
1361: if(isset($attrs['http://schemas.xmlsoap.org/wsdl/:arrayType'])){
1362: $v = $attrs['http://schemas.xmlsoap.org/wsdl/:arrayType'];
1363: } else {
1364: $v = '';
1365: }
1366: if(strpos($v,'[,]')){
1367: $this->complexTypes[$this->currentComplexType]['multidimensional'] = true;
1368: }
1369: $v = substr($v,0,strpos($v,'['));
1370: if(!strpos($v,':') && isset($this->typemap[$this->XMLSchemaVersion][$v])){
1371: $v = $this->XMLSchemaVersion.':'.$v;
1372: }
1373: $this->complexTypes[$this->currentComplexType]['arrayType'] = $v;
1374: }
1375: break;
1376: case 'complexContent':
1377: $this->xdebug("do nothing for element $name");
1378: break;
1379: case 'complexType':
1380: array_push($this->complexTypeStack, $this->currentComplexType);
1381: if(isset($attrs['name'])){
1382:
1383:
1384: $this->xdebug('processing named complexType '.$attrs['name']);
1385:
1386: $this->currentComplexType = $attrs['name'];
1387: $this->complexTypes[$this->currentComplexType] = $attrs;
1388: $this->complexTypes[$this->currentComplexType]['typeClass'] = 'complexType';
1389:
1390:
1391:
1392:
1393:
1394:
1395:
1396: if(isset($attrs['base']) && preg_match('/:Array$/',$attrs['base'])){
1397: $this->xdebug('complexType is unusual array');
1398: $this->complexTypes[$this->currentComplexType]['phpType'] = 'array';
1399: } else {
1400: $this->complexTypes[$this->currentComplexType]['phpType'] = 'struct';
1401: }
1402: } else {
1403: $name = $this->CreateTypeName($this->currentElement);
1404: $this->xdebug('processing unnamed complexType for element ' . $this->currentElement . ' named ' . $name);
1405: $this->currentComplexType = $name;
1406:
1407: $this->complexTypes[$this->currentComplexType] = $attrs;
1408: $this->complexTypes[$this->currentComplexType]['typeClass'] = 'complexType';
1409:
1410:
1411:
1412:
1413:
1414:
1415:
1416: if(isset($attrs['base']) && preg_match('/:Array$/',$attrs['base'])){
1417: $this->xdebug('complexType is unusual array');
1418: $this->complexTypes[$this->currentComplexType]['phpType'] = 'array';
1419: } else {
1420: $this->complexTypes[$this->currentComplexType]['phpType'] = 'struct';
1421: }
1422: }
1423: $this->complexTypes[$this->currentComplexType]['simpleContent'] = 'false';
1424: break;
1425: case 'element':
1426: array_push($this->elementStack, $this->currentElement);
1427: if (!isset($attrs['form'])) {
1428: if ($this->currentComplexType) {
1429: $attrs['form'] = $this->schemaInfo['elementFormDefault'];
1430: } else {
1431:
1432: $attrs['form'] = 'qualified';
1433: }
1434: }
1435: if(isset($attrs['type'])){
1436: $this->xdebug("processing typed element ".$attrs['name']." of type ".$attrs['type']);
1437: if (! $this->getPrefix($attrs['type'])) {
1438: if ($this->defaultNamespace[$pos]) {
1439: $attrs['type'] = $this->defaultNamespace[$pos] . ':' . $attrs['type'];
1440: $this->xdebug('used default namespace to make type ' . $attrs['type']);
1441: }
1442: }
1443:
1444:
1445:
1446:
1447:
1448:
1449:
1450: if ($this->currentComplexType && $this->complexTypes[$this->currentComplexType]['phpType'] == 'array') {
1451: $this->xdebug('arrayType for unusual array is ' . $attrs['type']);
1452: $this->complexTypes[$this->currentComplexType]['arrayType'] = $attrs['type'];
1453: }
1454: $this->currentElement = $attrs['name'];
1455: $ename = $attrs['name'];
1456: } elseif(isset($attrs['ref'])){
1457: $this->xdebug("processing element as ref to ".$attrs['ref']);
1458: $this->currentElement = "ref to ".$attrs['ref'];
1459: $ename = $this->getLocalPart($attrs['ref']);
1460: } else {
1461: $type = $this->CreateTypeName($this->currentComplexType . '_' . $attrs['name']);
1462: $this->xdebug("processing untyped element " . $attrs['name'] . ' type ' . $type);
1463: $this->currentElement = $attrs['name'];
1464: $attrs['type'] = $this->schemaTargetNamespace . ':' . $type;
1465: $ename = $attrs['name'];
1466: }
1467: if (isset($ename) && $this->currentComplexType) {
1468: $this->xdebug("add element $ename to complexType $this->currentComplexType");
1469: $this->complexTypes[$this->currentComplexType]['elements'][$ename] = $attrs;
1470: } elseif (!isset($attrs['ref'])) {
1471: $this->xdebug("add element $ename to elements array");
1472: $this->elements[ $attrs['name'] ] = $attrs;
1473: $this->elements[ $attrs['name'] ]['typeClass'] = 'element';
1474: }
1475: break;
1476: case 'enumeration':
1477: $this->xdebug('enumeration ' . $attrs['value']);
1478: if ($this->currentSimpleType) {
1479: $this->simpleTypes[$this->currentSimpleType]['enumeration'][] = $attrs['value'];
1480: } elseif ($this->currentComplexType) {
1481: $this->complexTypes[$this->currentComplexType]['enumeration'][] = $attrs['value'];
1482: }
1483: break;
1484: case 'extension':
1485: $this->xdebug('extension ' . $attrs['base']);
1486: if ($this->currentComplexType) {
1487: $ns = $this->getPrefix($attrs['base']);
1488: if ($ns == '') {
1489: $this->complexTypes[$this->currentComplexType]['extensionBase'] = $this->schemaTargetNamespace . ':' . $attrs['base'];
1490: } else {
1491: $this->complexTypes[$this->currentComplexType]['extensionBase'] = $attrs['base'];
1492: }
1493: } else {
1494: $this->xdebug('no current complexType to set extensionBase');
1495: }
1496: break;
1497: case 'import':
1498: if (isset($attrs['schemaLocation'])) {
1499: $this->xdebug('import namespace ' . $attrs['namespace'] . ' from ' . $attrs['schemaLocation']);
1500: $this->imports[$attrs['namespace']][] = array('location' => $attrs['schemaLocation'], 'loaded' => false);
1501: } else {
1502: $this->xdebug('import namespace ' . $attrs['namespace']);
1503: $this->imports[$attrs['namespace']][] = array('location' => '', 'loaded' => true);
1504: if (! $this->getPrefixFromNamespace($attrs['namespace'])) {
1505: $this->namespaces['ns'.(count($this->namespaces)+1)] = $attrs['namespace'];
1506: }
1507: }
1508: break;
1509: case 'include':
1510: if (isset($attrs['schemaLocation'])) {
1511: $this->xdebug('include into namespace ' . $this->schemaTargetNamespace . ' from ' . $attrs['schemaLocation']);
1512: $this->imports[$this->schemaTargetNamespace][] = array('location' => $attrs['schemaLocation'], 'loaded' => false);
1513: } else {
1514: $this->xdebug('ignoring invalid XML Schema construct: include without schemaLocation attribute');
1515: }
1516: break;
1517: case 'list':
1518: $this->xdebug("do nothing for element $name");
1519: break;
1520: case 'restriction':
1521: $this->xdebug('restriction ' . $attrs['base']);
1522: if($this->currentSimpleType){
1523: $this->simpleTypes[$this->currentSimpleType]['type'] = $attrs['base'];
1524: } elseif($this->currentComplexType){
1525: $this->complexTypes[$this->currentComplexType]['restrictionBase'] = $attrs['base'];
1526: if(strstr($attrs['base'],':') == ':Array'){
1527: $this->complexTypes[$this->currentComplexType]['phpType'] = 'array';
1528: }
1529: }
1530: break;
1531: case 'schema':
1532: $this->schemaInfo = $attrs;
1533: $this->schemaInfo['schemaVersion'] = $this->getNamespaceFromPrefix($prefix);
1534: if (isset($attrs['targetNamespace'])) {
1535: $this->schemaTargetNamespace = $attrs['targetNamespace'];
1536: }
1537: if (!isset($attrs['elementFormDefault'])) {
1538: $this->schemaInfo['elementFormDefault'] = 'unqualified';
1539: }
1540: if (!isset($attrs['attributeFormDefault'])) {
1541: $this->schemaInfo['attributeFormDefault'] = 'unqualified';
1542: }
1543: break;
1544: case 'simpleContent':
1545: if ($this->currentComplexType) {
1546: $this->complexTypes[$this->currentComplexType]['simpleContent'] = 'true';
1547: } else {
1548: $this->xdebug("do nothing for element $name because there is no current complexType");
1549: }
1550: break;
1551: case 'simpleType':
1552: array_push($this->simpleTypeStack, $this->currentSimpleType);
1553: if(isset($attrs['name'])){
1554: $this->xdebug("processing simpleType for name " . $attrs['name']);
1555: $this->currentSimpleType = $attrs['name'];
1556: $this->simpleTypes[ $attrs['name'] ] = $attrs;
1557: $this->simpleTypes[ $attrs['name'] ]['typeClass'] = 'simpleType';
1558: $this->simpleTypes[ $attrs['name'] ]['phpType'] = 'scalar';
1559: } else {
1560: $name = $this->CreateTypeName($this->currentComplexType . '_' . $this->currentElement);
1561: $this->xdebug('processing unnamed simpleType for element ' . $this->currentElement . ' named ' . $name);
1562: $this->currentSimpleType = $name;
1563:
1564: $this->simpleTypes[$this->currentSimpleType] = $attrs;
1565: $this->simpleTypes[$this->currentSimpleType]['phpType'] = 'scalar';
1566: }
1567: break;
1568: case 'union':
1569: $this->xdebug("do nothing for element $name");
1570: break;
1571: default:
1572: $this->xdebug("do not have any logic to process element $name");
1573: }
1574: }
1575:
1576: 1577: 1578: 1579: 1580: 1581: 1582:
1583: function schemaEndElement($parser, $name) {
1584:
1585: $this->depth--;
1586:
1587: if(isset($this->depth_array[$this->depth])){
1588: $pos = $this->depth_array[$this->depth];
1589: }
1590:
1591: if ($prefix = $this->getPrefix($name)){
1592:
1593: $name = $this->getLocalPart($name);
1594: } else {
1595: $prefix = '';
1596: }
1597:
1598: if($name == 'complexType'){
1599: $this->xdebug('done processing complexType ' . ($this->currentComplexType ? $this->currentComplexType : '(unknown)'));
1600: $this->xdebug($this->varDump($this->complexTypes[$this->currentComplexType]));
1601: $this->currentComplexType = array_pop($this->complexTypeStack);
1602:
1603: }
1604: if($name == 'element'){
1605: $this->xdebug('done processing element ' . ($this->currentElement ? $this->currentElement : '(unknown)'));
1606: $this->currentElement = array_pop($this->elementStack);
1607: }
1608: if($name == 'simpleType'){
1609: $this->xdebug('done processing simpleType ' . ($this->currentSimpleType ? $this->currentSimpleType : '(unknown)'));
1610: $this->xdebug($this->varDump($this->simpleTypes[$this->currentSimpleType]));
1611: $this->currentSimpleType = array_pop($this->simpleTypeStack);
1612: }
1613: }
1614:
1615: 1616: 1617: 1618: 1619: 1620: 1621:
1622: function schemaCharacterData($parser, $data){
1623: $pos = $this->depth_array[$this->depth - 1];
1624: $this->message[$pos]['cdata'] .= $data;
1625: }
1626:
1627: 1628: 1629: 1630: 1631:
1632: function serializeSchema(){
1633:
1634: $schemaPrefix = $this->getPrefixFromNamespace($this->XMLSchemaVersion);
1635: $xml = '';
1636:
1637: if (sizeof($this->imports) > 0) {
1638: foreach($this->imports as $ns => $list) {
1639: foreach ($list as $ii) {
1640: if ($ii['location'] != '') {
1641: $xml .= " <$schemaPrefix:import location=\"" . $ii['location'] . '" namespace="' . $ns . "\" />\n";
1642: } else {
1643: $xml .= " <$schemaPrefix:import namespace=\"" . $ns . "\" />\n";
1644: }
1645: }
1646: }
1647: }
1648:
1649: foreach($this->complexTypes as $typeName => $attrs){
1650: $contentStr = '';
1651:
1652: if(isset($attrs['elements']) && (count($attrs['elements']) > 0)){
1653: foreach($attrs['elements'] as $element => $eParts){
1654: if(isset($eParts['ref'])){
1655: $contentStr .= " <$schemaPrefix:element ref=\"$element\"/>\n";
1656: } else {
1657: $contentStr .= " <$schemaPrefix:element name=\"$element\" type=\"" . $this->contractQName($eParts['type']) . "\"";
1658: foreach ($eParts as $aName => $aValue) {
1659:
1660: if ($aName != 'name' && $aName != 'type') {
1661: $contentStr .= " $aName=\"$aValue\"";
1662: }
1663: }
1664: $contentStr .= "/>\n";
1665: }
1666: }
1667:
1668: if (isset($attrs['compositor']) && ($attrs['compositor'] != '')) {
1669: $contentStr = " <$schemaPrefix:$attrs[compositor]>\n".$contentStr." </$schemaPrefix:$attrs[compositor]>\n";
1670: }
1671: }
1672:
1673: if(isset($attrs['attrs']) && (count($attrs['attrs']) >= 1)){
1674: foreach($attrs['attrs'] as $attr => $aParts){
1675: $contentStr .= " <$schemaPrefix:attribute";
1676: foreach ($aParts as $a => $v) {
1677: if ($a == 'ref' || $a == 'type') {
1678: $contentStr .= " $a=\"".$this->contractQName($v).'"';
1679: } elseif ($a == 'http://schemas.xmlsoap.org/wsdl/:arrayType') {
1680: $this->usedNamespaces['wsdl'] = $this->namespaces['wsdl'];
1681: $contentStr .= ' wsdl:arrayType="'.$this->contractQName($v).'"';
1682: } else {
1683: $contentStr .= " $a=\"$v\"";
1684: }
1685: }
1686: $contentStr .= "/>\n";
1687: }
1688: }
1689:
1690: if (isset($attrs['restrictionBase']) && $attrs['restrictionBase'] != ''){
1691: $contentStr = " <$schemaPrefix:restriction base=\"".$this->contractQName($attrs['restrictionBase'])."\">\n".$contentStr." </$schemaPrefix:restriction>\n";
1692:
1693: if ((isset($attrs['elements']) && count($attrs['elements']) > 0) || (isset($attrs['attrs']) && count($attrs['attrs']) > 0)){
1694: $contentStr = " <$schemaPrefix:complexContent>\n".$contentStr." </$schemaPrefix:complexContent>\n";
1695: }
1696: }
1697:
1698: if($contentStr != ''){
1699: $contentStr = " <$schemaPrefix:complexType name=\"$typeName\">\n".$contentStr." </$schemaPrefix:complexType>\n";
1700: } else {
1701: $contentStr = " <$schemaPrefix:complexType name=\"$typeName\"/>\n";
1702: }
1703: $xml .= $contentStr;
1704: }
1705:
1706: if(isset($this->simpleTypes) && count($this->simpleTypes) > 0){
1707: foreach($this->simpleTypes as $typeName => $eParts){
1708: $xml .= " <$schemaPrefix:simpleType name=\"$typeName\">\n <$schemaPrefix:restriction base=\"".$this->contractQName($eParts['type'])."\">\n";
1709: if (isset($eParts['enumeration'])) {
1710: foreach ($eParts['enumeration'] as $e) {
1711: $xml .= " <$schemaPrefix:enumeration value=\"$e\"/>\n";
1712: }
1713: }
1714: $xml .= " </$schemaPrefix:restriction>\n </$schemaPrefix:simpleType>";
1715: }
1716: }
1717:
1718: if(isset($this->elements) && count($this->elements) > 0){
1719: foreach($this->elements as $element => $eParts){
1720: $xml .= " <$schemaPrefix:element name=\"$element\" type=\"".$this->contractQName($eParts['type'])."\"/>\n";
1721: }
1722: }
1723:
1724: if(isset($this->attributes) && count($this->attributes) > 0){
1725: foreach($this->attributes as $attr => $aParts){
1726: $xml .= " <$schemaPrefix:attribute name=\"$attr\" type=\"".$this->contractQName($aParts['type'])."\"\n/>";
1727: }
1728: }
1729:
1730: $attr = '';
1731: foreach ($this->schemaInfo as $k => $v) {
1732: if ($k == 'elementFormDefault' || $k == 'attributeFormDefault') {
1733: $attr .= " $k=\"$v\"";
1734: }
1735: }
1736: $el = "<$schemaPrefix:schema$attr targetNamespace=\"$this->schemaTargetNamespace\"\n";
1737: foreach (array_diff($this->usedNamespaces, $this->enclosingNamespaces) as $nsp => $ns) {
1738: $el .= " xmlns:$nsp=\"$ns\"";
1739: }
1740: $xml = $el . ">\n".$xml."</$schemaPrefix:schema>\n";
1741: return $xml;
1742: }
1743:
1744: 1745: 1746: 1747: 1748: 1749:
1750: function xdebug($string){
1751: $this->debug('<' . $this->schemaTargetNamespace . '> '.$string);
1752: }
1753:
1754: 1755: 1756: 1757: 1758: 1759: 1760: 1761: 1762: 1763: 1764: 1765:
1766: function getPHPType($type,$ns){
1767: if(isset($this->typemap[$ns][$type])){
1768:
1769: return $this->typemap[$ns][$type];
1770: } elseif(isset($this->complexTypes[$type])){
1771:
1772: return $this->complexTypes[$type]['phpType'];
1773: }
1774: return false;
1775: }
1776:
1777: 1778: 1779: 1780: 1781: 1782: 1783: 1784: 1785: 1786: 1787: 1788: 1789: 1790: 1791: 1792: 1793: 1794: 1795: 1796: 1797: 1798:
1799: function getTypeDef($type){
1800:
1801: if (substr($type, -1) == '^') {
1802: $is_element = 1;
1803: $type = substr($type, 0, -1);
1804: } else {
1805: $is_element = 0;
1806: }
1807:
1808: if((! $is_element) && isset($this->complexTypes[$type])){
1809: $this->xdebug("in getTypeDef, found complexType $type");
1810: return $this->complexTypes[$type];
1811: } elseif((! $is_element) && isset($this->simpleTypes[$type])){
1812: $this->xdebug("in getTypeDef, found simpleType $type");
1813: if (!isset($this->simpleTypes[$type]['phpType'])) {
1814:
1815:
1816: $uqType = substr($this->simpleTypes[$type]['type'], strrpos($this->simpleTypes[$type]['type'], ':') + 1);
1817: $ns = substr($this->simpleTypes[$type]['type'], 0, strrpos($this->simpleTypes[$type]['type'], ':'));
1818: $etype = $this->getTypeDef($uqType);
1819: if ($etype) {
1820: $this->xdebug("in getTypeDef, found type for simpleType $type:");
1821: $this->xdebug($this->varDump($etype));
1822: if (isset($etype['phpType'])) {
1823: $this->simpleTypes[$type]['phpType'] = $etype['phpType'];
1824: }
1825: if (isset($etype['elements'])) {
1826: $this->simpleTypes[$type]['elements'] = $etype['elements'];
1827: }
1828: }
1829: }
1830: return $this->simpleTypes[$type];
1831: } elseif(isset($this->elements[$type])){
1832: $this->xdebug("in getTypeDef, found element $type");
1833: if (!isset($this->elements[$type]['phpType'])) {
1834:
1835: $uqType = substr($this->elements[$type]['type'], strrpos($this->elements[$type]['type'], ':') + 1);
1836: $ns = substr($this->elements[$type]['type'], 0, strrpos($this->elements[$type]['type'], ':'));
1837: $etype = $this->getTypeDef($uqType);
1838: if ($etype) {
1839: $this->xdebug("in getTypeDef, found type for element $type:");
1840: $this->xdebug($this->varDump($etype));
1841: if (isset($etype['phpType'])) {
1842: $this->elements[$type]['phpType'] = $etype['phpType'];
1843: }
1844: if (isset($etype['elements'])) {
1845: $this->elements[$type]['elements'] = $etype['elements'];
1846: }
1847: if (isset($etype['extensionBase'])) {
1848: $this->elements[$type]['extensionBase'] = $etype['extensionBase'];
1849: }
1850: } elseif ($ns == 'http://www.w3.org/2001/XMLSchema') {
1851: $this->xdebug("in getTypeDef, element $type is an XSD type");
1852: $this->elements[$type]['phpType'] = 'scalar';
1853: }
1854: }
1855: return $this->elements[$type];
1856: } elseif(isset($this->attributes[$type])){
1857: $this->xdebug("in getTypeDef, found attribute $type");
1858: return $this->attributes[$type];
1859: } elseif (preg_match('/_ContainedType$/', $type)) {
1860: $this->xdebug("in getTypeDef, have an untyped element $type");
1861: $typeDef['typeClass'] = 'simpleType';
1862: $typeDef['phpType'] = 'scalar';
1863: $typeDef['type'] = 'http://www.w3.org/2001/XMLSchema:string';
1864: return $typeDef;
1865: }
1866: $this->xdebug("in getTypeDef, did not find $type");
1867: return false;
1868: }
1869:
1870: 1871: 1872: 1873: 1874: 1875: 1876: 1877:
1878: function serializeTypeDef($type){
1879:
1880: if($typeDef = $this->getTypeDef($type)){
1881: $str .= '<'.$type;
1882: if(is_array($typeDef['attrs'])){
1883: foreach($typeDef['attrs'] as $attName => $data){
1884: $str .= " $attName=\"{type = ".$data['type']."}\"";
1885: }
1886: }
1887: $str .= " xmlns=\"".$this->schema['targetNamespace']."\"";
1888: if(count($typeDef['elements']) > 0){
1889: $str .= ">";
1890: foreach($typeDef['elements'] as $element => $eData){
1891: $str .= $this->serializeTypeDef($element);
1892: }
1893: $str .= "</$type>";
1894: } elseif($typeDef['typeClass'] == 'element') {
1895: $str .= "></$type>";
1896: } else {
1897: $str .= "/>";
1898: }
1899: return $str;
1900: }
1901: return false;
1902: }
1903:
1904: 1905: 1906: 1907: 1908: 1909: 1910: 1911: 1912: 1913:
1914: function typeToForm($name,$type){
1915:
1916: if($typeDef = $this->getTypeDef($type)){
1917:
1918: if($typeDef['phpType'] == 'struct'){
1919: $buffer .= '<table>';
1920: foreach($typeDef['elements'] as $child => $childDef){
1921: $buffer .= "
1922: <tr><td align='right'>$childDef[name] (type: ".$this->getLocalPart($childDef['type'])."):</td>
1923: <td><input type='text' name='parameters[".$name."][$childDef[name]]'></td></tr>";
1924: }
1925: $buffer .= '</table>';
1926:
1927: } elseif($typeDef['phpType'] == 'array'){
1928: $buffer .= '<table>';
1929: for($i=0;$i < 3; $i++){
1930: $buffer .= "
1931: <tr><td align='right'>array item (type: $typeDef[arrayType]):</td>
1932: <td><input type='text' name='parameters[".$name."][]'></td></tr>";
1933: }
1934: $buffer .= '</table>';
1935:
1936: } else {
1937: $buffer .= "<input type='text' name='parameters[$name]'>";
1938: }
1939: } else {
1940: $buffer .= "<input type='text' name='parameters[$name]'>";
1941: }
1942: return $buffer;
1943: }
1944:
1945: 1946: 1947: 1948: 1949: 1950: 1951: 1952: 1953: 1954: 1955: 1956: 1957: 1958: 1959: 1960: 1961: 1962: 1963: 1964: 1965: 1966: 1967: 1968: 1969: 1970: 1971: 1972: 1973: 1974: 1975: 1976: 1977: 1978: 1979: 1980: 1981: 1982: 1983: 1984: 1985:
1986: function addComplexType($name,$typeClass='complexType',$phpType='array',$compositor='',$restrictionBase='',$elements=array(),$attrs=array(),$arrayType=''){
1987: $this->complexTypes[$name] = array(
1988: 'name' => $name,
1989: 'typeClass' => $typeClass,
1990: 'phpType' => $phpType,
1991: 'compositor'=> $compositor,
1992: 'restrictionBase' => $restrictionBase,
1993: 'elements' => $elements,
1994: 'attrs' => $attrs,
1995: 'arrayType' => $arrayType
1996: );
1997:
1998: $this->xdebug("addComplexType $name:");
1999: $this->appendDebug($this->varDump($this->complexTypes[$name]));
2000: }
2001:
2002: 2003: 2004: 2005: 2006: 2007: 2008: 2009: 2010: 2011: 2012: 2013:
2014: function addSimpleType($name, $restrictionBase='', $typeClass='simpleType', $phpType='scalar', $enumeration=array()) {
2015: $this->simpleTypes[$name] = array(
2016: 'name' => $name,
2017: 'typeClass' => $typeClass,
2018: 'phpType' => $phpType,
2019: 'type' => $restrictionBase,
2020: 'enumeration' => $enumeration
2021: );
2022:
2023: $this->xdebug("addSimpleType $name:");
2024: $this->appendDebug($this->varDump($this->simpleTypes[$name]));
2025: }
2026:
2027: 2028: 2029: 2030: 2031: 2032: 2033:
2034: function addElement($attrs) {
2035: if (! $this->getPrefix($attrs['type'])) {
2036: $attrs['type'] = $this->schemaTargetNamespace . ':' . $attrs['type'];
2037: }
2038: $this->elements[ $attrs['name'] ] = $attrs;
2039: $this->elements[ $attrs['name'] ]['typeClass'] = 'element';
2040:
2041: $this->xdebug("addElement " . $attrs['name']);
2042: $this->appendDebug($this->varDump($this->elements[ $attrs['name'] ]));
2043: }
2044: }
2045:
2046: 2047: 2048:
2049: class XMLSchema extends nusoap_xmlschema {
2050: }
2051:
2052: ?><?php
2053:
2054:
2055:
2056: 2057: 2058: 2059: 2060: 2061: 2062: 2063: 2064: 2065: 2066:
2067: class soapval extends nusoap_base {
2068: 2069: 2070: 2071: 2072: 2073:
2074: var $name;
2075: 2076: 2077: 2078: 2079: 2080:
2081: var $type;
2082: 2083: 2084: 2085: 2086: 2087:
2088: var $value;
2089: 2090: 2091: 2092: 2093: 2094:
2095: var $element_ns;
2096: 2097: 2098: 2099: 2100: 2101:
2102: var $type_ns;
2103: 2104: 2105: 2106: 2107: 2108:
2109: var $attributes;
2110:
2111: 2112: 2113: 2114: 2115: 2116: 2117: 2118: 2119: 2120: 2121:
2122: function soapval($name='soapval',$type=false,$value=-1,$element_ns=false,$type_ns=false,$attributes=false) {
2123: parent::nusoap_base();
2124: $this->name = $name;
2125: $this->type = $type;
2126: $this->value = $value;
2127: $this->element_ns = $element_ns;
2128: $this->type_ns = $type_ns;
2129: $this->attributes = $attributes;
2130: }
2131:
2132: 2133: 2134: 2135: 2136: 2137: 2138:
2139: function serialize($use='encoded') {
2140: return $this->serialize_val($this->value, $this->name, $this->type, $this->element_ns, $this->type_ns, $this->attributes, $use, true);
2141: }
2142:
2143: 2144: 2145: 2146: 2147: 2148:
2149: function decode(){
2150: return $this->value;
2151: }
2152: }
2153:
2154:
2155:
2156: ?><?php
2157:
2158:
2159:
2160: 2161: 2162: 2163: 2164: 2165: 2166: 2167: 2168:
2169: class soap_transport_http extends nusoap_base {
2170:
2171: var $url = '';
2172: var $uri = '';
2173: var $digest_uri = '';
2174: var $scheme = '';
2175: var $host = '';
2176: var $port = '';
2177: var $path = '';
2178: var $request_method = 'POST';
2179: var $protocol_version = '1.0';
2180: var $encoding = '';
2181: var $outgoing_headers = array();
2182: var $incoming_headers = array();
2183: var $incoming_cookies = array();
2184: var $outgoing_payload = '';
2185: var $incoming_payload = '';
2186: var $response_status_line;
2187: var $useSOAPAction = true;
2188: var $persistentConnection = false;
2189: var $ch = false;
2190: var $ch_options = array();
2191: var $use_curl = false;
2192: var $proxy = null;
2193: var $username = '';
2194: var $password = '';
2195: var $authtype = '';
2196: var $digestRequest = array();
2197: var $certRequest = array();
2198:
2199:
2200:
2201:
2202:
2203:
2204:
2205:
2206: 2207: 2208: 2209: 2210: 2211: 2212: 2213:
2214: function soap_transport_http($url, $curl_options = NULL, $use_curl = false){
2215: parent::nusoap_base();
2216: $this->debug("ctor url=$url use_curl=$use_curl curl_options:");
2217: $this->appendDebug($this->varDump($curl_options));
2218: $this->setURL($url);
2219: if (is_array($curl_options)) {
2220: $this->ch_options = $curl_options;
2221: }
2222: $this->use_curl = $use_curl;
2223: preg_match('/\$Revisio' . 'n: ([^ ]+)/', $this->revision, $rev);
2224: $this->setHeader('User-Agent', $this->title.'/'.$this->version.' ('.$rev[1].')');
2225: }
2226:
2227: 2228: 2229: 2230: 2231: 2232: 2233:
2234: function setCurlOption($option, $value) {
2235: $this->debug("setCurlOption option=$option, value=");
2236: $this->appendDebug($this->varDump($value));
2237: curl_setopt($this->ch, $option, $value);
2238: }
2239:
2240: 2241: 2242: 2243: 2244: 2245: 2246:
2247: function setHeader($name, $value) {
2248: $this->outgoing_headers[$name] = $value;
2249: $this->debug("set header $name: $value");
2250: }
2251:
2252: 2253: 2254: 2255: 2256: 2257:
2258: function unsetHeader($name) {
2259: if (isset($this->outgoing_headers[$name])) {
2260: $this->debug("unset header $name");
2261: unset($this->outgoing_headers[$name]);
2262: }
2263: }
2264:
2265: 2266: 2267: 2268: 2269: 2270:
2271: function setURL($url) {
2272: $this->url = $url;
2273:
2274: $u = parse_url($url);
2275: foreach($u as $k => $v){
2276: $this->debug("parsed URL $k = $v");
2277: $this->$k = $v;
2278: }
2279:
2280:
2281: if(isset($u['query']) && $u['query'] != ''){
2282: $this->path .= '?' . $u['query'];
2283: }
2284:
2285:
2286: if(!isset($u['port'])){
2287: if($u['scheme'] == 'https'){
2288: $this->port = 443;
2289: } else {
2290: $this->port = 80;
2291: }
2292: }
2293:
2294: $this->uri = $this->path;
2295: $this->digest_uri = $this->uri;
2296:
2297:
2298: if (!isset($u['port'])) {
2299: $this->setHeader('Host', $this->host);
2300: } else {
2301: $this->setHeader('Host', $this->host.':'.$this->port);
2302: }
2303:
2304: if (isset($u['user']) && $u['user'] != '') {
2305: $this->setCredentials(urldecode($u['user']), isset($u['pass']) ? urldecode($u['pass']) : '');
2306: }
2307: }
2308:
2309: 2310: 2311: 2312: 2313: 2314:
2315: function io_method() {
2316: if ($this->use_curl || ($this->scheme == 'https') || ($this->scheme == 'http' && $this->authtype == 'ntlm') || ($this->scheme == 'http' && is_array($this->proxy) && $this->proxy['authtype'] == 'ntlm'))
2317: return 'curl';
2318: if (($this->scheme == 'http' || $this->scheme == 'ssl') && $this->authtype != 'ntlm' && (!is_array($this->proxy) || $this->proxy['authtype'] != 'ntlm'))
2319: return 'socket';
2320: return 'unknown';
2321: }
2322:
2323: 2324: 2325: 2326: 2327: 2328: 2329: 2330:
2331: function connect($connection_timeout=0,$response_timeout=30){
2332:
2333:
2334:
2335:
2336:
2337:
2338:
2339:
2340:
2341:
2342:
2343:
2344: $this->debug("connect connection_timeout $connection_timeout, response_timeout $response_timeout, scheme $this->scheme, host $this->host, port $this->port");
2345: if ($this->io_method() == 'socket') {
2346: if (!is_array($this->proxy)) {
2347: $host = $this->host;
2348: $port = $this->port;
2349: } else {
2350: $host = $this->proxy['host'];
2351: $port = $this->proxy['port'];
2352: }
2353:
2354:
2355: if($this->persistentConnection && isset($this->fp) && is_resource($this->fp)){
2356: if (!feof($this->fp)) {
2357: $this->debug('Re-use persistent connection');
2358: return true;
2359: }
2360: fclose($this->fp);
2361: $this->debug('Closed persistent connection at EOF');
2362: }
2363:
2364:
2365: if ($this->scheme == 'ssl') {
2366: $host = 'ssl://' . $host;
2367: }
2368: $this->debug('calling fsockopen with host ' . $host . ' connection_timeout ' . $connection_timeout);
2369:
2370:
2371: if($connection_timeout > 0){
2372: $this->fp = @fsockopen( $host, $this->port, $this->errno, $this->error_str, $connection_timeout);
2373: } else {
2374: $this->fp = @fsockopen( $host, $this->port, $this->errno, $this->error_str);
2375: }
2376:
2377:
2378: if(!$this->fp) {
2379: $msg = 'Couldn\'t open socket connection to server ' . $this->url;
2380: if ($this->errno) {
2381: $msg .= ', Error ('.$this->errno.'): '.$this->error_str;
2382: } else {
2383: $msg .= ' prior to connect(). This is often a problem looking up the host name.';
2384: }
2385: $this->debug($msg);
2386: $this->setError($msg);
2387: return false;
2388: }
2389:
2390:
2391: $this->debug('set response timeout to ' . $response_timeout);
2392: socket_set_timeout( $this->fp, $response_timeout);
2393:
2394: $this->debug('socket connected');
2395: return true;
2396: } else if ($this->io_method() == 'curl') {
2397: if (!extension_loaded('curl')) {
2398:
2399: $this->setError('The PHP cURL Extension is required for HTTPS or NLTM. You will need to re-build or update your PHP to include cURL or change php.ini to load the PHP cURL extension.');
2400: return false;
2401: }
2402:
2403: if (defined('CURLOPT_CONNECTIONTIMEOUT'))
2404: $CURLOPT_CONNECTIONTIMEOUT = CURLOPT_CONNECTIONTIMEOUT;
2405: else
2406: $CURLOPT_CONNECTIONTIMEOUT = 78;
2407: if (defined('CURLOPT_HTTPAUTH'))
2408: $CURLOPT_HTTPAUTH = CURLOPT_HTTPAUTH;
2409: else
2410: $CURLOPT_HTTPAUTH = 107;
2411: if (defined('CURLOPT_PROXYAUTH'))
2412: $CURLOPT_PROXYAUTH = CURLOPT_PROXYAUTH;
2413: else
2414: $CURLOPT_PROXYAUTH = 111;
2415: if (defined('CURLAUTH_BASIC'))
2416: $CURLAUTH_BASIC = CURLAUTH_BASIC;
2417: else
2418: $CURLAUTH_BASIC = 1;
2419: if (defined('CURLAUTH_DIGEST'))
2420: $CURLAUTH_DIGEST = CURLAUTH_DIGEST;
2421: else
2422: $CURLAUTH_DIGEST = 2;
2423: if (defined('CURLAUTH_NTLM'))
2424: $CURLAUTH_NTLM = CURLAUTH_NTLM;
2425: else
2426: $CURLAUTH_NTLM = 8;
2427:
2428: $this->debug('connect using cURL');
2429:
2430: $this->ch = curl_init();
2431:
2432: $hostURL = ($this->port != '') ? "$this->scheme://$this->host:$this->port" : "$this->scheme://$this->host";
2433:
2434: $hostURL .= $this->path;
2435: $this->setCurlOption(CURLOPT_URL, $hostURL);
2436:
2437: if (ini_get('safe_mode') || ini_get('open_basedir')) {
2438: $this->debug('safe_mode or open_basedir set, so do not set CURLOPT_FOLLOWLOCATION');
2439: $this->debug('safe_mode = ');
2440: $this->appendDebug($this->varDump(ini_get('safe_mode')));
2441: $this->debug('open_basedir = ');
2442: $this->appendDebug($this->varDump(ini_get('open_basedir')));
2443: } else {
2444: $this->setCurlOption(CURLOPT_FOLLOWLOCATION, 1);
2445: }
2446:
2447: $this->setCurlOption(CURLOPT_HEADER, 1);
2448:
2449: $this->setCurlOption(CURLOPT_RETURNTRANSFER, 1);
2450:
2451:
2452:
2453:
2454:
2455:
2456: if ($this->persistentConnection) {
2457:
2458:
2459:
2460:
2461:
2462: $this->persistentConnection = false;
2463: $this->setHeader('Connection', 'close');
2464: }
2465:
2466: if ($connection_timeout != 0) {
2467: $this->setCurlOption($CURLOPT_CONNECTIONTIMEOUT, $connection_timeout);
2468: }
2469: if ($response_timeout != 0) {
2470: $this->setCurlOption(CURLOPT_TIMEOUT, $response_timeout);
2471: }
2472:
2473: if ($this->scheme == 'https') {
2474: $this->debug('set cURL SSL verify options');
2475:
2476:
2477:
2478:
2479: $this->setCurlOption(CURLOPT_SSL_VERIFYPEER, 0);
2480: $this->setCurlOption(CURLOPT_SSL_VERIFYHOST, 0);
2481:
2482:
2483: if ($this->authtype == 'certificate') {
2484: $this->debug('set cURL certificate options');
2485: if (isset($this->certRequest['cainfofile'])) {
2486: $this->setCurlOption(CURLOPT_CAINFO, $this->certRequest['cainfofile']);
2487: }
2488: if (isset($this->certRequest['verifypeer'])) {
2489: $this->setCurlOption(CURLOPT_SSL_VERIFYPEER, $this->certRequest['verifypeer']);
2490: } else {
2491: $this->setCurlOption(CURLOPT_SSL_VERIFYPEER, 1);
2492: }
2493: if (isset($this->certRequest['verifyhost'])) {
2494: $this->setCurlOption(CURLOPT_SSL_VERIFYHOST, $this->certRequest['verifyhost']);
2495: } else {
2496: $this->setCurlOption(CURLOPT_SSL_VERIFYHOST, 1);
2497: }
2498: if (isset($this->certRequest['sslcertfile'])) {
2499: $this->setCurlOption(CURLOPT_SSLCERT, $this->certRequest['sslcertfile']);
2500: }
2501: if (isset($this->certRequest['sslkeyfile'])) {
2502: $this->setCurlOption(CURLOPT_SSLKEY, $this->certRequest['sslkeyfile']);
2503: }
2504: if (isset($this->certRequest['passphrase'])) {
2505: $this->setCurlOption(CURLOPT_SSLKEYPASSWD, $this->certRequest['passphrase']);
2506: }
2507: if (isset($this->certRequest['certpassword'])) {
2508: $this->setCurlOption(CURLOPT_SSLCERTPASSWD, $this->certRequest['certpassword']);
2509: }
2510: }
2511: }
2512: if ($this->authtype && ($this->authtype != 'certificate')) {
2513: if ($this->username) {
2514: $this->debug('set cURL username/password');
2515: $this->setCurlOption(CURLOPT_USERPWD, "$this->username:$this->password");
2516: }
2517: if ($this->authtype == 'basic') {
2518: $this->debug('set cURL for Basic authentication');
2519: $this->setCurlOption($CURLOPT_HTTPAUTH, $CURLAUTH_BASIC);
2520: }
2521: if ($this->authtype == 'digest') {
2522: $this->debug('set cURL for digest authentication');
2523: $this->setCurlOption($CURLOPT_HTTPAUTH, $CURLAUTH_DIGEST);
2524: }
2525: if ($this->authtype == 'ntlm') {
2526: $this->debug('set cURL for NTLM authentication');
2527: $this->setCurlOption($CURLOPT_HTTPAUTH, $CURLAUTH_NTLM);
2528: }
2529: }
2530: if (is_array($this->proxy)) {
2531: $this->debug('set cURL proxy options');
2532: if ($this->proxy['port'] != '') {
2533: $this->setCurlOption(CURLOPT_PROXY, $this->proxy['host'].':'.$this->proxy['port']);
2534: } else {
2535: $this->setCurlOption(CURLOPT_PROXY, $this->proxy['host']);
2536: }
2537: if ($this->proxy['username'] || $this->proxy['password']) {
2538: $this->debug('set cURL proxy authentication options');
2539: $this->setCurlOption(CURLOPT_PROXYUSERPWD, $this->proxy['username'].':'.$this->proxy['password']);
2540: if ($this->proxy['authtype'] == 'basic') {
2541: $this->setCurlOption($CURLOPT_PROXYAUTH, $CURLAUTH_BASIC);
2542: }
2543: if ($this->proxy['authtype'] == 'ntlm') {
2544: $this->setCurlOption($CURLOPT_PROXYAUTH, $CURLAUTH_NTLM);
2545: }
2546: }
2547: }
2548: $this->debug('cURL connection set up');
2549: return true;
2550: } else {
2551: $this->setError('Unknown scheme ' . $this->scheme);
2552: $this->debug('Unknown scheme ' . $this->scheme);
2553: return false;
2554: }
2555: }
2556:
2557: 2558: 2559: 2560: 2561: 2562: 2563: 2564: 2565: 2566:
2567: function send($data, $timeout=0, $response_timeout=30, $cookies=NULL) {
2568:
2569: $this->debug('entered send() with data of length: '.strlen($data));
2570:
2571: $this->tryagain = true;
2572: $tries = 0;
2573: while ($this->tryagain) {
2574: $this->tryagain = false;
2575: if ($tries++ < 2) {
2576:
2577: if (!$this->connect($timeout, $response_timeout)){
2578: return false;
2579: }
2580:
2581:
2582: if (!$this->sendRequest($data, $cookies)){
2583: return false;
2584: }
2585:
2586:
2587: $respdata = $this->getResponse();
2588: } else {
2589: $this->setError("Too many tries to get an OK response ($this->response_status_line)");
2590: }
2591: }
2592: $this->debug('end of send()');
2593: return $respdata;
2594: }
2595:
2596:
2597: 2598: 2599: 2600: 2601: 2602: 2603: 2604: 2605: 2606: 2607:
2608: function sendHTTPS($data, $timeout=0, $response_timeout=30, $cookies) {
2609: return $this->send($data, $timeout, $response_timeout, $cookies);
2610: }
2611:
2612: 2613: 2614: 2615: 2616: 2617: 2618: 2619: 2620: 2621:
2622: function setCredentials($username, $password, $authtype = 'basic', $digestRequest = array(), $certRequest = array()) {
2623: $this->debug("setCredentials username=$username authtype=$authtype digestRequest=");
2624: $this->appendDebug($this->varDump($digestRequest));
2625: $this->debug("certRequest=");
2626: $this->appendDebug($this->varDump($certRequest));
2627:
2628: if ($authtype == 'basic') {
2629: $this->setHeader('Authorization', 'Basic '.base64_encode(str_replace(':','',$username).':'.$password));
2630: } elseif ($authtype == 'digest') {
2631: if (isset($digestRequest['nonce'])) {
2632: $digestRequest['nc'] = isset($digestRequest['nc']) ? $digestRequest['nc']++ : 1;
2633:
2634:
2635:
2636:
2637: $A1 = $username. ':' . (isset($digestRequest['realm']) ? $digestRequest['realm'] : '') . ':' . $password;
2638:
2639:
2640: $HA1 = md5($A1);
2641:
2642:
2643: $A2 = $this->request_method . ':' . $this->digest_uri;
2644:
2645:
2646: $HA2 = md5($A2);
2647:
2648:
2649:
2650:
2651:
2652:
2653:
2654:
2655:
2656:
2657:
2658:
2659: $unhashedDigest = '';
2660: $nonce = isset($digestRequest['nonce']) ? $digestRequest['nonce'] : '';
2661: $cnonce = $nonce;
2662: if ($digestRequest['qop'] != '') {
2663: $unhashedDigest = $HA1 . ':' . $nonce . ':' . sprintf("%08d", $digestRequest['nc']) . ':' . $cnonce . ':' . $digestRequest['qop'] . ':' . $HA2;
2664: } else {
2665: $unhashedDigest = $HA1 . ':' . $nonce . ':' . $HA2;
2666: }
2667:
2668: $hashedDigest = md5($unhashedDigest);
2669:
2670: $opaque = '';
2671: if (isset($digestRequest['opaque'])) {
2672: $opaque = ', opaque="' . $digestRequest['opaque'] . '"';
2673: }
2674:
2675: $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 . '"');
2676: }
2677: } elseif ($authtype == 'certificate') {
2678: $this->certRequest = $certRequest;
2679: $this->debug('Authorization header not set for certificate');
2680: } elseif ($authtype == 'ntlm') {
2681:
2682: $this->debug('Authorization header not set for ntlm');
2683: }
2684: $this->username = $username;
2685: $this->password = $password;
2686: $this->authtype = $authtype;
2687: $this->digestRequest = $digestRequest;
2688: }
2689:
2690: 2691: 2692: 2693: 2694: 2695:
2696: function setSOAPAction($soapaction) {
2697: $this->setHeader('SOAPAction', '"' . $soapaction . '"');
2698: }
2699:
2700: 2701: 2702: 2703: 2704: 2705:
2706: function setEncoding($enc='gzip, deflate') {
2707: if (function_exists('gzdeflate')) {
2708: $this->protocol_version = '1.1';
2709: $this->setHeader('Accept-Encoding', $enc);
2710: if (!isset($this->outgoing_headers['Connection'])) {
2711: $this->setHeader('Connection', 'close');
2712: $this->persistentConnection = false;
2713: }
2714:
2715:
2716: $this->encoding = $enc;
2717: }
2718: }
2719:
2720: 2721: 2722: 2723: 2724: 2725: 2726: 2727: 2728: 2729:
2730: function setProxy($proxyhost, $proxyport, $proxyusername = '', $proxypassword = '', $proxyauthtype = 'basic') {
2731: if ($proxyhost) {
2732: $this->proxy = array(
2733: 'host' => $proxyhost,
2734: 'port' => $proxyport,
2735: 'username' => $proxyusername,
2736: 'password' => $proxypassword,
2737: 'authtype' => $proxyauthtype
2738: );
2739: if ($proxyusername != '' && $proxypassword != '' && $proxyauthtype = 'basic') {
2740: $this->setHeader('Proxy-Authorization', ' Basic '.base64_encode($proxyusername.':'.$proxypassword));
2741: }
2742: } else {
2743: $this->debug('remove proxy');
2744: $proxy = null;
2745: unsetHeader('Proxy-Authorization');
2746: }
2747: }
2748:
2749:
2750: 2751: 2752: 2753: 2754: 2755: 2756: 2757:
2758: function isSkippableCurlHeader(&$data) {
2759: $skipHeaders = array( 'HTTP/1.1 100',
2760: 'HTTP/1.0 301',
2761: 'HTTP/1.1 301',
2762: 'HTTP/1.0 302',
2763: 'HTTP/1.1 302',
2764: 'HTTP/1.0 401',
2765: 'HTTP/1.1 401',
2766: 'HTTP/1.0 200 Connection established');
2767: foreach ($skipHeaders as $hd) {
2768: $prefix = substr($data, 0, strlen($hd));
2769: if ($prefix == $hd) return true;
2770: }
2771:
2772: return false;
2773: }
2774:
2775: 2776: 2777: 2778: 2779: 2780: 2781: 2782: 2783: 2784:
2785: function decodeChunked($buffer, $lb){
2786:
2787: $length = 0;
2788: $new = '';
2789:
2790:
2791:
2792: $chunkend = strpos($buffer, $lb);
2793: if ($chunkend == FALSE) {
2794: $this->debug('no linebreak found in decodeChunked');
2795: return $new;
2796: }
2797: $temp = substr($buffer,0,$chunkend);
2798: $chunk_size = hexdec( trim($temp) );
2799: $chunkstart = $chunkend + strlen($lb);
2800:
2801: while ($chunk_size > 0) {
2802: $this->debug("chunkstart: $chunkstart chunk_size: $chunk_size");
2803: $chunkend = strpos( $buffer, $lb, $chunkstart + $chunk_size);
2804:
2805:
2806: if ($chunkend == FALSE) {
2807: $chunk = substr($buffer,$chunkstart);
2808:
2809: $new .= $chunk;
2810: $length += strlen($chunk);
2811: break;
2812: }
2813:
2814:
2815: $chunk = substr($buffer,$chunkstart,$chunkend-$chunkstart);
2816:
2817: $new .= $chunk;
2818:
2819: $length += strlen($chunk);
2820:
2821: $chunkstart = $chunkend + strlen($lb);
2822:
2823: $chunkend = strpos($buffer, $lb, $chunkstart) + strlen($lb);
2824: if ($chunkend == FALSE) {
2825: break;
2826: }
2827: $temp = substr($buffer,$chunkstart,$chunkend-$chunkstart);
2828: $chunk_size = hexdec( trim($temp) );
2829: $chunkstart = $chunkend;
2830: }
2831: return $new;
2832: }
2833:
2834: 2835: 2836: 2837: 2838: 2839: 2840: 2841:
2842: function buildPayload($data, $cookie_str = '') {
2843:
2844:
2845:
2846:
2847:
2848: if ($this->request_method != 'GET') {
2849: $this->setHeader('Content-Length', strlen($data));
2850: }
2851:
2852:
2853: if ($this->proxy) {
2854: $uri = $this->url;
2855: } else {
2856: $uri = $this->uri;
2857: }
2858: $req = "$this->request_method $uri HTTP/$this->protocol_version";
2859: $this->debug("HTTP request: $req");
2860: $this->outgoing_payload = "$req\r\n";
2861:
2862:
2863: foreach($this->outgoing_headers as $k => $v){
2864: $hdr = $k.': '.$v;
2865: $this->debug("HTTP header: $hdr");
2866: $this->outgoing_payload .= "$hdr\r\n";
2867: }
2868:
2869:
2870: if ($cookie_str != '') {
2871: $hdr = 'Cookie: '.$cookie_str;
2872: $this->debug("HTTP header: $hdr");
2873: $this->outgoing_payload .= "$hdr\r\n";
2874: }
2875:
2876:
2877: $this->outgoing_payload .= "\r\n";
2878:
2879:
2880: $this->outgoing_payload .= $data;
2881: }
2882:
2883: 2884: 2885: 2886: 2887: 2888: 2889: 2890:
2891: function sendRequest($data, $cookies = NULL) {
2892:
2893: $cookie_str = $this->getCookiesForRequest($cookies, (($this->scheme == 'ssl') || ($this->scheme == 'https')));
2894:
2895:
2896: $this->buildPayload($data, $cookie_str);
2897:
2898: if ($this->io_method() == 'socket') {
2899:
2900: if(!fputs($this->fp, $this->outgoing_payload, strlen($this->outgoing_payload))) {
2901: $this->setError('couldn\'t write message data to socket');
2902: $this->debug('couldn\'t write message data to socket');
2903: return false;
2904: }
2905: $this->debug('wrote data to socket, length = ' . strlen($this->outgoing_payload));
2906: return true;
2907: } else if ($this->io_method() == 'curl') {
2908:
2909:
2910:
2911:
2912:
2913: $curl_headers = array();
2914: foreach($this->outgoing_headers as $k => $v){
2915: if ($k == 'Connection' || $k == 'Content-Length' || $k == 'Host' || $k == 'Authorization' || $k == 'Proxy-Authorization') {
2916: $this->debug("Skip cURL header $k: $v");
2917: } else {
2918: $curl_headers[] = "$k: $v";
2919: }
2920: }
2921: if ($cookie_str != '') {
2922: $curl_headers[] = 'Cookie: ' . $cookie_str;
2923: }
2924: $this->setCurlOption(CURLOPT_HTTPHEADER, $curl_headers);
2925: $this->debug('set cURL HTTP headers');
2926: if ($this->request_method == "POST") {
2927: $this->setCurlOption(CURLOPT_POST, 1);
2928: $this->setCurlOption(CURLOPT_POSTFIELDS, $data);
2929: $this->debug('set cURL POST data');
2930: } else {
2931: }
2932:
2933: foreach ($this->ch_options as $key => $val) {
2934: $this->setCurlOption($key, $val);
2935: }
2936:
2937: $this->debug('set cURL payload');
2938: return true;
2939: }
2940: }
2941:
2942: 2943: 2944: 2945: 2946: 2947:
2948: function getResponse(){
2949: $this->incoming_payload = '';
2950:
2951: if ($this->io_method() == 'socket') {
2952:
2953: $data = '';
2954: while (!isset($lb)){
2955:
2956:
2957: if(feof($this->fp)) {
2958: $this->incoming_payload = $data;
2959: $this->debug('found no headers before EOF after length ' . strlen($data));
2960: $this->debug("received before EOF:\n" . $data);
2961: $this->setError('server failed to send headers');
2962: return false;
2963: }
2964:
2965: $tmp = fgets($this->fp, 256);
2966: $tmplen = strlen($tmp);
2967: $this->debug("read line of $tmplen bytes: " . trim($tmp));
2968:
2969: if ($tmplen == 0) {
2970: $this->incoming_payload = $data;
2971: $this->debug('socket read of headers timed out after length ' . strlen($data));
2972: $this->debug("read before timeout: " . $data);
2973: $this->setError('socket read of headers timed out');
2974: return false;
2975: }
2976:
2977: $data .= $tmp;
2978: $pos = strpos($data,"\r\n\r\n");
2979: if($pos > 1){
2980: $lb = "\r\n";
2981: } else {
2982: $pos = strpos($data,"\n\n");
2983: if($pos > 1){
2984: $lb = "\n";
2985: }
2986: }
2987:
2988: if (isset($lb) && preg_match('/^HTTP\/1.1 100/',$data)) {
2989: unset($lb);
2990: $data = '';
2991: }
2992: }
2993:
2994: $this->incoming_payload .= $data;
2995: $this->debug('found end of headers after length ' . strlen($data));
2996:
2997: $header_data = trim(substr($data,0,$pos));
2998: $header_array = explode($lb,$header_data);
2999: $this->incoming_headers = array();
3000: $this->incoming_cookies = array();
3001: foreach($header_array as $header_line){
3002: $arr = explode(':',$header_line, 2);
3003: if(count($arr) > 1){
3004: $header_name = strtolower(trim($arr[0]));
3005: $this->incoming_headers[$header_name] = trim($arr[1]);
3006: if ($header_name == 'set-cookie') {
3007:
3008: $cookie = $this->parseCookie(trim($arr[1]));
3009: if ($cookie) {
3010: $this->incoming_cookies[] = $cookie;
3011: $this->debug('found cookie: ' . $cookie['name'] . ' = ' . $cookie['value']);
3012: } else {
3013: $this->debug('did not find cookie in ' . trim($arr[1]));
3014: }
3015: }
3016: } else if (isset($header_name)) {
3017:
3018: $this->incoming_headers[$header_name] .= $lb . ' ' . $header_line;
3019: }
3020: }
3021:
3022:
3023: if (isset($this->incoming_headers['transfer-encoding']) && strtolower($this->incoming_headers['transfer-encoding']) == 'chunked') {
3024: $content_length = 2147483647;
3025: $chunked = true;
3026: $this->debug("want to read chunked content");
3027: } elseif (isset($this->incoming_headers['content-length'])) {
3028: $content_length = $this->incoming_headers['content-length'];
3029: $chunked = false;
3030: $this->debug("want to read content of length $content_length");
3031: } else {
3032: $content_length = 2147483647;
3033: $chunked = false;
3034: $this->debug("want to read content to EOF");
3035: }
3036: $data = '';
3037: do {
3038: if ($chunked) {
3039: $tmp = fgets($this->fp, 256);
3040: $tmplen = strlen($tmp);
3041: $this->debug("read chunk line of $tmplen bytes");
3042: if ($tmplen == 0) {
3043: $this->incoming_payload = $data;
3044: $this->debug('socket read of chunk length timed out after length ' . strlen($data));
3045: $this->debug("read before timeout:\n" . $data);
3046: $this->setError('socket read of chunk length timed out');
3047: return false;
3048: }
3049: $content_length = hexdec(trim($tmp));
3050: $this->debug("chunk length $content_length");
3051: }
3052: $strlen = 0;
3053: while (($strlen < $content_length) && (!feof($this->fp))) {
3054: $readlen = min(8192, $content_length - $strlen);
3055: $tmp = fread($this->fp, $readlen);
3056: $tmplen = strlen($tmp);
3057: $this->debug("read buffer of $tmplen bytes");
3058: if (($tmplen == 0) && (!feof($this->fp))) {
3059: $this->incoming_payload = $data;
3060: $this->debug('socket read of body timed out after length ' . strlen($data));
3061: $this->debug("read before timeout:\n" . $data);
3062: $this->setError('socket read of body timed out');
3063: return false;
3064: }
3065: $strlen += $tmplen;
3066: $data .= $tmp;
3067: }
3068: if ($chunked && ($content_length > 0)) {
3069: $tmp = fgets($this->fp, 256);
3070: $tmplen = strlen($tmp);
3071: $this->debug("read chunk terminator of $tmplen bytes");
3072: if ($tmplen == 0) {
3073: $this->incoming_payload = $data;
3074: $this->debug('socket read of chunk terminator timed out after length ' . strlen($data));
3075: $this->debug("read before timeout:\n" . $data);
3076: $this->setError('socket read of chunk terminator timed out');
3077: return false;
3078: }
3079: }
3080: } while ($chunked && ($content_length > 0) && (!feof($this->fp)));
3081: if (feof($this->fp)) {
3082: $this->debug('read to EOF');
3083: }
3084: $this->debug('read body of length ' . strlen($data));
3085: $this->incoming_payload .= $data;
3086: $this->debug('received a total of '.strlen($this->incoming_payload).' bytes of data from server');
3087:
3088:
3089: if(
3090: (isset($this->incoming_headers['connection']) && strtolower($this->incoming_headers['connection']) == 'close') ||
3091: (! $this->persistentConnection) || feof($this->fp)){
3092: fclose($this->fp);
3093: $this->fp = false;
3094: $this->debug('closed socket');
3095: }
3096:
3097:
3098: if($this->incoming_payload == ''){
3099: $this->setError('no response from server');
3100: return false;
3101: }
3102:
3103:
3104:
3105:
3106:
3107:
3108:
3109:
3110:
3111:
3112:
3113:
3114: } else if ($this->io_method() == 'curl') {
3115:
3116: $this->debug('send and receive with cURL');
3117: $this->incoming_payload = curl_exec($this->ch);
3118: $data = $this->incoming_payload;
3119:
3120: $cErr = curl_error($this->ch);
3121: if ($cErr != '') {
3122: $err = 'cURL ERROR: '.curl_errno($this->ch).': '.$cErr.'<br>';
3123:
3124: foreach(curl_getinfo($this->ch) as $k => $v){
3125: $err .= "$k: $v<br>";
3126: }
3127: $this->debug($err);
3128: $this->setError($err);
3129: curl_close($this->ch);
3130: return false;
3131: } else {
3132:
3133:
3134:
3135: }
3136:
3137: $this->debug('No cURL error, closing cURL');
3138: curl_close($this->ch);
3139:
3140:
3141: $savedata = $data;
3142: while ($this->isSkippableCurlHeader($data)) {
3143: $this->debug("Found HTTP header to skip");
3144: if ($pos = strpos($data,"\r\n\r\n")) {
3145: $data = ltrim(substr($data,$pos));
3146: } elseif($pos = strpos($data,"\n\n") ) {
3147: $data = ltrim(substr($data,$pos));
3148: }
3149: }
3150:
3151: if ($data == '') {
3152:
3153: $data = $savedata;
3154: while (preg_match('/^HTTP\/1.1 100/',$data)) {
3155: if ($pos = strpos($data,"\r\n\r\n")) {
3156: $data = ltrim(substr($data,$pos));
3157: } elseif($pos = strpos($data,"\n\n") ) {
3158: $data = ltrim(substr($data,$pos));
3159: }
3160: }
3161: }
3162:
3163:
3164: if ($pos = strpos($data,"\r\n\r\n")) {
3165: $lb = "\r\n";
3166: } elseif( $pos = strpos($data,"\n\n")) {
3167: $lb = "\n";
3168: } else {
3169: $this->debug('no proper separation of headers and document');
3170: $this->setError('no proper separation of headers and document');
3171: return false;
3172: }
3173: $header_data = trim(substr($data,0,$pos));
3174: $header_array = explode($lb,$header_data);
3175: $data = ltrim(substr($data,$pos));
3176: $this->debug('found proper separation of headers and document');
3177: $this->debug('cleaned data, stringlen: '.strlen($data));
3178:
3179: foreach ($header_array as $header_line) {
3180: $arr = explode(':',$header_line,2);
3181: if(count($arr) > 1){
3182: $header_name = strtolower(trim($arr[0]));
3183: $this->incoming_headers[$header_name] = trim($arr[1]);
3184: if ($header_name == 'set-cookie') {
3185:
3186: $cookie = $this->parseCookie(trim($arr[1]));
3187: if ($cookie) {
3188: $this->incoming_cookies[] = $cookie;
3189: $this->debug('found cookie: ' . $cookie['name'] . ' = ' . $cookie['value']);
3190: } else {
3191: $this->debug('did not find cookie in ' . trim($arr[1]));
3192: }
3193: }
3194: } else if (isset($header_name)) {
3195:
3196: $this->incoming_headers[$header_name] .= $lb . ' ' . $header_line;
3197: }
3198: }
3199: }
3200:
3201: $this->response_status_line = $header_array[0];
3202: $arr = explode(' ', $this->response_status_line, 3);
3203: $http_version = $arr[0];
3204: $http_status = intval($arr[1]);
3205: $http_reason = count($arr) > 2 ? $arr[2] : '';
3206:
3207:
3208: if (isset($this->incoming_headers['location']) && ($http_status == 301 || $http_status == 302)) {
3209: $this->debug("Got $http_status $http_reason with Location: " . $this->incoming_headers['location']);
3210: $this->setURL($this->incoming_headers['location']);
3211: $this->tryagain = true;
3212: return false;
3213: }
3214:
3215:
3216: if (isset($this->incoming_headers['www-authenticate']) && $http_status == 401) {
3217: $this->debug("Got 401 $http_reason with WWW-Authenticate: " . $this->incoming_headers['www-authenticate']);
3218: if (strstr($this->incoming_headers['www-authenticate'], "Digest ")) {
3219: $this->debug('Server wants digest authentication');
3220:
3221: $digestString = str_replace('Digest ', '', $this->incoming_headers['www-authenticate']);
3222:
3223:
3224: $digestElements = explode(',', $digestString);
3225: foreach ($digestElements as $val) {
3226: $tempElement = explode('=', trim($val), 2);
3227: $digestRequest[$tempElement[0]] = str_replace("\"", '', $tempElement[1]);
3228: }
3229:
3230:
3231: if (isset($digestRequest['nonce'])) {
3232: $this->setCredentials($this->username, $this->password, 'digest', $digestRequest);
3233: $this->tryagain = true;
3234: return false;
3235: }
3236: }
3237: $this->debug('HTTP authentication failed');
3238: $this->setError('HTTP authentication failed');
3239: return false;
3240: }
3241:
3242: if (
3243: ($http_status >= 300 && $http_status <= 307) ||
3244: ($http_status >= 400 && $http_status <= 417) ||
3245: ($http_status >= 501 && $http_status <= 505)
3246: ) {
3247: $this->setError("Unsupported HTTP response status $http_status $http_reason (soapclient->response has contents of the response)");
3248: return false;
3249: }
3250:
3251:
3252: if(isset($this->incoming_headers['content-encoding']) && $this->incoming_headers['content-encoding'] != ''){
3253: if(strtolower($this->incoming_headers['content-encoding']) == 'deflate' || strtolower($this->incoming_headers['content-encoding']) == 'gzip'){
3254:
3255: if(function_exists('gzinflate')){
3256:
3257:
3258:
3259: $this->debug('The gzinflate function exists');
3260: $datalen = strlen($data);
3261: if ($this->incoming_headers['content-encoding'] == 'deflate') {
3262: if ($degzdata = @gzinflate($data)) {
3263: $data = $degzdata;
3264: $this->debug('The payload has been inflated to ' . strlen($data) . ' bytes');
3265: if (strlen($data) < $datalen) {
3266:
3267: $this->debug('The inflated payload is smaller than the gzipped one; try again');
3268: if ($degzdata = @gzinflate($data)) {
3269: $data = $degzdata;
3270: $this->debug('The payload has been inflated again to ' . strlen($data) . ' bytes');
3271: }
3272: }
3273: } else {
3274: $this->debug('Error using gzinflate to inflate the payload');
3275: $this->setError('Error using gzinflate to inflate the payload');
3276: }
3277: } elseif ($this->incoming_headers['content-encoding'] == 'gzip') {
3278: if ($degzdata = @gzinflate(substr($data, 10))) {
3279: $data = $degzdata;
3280: $this->debug('The payload has been un-gzipped to ' . strlen($data) . ' bytes');
3281: if (strlen($data) < $datalen) {
3282:
3283: $this->debug('The un-gzipped payload is smaller than the gzipped one; try again');
3284: if ($degzdata = @gzinflate(substr($data, 10))) {
3285: $data = $degzdata;
3286: $this->debug('The payload has been un-gzipped again to ' . strlen($data) . ' bytes');
3287: }
3288: }
3289: } else {
3290: $this->debug('Error using gzinflate to un-gzip the payload');
3291: $this->setError('Error using gzinflate to un-gzip the payload');
3292: }
3293: }
3294:
3295:
3296:
3297: $this->incoming_payload = $header_data.$lb.$lb.$data;
3298: } else {
3299: $this->debug('The server sent compressed data. Your php install must have the Zlib extension compiled in to support this.');
3300: $this->setError('The server sent compressed data. Your php install must have the Zlib extension compiled in to support this.');
3301: }
3302: } else {
3303: $this->debug('Unsupported Content-Encoding ' . $this->incoming_headers['content-encoding']);
3304: $this->setError('Unsupported Content-Encoding ' . $this->incoming_headers['content-encoding']);
3305: }
3306: } else {
3307: $this->debug('No Content-Encoding header');
3308: }
3309:
3310: if(strlen($data) == 0){
3311: $this->debug('no data after headers!');
3312: $this->setError('no data present after HTTP headers');
3313: return false;
3314: }
3315:
3316: return $data;
3317: }
3318:
3319: 3320: 3321: 3322: 3323: 3324: 3325:
3326: function setContentType($type, $charset = false) {
3327: $this->setHeader('Content-Type', $type . ($charset ? '; charset=' . $charset : ''));
3328: }
3329:
3330: 3331: 3332: 3333: 3334: 3335:
3336: function usePersistentConnection(){
3337: if (isset($this->outgoing_headers['Accept-Encoding'])) {
3338: return false;
3339: }
3340: $this->protocol_version = '1.1';
3341: $this->persistentConnection = true;
3342: $this->setHeader('Connection', 'Keep-Alive');
3343: return true;
3344: }
3345:
3346: 3347: 3348: 3349: 3350: 3351: 3352:
3353: 3354: 3355:
3356: function parseCookie($cookie_str) {
3357: $cookie_str = str_replace('; ', ';', $cookie_str) . ';';
3358: $data = preg_split('/;/', $cookie_str);
3359: $value_str = $data[0];
3360:
3361: $cookie_param = 'domain=';
3362: $start = strpos($cookie_str, $cookie_param);
3363: if ($start > 0) {
3364: $domain = substr($cookie_str, $start + strlen($cookie_param));
3365: $domain = substr($domain, 0, strpos($domain, ';'));
3366: } else {
3367: $domain = '';
3368: }
3369:
3370: $cookie_param = 'expires=';
3371: $start = strpos($cookie_str, $cookie_param);
3372: if ($start > 0) {
3373: $expires = substr($cookie_str, $start + strlen($cookie_param));
3374: $expires = substr($expires, 0, strpos($expires, ';'));
3375: } else {
3376: $expires = '';
3377: }
3378:
3379: $cookie_param = 'path=';
3380: $start = strpos($cookie_str, $cookie_param);
3381: if ( $start > 0 ) {
3382: $path = substr($cookie_str, $start + strlen($cookie_param));
3383: $path = substr($path, 0, strpos($path, ';'));
3384: } else {
3385: $path = '/';
3386: }
3387:
3388: $cookie_param = ';secure;';
3389: if (strpos($cookie_str, $cookie_param) !== FALSE) {
3390: $secure = true;
3391: } else {
3392: $secure = false;
3393: }
3394:
3395: $sep_pos = strpos($value_str, '=');
3396:
3397: if ($sep_pos) {
3398: $name = substr($value_str, 0, $sep_pos);
3399: $value = substr($value_str, $sep_pos + 1);
3400: $cookie= array( 'name' => $name,
3401: 'value' => $value,
3402: 'domain' => $domain,
3403: 'path' => $path,
3404: 'expires' => $expires,
3405: 'secure' => $secure
3406: );
3407: return $cookie;
3408: }
3409: return false;
3410: }
3411:
3412: 3413: 3414: 3415: 3416: 3417: 3418: 3419:
3420: function getCookiesForRequest($cookies, $secure=false) {
3421: $cookie_str = '';
3422: if ((! is_null($cookies)) && (is_array($cookies))) {
3423: foreach ($cookies as $cookie) {
3424: if (! is_array($cookie)) {
3425: continue;
3426: }
3427: $this->debug("check cookie for validity: ".$cookie['name'].'='.$cookie['value']);
3428: if ((isset($cookie['expires'])) && (! empty($cookie['expires']))) {
3429: if (strtotime($cookie['expires']) <= time()) {
3430: $this->debug('cookie has expired');
3431: continue;
3432: }
3433: }
3434: if ((isset($cookie['domain'])) && (! empty($cookie['domain']))) {
3435: $domain = preg_quote($cookie['domain']);
3436: if (! preg_match("'.*$domain$'i", $this->host)) {
3437: $this->debug('cookie has different domain');
3438: continue;
3439: }
3440: }
3441: if ((isset($cookie['path'])) && (! empty($cookie['path']))) {
3442: $path = preg_quote($cookie['path']);
3443: if (! preg_match("'^$path.*'i", $this->path)) {
3444: $this->debug('cookie is for a different path');
3445: continue;
3446: }
3447: }
3448: if ((! $secure) && (isset($cookie['secure'])) && ($cookie['secure'])) {
3449: $this->debug('cookie is secure, transport is not');
3450: continue;
3451: }
3452: $cookie_str .= $cookie['name'] . '=' . $cookie['value'] . '; ';
3453: $this->debug('add cookie to Cookie-String: ' . $cookie['name'] . '=' . $cookie['value']);
3454: }
3455: }
3456: return $cookie_str;
3457: }
3458: }
3459:
3460: ?><?php
3461:
3462:
3463:
3464: 3465: 3466: 3467: 3468: 3469: 3470: 3471: 3472: 3473:
3474: class nusoap_server extends nusoap_base {
3475: 3476: 3477: 3478: 3479:
3480: var $headers = array();
3481: 3482: 3483: 3484: 3485:
3486: var $request = '';
3487: 3488: 3489: 3490: 3491:
3492: var $requestHeaders = '';
3493: 3494: 3495: 3496: 3497:
3498: var $requestHeader = NULL;
3499: 3500: 3501: 3502: 3503:
3504: var $document = '';
3505: 3506: 3507: 3508: 3509:
3510: var $requestSOAP = '';
3511: 3512: 3513: 3514: 3515:
3516: var $methodURI = '';
3517: 3518: 3519: 3520: 3521:
3522: var $methodname = '';
3523: 3524: 3525: 3526: 3527:
3528: var $methodparams = array();
3529: 3530: 3531: 3532: 3533:
3534: var $SOAPAction = '';
3535: 3536: 3537: 3538: 3539:
3540: var $xml_encoding = '';
3541: 3542: 3543: 3544: 3545:
3546: var $decode_utf8 = true;
3547:
3548: 3549: 3550: 3551: 3552:
3553: var $outgoing_headers = array();
3554: 3555: 3556: 3557: 3558:
3559: var $response = '';
3560: 3561: 3562: 3563: 3564:
3565: var $responseHeaders = '';
3566: 3567: 3568: 3569: 3570:
3571: var $responseSOAP = '';
3572: 3573: 3574: 3575: 3576:
3577: var $methodreturn = false;
3578: 3579: 3580: 3581: 3582:
3583: var $methodreturnisliteralxml = false;
3584: 3585: 3586: 3587: 3588:
3589: var $fault = false;
3590: 3591: 3592: 3593: 3594:
3595: var $result = 'successful';
3596:
3597: 3598: 3599: 3600: 3601: 3602:
3603: var $operations = array();
3604: 3605: 3606: 3607: 3608:
3609: var $wsdl = false;
3610: 3611: 3612: 3613: 3614:
3615: var $externalWSDLURL = false;
3616: 3617: 3618: 3619: 3620:
3621: var $debug_flag = false;
3622:
3623:
3624: 3625: 3626: 3627: 3628: 3629: 3630:
3631: function nusoap_server($wsdl=false){
3632: parent::nusoap_base();
3633:
3634: global $debug;
3635: global $HTTP_SERVER_VARS;
3636:
3637: if (isset($_SERVER)) {
3638: $this->debug("_SERVER is defined:");
3639: $this->appendDebug($this->varDump($_SERVER));
3640: } elseif (isset($HTTP_SERVER_VARS)) {
3641: $this->debug("HTTP_SERVER_VARS is defined:");
3642: $this->appendDebug($this->varDump($HTTP_SERVER_VARS));
3643: } else {
3644: $this->debug("Neither _SERVER nor HTTP_SERVER_VARS is defined.");
3645: }
3646:
3647: if (isset($debug)) {
3648: $this->debug("In nusoap_server, set debug_flag=$debug based on global flag");
3649: $this->debug_flag = $debug;
3650: } elseif (isset($_SERVER['QUERY_STRING'])) {
3651: $qs = explode('&', $_SERVER['QUERY_STRING']);
3652: foreach ($qs as $v) {
3653: if (substr($v, 0, 6) == 'debug=') {
3654: $this->debug("In nusoap_server, set debug_flag=" . substr($v, 6) . " based on query string #1");
3655: $this->debug_flag = substr($v, 6);
3656: }
3657: }
3658: } elseif (isset($HTTP_SERVER_VARS['QUERY_STRING'])) {
3659: $qs = explode('&', $HTTP_SERVER_VARS['QUERY_STRING']);
3660: foreach ($qs as $v) {
3661: if (substr($v, 0, 6) == 'debug=') {
3662: $this->debug("In nusoap_server, set debug_flag=" . substr($v, 6) . " based on query string #2");
3663: $this->debug_flag = substr($v, 6);
3664: }
3665: }
3666: }
3667:
3668:
3669: if($wsdl){
3670: $this->debug("In nusoap_server, WSDL is specified");
3671: if (is_object($wsdl) && (get_class($wsdl) == 'wsdl')) {
3672: $this->wsdl = $wsdl;
3673: $this->externalWSDLURL = $this->wsdl->wsdl;
3674: $this->debug('Use existing wsdl instance from ' . $this->externalWSDLURL);
3675: } else {
3676: $this->debug('Create wsdl from ' . $wsdl);
3677: $this->wsdl = new wsdl($wsdl);
3678: $this->externalWSDLURL = $wsdl;
3679: }
3680: $this->appendDebug($this->wsdl->getDebug());
3681: $this->wsdl->clearDebug();
3682: if($err = $this->wsdl->getError()){
3683: die('WSDL ERROR: '.$err);
3684: }
3685: }
3686: }
3687:
3688: 3689: 3690: 3691: 3692: 3693:
3694: function service($data){
3695: global $HTTP_SERVER_VARS;
3696:
3697: if (isset($_SERVER['REQUEST_METHOD'])) {
3698: $rm = $_SERVER['REQUEST_METHOD'];
3699: } elseif (isset($HTTP_SERVER_VARS['REQUEST_METHOD'])) {
3700: $rm = $HTTP_SERVER_VARS['REQUEST_METHOD'];
3701: } else {
3702: $rm = '';
3703: }
3704:
3705: if (isset($_SERVER['QUERY_STRING'])) {
3706: $qs = $_SERVER['QUERY_STRING'];
3707: } elseif (isset($HTTP_SERVER_VARS['QUERY_STRING'])) {
3708: $qs = $HTTP_SERVER_VARS['QUERY_STRING'];
3709: } else {
3710: $qs = '';
3711: }
3712: $this->debug("In service, request method=$rm query string=$qs strlen(\$data)=" . strlen($data));
3713:
3714: if ($rm == 'POST') {
3715: $this->debug("In service, invoke the request");
3716: $this->parse_request($data);
3717: if (! $this->fault) {
3718: $this->invoke_method();
3719: }
3720: if (! $this->fault) {
3721: $this->serialize_return();
3722: }
3723: $this->send_response();
3724: } elseif (preg_match('/wsdl/', $qs) ){
3725: $this->debug("In service, this is a request for WSDL");
3726: if ($this->externalWSDLURL){
3727: if (strpos($this->externalWSDLURL, "http://") !== false) {
3728: $this->debug("In service, re-direct for WSDL");
3729: header('Location: '.$this->externalWSDLURL);
3730: } else {
3731: $this->debug("In service, use file passthru for WSDL");
3732: header("Content-Type: text/xml\r\n");
3733: $pos = strpos($this->externalWSDLURL, "file://");
3734: if ($pos === false) {
3735: $filename = $this->externalWSDLURL;
3736: } else {
3737: $filename = substr($this->externalWSDLURL, $pos + 7);
3738: }
3739: $fp = fopen($this->externalWSDLURL, 'r');
3740: fpassthru($fp);
3741: }
3742: } elseif ($this->wsdl) {
3743: $this->debug("In service, serialize WSDL");
3744: header("Content-Type: text/xml; charset=ISO-8859-1\r\n");
3745: print $this->wsdl->serialize($this->debug_flag);
3746: if ($this->debug_flag) {
3747: $this->debug('wsdl:');
3748: $this->appendDebug($this->varDump($this->wsdl));
3749: print $this->getDebugAsXMLComment();
3750: }
3751: } else {
3752: $this->debug("In service, there is no WSDL");
3753: header("Content-Type: text/html; charset=ISO-8859-1\r\n");
3754: print "This service does not provide WSDL";
3755: }
3756: } elseif ($this->wsdl) {
3757: $this->debug("In service, return Web description");
3758: print $this->wsdl->webDescription();
3759: } else {
3760: $this->debug("In service, no Web description");
3761: header("Content-Type: text/html; charset=ISO-8859-1\r\n");
3762: print "This service does not provide a Web description";
3763: }
3764: }
3765:
3766: 3767: 3768: 3769: 3770: 3771: 3772: 3773: 3774: 3775: 3776: 3777:
3778: function parse_http_headers() {
3779: global $HTTP_SERVER_VARS;
3780:
3781: $this->request = '';
3782: $this->SOAPAction = '';
3783: if(function_exists('getallheaders')){
3784: $this->debug("In parse_http_headers, use getallheaders");
3785: $headers = getallheaders();
3786: foreach($headers as $k=>$v){
3787: $k = strtolower($k);
3788: $this->headers[$k] = $v;
3789: $this->request .= "$k: $v\r\n";
3790: $this->debug("$k: $v");
3791: }
3792:
3793: if(isset($this->headers['soapaction'])){
3794: $this->SOAPAction = str_replace('"','',$this->headers['soapaction']);
3795: }
3796:
3797: if(isset($this->headers['content-type']) && strpos($this->headers['content-type'],'=')){
3798: $enc = str_replace('"','',substr(strstr($this->headers["content-type"],'='),1));
3799: if(preg_match('/^(ISO-8859-1|US-ASCII|UTF-8)$/i',$enc)){
3800: $this->xml_encoding = strtoupper($enc);
3801: } else {
3802: $this->xml_encoding = 'US-ASCII';
3803: }
3804: } else {
3805:
3806: $this->xml_encoding = 'ISO-8859-1';
3807: }
3808: } elseif(isset($_SERVER) && is_array($_SERVER)){
3809: $this->debug("In parse_http_headers, use _SERVER");
3810: foreach ($_SERVER as $k => $v) {
3811: if (substr($k, 0, 5) == 'HTTP_') {
3812: $k = str_replace(' ', '-', strtolower(str_replace('_', ' ', substr($k, 5))));
3813: } else {
3814: $k = str_replace(' ', '-', strtolower(str_replace('_', ' ', $k)));
3815: }
3816: if ($k == 'soapaction') {
3817:
3818: $k = 'SOAPAction';
3819: $v = str_replace('"', '', $v);
3820: $v = str_replace('\\', '', $v);
3821: $this->SOAPAction = $v;
3822: } else if ($k == 'content-type') {
3823:
3824: if (strpos($v, '=')) {
3825: $enc = substr(strstr($v, '='), 1);
3826: $enc = str_replace('"', '', $enc);
3827: $enc = str_replace('\\', '', $enc);
3828: if (preg_match('/^(ISO-8859-1|US-ASCII|UTF-8)$/i',$enc)) {
3829: $this->xml_encoding = strtoupper($enc);
3830: } else {
3831: $this->xml_encoding = 'US-ASCII';
3832: }
3833: } else {
3834:
3835: $this->xml_encoding = 'ISO-8859-1';
3836: }
3837: }
3838: $this->headers[$k] = $v;
3839: $this->request .= "$k: $v\r\n";
3840: $this->debug("$k: $v");
3841: }
3842: } elseif (is_array($HTTP_SERVER_VARS)) {
3843: $this->debug("In parse_http_headers, use HTTP_SERVER_VARS");
3844: foreach ($HTTP_SERVER_VARS as $k => $v) {
3845: if (substr($k, 0, 5) == 'HTTP_') {
3846: $k = str_replace(' ', '-', strtolower(str_replace('_', ' ', substr($k, 5)))); $k = strtolower(substr($k, 5));
3847: } else {
3848: $k = str_replace(' ', '-', strtolower(str_replace('_', ' ', $k))); $k = strtolower($k);
3849: }
3850: if ($k == 'soapaction') {
3851:
3852: $k = 'SOAPAction';
3853: $v = str_replace('"', '', $v);
3854: $v = str_replace('\\', '', $v);
3855: $this->SOAPAction = $v;
3856: } else if ($k == 'content-type') {
3857:
3858: if (strpos($v, '=')) {
3859: $enc = substr(strstr($v, '='), 1);
3860: $enc = str_replace('"', '', $enc);
3861: $enc = str_replace('\\', '', $enc);
3862: if (preg_match('/^(ISO-8859-1|US-ASCII|UTF-8)$/i',$enc)) {
3863: $this->xml_encoding = strtoupper($enc);
3864: } else {
3865: $this->xml_encoding = 'US-ASCII';
3866: }
3867: } else {
3868:
3869: $this->xml_encoding = 'ISO-8859-1';
3870: }
3871: }
3872: $this->headers[$k] = $v;
3873: $this->request .= "$k: $v\r\n";
3874: $this->debug("$k: $v");
3875: }
3876: } else {
3877: $this->debug("In parse_http_headers, HTTP headers not accessible");
3878: $this->setError("HTTP headers not accessible");
3879: }
3880: }
3881:
3882: 3883: 3884: 3885: 3886: 3887: 3888: 3889: 3890: 3891: 3892: 3893: 3894: 3895: 3896: 3897: 3898: 3899: 3900: 3901: 3902: 3903:
3904: function parse_request($data='') {
3905: $this->debug('entering parse_request()');
3906: $this->parse_http_headers();
3907: $this->debug('got character encoding: '.$this->xml_encoding);
3908:
3909: if (isset($this->headers['content-encoding']) && $this->headers['content-encoding'] != '') {
3910: $this->debug('got content encoding: ' . $this->headers['content-encoding']);
3911: if ($this->headers['content-encoding'] == 'deflate' || $this->headers['content-encoding'] == 'gzip') {
3912:
3913: if (function_exists('gzuncompress')) {
3914: if ($this->headers['content-encoding'] == 'deflate' && $degzdata = @gzuncompress($data)) {
3915: $data = $degzdata;
3916: } elseif ($this->headers['content-encoding'] == 'gzip' && $degzdata = gzinflate(substr($data, 10))) {
3917: $data = $degzdata;
3918: } else {
3919: $this->fault('SOAP-ENV:Client', 'Errors occurred when trying to decode the data');
3920: return;
3921: }
3922: } else {
3923: $this->fault('SOAP-ENV:Client', 'This Server does not support compressed data');
3924: return;
3925: }
3926: }
3927: }
3928: $this->request .= "\r\n".$data;
3929: $data = $this->parseRequest($this->headers, $data);
3930: $this->requestSOAP = $data;
3931: $this->debug('leaving parse_request');
3932: }
3933:
3934: 3935: 3936: 3937: 3938: 3939: 3940: 3941: 3942: 3943: 3944: 3945: 3946: 3947: 3948: 3949: 3950:
3951: function invoke_method() {
3952: $this->debug('in invoke_method, methodname=' . $this->methodname . ' methodURI=' . $this->methodURI . ' SOAPAction=' . $this->SOAPAction);
3953:
3954:
3955:
3956:
3957:
3958:
3959:
3960:
3961:
3962:
3963:
3964: $orig_methodname = $this->methodname;
3965: if ($this->wsdl) {
3966: if ($this->opData = $this->wsdl->getOperationData($this->methodname)) {
3967: $this->debug('in invoke_method, found WSDL operation=' . $this->methodname);
3968: $this->appendDebug('opData=' . $this->varDump($this->opData));
3969: } elseif ($this->opData = $this->wsdl->getOperationDataForSoapAction($this->SOAPAction)) {
3970:
3971: $this->debug('in invoke_method, found WSDL soapAction=' . $this->SOAPAction . ' for operation=' . $this->opData['name']);
3972: $this->appendDebug('opData=' . $this->varDump($this->opData));
3973: $this->methodname = $this->opData['name'];
3974: } else {
3975: $this->debug('in invoke_method, no WSDL for operation=' . $this->methodname);
3976: $this->fault('SOAP-ENV:Client', "Operation '" . $this->methodname . "' is not defined in the WSDL for this service");
3977: return;
3978: }
3979: } else {
3980: $this->debug('in invoke_method, no WSDL to validate method');
3981: }
3982:
3983:
3984:
3985:
3986: if (strpos($this->methodname, '..') > 0) {
3987: $delim = '..';
3988: } else if (strpos($this->methodname, '.') > 0) {
3989: $delim = '.';
3990: } else {
3991: $delim = '';
3992: }
3993: $this->debug("in invoke_method, delim=$delim");
3994:
3995: $class = '';
3996: $method = '';
3997: if (strlen($delim) > 0 && substr_count($this->methodname, $delim) == 1) {
3998: $try_class = substr($this->methodname, 0, strpos($this->methodname, $delim));
3999: if (class_exists($try_class)) {
4000:
4001: $class = $try_class;
4002: $method = substr($this->methodname, strpos($this->methodname, $delim) + strlen($delim));
4003: $this->debug("in invoke_method, class=$class method=$method delim=$delim");
4004: } else {
4005: $this->debug("in invoke_method, class=$try_class not found");
4006: }
4007: } else {
4008: $try_class = '';
4009: $this->debug("in invoke_method, no class to try");
4010: }
4011:
4012:
4013: if ($class == '') {
4014: if (!function_exists($this->methodname)) {
4015: $this->debug("in invoke_method, function '$this->methodname' not found!");
4016: $this->result = 'fault: method not found';
4017: $this->fault('SOAP-ENV:Client',"method '$this->methodname'('$orig_methodname') not defined in service('$try_class' '$delim')");
4018: return;
4019: }
4020: } else {
4021: $method_to_compare = (substr(phpversion(), 0, 2) == '4.') ? strtolower($method) : $method;
4022: if (!in_array($method_to_compare, get_class_methods($class))) {
4023: $this->debug("in invoke_method, method '$this->methodname' not found in class '$class'!");
4024: $this->result = 'fault: method not found';
4025: $this->fault('SOAP-ENV:Client',"method '$this->methodname'/'$method_to_compare'('$orig_methodname') not defined in service/'$class'('$try_class' '$delim')");
4026: return;
4027: }
4028: }
4029:
4030:
4031:
4032: if(! $this->verify_method($this->methodname,$this->methodparams)){
4033:
4034: $this->debug('ERROR: request not verified against method signature');
4035: $this->result = 'fault: request failed validation against method signature';
4036:
4037: $this->fault('SOAP-ENV:Client',"Operation '$this->methodname' not defined in service.");
4038: return;
4039: }
4040:
4041:
4042: $this->debug('in invoke_method, params:');
4043: $this->appendDebug($this->varDump($this->methodparams));
4044: $this->debug("in invoke_method, calling '$this->methodname'");
4045: if (!function_exists('call_user_func_array')) {
4046: if ($class == '') {
4047: $this->debug('in invoke_method, calling function using eval()');
4048: $funcCall = "\$this->methodreturn = $this->methodname(";
4049: } else {
4050: if ($delim == '..') {
4051: $this->debug('in invoke_method, calling class method using eval()');
4052: $funcCall = "\$this->methodreturn = ".$class."::".$method."(";
4053: } else {
4054: $this->debug('in invoke_method, calling instance method using eval()');
4055:
4056: $instname = "\$inst_".time();
4057: $funcCall = $instname." = new ".$class."(); ";
4058: $funcCall .= "\$this->methodreturn = ".$instname."->".$method."(";
4059: }
4060: }
4061: if ($this->methodparams) {
4062: foreach ($this->methodparams as $param) {
4063: if (is_array($param) || is_object($param)) {
4064: $this->fault('SOAP-ENV:Client', 'NuSOAP does not handle complexType parameters correctly when using eval; call_user_func_array must be available');
4065: return;
4066: }
4067: $funcCall .= "\"$param\",";
4068: }
4069: $funcCall = substr($funcCall, 0, -1);
4070: }
4071: $funcCall .= ');';
4072: $this->debug('in invoke_method, function call: '.$funcCall);
4073: @eval($funcCall);
4074: } else {
4075: if ($class == '') {
4076: $this->debug('in invoke_method, calling function using call_user_func_array()');
4077: $call_arg = "$this->methodname";
4078: } elseif ($delim == '..') {
4079: $this->debug('in invoke_method, calling class method using call_user_func_array()');
4080: $call_arg = array ($class, $method);
4081: } else {
4082: $this->debug('in invoke_method, calling instance method using call_user_func_array()');
4083: $instance = new $class ();
4084: $call_arg = array(&$instance, $method);
4085: }
4086: if (is_array($this->methodparams)) {
4087: $this->methodreturn = call_user_func_array($call_arg, array_values($this->methodparams));
4088: } else {
4089: $this->methodreturn = call_user_func_array($call_arg, array());
4090: }
4091: }
4092: $this->debug('in invoke_method, methodreturn:');
4093: $this->appendDebug($this->varDump($this->methodreturn));
4094: $this->debug("in invoke_method, called method $this->methodname, received data of type ".gettype($this->methodreturn));
4095: }
4096:
4097: 4098: 4099: 4100: 4101: 4102: 4103: 4104: 4105: 4106: 4107:
4108: function serialize_return() {
4109: $this->debug('Entering serialize_return methodname: ' . $this->methodname . ' methodURI: ' . $this->methodURI);
4110:
4111: if (isset($this->methodreturn) && is_object($this->methodreturn) && ((get_class($this->methodreturn) == 'soap_fault') || (get_class($this->methodreturn) == 'nusoap_fault'))) {
4112: $this->debug('got a fault object from method');
4113: $this->fault = $this->methodreturn;
4114: return;
4115: } elseif ($this->methodreturnisliteralxml) {
4116: $return_val = $this->methodreturn;
4117:
4118: } else {
4119: $this->debug('got a(n) '.gettype($this->methodreturn).' from method');
4120: $this->debug('serializing return value');
4121: if($this->wsdl){
4122: if (sizeof($this->opData['output']['parts']) > 1) {
4123: $this->debug('more than one output part, so use the method return unchanged');
4124: $opParams = $this->methodreturn;
4125: } elseif (sizeof($this->opData['output']['parts']) == 1) {
4126: $this->debug('exactly one output part, so wrap the method return in a simple array');
4127:
4128:
4129:
4130:
4131: $opParams = array($this->methodreturn);
4132: }
4133: $return_val = $this->wsdl->serializeRPCParameters($this->methodname,'output',$opParams);
4134: $this->appendDebug($this->wsdl->getDebug());
4135: $this->wsdl->clearDebug();
4136: if($errstr = $this->wsdl->getError()){
4137: $this->debug('got wsdl error: '.$errstr);
4138: $this->fault('SOAP-ENV:Server', 'unable to serialize result');
4139: return;
4140: }
4141: } else {
4142: if (isset($this->methodreturn)) {
4143: $return_val = $this->serialize_val($this->methodreturn, 'return');
4144: } else {
4145: $return_val = '';
4146: $this->debug('in absence of WSDL, assume void return for backward compatibility');
4147: }
4148: }
4149: }
4150: $this->debug('return value:');
4151: $this->appendDebug($this->varDump($return_val));
4152:
4153: $this->debug('serializing response');
4154: if ($this->wsdl) {
4155: $this->debug('have WSDL for serialization: style is ' . $this->opData['style']);
4156: if ($this->opData['style'] == 'rpc') {
4157: $this->debug('style is rpc for serialization: use is ' . $this->opData['output']['use']);
4158: if ($this->opData['output']['use'] == 'literal') {
4159:
4160: if ($this->methodURI) {
4161: $payload = '<ns1:'.$this->methodname.'Response xmlns:ns1="'.$this->methodURI.'">'.$return_val.'</ns1:'.$this->methodname."Response>";
4162: } else {
4163: $payload = '<'.$this->methodname.'Response>'.$return_val.'</'.$this->methodname.'Response>';
4164: }
4165: } else {
4166: if ($this->methodURI) {
4167: $payload = '<ns1:'.$this->methodname.'Response xmlns:ns1="'.$this->methodURI.'">'.$return_val.'</ns1:'.$this->methodname."Response>";
4168: } else {
4169: $payload = '<'.$this->methodname.'Response>'.$return_val.'</'.$this->methodname.'Response>';
4170: }
4171: }
4172: } else {
4173: $this->debug('style is not rpc for serialization: assume document');
4174: $payload = $return_val;
4175: }
4176: } else {
4177: $this->debug('do not have WSDL for serialization: assume rpc/encoded');
4178: $payload = '<ns1:'.$this->methodname.'Response xmlns:ns1="'.$this->methodURI.'">'.$return_val.'</ns1:'.$this->methodname."Response>";
4179: }
4180: $this->result = 'successful';
4181: if($this->wsdl){
4182:
4183: $this->appendDebug($this->wsdl->getDebug());
4184:
4185: if (isset($this->opData['output']['encodingStyle'])) {
4186: $encodingStyle = $this->opData['output']['encodingStyle'];
4187: } else {
4188: $encodingStyle = '';
4189: }
4190:
4191: $this->responseSOAP = $this->serializeEnvelope($payload,$this->responseHeaders,$this->wsdl->usedNamespaces,$this->opData['style'],$this->opData['output']['use'],$encodingStyle);
4192: } else {
4193: $this->responseSOAP = $this->serializeEnvelope($payload,$this->responseHeaders);
4194: }
4195: $this->debug("Leaving serialize_return");
4196: }
4197:
4198: 4199: 4200: 4201: 4202: 4203: 4204: 4205: 4206: 4207:
4208: function send_response() {
4209: $this->debug('Enter send_response');
4210: if ($this->fault) {
4211: $payload = $this->fault->serialize();
4212: $this->outgoing_headers[] = "HTTP/1.0 500 Internal Server Error";
4213: $this->outgoing_headers[] = "Status: 500 Internal Server Error";
4214: } else {
4215: $payload = $this->responseSOAP;
4216:
4217:
4218:
4219:
4220:
4221: }
4222:
4223: if(isset($this->debug_flag) && $this->debug_flag){
4224: $payload .= $this->getDebugAsXMLComment();
4225: }
4226: $this->outgoing_headers[] = "Server: $this->title Server v$this->version";
4227: preg_match('/\$Revisio' . 'n: ([^ ]+)/', $this->revision, $rev);
4228: $this->outgoing_headers[] = "X-SOAP-Server: $this->title/$this->version (".$rev[1].")";
4229:
4230:
4231: $payload = $this->getHTTPBody($payload);
4232: $type = $this->getHTTPContentType();
4233: $charset = $this->getHTTPContentTypeCharset();
4234: $this->outgoing_headers[] = "Content-Type: $type" . ($charset ? '; charset=' . $charset : '');
4235:
4236:
4237:
4238: if (strlen($payload) > 1024 && isset($this->headers) && isset($this->headers['accept-encoding'])) {
4239: if (strstr($this->headers['accept-encoding'], 'gzip')) {
4240: if (function_exists('gzencode')) {
4241: if (isset($this->debug_flag) && $this->debug_flag) {
4242: $payload .= "<!-- Content being gzipped -->";
4243: }
4244: $this->outgoing_headers[] = "Content-Encoding: gzip";
4245: $payload = gzencode($payload);
4246: } else {
4247: if (isset($this->debug_flag) && $this->debug_flag) {
4248: $payload .= "<!-- Content will not be gzipped: no gzencode -->";
4249: }
4250: }
4251: } elseif (strstr($this->headers['accept-encoding'], 'deflate')) {
4252:
4253:
4254:
4255: if (function_exists('gzdeflate')) {
4256: if (isset($this->debug_flag) && $this->debug_flag) {
4257: $payload .= "<!-- Content being deflated -->";
4258: }
4259: $this->outgoing_headers[] = "Content-Encoding: deflate";
4260: $payload = gzdeflate($payload);
4261: } else {
4262: if (isset($this->debug_flag) && $this->debug_flag) {
4263: $payload .= "<!-- Content will not be deflated: no gzcompress -->";
4264: }
4265: }
4266: }
4267: }
4268:
4269: $this->outgoing_headers[] = "Content-Length: ".strlen($payload);
4270: reset($this->outgoing_headers);
4271: foreach($this->outgoing_headers as $hdr){
4272: header($hdr, false);
4273: }
4274: print $payload;
4275: $this->response = join("\r\n",$this->outgoing_headers)."\r\n\r\n".$payload;
4276: }
4277:
4278: 4279: 4280: 4281: 4282: 4283: 4284: 4285: 4286:
4287: function verify_method($operation,$request){
4288: if(isset($this->wsdl) && is_object($this->wsdl)){
4289: if($this->wsdl->getOperationData($operation)){
4290: return true;
4291: }
4292: } elseif(isset($this->operations[$operation])){
4293: return true;
4294: }
4295: return false;
4296: }
4297:
4298: 4299: 4300: 4301: 4302: 4303: 4304: 4305:
4306: function parseRequest($headers, $data) {
4307: $this->debug('Entering parseRequest() for data of length ' . strlen($data) . ' headers:');
4308: $this->appendDebug($this->varDump($headers));
4309: if (!isset($headers['content-type'])) {
4310: $this->setError('Request not of type text/xml (no content-type header)');
4311: return false;
4312: }
4313: if (!strstr($headers['content-type'], 'text/xml')) {
4314: $this->setError('Request not of type text/xml');
4315: return false;
4316: }
4317: if (strpos($headers['content-type'], '=')) {
4318: $enc = str_replace('"', '', substr(strstr($headers["content-type"], '='), 1));
4319: $this->debug('Got response encoding: ' . $enc);
4320: if(preg_match('/^(ISO-8859-1|US-ASCII|UTF-8)$/i',$enc)){
4321: $this->xml_encoding = strtoupper($enc);
4322: } else {
4323: $this->xml_encoding = 'US-ASCII';
4324: }
4325: } else {
4326:
4327: $this->xml_encoding = 'ISO-8859-1';
4328: }
4329: $this->debug('Use encoding: ' . $this->xml_encoding . ' when creating nusoap_parser');
4330:
4331: $parser = new nusoap_parser($data,$this->xml_encoding,'',$this->decode_utf8);
4332:
4333: $this->debug("parser debug: \n".$parser->getDebug());
4334:
4335: if($err = $parser->getError()){
4336: $this->result = 'fault: error in msg parsing: '.$err;
4337: $this->fault('SOAP-ENV:Client',"error in msg parsing:\n".$err);
4338:
4339: } else {
4340:
4341: $this->methodURI = $parser->root_struct_namespace;
4342: $this->methodname = $parser->root_struct_name;
4343: $this->debug('methodname: '.$this->methodname.' methodURI: '.$this->methodURI);
4344: $this->debug('calling parser->get_soapbody()');
4345: $this->methodparams = $parser->get_soapbody();
4346:
4347: $this->requestHeaders = $parser->getHeaders();
4348:
4349: $this->requestHeader = $parser->get_soapheader();
4350:
4351: $this->document = $parser->document;
4352: }
4353: }
4354:
4355: 4356: 4357: 4358: 4359: 4360: 4361:
4362: function getHTTPBody($soapmsg) {
4363: return $soapmsg;
4364: }
4365:
4366: 4367: 4368: 4369: 4370: 4371: 4372: 4373:
4374: function getHTTPContentType() {
4375: return 'text/xml';
4376: }
4377:
4378: 4379: 4380: 4381: 4382: 4383: 4384: 4385: 4386:
4387: function getHTTPContentTypeCharset() {
4388: return $this->soap_defencoding;
4389: }
4390:
4391: 4392: 4393: 4394: 4395: 4396: 4397: 4398: 4399:
4400: function add_to_map($methodname,$in,$out){
4401: $this->operations[$methodname] = array('name' => $methodname,'in' => $in,'out' => $out);
4402: }
4403:
4404: 4405: 4406: 4407: 4408: 4409: 4410: 4411: 4412: 4413: 4414: 4415: 4416: 4417:
4418: function register($name,$in=array(),$out=array(),$namespace=false,$soapaction=false,$style=false,$use=false,$documentation='',$encodingStyle=''){
4419: global $HTTP_SERVER_VARS;
4420:
4421: if($this->externalWSDLURL){
4422: die('You cannot bind to an external WSDL file, and register methods outside of it! Please choose either WSDL or no WSDL.');
4423: }
4424: if (! $name) {
4425: die('You must specify a name when you register an operation');
4426: }
4427: if (!is_array($in)) {
4428: die('You must provide an array for operation inputs');
4429: }
4430: if (!is_array($out)) {
4431: die('You must provide an array for operation outputs');
4432: }
4433: if(false == $namespace) {
4434: }
4435: if(false == $soapaction) {
4436: if (isset($_SERVER)) {
4437: $SERVER_NAME = $_SERVER['SERVER_NAME'];
4438: $SCRIPT_NAME = isset($_SERVER['PHP_SELF']) ? $_SERVER['PHP_SELF'] : $_SERVER['SCRIPT_NAME'];
4439: $HTTPS = isset($_SERVER['HTTPS']) ? $_SERVER['HTTPS'] : (isset($HTTP_SERVER_VARS['HTTPS']) ? $HTTP_SERVER_VARS['HTTPS'] : 'off');
4440: } elseif (isset($HTTP_SERVER_VARS)) {
4441: $SERVER_NAME = $HTTP_SERVER_VARS['SERVER_NAME'];
4442: $SCRIPT_NAME = isset($HTTP_SERVER_VARS['PHP_SELF']) ? $HTTP_SERVER_VARS['PHP_SELF'] : $HTTP_SERVER_VARS['SCRIPT_NAME'];
4443: $HTTPS = isset($HTTP_SERVER_VARS['HTTPS']) ? $HTTP_SERVER_VARS['HTTPS'] : 'off';
4444: } else {
4445: $this->setError("Neither _SERVER nor HTTP_SERVER_VARS is available");
4446: }
4447: if ($HTTPS == '1' || $HTTPS == 'on') {
4448: $SCHEME = 'https';
4449: } else {
4450: $SCHEME = 'http';
4451: }
4452: $soapaction = "$SCHEME://$SERVER_NAME$SCRIPT_NAME/$name";
4453: }
4454: if(false == $style) {
4455: $style = "rpc";
4456: }
4457: if(false == $use) {
4458: $use = "encoded";
4459: }
4460: if ($use == 'encoded' && $encodingStyle == '') {
4461: $encodingStyle = 'http://schemas.xmlsoap.org/soap/encoding/';
4462: }
4463:
4464: $this->operations[$name] = array(
4465: 'name' => $name,
4466: 'in' => $in,
4467: 'out' => $out,
4468: 'namespace' => $namespace,
4469: 'soapaction' => $soapaction,
4470: 'style' => $style);
4471: if($this->wsdl){
4472: $this->wsdl->addOperation($name,$in,$out,$namespace,$soapaction,$style,$use,$documentation,$encodingStyle);
4473: }
4474: return true;
4475: }
4476:
4477: 4478: 4479: 4480: 4481: 4482: 4483: 4484: 4485: 4486:
4487: function fault($faultcode,$faultstring,$faultactor='',$faultdetail=''){
4488: if ($faultdetail == '' && $this->debug_flag) {
4489: $faultdetail = $this->getDebug();
4490: }
4491: $this->fault = new nusoap_fault($faultcode,$faultactor,$faultstring,$faultdetail);
4492: $this->fault->soap_defencoding = $this->soap_defencoding;
4493: }
4494:
4495: 4496: 4497: 4498: 4499: 4500: 4501: 4502: 4503: 4504: 4505:
4506: function configureWSDL($serviceName,$namespace = false,$endpoint = false,$style='rpc', $transport = 'http://schemas.xmlsoap.org/soap/http', $schemaTargetNamespace = false)
4507: {
4508: global $HTTP_SERVER_VARS;
4509:
4510: if (isset($_SERVER)) {
4511: $SERVER_NAME = $_SERVER['SERVER_NAME'];
4512: $SERVER_PORT = $_SERVER['SERVER_PORT'];
4513: $SCRIPT_NAME = isset($_SERVER['PHP_SELF']) ? $_SERVER['PHP_SELF'] : $_SERVER['SCRIPT_NAME'];
4514: $HTTPS = isset($_SERVER['HTTPS']) ? $_SERVER['HTTPS'] : (isset($HTTP_SERVER_VARS['HTTPS']) ? $HTTP_SERVER_VARS['HTTPS'] : 'off');
4515: } elseif (isset($HTTP_SERVER_VARS)) {
4516: $SERVER_NAME = $HTTP_SERVER_VARS['SERVER_NAME'];
4517: $SERVER_PORT = $HTTP_SERVER_VARS['SERVER_PORT'];
4518: $SCRIPT_NAME = isset($HTTP_SERVER_VARS['PHP_SELF']) ? $HTTP_SERVER_VARS['PHP_SELF'] : $HTTP_SERVER_VARS['SCRIPT_NAME'];
4519: $HTTPS = isset($HTTP_SERVER_VARS['HTTPS']) ? $HTTP_SERVER_VARS['HTTPS'] : 'off';
4520: } else {
4521: $this->setError("Neither _SERVER nor HTTP_SERVER_VARS is available");
4522: }
4523:
4524: $colon = strpos($SERVER_NAME,":");
4525: if ($colon) {
4526: $SERVER_NAME = substr($SERVER_NAME, 0, $colon);
4527: }
4528: if ($SERVER_PORT == 80) {
4529: $SERVER_PORT = '';
4530: } else {
4531: $SERVER_PORT = ':' . $SERVER_PORT;
4532: }
4533: if(false == $namespace) {
4534: $namespace = "http://$SERVER_NAME/soap/$serviceName";
4535: }
4536:
4537: if(false == $endpoint) {
4538: if ($HTTPS == '1' || $HTTPS == 'on') {
4539: $SCHEME = 'https';
4540: } else {
4541: $SCHEME = 'http';
4542: }
4543: $endpoint = "$SCHEME://$SERVER_NAME$SERVER_PORT$SCRIPT_NAME";
4544: }
4545:
4546: if(false == $schemaTargetNamespace) {
4547: $schemaTargetNamespace = $namespace;
4548: }
4549:
4550: $this->wsdl = new wsdl;
4551: $this->wsdl->serviceName = $serviceName;
4552: $this->wsdl->endpoint = $endpoint;
4553: $this->wsdl->namespaces['tns'] = $namespace;
4554: $this->wsdl->namespaces['soap'] = 'http://schemas.xmlsoap.org/wsdl/soap/';
4555: $this->wsdl->namespaces['wsdl'] = 'http://schemas.xmlsoap.org/wsdl/';
4556: if ($schemaTargetNamespace != $namespace) {
4557: $this->wsdl->namespaces['types'] = $schemaTargetNamespace;
4558: }
4559: $this->wsdl->schemas[$schemaTargetNamespace][0] = new nusoap_xmlschema('', '', $this->wsdl->namespaces);
4560: if ($style == 'document') {
4561: $this->wsdl->schemas[$schemaTargetNamespace][0]->schemaInfo['elementFormDefault'] = 'qualified';
4562: }
4563: $this->wsdl->schemas[$schemaTargetNamespace][0]->schemaTargetNamespace = $schemaTargetNamespace;
4564: $this->wsdl->schemas[$schemaTargetNamespace][0]->imports['http://schemas.xmlsoap.org/soap/encoding/'][0] = array('location' => '', 'loaded' => true);
4565: $this->wsdl->schemas[$schemaTargetNamespace][0]->imports['http://schemas.xmlsoap.org/wsdl/'][0] = array('location' => '', 'loaded' => true);
4566: $this->wsdl->bindings[$serviceName.'Binding'] = array(
4567: 'name'=>$serviceName.'Binding',
4568: 'style'=>$style,
4569: 'transport'=>$transport,
4570: 'portType'=>$serviceName.'PortType');
4571: $this->wsdl->ports[$serviceName.'Port'] = array(
4572: 'binding'=>$serviceName.'Binding',
4573: 'location'=>$endpoint,
4574: 'bindingType'=>'http://schemas.xmlsoap.org/wsdl/soap/');
4575: }
4576: }
4577:
4578: 4579: 4580:
4581: class soap_server extends nusoap_server {
4582: }
4583:
4584: ?><?php
4585:
4586:
4587:
4588: 4589: 4590: 4591: 4592: 4593: 4594: 4595: 4596:
4597: class wsdl extends nusoap_base {
4598:
4599: var $wsdl;
4600:
4601: var $schemas = array();
4602: var $currentSchema;
4603: var $message = array();
4604: var $complexTypes = array();
4605: var $messages = array();
4606: var $currentMessage;
4607: var $currentOperation;
4608: var $portTypes = array();
4609: var $currentPortType;
4610: var $bindings = array();
4611: var $currentBinding;
4612: var $ports = array();
4613: var $currentPort;
4614: var $opData = array();
4615: var $status = '';
4616: var $documentation = false;
4617: var $endpoint = '';
4618:
4619: var $import = array();
4620:
4621: var $parser;
4622: var $position = 0;
4623: var $depth = 0;
4624: var $depth_array = array();
4625:
4626: var $proxyhost = '';
4627: var $proxyport = '';
4628: var $proxyusername = '';
4629: var $proxypassword = '';
4630: var $timeout = 0;
4631: var $response_timeout = 30;
4632: var $curl_options = array();
4633: var $use_curl = false;
4634:
4635: var $username = '';
4636: var $password = '';
4637: var $authtype = '';
4638: var $certRequest = array();
4639:
4640: 4641: 4642: 4643: 4644: 4645: 4646: 4647: 4648: 4649: 4650: 4651: 4652: 4653:
4654: function wsdl($wsdl = '',$proxyhost=false,$proxyport=false,$proxyusername=false,$proxypassword=false,$timeout=0,$response_timeout=30,$curl_options=null,$use_curl=false){
4655: parent::nusoap_base();
4656: $this->debug("ctor wsdl=$wsdl timeout=$timeout response_timeout=$response_timeout");
4657: $this->proxyhost = $proxyhost;
4658: $this->proxyport = $proxyport;
4659: $this->proxyusername = $proxyusername;
4660: $this->proxypassword = $proxypassword;
4661: $this->timeout = $timeout;
4662: $this->response_timeout = $response_timeout;
4663: if (is_array($curl_options))
4664: $this->curl_options = $curl_options;
4665: $this->use_curl = $use_curl;
4666: $this->fetchWSDL($wsdl);
4667: }
4668:
4669: 4670: 4671: 4672: 4673:
4674: function fetchWSDL($wsdl) {
4675: $this->debug("parse and process WSDL path=$wsdl");
4676: $this->wsdl = $wsdl;
4677:
4678: if ($this->wsdl != "") {
4679: $this->parseWSDL($this->wsdl);
4680: }
4681:
4682:
4683: $imported_urls = array();
4684: $imported = 1;
4685: while ($imported > 0) {
4686: $imported = 0;
4687:
4688: foreach ($this->schemas as $ns => $list) {
4689: foreach ($list as $xs) {
4690: $wsdlparts = parse_url($this->wsdl);
4691: foreach ($xs->imports as $ns2 => $list2) {
4692: for ($ii = 0; $ii < count($list2); $ii++) {
4693: if (! $list2[$ii]['loaded']) {
4694: $this->schemas[$ns]->imports[$ns2][$ii]['loaded'] = true;
4695: $url = $list2[$ii]['location'];
4696: if ($url != '') {
4697: $urlparts = parse_url($url);
4698: if (!isset($urlparts['host'])) {
4699: $url = $wsdlparts['scheme'] . '://' . $wsdlparts['host'] . (isset($wsdlparts['port']) ? ':' .$wsdlparts['port'] : '') .
4700: substr($wsdlparts['path'],0,strrpos($wsdlparts['path'],'/') + 1) .$urlparts['path'];
4701: }
4702: if (! in_array($url, $imported_urls)) {
4703: $this->parseWSDL($url);
4704: $imported++;
4705: $imported_urls[] = $url;
4706: }
4707: } else {
4708: $this->debug("Unexpected scenario: empty URL for unloaded import");
4709: }
4710: }
4711: }
4712: }
4713: }
4714: }
4715:
4716: $wsdlparts = parse_url($this->wsdl);
4717: foreach ($this->import as $ns => $list) {
4718: for ($ii = 0; $ii < count($list); $ii++) {
4719: if (! $list[$ii]['loaded']) {
4720: $this->import[$ns][$ii]['loaded'] = true;
4721: $url = $list[$ii]['location'];
4722: if ($url != '') {
4723: $urlparts = parse_url($url);
4724: if (!isset($urlparts['host'])) {
4725: $url = $wsdlparts['scheme'] . '://' . $wsdlparts['host'] . (isset($wsdlparts['port']) ? ':' . $wsdlparts['port'] : '') .
4726: substr($wsdlparts['path'],0,strrpos($wsdlparts['path'],'/') + 1) .$urlparts['path'];
4727: }
4728: if (! in_array($url, $imported_urls)) {
4729: $this->parseWSDL($url);
4730: $imported++;
4731: $imported_urls[] = $url;
4732: }
4733: } else {
4734: $this->debug("Unexpected scenario: empty URL for unloaded import");
4735: }
4736: }
4737: }
4738: }
4739: }
4740:
4741: foreach($this->bindings as $binding => $bindingData) {
4742: if (isset($bindingData['operations']) && is_array($bindingData['operations'])) {
4743: foreach($bindingData['operations'] as $operation => $data) {
4744: $this->debug('post-parse data gathering for ' . $operation);
4745: $this->bindings[$binding]['operations'][$operation]['input'] =
4746: isset($this->bindings[$binding]['operations'][$operation]['input']) ?
4747: array_merge($this->bindings[$binding]['operations'][$operation]['input'], $this->portTypes[ $bindingData['portType'] ][$operation]['input']) :
4748: $this->portTypes[ $bindingData['portType'] ][$operation]['input'];
4749: $this->bindings[$binding]['operations'][$operation]['output'] =
4750: isset($this->bindings[$binding]['operations'][$operation]['output']) ?
4751: array_merge($this->bindings[$binding]['operations'][$operation]['output'], $this->portTypes[ $bindingData['portType'] ][$operation]['output']) :
4752: $this->portTypes[ $bindingData['portType'] ][$operation]['output'];
4753: if(isset($this->messages[ $this->bindings[$binding]['operations'][$operation]['input']['message'] ])){
4754: $this->bindings[$binding]['operations'][$operation]['input']['parts'] = $this->messages[ $this->bindings[$binding]['operations'][$operation]['input']['message'] ];
4755: }
4756: if(isset($this->messages[ $this->bindings[$binding]['operations'][$operation]['output']['message'] ])){
4757: $this->bindings[$binding]['operations'][$operation]['output']['parts'] = $this->messages[ $this->bindings[$binding]['operations'][$operation]['output']['message'] ];
4758: }
4759:
4760: if (isset($bindingData['style']) && !isset($this->bindings[$binding]['operations'][$operation]['style'])) {
4761: $this->bindings[$binding]['operations'][$operation]['style'] = $bindingData['style'];
4762: }
4763: $this->bindings[$binding]['operations'][$operation]['transport'] = isset($bindingData['transport']) ? $bindingData['transport'] : '';
4764: $this->bindings[$binding]['operations'][$operation]['documentation'] = isset($this->portTypes[ $bindingData['portType'] ][$operation]['documentation']) ? $this->portTypes[ $bindingData['portType'] ][$operation]['documentation'] : '';
4765: $this->bindings[$binding]['operations'][$operation]['endpoint'] = isset($bindingData['endpoint']) ? $bindingData['endpoint'] : '';
4766: }
4767: }
4768: }
4769: }
4770:
4771: 4772: 4773: 4774: 4775: 4776:
4777: function parseWSDL($wsdl = '') {
4778: $this->debug("parse WSDL at path=$wsdl");
4779:
4780: if ($wsdl == '') {
4781: $this->debug('no wsdl passed to parseWSDL()!!');
4782: $this->setError('no wsdl passed to parseWSDL()!!');
4783: return false;
4784: }
4785:
4786:
4787: $wsdl_props = parse_url($wsdl);
4788:
4789: if (isset($wsdl_props['scheme']) && ($wsdl_props['scheme'] == 'http' || $wsdl_props['scheme'] == 'https')) {
4790: $this->debug('getting WSDL http(s) URL ' . $wsdl);
4791:
4792: $tr = new soap_transport_http($wsdl, $this->curl_options, $this->use_curl);
4793: $tr->request_method = 'GET';
4794: $tr->useSOAPAction = false;
4795: if($this->proxyhost && $this->proxyport){
4796: $tr->setProxy($this->proxyhost,$this->proxyport,$this->proxyusername,$this->proxypassword);
4797: }
4798: if ($this->authtype != '') {
4799: $tr->setCredentials($this->username, $this->password, $this->authtype, array(), $this->certRequest);
4800: }
4801: $tr->setEncoding('gzip, deflate');
4802: $wsdl_string = $tr->send('', $this->timeout, $this->response_timeout);
4803:
4804:
4805: $this->appendDebug($tr->getDebug());
4806:
4807: if($err = $tr->getError() ){
4808: $errstr = 'Getting ' . $wsdl . ' - HTTP ERROR: '.$err;
4809: $this->debug($errstr);
4810: $this->setError($errstr);
4811: unset($tr);
4812: return false;
4813: }
4814: unset($tr);
4815: $this->debug("got WSDL URL");
4816: } else {
4817:
4818: if (isset($wsdl_props['scheme']) && ($wsdl_props['scheme'] == 'file') && isset($wsdl_props['path'])) {
4819: $path = isset($wsdl_props['host']) ? ($wsdl_props['host'] . ':' . $wsdl_props['path']) : $wsdl_props['path'];
4820: } else {
4821: $path = $wsdl;
4822: }
4823: $this->debug('getting WSDL file ' . $path);
4824: if ($fp = @fopen($path, 'r')) {
4825: $wsdl_string = '';
4826: while ($data = fread($fp, 32768)) {
4827: $wsdl_string .= $data;
4828: }
4829: fclose($fp);
4830: } else {
4831: $errstr = "Bad path to WSDL file $path";
4832: $this->debug($errstr);
4833: $this->setError($errstr);
4834: return false;
4835: }
4836: }
4837: $this->debug('Parse WSDL');
4838:
4839:
4840: $this->parser = xml_parser_create();
4841:
4842:
4843: xml_parser_set_option($this->parser, XML_OPTION_CASE_FOLDING, 0);
4844:
4845: xml_set_object($this->parser, $this);
4846:
4847: xml_set_element_handler($this->parser, 'start_element', 'end_element');
4848: xml_set_character_data_handler($this->parser, 'character_data');
4849:
4850: if (!xml_parse($this->parser, $wsdl_string, true)) {
4851:
4852: $errstr = sprintf(
4853: 'XML error parsing WSDL from %s on line %d: %s',
4854: $wsdl,
4855: xml_get_current_line_number($this->parser),
4856: xml_error_string(xml_get_error_code($this->parser))
4857: );
4858: $this->debug($errstr);
4859: $this->debug("XML payload:\n" . $wsdl_string);
4860: $this->setError($errstr);
4861: return false;
4862: }
4863:
4864: xml_parser_free($this->parser);
4865: $this->debug('Parsing WSDL done');
4866:
4867: if($this->getError()){
4868: return false;
4869: }
4870: return true;
4871: }
4872:
4873: 4874: 4875: 4876: 4877: 4878: 4879: 4880:
4881: function start_element($parser, $name, $attrs)
4882: {
4883: if ($this->status == 'schema') {
4884: $this->currentSchema->schemaStartElement($parser, $name, $attrs);
4885: $this->appendDebug($this->currentSchema->getDebug());
4886: $this->currentSchema->clearDebug();
4887: } elseif (preg_match('/schema$/', $name)) {
4888: $this->debug('Parsing WSDL schema');
4889:
4890: $this->status = 'schema';
4891: $this->currentSchema = new nusoap_xmlschema('', '', $this->namespaces);
4892: $this->currentSchema->schemaStartElement($parser, $name, $attrs);
4893: $this->appendDebug($this->currentSchema->getDebug());
4894: $this->currentSchema->clearDebug();
4895: } else {
4896:
4897: $pos = $this->position++;
4898: $depth = $this->depth++;
4899:
4900: $this->depth_array[$depth] = $pos;
4901: $this->message[$pos] = array('cdata' => '');
4902:
4903: if (count($attrs) > 0) {
4904:
4905: foreach($attrs as $k => $v) {
4906: if (preg_match('/^xmlns/',$k)) {
4907: if ($ns_prefix = substr(strrchr($k, ':'), 1)) {
4908: $this->namespaces[$ns_prefix] = $v;
4909: } else {
4910: $this->namespaces['ns' . (count($this->namespaces) + 1)] = $v;
4911: }
4912: if ($v == 'http://www.w3.org/2001/XMLSchema' || $v == 'http://www.w3.org/1999/XMLSchema' || $v == 'http://www.w3.org/2000/10/XMLSchema') {
4913: $this->XMLSchemaVersion = $v;
4914: $this->namespaces['xsi'] = $v . '-instance';
4915: }
4916: }
4917: }
4918:
4919: foreach($attrs as $k => $v) {
4920: $k = strpos($k, ':') ? $this->expandQname($k) : $k;
4921: if ($k != 'location' && $k != 'soapAction' && $k != 'namespace') {
4922: $v = strpos($v, ':') ? $this->expandQname($v) : $v;
4923: }
4924: $eAttrs[$k] = $v;
4925: }
4926: $attrs = $eAttrs;
4927: } else {
4928: $attrs = array();
4929: }
4930:
4931: if (preg_match('/:/', $name)) {
4932:
4933: $prefix = substr($name, 0, strpos($name, ':'));
4934:
4935: $namespace = isset($this->namespaces[$prefix]) ? $this->namespaces[$prefix] : '';
4936:
4937: $name = substr(strstr($name, ':'), 1);
4938: }
4939:
4940:
4941: switch ($this->status) {
4942: case 'message':
4943: if ($name == 'part') {
4944: if (isset($attrs['type'])) {
4945: $this->debug("msg " . $this->currentMessage . ": found part (with type) $attrs[name]: " . implode(',', $attrs));
4946: $this->messages[$this->currentMessage][$attrs['name']] = $attrs['type'];
4947: }
4948: if (isset($attrs['element'])) {
4949: $this->debug("msg " . $this->currentMessage . ": found part (with element) $attrs[name]: " . implode(',', $attrs));
4950: $this->messages[$this->currentMessage][$attrs['name']] = $attrs['element'] . '^';
4951: }
4952: }
4953: break;
4954: case 'portType':
4955: switch ($name) {
4956: case 'operation':
4957: $this->currentPortOperation = $attrs['name'];
4958: $this->debug("portType $this->currentPortType operation: $this->currentPortOperation");
4959: if (isset($attrs['parameterOrder'])) {
4960: $this->portTypes[$this->currentPortType][$attrs['name']]['parameterOrder'] = $attrs['parameterOrder'];
4961: }
4962: break;
4963: case 'documentation':
4964: $this->documentation = true;
4965: break;
4966:
4967: default:
4968: $m = isset($attrs['message']) ? $this->getLocalPart($attrs['message']) : '';
4969: $this->portTypes[$this->currentPortType][$this->currentPortOperation][$name]['message'] = $m;
4970: break;
4971: }
4972: break;
4973: case 'binding':
4974: switch ($name) {
4975: case 'binding':
4976:
4977: if (isset($attrs['style'])) {
4978: $this->bindings[$this->currentBinding]['prefix'] = $prefix;
4979: }
4980: $this->bindings[$this->currentBinding] = array_merge($this->bindings[$this->currentBinding], $attrs);
4981: break;
4982: case 'header':
4983: $this->bindings[$this->currentBinding]['operations'][$this->currentOperation][$this->opStatus]['headers'][] = $attrs;
4984: break;
4985: case 'operation':
4986: if (isset($attrs['soapAction'])) {
4987: $this->bindings[$this->currentBinding]['operations'][$this->currentOperation]['soapAction'] = $attrs['soapAction'];
4988: }
4989: if (isset($attrs['style'])) {
4990: $this->bindings[$this->currentBinding]['operations'][$this->currentOperation]['style'] = $attrs['style'];
4991: }
4992: if (isset($attrs['name'])) {
4993: $this->currentOperation = $attrs['name'];
4994: $this->debug("current binding operation: $this->currentOperation");
4995: $this->bindings[$this->currentBinding]['operations'][$this->currentOperation]['name'] = $attrs['name'];
4996: $this->bindings[$this->currentBinding]['operations'][$this->currentOperation]['binding'] = $this->currentBinding;
4997: $this->bindings[$this->currentBinding]['operations'][$this->currentOperation]['endpoint'] = isset($this->bindings[$this->currentBinding]['endpoint']) ? $this->bindings[$this->currentBinding]['endpoint'] : '';
4998: }
4999: break;
5000: case 'input':
5001: $this->opStatus = 'input';
5002: break;
5003: case 'output':
5004: $this->opStatus = 'output';
5005: break;
5006: case 'body':
5007: if (isset($this->bindings[$this->currentBinding]['operations'][$this->currentOperation][$this->opStatus])) {
5008: $this->bindings[$this->currentBinding]['operations'][$this->currentOperation][$this->opStatus] = array_merge($this->bindings[$this->currentBinding]['operations'][$this->currentOperation][$this->opStatus], $attrs);
5009: } else {
5010: $this->bindings[$this->currentBinding]['operations'][$this->currentOperation][$this->opStatus] = $attrs;
5011: }
5012: break;
5013: }
5014: break;
5015: case 'service':
5016: switch ($name) {
5017: case 'port':
5018: $this->currentPort = $attrs['name'];
5019: $this->debug('current port: ' . $this->currentPort);
5020: $this->ports[$this->currentPort]['binding'] = $this->getLocalPart($attrs['binding']);
5021:
5022: break;
5023: case 'address':
5024: $this->ports[$this->currentPort]['location'] = $attrs['location'];
5025: $this->ports[$this->currentPort]['bindingType'] = $namespace;
5026: $this->bindings[ $this->ports[$this->currentPort]['binding'] ]['bindingType'] = $namespace;
5027: $this->bindings[ $this->ports[$this->currentPort]['binding'] ]['endpoint'] = $attrs['location'];
5028: break;
5029: }
5030: break;
5031: }
5032:
5033: switch ($name) {
5034: case 'import':
5035: if (isset($attrs['location'])) {
5036: $this->import[$attrs['namespace']][] = array('location' => $attrs['location'], 'loaded' => false);
5037: $this->debug('parsing import ' . $attrs['namespace']. ' - ' . $attrs['location'] . ' (' . count($this->import[$attrs['namespace']]).')');
5038: } else {
5039: $this->import[$attrs['namespace']][] = array('location' => '', 'loaded' => true);
5040: if (! $this->getPrefixFromNamespace($attrs['namespace'])) {
5041: $this->namespaces['ns'.(count($this->namespaces)+1)] = $attrs['namespace'];
5042: }
5043: $this->debug('parsing import ' . $attrs['namespace']. ' - [no location] (' . count($this->import[$attrs['namespace']]).')');
5044: }
5045: break;
5046:
5047:
5048:
5049:
5050: case 'message':
5051: $this->status = 'message';
5052: $this->messages[$attrs['name']] = array();
5053: $this->currentMessage = $attrs['name'];
5054: break;
5055: case 'portType':
5056: $this->status = 'portType';
5057: $this->portTypes[$attrs['name']] = array();
5058: $this->currentPortType = $attrs['name'];
5059: break;
5060: case "binding":
5061: if (isset($attrs['name'])) {
5062:
5063: if (strpos($attrs['name'], ':')) {
5064: $this->currentBinding = $this->getLocalPart($attrs['name']);
5065: } else {
5066: $this->currentBinding = $attrs['name'];
5067: }
5068: $this->status = 'binding';
5069: $this->bindings[$this->currentBinding]['portType'] = $this->getLocalPart($attrs['type']);
5070: $this->debug("current binding: $this->currentBinding of portType: " . $attrs['type']);
5071: }
5072: break;
5073: case 'service':
5074: $this->serviceName = $attrs['name'];
5075: $this->status = 'service';
5076: $this->debug('current service: ' . $this->serviceName);
5077: break;
5078: case 'definitions':
5079: foreach ($attrs as $name => $value) {
5080: $this->wsdl_info[$name] = $value;
5081: }
5082: break;
5083: }
5084: }
5085: }
5086:
5087: 5088: 5089: 5090: 5091: 5092: 5093:
5094: function end_element($parser, $name){
5095:
5096: if ( preg_match('/schema$/', $name)) {
5097: $this->status = "";
5098: $this->appendDebug($this->currentSchema->getDebug());
5099: $this->currentSchema->clearDebug();
5100: $this->schemas[$this->currentSchema->schemaTargetNamespace][] = $this->currentSchema;
5101: $this->debug('Parsing WSDL schema done');
5102: }
5103: if ($this->status == 'schema') {
5104: $this->currentSchema->schemaEndElement($parser, $name);
5105: } else {
5106:
5107: $this->depth--;
5108: }
5109:
5110: if ($this->documentation) {
5111:
5112:
5113: $this->documentation = false;
5114: }
5115: }
5116:
5117: 5118: 5119: 5120: 5121: 5122: 5123:
5124: function character_data($parser, $data)
5125: {
5126: $pos = isset($this->depth_array[$this->depth]) ? $this->depth_array[$this->depth] : 0;
5127: if (isset($this->message[$pos]['cdata'])) {
5128: $this->message[$pos]['cdata'] .= $data;
5129: }
5130: if ($this->documentation) {
5131: $this->documentation .= $data;
5132: }
5133: }
5134:
5135: 5136: 5137: 5138: 5139: 5140: 5141: 5142: 5143:
5144: function setCredentials($username, $password, $authtype = 'basic', $certRequest = array()) {
5145: $this->debug("setCredentials username=$username authtype=$authtype certRequest=");
5146: $this->appendDebug($this->varDump($certRequest));
5147: $this->username = $username;
5148: $this->password = $password;
5149: $this->authtype = $authtype;
5150: $this->certRequest = $certRequest;
5151: }
5152:
5153: function getBindingData($binding)
5154: {
5155: if (is_array($this->bindings[$binding])) {
5156: return $this->bindings[$binding];
5157: }
5158: }
5159:
5160: 5161: 5162: 5163: 5164: 5165: 5166: 5167:
5168: function getOperations($portName = '', $bindingType = 'soap') {
5169: $ops = array();
5170: if ($bindingType == 'soap') {
5171: $bindingType = 'http://schemas.xmlsoap.org/wsdl/soap/';
5172: } elseif ($bindingType == 'soap12') {
5173: $bindingType = 'http://schemas.xmlsoap.org/wsdl/soap12/';
5174: } else {
5175: $this->debug("getOperations bindingType $bindingType may not be supported");
5176: }
5177: $this->debug("getOperations for port '$portName' bindingType $bindingType");
5178:
5179: foreach($this->ports as $port => $portData) {
5180: $this->debug("getOperations checking port $port bindingType " . $portData['bindingType']);
5181: if ($portName == '' || $port == $portName) {
5182:
5183: if ($portData['bindingType'] == $bindingType) {
5184: $this->debug("getOperations found port $port bindingType $bindingType");
5185:
5186:
5187:
5188: if (isset($this->bindings[ $portData['binding'] ]['operations'])) {
5189: $ops = array_merge ($ops, $this->bindings[ $portData['binding'] ]['operations']);
5190: }
5191: }
5192: }
5193: }
5194: if (count($ops) == 0) {
5195: $this->debug("getOperations found no operations for port '$portName' bindingType $bindingType");
5196: }
5197: return $ops;
5198: }
5199:
5200: 5201: 5202: 5203: 5204: 5205: 5206: 5207:
5208: function getOperationData($operation, $bindingType = 'soap')
5209: {
5210: if ($bindingType == 'soap') {
5211: $bindingType = 'http://schemas.xmlsoap.org/wsdl/soap/';
5212: } elseif ($bindingType == 'soap12') {
5213: $bindingType = 'http://schemas.xmlsoap.org/wsdl/soap12/';
5214: }
5215:
5216: foreach($this->ports as $port => $portData) {
5217:
5218: if ($portData['bindingType'] == $bindingType) {
5219:
5220:
5221: foreach(array_keys($this->bindings[ $portData['binding'] ]['operations']) as $bOperation) {
5222:
5223: if ($operation == $bOperation) {
5224: $opData = $this->bindings[ $portData['binding'] ]['operations'][$operation];
5225: return $opData;
5226: }
5227: }
5228: }
5229: }
5230: }
5231:
5232: 5233: 5234: 5235: 5236: 5237: 5238: 5239:
5240: function getOperationDataForSoapAction($soapAction, $bindingType = 'soap') {
5241: if ($bindingType == 'soap') {
5242: $bindingType = 'http://schemas.xmlsoap.org/wsdl/soap/';
5243: } elseif ($bindingType == 'soap12') {
5244: $bindingType = 'http://schemas.xmlsoap.org/wsdl/soap12/';
5245: }
5246:
5247: foreach($this->ports as $port => $portData) {
5248:
5249: if ($portData['bindingType'] == $bindingType) {
5250:
5251: foreach ($this->bindings[ $portData['binding'] ]['operations'] as $bOperation => $opData) {
5252: if ($opData['soapAction'] == $soapAction) {
5253: return $opData;
5254: }
5255: }
5256: }
5257: }
5258: }
5259:
5260: 5261: 5262: 5263: 5264: 5265: 5266: 5267: 5268: 5269: 5270: 5271: 5272: 5273: 5274: 5275: 5276: 5277:
5278: function getTypeDef($type, $ns) {
5279: $this->debug("in getTypeDef: type=$type, ns=$ns");
5280: if ((! $ns) && isset($this->namespaces['tns'])) {
5281: $ns = $this->namespaces['tns'];
5282: $this->debug("in getTypeDef: type namespace forced to $ns");
5283: }
5284: if (!isset($this->schemas[$ns])) {
5285: foreach ($this->schemas as $ns0 => $schema0) {
5286: if (strcasecmp($ns, $ns0) == 0) {
5287: $this->debug("in getTypeDef: replacing schema namespace $ns with $ns0");
5288: $ns = $ns0;
5289: break;
5290: }
5291: }
5292: }
5293: if (isset($this->schemas[$ns])) {
5294: $this->debug("in getTypeDef: have schema for namespace $ns");
5295: for ($i = 0; $i < count($this->schemas[$ns]); $i++) {
5296: $xs = &$this->schemas[$ns][$i];
5297: $t = $xs->getTypeDef($type);
5298: $this->appendDebug($xs->getDebug());
5299: $xs->clearDebug();
5300: if ($t) {
5301: $this->debug("in getTypeDef: found type $type");
5302: if (!isset($t['phpType'])) {
5303:
5304: $uqType = substr($t['type'], strrpos($t['type'], ':') + 1);
5305: $ns = substr($t['type'], 0, strrpos($t['type'], ':'));
5306: $etype = $this->getTypeDef($uqType, $ns);
5307: if ($etype) {
5308: $this->debug("found type for [element] $type:");
5309: $this->debug($this->varDump($etype));
5310: if (isset($etype['phpType'])) {
5311: $t['phpType'] = $etype['phpType'];
5312: }
5313: if (isset($etype['elements'])) {
5314: $t['elements'] = $etype['elements'];
5315: }
5316: if (isset($etype['attrs'])) {
5317: $t['attrs'] = $etype['attrs'];
5318: }
5319: } else {
5320: $this->debug("did not find type for [element] $type");
5321: }
5322: }
5323: return $t;
5324: }
5325: }
5326: $this->debug("in getTypeDef: did not find type $type");
5327: } else {
5328: $this->debug("in getTypeDef: do not have schema for namespace $ns");
5329: }
5330: return false;
5331: }
5332:
5333: 5334: 5335: 5336: 5337:
5338: function webDescription(){
5339: global $HTTP_SERVER_VARS;
5340:
5341: if (isset($_SERVER)) {
5342: $PHP_SELF = $_SERVER['PHP_SELF'];
5343: } elseif (isset($HTTP_SERVER_VARS)) {
5344: $PHP_SELF = $HTTP_SERVER_VARS['PHP_SELF'];
5345: } else {
5346: $this->setError("Neither _SERVER nor HTTP_SERVER_VARS is available");
5347: }
5348:
5349: $b = '
5350: <html><head><title>NuSOAP: '.$this->serviceName.'</title>
5351: <style type="text/css">
5352: body { font-family: arial; color: #000000; background-color: #ffffff; margin: 0px 0px 0px 0px; }
5353: p { font-family: arial; color: #000000; margin-top: 0px; margin-bottom: 12px; }
5354: pre { background-color: silver; padding: 5px; font-family: Courier New; font-size: x-small; color: #000000;}
5355: ul { margin-top: 10px; margin-left: 20px; }
5356: li { list-style-type: none; margin-top: 10px; color: #000000; }
5357: .content{
5358: margin-left: 0px; padding-bottom: 2em; }
5359: .nav {
5360: padding-top: 10px; padding-bottom: 10px; padding-left: 15px; font-size: .70em;
5361: margin-top: 10px; margin-left: 0px; color: #000000;
5362: background-color: #ccccff; width: 20%; margin-left: 20px; margin-top: 20px; }
5363: .title {
5364: font-family: arial; font-size: 26px; color: #ffffff;
5365: background-color: #999999; width: 100%;
5366: margin-left: 0px; margin-right: 0px;
5367: padding-top: 10px; padding-bottom: 10px;}
5368: .hidden {
5369: position: absolute; visibility: hidden; z-index: 200; left: 250px; top: 100px;
5370: font-family: arial; overflow: hidden; width: 600;
5371: padding: 20px; font-size: 10px; background-color: #999999;
5372: layer-background-color:#FFFFFF; }
5373: a,a:active { color: charcoal; font-weight: bold; }
5374: a:visited { color: #666666; font-weight: bold; }
5375: a:hover { color: cc3300; font-weight: bold; }
5376: </style>
5377: <script language="JavaScript" type="text/javascript">
5378: <!--
5379: // POP-UP CAPTIONS...
5380: function lib_bwcheck(){ //Browsercheck (needed)
5381: this.ver=navigator.appVersion
5382: this.agent=navigator.userAgent
5383: this.dom=document.getElementById?1:0
5384: this.opera5=this.agent.indexOf("Opera 5")>-1
5385: this.ie5=(this.ver.indexOf("MSIE 5")>-1 && this.dom && !this.opera5)?1:0;
5386: this.ie6=(this.ver.indexOf("MSIE 6")>-1 && this.dom && !this.opera5)?1:0;
5387: this.ie4=(document.all && !this.dom && !this.opera5)?1:0;
5388: this.ie=this.ie4||this.ie5||this.ie6
5389: this.mac=this.agent.indexOf("Mac")>-1
5390: this.ns6=(this.dom && parseInt(this.ver) >= 5) ?1:0;
5391: this.ns4=(document.layers && !this.dom)?1:0;
5392: this.bw=(this.ie6 || this.ie5 || this.ie4 || this.ns4 || this.ns6 || this.opera5)
5393: return this
5394: }
5395: var bw = new lib_bwcheck()
5396: //Makes crossbrowser object.
5397: function makeObj(obj){
5398: this.evnt=bw.dom? document.getElementById(obj):bw.ie4?document.all[obj]:bw.ns4?document.layers[obj]:0;
5399: if(!this.evnt) return false
5400: this.css=bw.dom||bw.ie4?this.evnt.style:bw.ns4?this.evnt:0;
5401: this.wref=bw.dom||bw.ie4?this.evnt:bw.ns4?this.css.document:0;
5402: this.writeIt=b_writeIt;
5403: return this
5404: }
5405: // A unit of measure that will be added when setting the position of a layer.
5406: //var px = bw.ns4||window.opera?"":"px";
5407: function b_writeIt(text){
5408: if (bw.ns4){this.wref.write(text);this.wref.close()}
5409: else this.wref.innerHTML = text
5410: }
5411: //Shows the messages
5412: var oDesc;
5413: function popup(divid){
5414: if(oDesc = new makeObj(divid)){
5415: oDesc.css.visibility = "visible"
5416: }
5417: }
5418: function popout(){ // Hides message
5419: if(oDesc) oDesc.css.visibility = "hidden"
5420: }
5421: //-->
5422: </script>
5423: </head>
5424: <body>
5425: <div class=content>
5426: <br><br>
5427: <div class=title>'.$this->serviceName.'</div>
5428: <div class=nav>
5429: <p>View the <a href="'.$PHP_SELF.'?wsdl">WSDL</a> for the service.
5430: Click on an operation name to view it's details.</p>
5431: <ul>';
5432: foreach($this->getOperations() as $op => $data){
5433: $b .= "<li><a href='#' onclick=\"popout();popup('$op')\">$op</a></li>";
5434:
5435: $b .= "<div id='$op' class='hidden'>
5436: <a href='#' onclick='popout()'><font color='#ffffff'>Close</font></a><br><br>";
5437: foreach($data as $donnie => $marie){
5438: if($donnie == 'input' || $donnie == 'output'){
5439: $b .= "<font color='white'>".ucfirst($donnie).':</font><br>';
5440: foreach($marie as $captain => $tenille){
5441: if($captain == 'parts'){
5442: $b .= " $captain:<br>";
5443:
5444: foreach($tenille as $joanie => $chachi){
5445: $b .= " $joanie: $chachi<br>";
5446: }
5447:
5448: } else {
5449: $b .= " $captain: $tenille<br>";
5450: }
5451: }
5452: } else {
5453: $b .= "<font color='white'>".ucfirst($donnie).":</font> $marie<br>";
5454: }
5455: }
5456: $b .= '</div>';
5457: }
5458: $b .= '
5459: <ul>
5460: </div>
5461: </div></body></html>';
5462: return $b;
5463: }
5464:
5465: 5466: 5467: 5468: 5469: 5470: 5471:
5472: function serialize($debug = 0)
5473: {
5474: $xml = '<?xml version="1.0" encoding="ISO-8859-1"?>';
5475: $xml .= "\n<definitions";
5476: foreach($this->namespaces as $k => $v) {
5477: $xml .= " xmlns:$k=\"$v\"";
5478: }
5479:
5480: if (isset($this->namespaces['wsdl'])) {
5481: $xml .= " xmlns=\"" . $this->namespaces['wsdl'] . "\"";
5482: }
5483: if (isset($this->namespaces['tns'])) {
5484: $xml .= " targetNamespace=\"" . $this->namespaces['tns'] . "\"";
5485: }
5486: $xml .= '>';
5487:
5488: if (sizeof($this->import) > 0) {
5489: foreach($this->import as $ns => $list) {
5490: foreach ($list as $ii) {
5491: if ($ii['location'] != '') {
5492: $xml .= '<import location="' . $ii['location'] . '" namespace="' . $ns . '" />';
5493: } else {
5494: $xml .= '<import namespace="' . $ns . '" />';
5495: }
5496: }
5497: }
5498: }
5499:
5500: if (count($this->schemas)>=1) {
5501: $xml .= "\n<types>\n";
5502: foreach ($this->schemas as $ns => $list) {
5503: foreach ($list as $xs) {
5504: $xml .= $xs->serializeSchema();
5505: }
5506: }
5507: $xml .= '</types>';
5508: }
5509:
5510: if (count($this->messages) >= 1) {
5511: foreach($this->messages as $msgName => $msgParts) {
5512: $xml .= "\n<message name=\"" . $msgName . '">';
5513: if(is_array($msgParts)){
5514: foreach($msgParts as $partName => $partType) {
5515:
5516: if (strpos($partType, ':')) {
5517: $typePrefix = $this->getPrefixFromNamespace($this->getPrefix($partType));
5518: } elseif (isset($this->typemap[$this->namespaces['xsd']][$partType])) {
5519:
5520: $typePrefix = 'xsd';
5521: } else {
5522: foreach($this->typemap as $ns => $types) {
5523: if (isset($types[$partType])) {
5524: $typePrefix = $this->getPrefixFromNamespace($ns);
5525: }
5526: }
5527: if (!isset($typePrefix)) {
5528: die("$partType has no namespace!");
5529: }
5530: }
5531: $ns = $this->getNamespaceFromPrefix($typePrefix);
5532: $localPart = $this->getLocalPart($partType);
5533: $typeDef = $this->getTypeDef($localPart, $ns);
5534: if ($typeDef['typeClass'] == 'element') {
5535: $elementortype = 'element';
5536: if (substr($localPart, -1) == '^') {
5537: $localPart = substr($localPart, 0, -1);
5538: }
5539: } else {
5540: $elementortype = 'type';
5541: }
5542: $xml .= "\n" . ' <part name="' . $partName . '" ' . $elementortype . '="' . $typePrefix . ':' . $localPart . '" />';
5543: }
5544: }
5545: $xml .= '</message>';
5546: }
5547: }
5548:
5549: if (count($this->bindings) >= 1) {
5550: $binding_xml = '';
5551: $portType_xml = '';
5552: foreach($this->bindings as $bindingName => $attrs) {
5553: $binding_xml .= "\n<binding name=\"" . $bindingName . '" type="tns:' . $attrs['portType'] . '">';
5554: $binding_xml .= "\n" . ' <soap:binding style="' . $attrs['style'] . '" transport="' . $attrs['transport'] . '"/>';
5555: $portType_xml .= "\n<portType name=\"" . $attrs['portType'] . '">';
5556: foreach($attrs['operations'] as $opName => $opParts) {
5557: $binding_xml .= "\n" . ' <operation name="' . $opName . '">';
5558: $binding_xml .= "\n" . ' <soap:operation soapAction="' . $opParts['soapAction'] . '" style="'. $opParts['style'] . '"/>';
5559: if (isset($opParts['input']['encodingStyle']) && $opParts['input']['encodingStyle'] != '') {
5560: $enc_style = ' encodingStyle="' . $opParts['input']['encodingStyle'] . '"';
5561: } else {
5562: $enc_style = '';
5563: }
5564: $binding_xml .= "\n" . ' <input><soap:body use="' . $opParts['input']['use'] . '" namespace="' . $opParts['input']['namespace'] . '"' . $enc_style . '/></input>';
5565: if (isset($opParts['output']['encodingStyle']) && $opParts['output']['encodingStyle'] != '') {
5566: $enc_style = ' encodingStyle="' . $opParts['output']['encodingStyle'] . '"';
5567: } else {
5568: $enc_style = '';
5569: }
5570: $binding_xml .= "\n" . ' <output><soap:body use="' . $opParts['output']['use'] . '" namespace="' . $opParts['output']['namespace'] . '"' . $enc_style . '/></output>';
5571: $binding_xml .= "\n" . ' </operation>';
5572: $portType_xml .= "\n" . ' <operation name="' . $opParts['name'] . '"';
5573: if (isset($opParts['parameterOrder'])) {
5574: $portType_xml .= ' parameterOrder="' . $opParts['parameterOrder'] . '"';
5575: }
5576: $portType_xml .= '>';
5577: if(isset($opParts['documentation']) && $opParts['documentation'] != '') {
5578: $portType_xml .= "\n" . ' <documentation>' . htmlspecialchars($opParts['documentation']) . '</documentation>';
5579: }
5580: $portType_xml .= "\n" . ' <input message="tns:' . $opParts['input']['message'] . '"/>';
5581: $portType_xml .= "\n" . ' <output message="tns:' . $opParts['output']['message'] . '"/>';
5582: $portType_xml .= "\n" . ' </operation>';
5583: }
5584: $portType_xml .= "\n" . '</portType>';
5585: $binding_xml .= "\n" . '</binding>';
5586: }
5587: $xml .= $portType_xml . $binding_xml;
5588: }
5589:
5590: $xml .= "\n<service name=\"" . $this->serviceName . '">';
5591: if (count($this->ports) >= 1) {
5592: foreach($this->ports as $pName => $attrs) {
5593: $xml .= "\n" . ' <port name="' . $pName . '" binding="tns:' . $attrs['binding'] . '">';
5594: $xml .= "\n" . ' <soap:address location="' . $attrs['location'] . ($debug ? '?debug=1' : '') . '"/>';
5595: $xml .= "\n" . ' </port>';
5596: }
5597: }
5598: $xml .= "\n" . '</service>';
5599: return $xml . "\n</definitions>";
5600: }
5601:
5602: 5603: 5604: 5605: 5606: 5607: 5608: 5609: 5610:
5611: function parametersMatchWrapped($type, &$parameters) {
5612: $this->debug("in parametersMatchWrapped type=$type, parameters=");
5613: $this->appendDebug($this->varDump($parameters));
5614:
5615:
5616: if (strpos($type, ':')) {
5617: $uqType = substr($type, strrpos($type, ':') + 1);
5618: $ns = substr($type, 0, strrpos($type, ':'));
5619: $this->debug("in parametersMatchWrapped: got a prefixed type: $uqType, $ns");
5620: if ($this->getNamespaceFromPrefix($ns)) {
5621: $ns = $this->getNamespaceFromPrefix($ns);
5622: $this->debug("in parametersMatchWrapped: expanded prefixed type: $uqType, $ns");
5623: }
5624: } else {
5625:
5626:
5627: $this->debug("in parametersMatchWrapped: No namespace for type $type");
5628: $ns = '';
5629: $uqType = $type;
5630: }
5631:
5632:
5633: if (!$typeDef = $this->getTypeDef($uqType, $ns)) {
5634: $this->debug("in parametersMatchWrapped: $type ($uqType) is not a supported type.");
5635: return false;
5636: }
5637: $this->debug("in parametersMatchWrapped: found typeDef=");
5638: $this->appendDebug($this->varDump($typeDef));
5639: if (substr($uqType, -1) == '^') {
5640: $uqType = substr($uqType, 0, -1);
5641: }
5642: $phpType = $typeDef['phpType'];
5643: $arrayType = (isset($typeDef['arrayType']) ? $typeDef['arrayType'] : '');
5644: $this->debug("in parametersMatchWrapped: uqType: $uqType, ns: $ns, phptype: $phpType, arrayType: $arrayType");
5645:
5646:
5647: if ($phpType != 'struct') {
5648: $this->debug("in parametersMatchWrapped: not a struct");
5649: return false;
5650: }
5651:
5652:
5653: if (isset($typeDef['elements']) && is_array($typeDef['elements'])) {
5654: $elements = 0;
5655: $matches = 0;
5656: foreach ($typeDef['elements'] as $name => $attrs) {
5657: if (isset($parameters[$name])) {
5658: $this->debug("in parametersMatchWrapped: have parameter named $name");
5659: $matches++;
5660: } else {
5661: $this->debug("in parametersMatchWrapped: do not have parameter named $name");
5662: }
5663: $elements++;
5664: }
5665:
5666: $this->debug("in parametersMatchWrapped: $matches parameter names match $elements wrapped parameter names");
5667: if ($matches == 0) {
5668: return false;
5669: }
5670: return true;
5671: }
5672:
5673:
5674:
5675: $this->debug("in parametersMatchWrapped: no elements type $ns:$uqType");
5676: return count($parameters) == 0;
5677: }
5678:
5679: 5680: 5681: 5682: 5683: 5684: 5685: 5686: 5687: 5688: 5689: 5690: 5691: 5692: 5693:
5694: function serializeRPCParameters($operation, $direction, $parameters, $bindingType = 'soap') {
5695: $this->debug("in serializeRPCParameters: operation=$operation, direction=$direction, XMLSchemaVersion=$this->XMLSchemaVersion, bindingType=$bindingType");
5696: $this->appendDebug('parameters=' . $this->varDump($parameters));
5697:
5698: if ($direction != 'input' && $direction != 'output') {
5699: $this->debug('The value of the \$direction argument needs to be either "input" or "output"');
5700: $this->setError('The value of the \$direction argument needs to be either "input" or "output"');
5701: return false;
5702: }
5703: if (!$opData = $this->getOperationData($operation, $bindingType)) {
5704: $this->debug('Unable to retrieve WSDL data for operation: ' . $operation . ' bindingType: ' . $bindingType);
5705: $this->setError('Unable to retrieve WSDL data for operation: ' . $operation . ' bindingType: ' . $bindingType);
5706: return false;
5707: }
5708: $this->debug('in serializeRPCParameters: opData:');
5709: $this->appendDebug($this->varDump($opData));
5710:
5711:
5712: $encodingStyle = 'http://schemas.xmlsoap.org/soap/encoding/';
5713: if(($direction == 'input') && isset($opData['output']['encodingStyle']) && ($opData['output']['encodingStyle'] != $encodingStyle)) {
5714: $encodingStyle = $opData['output']['encodingStyle'];
5715: $enc_style = $encodingStyle;
5716: }
5717:
5718:
5719: $xml = '';
5720: if (isset($opData[$direction]['parts']) && sizeof($opData[$direction]['parts']) > 0) {
5721: $parts = &$opData[$direction]['parts'];
5722: $part_count = sizeof($parts);
5723: $style = $opData['style'];
5724: $use = $opData[$direction]['use'];
5725: $this->debug("have $part_count part(s) to serialize using $style/$use");
5726: if (is_array($parameters)) {
5727: $parametersArrayType = $this->isArraySimpleOrStruct($parameters);
5728: $parameter_count = count($parameters);
5729: $this->debug("have $parameter_count parameter(s) provided as $parametersArrayType to serialize");
5730:
5731: if ($style == 'document' && $use == 'literal' && $part_count == 1 && isset($parts['parameters'])) {
5732: $this->debug('check whether the caller has wrapped the parameters');
5733: if ($direction == 'output' && $parametersArrayType == 'arraySimple' && $parameter_count == 1) {
5734:
5735:
5736: $this->debug("change simple array to associative with 'parameters' element");
5737: $parameters['parameters'] = $parameters[0];
5738: unset($parameters[0]);
5739: }
5740: if (($parametersArrayType == 'arrayStruct' || $parameter_count == 0) && !isset($parameters['parameters'])) {
5741: $this->debug('check whether caller\'s parameters match the wrapped ones');
5742: if ($this->parametersMatchWrapped($parts['parameters'], $parameters)) {
5743: $this->debug('wrap the parameters for the caller');
5744: $parameters = array('parameters' => $parameters);
5745: $parameter_count = 1;
5746: }
5747: }
5748: }
5749: foreach ($parts as $name => $type) {
5750: $this->debug("serializing part $name of type $type");
5751:
5752: if (isset($opData[$direction]['encodingStyle']) && $encodingStyle != $opData[$direction]['encodingStyle']) {
5753: $encodingStyle = $opData[$direction]['encodingStyle'];
5754: $enc_style = $encodingStyle;
5755: } else {
5756: $enc_style = false;
5757: }
5758:
5759:
5760: if ($parametersArrayType == 'arraySimple') {
5761: $p = array_shift($parameters);
5762: $this->debug('calling serializeType w/indexed param');
5763: $xml .= $this->serializeType($name, $type, $p, $use, $enc_style);
5764: } elseif (isset($parameters[$name])) {
5765: $this->debug('calling serializeType w/named param');
5766: $xml .= $this->serializeType($name, $type, $parameters[$name], $use, $enc_style);
5767: } else {
5768:
5769: $this->debug('calling serializeType w/null param');
5770: $xml .= $this->serializeType($name, $type, null, $use, $enc_style);
5771: }
5772: }
5773: } else {
5774: $this->debug('no parameters passed.');
5775: }
5776: }
5777: $this->debug("serializeRPCParameters returning: $xml");
5778: return $xml;
5779: }
5780:
5781: 5782: 5783: 5784: 5785: 5786: 5787: 5788: 5789: 5790: 5791: 5792: 5793: 5794:
5795: function serializeParameters($operation, $direction, $parameters)
5796: {
5797: $this->debug("in serializeParameters: operation=$operation, direction=$direction, XMLSchemaVersion=$this->XMLSchemaVersion");
5798: $this->appendDebug('parameters=' . $this->varDump($parameters));
5799:
5800: if ($direction != 'input' && $direction != 'output') {
5801: $this->debug('The value of the \$direction argument needs to be either "input" or "output"');
5802: $this->setError('The value of the \$direction argument needs to be either "input" or "output"');
5803: return false;
5804: }
5805: if (!$opData = $this->getOperationData($operation)) {
5806: $this->debug('Unable to retrieve WSDL data for operation: ' . $operation);
5807: $this->setError('Unable to retrieve WSDL data for operation: ' . $operation);
5808: return false;
5809: }
5810: $this->debug('opData:');
5811: $this->appendDebug($this->varDump($opData));
5812:
5813:
5814: $encodingStyle = 'http://schemas.xmlsoap.org/soap/encoding/';
5815: if(($direction == 'input') && isset($opData['output']['encodingStyle']) && ($opData['output']['encodingStyle'] != $encodingStyle)) {
5816: $encodingStyle = $opData['output']['encodingStyle'];
5817: $enc_style = $encodingStyle;
5818: }
5819:
5820:
5821: $xml = '';
5822: if (isset($opData[$direction]['parts']) && sizeof($opData[$direction]['parts']) > 0) {
5823:
5824: $use = $opData[$direction]['use'];
5825: $this->debug("use=$use");
5826: $this->debug('got ' . count($opData[$direction]['parts']) . ' part(s)');
5827: if (is_array($parameters)) {
5828: $parametersArrayType = $this->isArraySimpleOrStruct($parameters);
5829: $this->debug('have ' . $parametersArrayType . ' parameters');
5830: foreach($opData[$direction]['parts'] as $name => $type) {
5831: $this->debug('serializing part "'.$name.'" of type "'.$type.'"');
5832:
5833: if(isset($opData[$direction]['encodingStyle']) && $encodingStyle != $opData[$direction]['encodingStyle']) {
5834: $encodingStyle = $opData[$direction]['encodingStyle'];
5835: $enc_style = $encodingStyle;
5836: } else {
5837: $enc_style = false;
5838: }
5839:
5840:
5841: if ($parametersArrayType == 'arraySimple') {
5842: $p = array_shift($parameters);
5843: $this->debug('calling serializeType w/indexed param');
5844: $xml .= $this->serializeType($name, $type, $p, $use, $enc_style);
5845: } elseif (isset($parameters[$name])) {
5846: $this->debug('calling serializeType w/named param');
5847: $xml .= $this->serializeType($name, $type, $parameters[$name], $use, $enc_style);
5848: } else {
5849:
5850: $this->debug('calling serializeType w/null param');
5851: $xml .= $this->serializeType($name, $type, null, $use, $enc_style);
5852: }
5853: }
5854: } else {
5855: $this->debug('no parameters passed.');
5856: }
5857: }
5858: $this->debug("serializeParameters returning: $xml");
5859: return $xml;
5860: }
5861:
5862: 5863: 5864: 5865: 5866: 5867: 5868: 5869: 5870: 5871: 5872: 5873:
5874: function serializeType($name, $type, $value, $use='encoded', $encodingStyle=false, $unqualified=false)
5875: {
5876: $this->debug("in serializeType: name=$name, type=$type, use=$use, encodingStyle=$encodingStyle, unqualified=" . ($unqualified ? "unqualified" : "qualified"));
5877: $this->appendDebug("value=" . $this->varDump($value));
5878: if($use == 'encoded' && $encodingStyle) {
5879: $encodingStyle = ' SOAP-ENV:encodingStyle="' . $encodingStyle . '"';
5880: }
5881:
5882:
5883: if (is_object($value) && get_class($value) == 'soapval') {
5884: if ($value->type_ns) {
5885: $type = $value->type_ns . ':' . $value->type;
5886: $forceType = true;
5887: $this->debug("in serializeType: soapval overrides type to $type");
5888: } elseif ($value->type) {
5889: $type = $value->type;
5890: $forceType = true;
5891: $this->debug("in serializeType: soapval overrides type to $type");
5892: } else {
5893: $forceType = false;
5894: $this->debug("in serializeType: soapval does not override type");
5895: }
5896: $attrs = $value->attributes;
5897: $value = $value->value;
5898: $this->debug("in serializeType: soapval overrides value to $value");
5899: if ($attrs) {
5900: if (!is_array($value)) {
5901: $value['!'] = $value;
5902: }
5903: foreach ($attrs as $n => $v) {
5904: $value['!' . $n] = $v;
5905: }
5906: $this->debug("in serializeType: soapval provides attributes");
5907: }
5908: } else {
5909: $forceType = false;
5910: }
5911:
5912: $xml = '';
5913: if (strpos($type, ':')) {
5914: $uqType = substr($type, strrpos($type, ':') + 1);
5915: $ns = substr($type, 0, strrpos($type, ':'));
5916: $this->debug("in serializeType: got a prefixed type: $uqType, $ns");
5917: if ($this->getNamespaceFromPrefix($ns)) {
5918: $ns = $this->getNamespaceFromPrefix($ns);
5919: $this->debug("in serializeType: expanded prefixed type: $uqType, $ns");
5920: }
5921:
5922: if($ns == $this->XMLSchemaVersion || $ns == 'http://schemas.xmlsoap.org/soap/encoding/'){
5923: $this->debug('in serializeType: type namespace indicates XML Schema or SOAP Encoding type');
5924: if ($unqualified && $use == 'literal') {
5925: $elementNS = " xmlns=\"\"";
5926: } else {
5927: $elementNS = '';
5928: }
5929: if (is_null($value)) {
5930: if ($use == 'literal') {
5931:
5932: $xml = "<$name$elementNS/>";
5933: } else {
5934:
5935: $xml = "<$name$elementNS xsi:nil=\"true\" xsi:type=\"" . $this->getPrefixFromNamespace($ns) . ":$uqType\"/>";
5936: }
5937: $this->debug("in serializeType: returning: $xml");
5938: return $xml;
5939: }
5940: if ($uqType == 'Array') {
5941:
5942: return $this->serialize_val($value, $name, false, false, false, false, $use);
5943: }
5944: if ($uqType == 'boolean') {
5945: if ((is_string($value) && $value == 'false') || (! $value)) {
5946: $value = 'false';
5947: } else {
5948: $value = 'true';
5949: }
5950: }
5951: if ($uqType == 'string' && gettype($value) == 'string') {
5952: $value = $this->expandEntities($value);
5953: }
5954: if (($uqType == 'long' || $uqType == 'unsignedLong') && gettype($value) == 'double') {
5955: $value = sprintf("%.0lf", $value);
5956: }
5957:
5958:
5959:
5960: if (!$this->getTypeDef($uqType, $ns)) {
5961: if ($use == 'literal') {
5962: if ($forceType) {
5963: $xml = "<$name$elementNS xsi:type=\"" . $this->getPrefixFromNamespace($ns) . ":$uqType\">$value</$name>";
5964: } else {
5965: $xml = "<$name$elementNS>$value</$name>";
5966: }
5967: } else {
5968: $xml = "<$name$elementNS xsi:type=\"" . $this->getPrefixFromNamespace($ns) . ":$uqType\"$encodingStyle>$value</$name>";
5969: }
5970: $this->debug("in serializeType: returning: $xml");
5971: return $xml;
5972: }
5973: $this->debug('custom type extends XML Schema or SOAP Encoding namespace (yuck)');
5974: } else if ($ns == 'http://xml.apache.org/xml-soap') {
5975: $this->debug('in serializeType: appears to be Apache SOAP type');
5976: if ($uqType == 'Map') {
5977: $tt_prefix = $this->getPrefixFromNamespace('http://xml.apache.org/xml-soap');
5978: if (! $tt_prefix) {
5979: $this->debug('in serializeType: Add namespace for Apache SOAP type');
5980: $tt_prefix = 'ns' . rand(1000, 9999);
5981: $this->namespaces[$tt_prefix] = 'http://xml.apache.org/xml-soap';
5982:
5983: $tt_prefix = $this->getPrefixFromNamespace('http://xml.apache.org/xml-soap');
5984: }
5985: $contents = '';
5986: foreach($value as $k => $v) {
5987: $this->debug("serializing map element: key $k, value $v");
5988: $contents .= '<item>';
5989: $contents .= $this->serialize_val($k,'key',false,false,false,false,$use);
5990: $contents .= $this->serialize_val($v,'value',false,false,false,false,$use);
5991: $contents .= '</item>';
5992: }
5993: if ($use == 'literal') {
5994: if ($forceType) {
5995: $xml = "<$name xsi:type=\"" . $tt_prefix . ":$uqType\">$contents</$name>";
5996: } else {
5997: $xml = "<$name>$contents</$name>";
5998: }
5999: } else {
6000: $xml = "<$name xsi:type=\"" . $tt_prefix . ":$uqType\"$encodingStyle>$contents</$name>";
6001: }
6002: $this->debug("in serializeType: returning: $xml");
6003: return $xml;
6004: }
6005: $this->debug('in serializeType: Apache SOAP type, but only support Map');
6006: }
6007: } else {
6008:
6009:
6010: $this->debug("in serializeType: No namespace for type $type");
6011: $ns = '';
6012: $uqType = $type;
6013: }
6014: if(!$typeDef = $this->getTypeDef($uqType, $ns)){
6015: $this->setError("$type ($uqType) is not a supported type.");
6016: $this->debug("in serializeType: $type ($uqType) is not a supported type.");
6017: return false;
6018: } else {
6019: $this->debug("in serializeType: found typeDef");
6020: $this->appendDebug('typeDef=' . $this->varDump($typeDef));
6021: if (substr($uqType, -1) == '^') {
6022: $uqType = substr($uqType, 0, -1);
6023: }
6024: }
6025: if (!isset($typeDef['phpType'])) {
6026: $this->setError("$type ($uqType) has no phpType.");
6027: $this->debug("in serializeType: $type ($uqType) has no phpType.");
6028: return false;
6029: }
6030: $phpType = $typeDef['phpType'];
6031: $this->debug("in serializeType: uqType: $uqType, ns: $ns, phptype: $phpType, arrayType: " . (isset($typeDef['arrayType']) ? $typeDef['arrayType'] : '') );
6032:
6033: if ($phpType == 'struct') {
6034: if (isset($typeDef['typeClass']) && $typeDef['typeClass'] == 'element') {
6035: $elementName = $uqType;
6036: if (isset($typeDef['form']) && ($typeDef['form'] == 'qualified')) {
6037: $elementNS = " xmlns=\"$ns\"";
6038: } else {
6039: $elementNS = " xmlns=\"\"";
6040: }
6041: } else {
6042: $elementName = $name;
6043: if ($unqualified) {
6044: $elementNS = " xmlns=\"\"";
6045: } else {
6046: $elementNS = '';
6047: }
6048: }
6049: if (is_null($value)) {
6050: if ($use == 'literal') {
6051:
6052: $xml = "<$elementName$elementNS/>";
6053: } else {
6054: $xml = "<$elementName$elementNS xsi:nil=\"true\" xsi:type=\"" . $this->getPrefixFromNamespace($ns) . ":$uqType\"/>";
6055: }
6056: $this->debug("in serializeType: returning: $xml");
6057: return $xml;
6058: }
6059: if (is_object($value)) {
6060: $value = get_object_vars($value);
6061: }
6062: if (is_array($value)) {
6063: $elementAttrs = $this->serializeComplexTypeAttributes($typeDef, $value, $ns, $uqType);
6064: if ($use == 'literal') {
6065: if ($forceType) {
6066: $xml = "<$elementName$elementNS$elementAttrs xsi:type=\"" . $this->getPrefixFromNamespace($ns) . ":$uqType\">";
6067: } else {
6068: $xml = "<$elementName$elementNS$elementAttrs>";
6069: }
6070: } else {
6071: $xml = "<$elementName$elementNS$elementAttrs xsi:type=\"" . $this->getPrefixFromNamespace($ns) . ":$uqType\"$encodingStyle>";
6072: }
6073:
6074: if (isset($typeDef['simpleContent']) && $typeDef['simpleContent'] == 'true') {
6075: if (isset($value['!'])) {
6076: $xml .= $value['!'];
6077: $this->debug("in serializeType: serialized simpleContent for type $type");
6078: } else {
6079: $this->debug("in serializeType: no simpleContent to serialize for type $type");
6080: }
6081: } else {
6082:
6083: $xml .= $this->serializeComplexTypeElements($typeDef, $value, $ns, $uqType, $use, $encodingStyle);
6084: }
6085: $xml .= "</$elementName>";
6086: } else {
6087: $this->debug("in serializeType: phpType is struct, but value is not an array");
6088: $this->setError("phpType is struct, but value is not an array: see debug output for details");
6089: $xml = '';
6090: }
6091: } elseif ($phpType == 'array') {
6092: if (isset($typeDef['form']) && ($typeDef['form'] == 'qualified')) {
6093: $elementNS = " xmlns=\"$ns\"";
6094: } else {
6095: if ($unqualified) {
6096: $elementNS = " xmlns=\"\"";
6097: } else {
6098: $elementNS = '';
6099: }
6100: }
6101: if (is_null($value)) {
6102: if ($use == 'literal') {
6103:
6104: $xml = "<$name$elementNS/>";
6105: } else {
6106: $xml = "<$name$elementNS xsi:nil=\"true\" xsi:type=\"" .
6107: $this->getPrefixFromNamespace('http://schemas.xmlsoap.org/soap/encoding/') .
6108: ":Array\" " .
6109: $this->getPrefixFromNamespace('http://schemas.xmlsoap.org/soap/encoding/') .
6110: ':arrayType="' .
6111: $this->getPrefixFromNamespace($this->getPrefix($typeDef['arrayType'])) .
6112: ':' .
6113: $this->getLocalPart($typeDef['arrayType'])."[0]\"/>";
6114: }
6115: $this->debug("in serializeType: returning: $xml");
6116: return $xml;
6117: }
6118: if (isset($typeDef['multidimensional'])) {
6119: $nv = array();
6120: foreach($value as $v) {
6121: $cols = ',' . sizeof($v);
6122: $nv = array_merge($nv, $v);
6123: }
6124: $value = $nv;
6125: } else {
6126: $cols = '';
6127: }
6128: if (is_array($value) && sizeof($value) >= 1) {
6129: $rows = sizeof($value);
6130: $contents = '';
6131: foreach($value as $k => $v) {
6132: $this->debug("serializing array element: $k, $v of type: $typeDef[arrayType]");
6133:
6134: if (!in_array($typeDef['arrayType'],$this->typemap['http://www.w3.org/2001/XMLSchema'])) {
6135: $contents .= $this->serializeType('item', $typeDef['arrayType'], $v, $use);
6136: } else {
6137: $contents .= $this->serialize_val($v, 'item', $typeDef['arrayType'], null, $this->XMLSchemaVersion, false, $use);
6138: }
6139: }
6140: } else {
6141: $rows = 0;
6142: $contents = null;
6143: }
6144:
6145:
6146: if ($use == 'literal') {
6147: $xml = "<$name$elementNS>"
6148: .$contents
6149: ."</$name>";
6150: } else {
6151: $xml = "<$name$elementNS xsi:type=\"".$this->getPrefixFromNamespace('http://schemas.xmlsoap.org/soap/encoding/').':Array" '.
6152: $this->getPrefixFromNamespace('http://schemas.xmlsoap.org/soap/encoding/')
6153: .':arrayType="'
6154: .$this->getPrefixFromNamespace($this->getPrefix($typeDef['arrayType']))
6155: .":".$this->getLocalPart($typeDef['arrayType'])."[$rows$cols]\">"
6156: .$contents
6157: ."</$name>";
6158: }
6159: } elseif ($phpType == 'scalar') {
6160: if (isset($typeDef['form']) && ($typeDef['form'] == 'qualified')) {
6161: $elementNS = " xmlns=\"$ns\"";
6162: } else {
6163: if ($unqualified) {
6164: $elementNS = " xmlns=\"\"";
6165: } else {
6166: $elementNS = '';
6167: }
6168: }
6169: if ($use == 'literal') {
6170: if ($forceType) {
6171: $xml = "<$name$elementNS xsi:type=\"" . $this->getPrefixFromNamespace($ns) . ":$uqType\">$value</$name>";
6172: } else {
6173: $xml = "<$name$elementNS>$value</$name>";
6174: }
6175: } else {
6176: $xml = "<$name$elementNS xsi:type=\"" . $this->getPrefixFromNamespace($ns) . ":$uqType\"$encodingStyle>$value</$name>";
6177: }
6178: }
6179: $this->debug("in serializeType: returning: $xml");
6180: return $xml;
6181: }
6182:
6183: 6184: 6185: 6186: 6187: 6188: 6189: 6190: 6191: 6192:
6193: function serializeComplexTypeAttributes($typeDef, $value, $ns, $uqType) {
6194: $this->debug("serializeComplexTypeAttributes for XML Schema type $ns:$uqType");
6195: $xml = '';
6196: if (isset($typeDef['extensionBase'])) {
6197: $nsx = $this->getPrefix($typeDef['extensionBase']);
6198: $uqTypex = $this->getLocalPart($typeDef['extensionBase']);
6199: if ($this->getNamespaceFromPrefix($nsx)) {
6200: $nsx = $this->getNamespaceFromPrefix($nsx);
6201: }
6202: if ($typeDefx = $this->getTypeDef($uqTypex, $nsx)) {
6203: $this->debug("serialize attributes for extension base $nsx:$uqTypex");
6204: $xml .= $this->serializeComplexTypeAttributes($typeDefx, $value, $nsx, $uqTypex);
6205: } else {
6206: $this->debug("extension base $nsx:$uqTypex is not a supported type");
6207: }
6208: }
6209: if (isset($typeDef['attrs']) && is_array($typeDef['attrs'])) {
6210: $this->debug("serialize attributes for XML Schema type $ns:$uqType");
6211: if (is_array($value)) {
6212: $xvalue = $value;
6213: } elseif (is_object($value)) {
6214: $xvalue = get_object_vars($value);
6215: } else {
6216: $this->debug("value is neither an array nor an object for XML Schema type $ns:$uqType");
6217: $xvalue = array();
6218: }
6219: foreach ($typeDef['attrs'] as $aName => $attrs) {
6220: if (isset($xvalue['!' . $aName])) {
6221: $xname = '!' . $aName;
6222: $this->debug("value provided for attribute $aName with key $xname");
6223: } elseif (isset($xvalue[$aName])) {
6224: $xname = $aName;
6225: $this->debug("value provided for attribute $aName with key $xname");
6226: } elseif (isset($attrs['default'])) {
6227: $xname = '!' . $aName;
6228: $xvalue[$xname] = $attrs['default'];
6229: $this->debug('use default value of ' . $xvalue[$aName] . ' for attribute ' . $aName);
6230: } else {
6231: $xname = '';
6232: $this->debug("no value provided for attribute $aName");
6233: }
6234: if ($xname) {
6235: $xml .= " $aName=\"" . $this->expandEntities($xvalue[$xname]) . "\"";
6236: }
6237: }
6238: } else {
6239: $this->debug("no attributes to serialize for XML Schema type $ns:$uqType");
6240: }
6241: return $xml;
6242: }
6243:
6244: 6245: 6246: 6247: 6248: 6249: 6250: 6251: 6252: 6253: 6254: 6255:
6256: function serializeComplexTypeElements($typeDef, $value, $ns, $uqType, $use='encoded', $encodingStyle=false) {
6257: $this->debug("in serializeComplexTypeElements for XML Schema type $ns:$uqType");
6258: $xml = '';
6259: if (isset($typeDef['extensionBase'])) {
6260: $nsx = $this->getPrefix($typeDef['extensionBase']);
6261: $uqTypex = $this->getLocalPart($typeDef['extensionBase']);
6262: if ($this->getNamespaceFromPrefix($nsx)) {
6263: $nsx = $this->getNamespaceFromPrefix($nsx);
6264: }
6265: if ($typeDefx = $this->getTypeDef($uqTypex, $nsx)) {
6266: $this->debug("serialize elements for extension base $nsx:$uqTypex");
6267: $xml .= $this->serializeComplexTypeElements($typeDefx, $value, $nsx, $uqTypex, $use, $encodingStyle);
6268: } else {
6269: $this->debug("extension base $nsx:$uqTypex is not a supported type");
6270: }
6271: }
6272: if (isset($typeDef['elements']) && is_array($typeDef['elements'])) {
6273: $this->debug("in serializeComplexTypeElements, serialize elements for XML Schema type $ns:$uqType");
6274: if (is_array($value)) {
6275: $xvalue = $value;
6276: } elseif (is_object($value)) {
6277: $xvalue = get_object_vars($value);
6278: } else {
6279: $this->debug("value is neither an array nor an object for XML Schema type $ns:$uqType");
6280: $xvalue = array();
6281: }
6282:
6283: if (count($typeDef['elements']) != count($xvalue)){
6284: $optionals = true;
6285: }
6286: foreach ($typeDef['elements'] as $eName => $attrs) {
6287: if (!isset($xvalue[$eName])) {
6288: if (isset($attrs['default'])) {
6289: $xvalue[$eName] = $attrs['default'];
6290: $this->debug('use default value of ' . $xvalue[$eName] . ' for element ' . $eName);
6291: }
6292: }
6293:
6294: if (isset($optionals)
6295: && (!isset($xvalue[$eName]))
6296: && ( (!isset($attrs['nillable'])) || $attrs['nillable'] != 'true')
6297: ){
6298: if (isset($attrs['minOccurs']) && $attrs['minOccurs'] <> '0') {
6299: $this->debug("apparent error: no value provided for element $eName with minOccurs=" . $attrs['minOccurs']);
6300: }
6301:
6302: $this->debug("no value provided for complexType element $eName and element is not nillable, so serialize nothing");
6303: } else {
6304:
6305: if (isset($xvalue[$eName])) {
6306: $v = $xvalue[$eName];
6307: } else {
6308: $v = null;
6309: }
6310: if (isset($attrs['form'])) {
6311: $unqualified = ($attrs['form'] == 'unqualified');
6312: } else {
6313: $unqualified = false;
6314: }
6315: if (isset($attrs['maxOccurs']) && ($attrs['maxOccurs'] == 'unbounded' || $attrs['maxOccurs'] > 1) && isset($v) && is_array($v) && $this->isArraySimpleOrStruct($v) == 'arraySimple') {
6316: $vv = $v;
6317: foreach ($vv as $k => $v) {
6318: if (isset($attrs['type']) || isset($attrs['ref'])) {
6319:
6320: $xml .= $this->serializeType($eName, isset($attrs['type']) ? $attrs['type'] : $attrs['ref'], $v, $use, $encodingStyle, $unqualified);
6321: } else {
6322:
6323: $this->debug("calling serialize_val() for $v, $eName, false, false, false, false, $use");
6324: $xml .= $this->serialize_val($v, $eName, false, false, false, false, $use);
6325: }
6326: }
6327: } else {
6328: if (is_null($v) && isset($attrs['minOccurs']) && $attrs['minOccurs'] == '0') {
6329:
6330: } elseif (is_null($v) && isset($attrs['nillable']) && $attrs['nillable'] == 'true') {
6331:
6332: $xml .= $this->serializeType($eName, isset($attrs['type']) ? $attrs['type'] : $attrs['ref'], $v, $use, $encodingStyle, $unqualified);
6333: } elseif (isset($attrs['type']) || isset($attrs['ref'])) {
6334:
6335: $xml .= $this->serializeType($eName, isset($attrs['type']) ? $attrs['type'] : $attrs['ref'], $v, $use, $encodingStyle, $unqualified);
6336: } else {
6337:
6338: $this->debug("calling serialize_val() for $v, $eName, false, false, false, false, $use");
6339: $xml .= $this->serialize_val($v, $eName, false, false, false, false, $use);
6340: }
6341: }
6342: }
6343: }
6344: } else {
6345: $this->debug("no elements to serialize for XML Schema type $ns:$uqType");
6346: }
6347: return $xml;
6348: }
6349:
6350: 6351: 6352: 6353: 6354: 6355: 6356: 6357: 6358: 6359: 6360: 6361: 6362: 6363:
6364: function addComplexType($name,$typeClass='complexType',$phpType='array',$compositor='',$restrictionBase='',$elements=array(),$attrs=array(),$arrayType='') {
6365: if (count($elements) > 0) {
6366: $eElements = array();
6367: foreach($elements as $n => $e){
6368:
6369: $ee = array();
6370: foreach ($e as $k => $v) {
6371: $k = strpos($k,':') ? $this->expandQname($k) : $k;
6372: $v = strpos($v,':') ? $this->expandQname($v) : $v;
6373: $ee[$k] = $v;
6374: }
6375: $eElements[$n] = $ee;
6376: }
6377: $elements = $eElements;
6378: }
6379:
6380: if (count($attrs) > 0) {
6381: foreach($attrs as $n => $a){
6382:
6383: foreach ($a as $k => $v) {
6384: $k = strpos($k,':') ? $this->expandQname($k) : $k;
6385: $v = strpos($v,':') ? $this->expandQname($v) : $v;
6386: $aa[$k] = $v;
6387: }
6388: $eAttrs[$n] = $aa;
6389: }
6390: $attrs = $eAttrs;
6391: }
6392:
6393: $restrictionBase = strpos($restrictionBase,':') ? $this->expandQname($restrictionBase) : $restrictionBase;
6394: $arrayType = strpos($arrayType,':') ? $this->expandQname($arrayType) : $arrayType;
6395:
6396: $typens = isset($this->namespaces['types']) ? $this->namespaces['types'] : $this->namespaces['tns'];
6397: $this->schemas[$typens][0]->addComplexType($name,$typeClass,$phpType,$compositor,$restrictionBase,$elements,$attrs,$arrayType);
6398: }
6399:
6400: 6401: 6402: 6403: 6404: 6405: 6406: 6407: 6408: 6409: 6410:
6411: function addSimpleType($name, $restrictionBase='', $typeClass='simpleType', $phpType='scalar', $enumeration=array()) {
6412: $restrictionBase = strpos($restrictionBase,':') ? $this->expandQname($restrictionBase) : $restrictionBase;
6413:
6414: $typens = isset($this->namespaces['types']) ? $this->namespaces['types'] : $this->namespaces['tns'];
6415: $this->schemas[$typens][0]->addSimpleType($name, $restrictionBase, $typeClass, $phpType, $enumeration);
6416: }
6417:
6418: 6419: 6420: 6421: 6422: 6423: 6424:
6425: function addElement($attrs) {
6426: $typens = isset($this->namespaces['types']) ? $this->namespaces['types'] : $this->namespaces['tns'];
6427: $this->schemas[$typens][0]->addElement($attrs);
6428: }
6429:
6430: 6431: 6432: 6433: 6434: 6435: 6436: 6437: 6438: 6439: 6440: 6441: 6442: 6443:
6444: function addOperation($name, $in = false, $out = false, $namespace = false, $soapaction = false, $style = 'rpc', $use = 'encoded', $documentation = '', $encodingStyle = ''){
6445: if ($use == 'encoded' && $encodingStyle == '') {
6446: $encodingStyle = 'http://schemas.xmlsoap.org/soap/encoding/';
6447: }
6448:
6449: if ($style == 'document') {
6450: $elements = array();
6451: foreach ($in as $n => $t) {
6452: $elements[$n] = array('name' => $n, 'type' => $t, 'form' => 'unqualified');
6453: }
6454: $this->addComplexType($name . 'RequestType', 'complexType', 'struct', 'all', '', $elements);
6455: $this->addElement(array('name' => $name, 'type' => $name . 'RequestType'));
6456: $in = array('parameters' => 'tns:' . $name . '^');
6457:
6458: $elements = array();
6459: foreach ($out as $n => $t) {
6460: $elements[$n] = array('name' => $n, 'type' => $t, 'form' => 'unqualified');
6461: }
6462: $this->addComplexType($name . 'ResponseType', 'complexType', 'struct', 'all', '', $elements);
6463: $this->addElement(array('name' => $name . 'Response', 'type' => $name . 'ResponseType', 'form' => 'qualified'));
6464: $out = array('parameters' => 'tns:' . $name . 'Response' . '^');
6465: }
6466:
6467:
6468: $this->bindings[ $this->serviceName . 'Binding' ]['operations'][$name] =
6469: array(
6470: 'name' => $name,
6471: 'binding' => $this->serviceName . 'Binding',
6472: 'endpoint' => $this->endpoint,
6473: 'soapAction' => $soapaction,
6474: 'style' => $style,
6475: 'input' => array(
6476: 'use' => $use,
6477: 'namespace' => $namespace,
6478: 'encodingStyle' => $encodingStyle,
6479: 'message' => $name . 'Request',
6480: 'parts' => $in),
6481: 'output' => array(
6482: 'use' => $use,
6483: 'namespace' => $namespace,
6484: 'encodingStyle' => $encodingStyle,
6485: 'message' => $name . 'Response',
6486: 'parts' => $out),
6487: 'namespace' => $namespace,
6488: 'transport' => 'http://schemas.xmlsoap.org/soap/http',
6489: 'documentation' => $documentation);
6490:
6491:
6492: if($in)
6493: {
6494: foreach($in as $pName => $pType)
6495: {
6496: if(strpos($pType,':')) {
6497: $pType = $this->getNamespaceFromPrefix($this->getPrefix($pType)).":".$this->getLocalPart($pType);
6498: }
6499: $this->messages[$name.'Request'][$pName] = $pType;
6500: }
6501: } else {
6502: $this->messages[$name.'Request']= '0';
6503: }
6504: if($out)
6505: {
6506: foreach($out as $pName => $pType)
6507: {
6508: if(strpos($pType,':')) {
6509: $pType = $this->getNamespaceFromPrefix($this->getPrefix($pType)).":".$this->getLocalPart($pType);
6510: }
6511: $this->messages[$name.'Response'][$pName] = $pType;
6512: }
6513: } else {
6514: $this->messages[$name.'Response']= '0';
6515: }
6516: return true;
6517: }
6518: }
6519: ?><?php
6520:
6521:
6522:
6523: 6524: 6525: 6526: 6527: 6528: 6529: 6530: 6531:
6532: class nusoap_parser extends nusoap_base {
6533:
6534: var $xml = '';
6535: var $xml_encoding = '';
6536: var $method = '';
6537: var $root_struct = '';
6538: var $root_struct_name = '';
6539: var $root_struct_namespace = '';
6540: var $root_header = '';
6541: var $document = '';
6542:
6543: var $status = '';
6544: var $position = 0;
6545: var $depth = 0;
6546: var $default_namespace = '';
6547: var $namespaces = array();
6548: var $message = array();
6549: var $parent = '';
6550: var $fault = false;
6551: var $fault_code = '';
6552: var $fault_str = '';
6553: var $fault_detail = '';
6554: var $depth_array = array();
6555: var $debug_flag = true;
6556: var $soapresponse = NULL;
6557: var $soapheader = NULL;
6558: var $responseHeaders = '';
6559: var $body_position = 0;
6560:
6561:
6562: var $ids = array();
6563:
6564: var $multirefs = array();
6565:
6566: var $decode_utf8 = true;
6567:
6568: 6569: 6570: 6571: 6572: 6573: 6574: 6575: 6576:
6577: function nusoap_parser($xml,$encoding='UTF-8',$method='',$decode_utf8=true){
6578: parent::nusoap_base();
6579: $this->xml = $xml;
6580: $this->xml_encoding = $encoding;
6581: $this->method = $method;
6582: $this->decode_utf8 = $decode_utf8;
6583:
6584:
6585: if(!empty($xml)){
6586:
6587: $pos_xml = strpos($xml, '<?xml');
6588: if ($pos_xml !== FALSE) {
6589: $xml_decl = substr($xml, $pos_xml, strpos($xml, '?>', $pos_xml + 2) - $pos_xml + 1);
6590: if (preg_match("/encoding=[\"']([^\"']*)[\"']/", $xml_decl, $res)) {
6591: $xml_encoding = $res[1];
6592: if (strtoupper($xml_encoding) != $encoding) {
6593: $err = "Charset from HTTP Content-Type '" . $encoding . "' does not match encoding from XML declaration '" . $xml_encoding . "'";
6594: $this->debug($err);
6595: if ($encoding != 'ISO-8859-1' || strtoupper($xml_encoding) != 'UTF-8') {
6596: $this->setError($err);
6597: return;
6598: }
6599:
6600: } else {
6601: $this->debug('Charset from HTTP Content-Type matches encoding from XML declaration');
6602: }
6603: } else {
6604: $this->debug('No encoding specified in XML declaration');
6605: }
6606: } else {
6607: $this->debug('No XML declaration');
6608: }
6609: $this->debug('Entering nusoap_parser(), length='.strlen($xml).', encoding='.$encoding);
6610:
6611: $this->parser = xml_parser_create($this->xml_encoding);
6612:
6613:
6614: xml_parser_set_option($this->parser, XML_OPTION_CASE_FOLDING, 0);
6615: xml_parser_set_option($this->parser, XML_OPTION_TARGET_ENCODING, $this->xml_encoding);
6616:
6617: xml_set_object($this->parser, $this);
6618:
6619: xml_set_element_handler($this->parser, 'start_element','end_element');
6620: xml_set_character_data_handler($this->parser,'character_data');
6621:
6622:
6623: if(!xml_parse($this->parser,$xml,true)){
6624:
6625: $err = sprintf('XML error parsing SOAP payload on line %d: %s',
6626: xml_get_current_line_number($this->parser),
6627: xml_error_string(xml_get_error_code($this->parser)));
6628: $this->debug($err);
6629: $this->debug("XML payload:\n" . $xml);
6630: $this->setError($err);
6631: } else {
6632: $this->debug('in nusoap_parser ctor, message:');
6633: $this->appendDebug($this->varDump($this->message));
6634: $this->debug('parsed successfully, found root struct: '.$this->root_struct.' of name '.$this->root_struct_name);
6635:
6636: $this->soapresponse = $this->message[$this->root_struct]['result'];
6637:
6638: if($this->root_header != '' && isset($this->message[$this->root_header]['result'])){
6639: $this->soapheader = $this->message[$this->root_header]['result'];
6640: }
6641:
6642: if(sizeof($this->multirefs) > 0){
6643: foreach($this->multirefs as $id => $hrefs){
6644: $this->debug('resolving multirefs for id: '.$id);
6645: $idVal = $this->buildVal($this->ids[$id]);
6646: if (is_array($idVal) && isset($idVal['!id'])) {
6647: unset($idVal['!id']);
6648: }
6649: foreach($hrefs as $refPos => $ref){
6650: $this->debug('resolving href at pos '.$refPos);
6651: $this->multirefs[$id][$refPos] = $idVal;
6652: }
6653: }
6654: }
6655: }
6656: xml_parser_free($this->parser);
6657: } else {
6658: $this->debug('xml was empty, didn\'t parse!');
6659: $this->setError('xml was empty, didn\'t parse!');
6660: }
6661: }
6662:
6663: 6664: 6665: 6666: 6667: 6668: 6669: 6670:
6671: function start_element($parser, $name, $attrs) {
6672:
6673:
6674: $pos = $this->position++;
6675:
6676: $this->message[$pos] = array('pos' => $pos,'children'=>'','cdata'=>'');
6677:
6678:
6679: $this->message[$pos]['depth'] = $this->depth++;
6680:
6681:
6682: if($pos != 0){
6683: $this->message[$this->parent]['children'] .= '|'.$pos;
6684: }
6685:
6686: $this->message[$pos]['parent'] = $this->parent;
6687:
6688: $this->parent = $pos;
6689:
6690: $this->depth_array[$this->depth] = $pos;
6691:
6692: if(strpos($name,':')){
6693:
6694: $prefix = substr($name,0,strpos($name,':'));
6695:
6696: $name = substr(strstr($name,':'),1);
6697: }
6698:
6699: if ($name == 'Envelope' && $this->status == '') {
6700: $this->status = 'envelope';
6701: } elseif ($name == 'Header' && $this->status == 'envelope') {
6702: $this->root_header = $pos;
6703: $this->status = 'header';
6704: } elseif ($name == 'Body' && $this->status == 'envelope'){
6705: $this->status = 'body';
6706: $this->body_position = $pos;
6707:
6708: } elseif($this->status == 'body' && $pos == ($this->body_position+1)) {
6709: $this->status = 'method';
6710: $this->root_struct_name = $name;
6711: $this->root_struct = $pos;
6712: $this->message[$pos]['type'] = 'struct';
6713: $this->debug("found root struct $this->root_struct_name, pos $this->root_struct");
6714: }
6715:
6716: $this->message[$pos]['status'] = $this->status;
6717:
6718: $this->message[$pos]['name'] = htmlspecialchars($name);
6719:
6720: $this->message[$pos]['attrs'] = $attrs;
6721:
6722:
6723: $attstr = '';
6724: foreach($attrs as $key => $value){
6725: $key_prefix = $this->getPrefix($key);
6726: $key_localpart = $this->getLocalPart($key);
6727:
6728: if($key_prefix == 'xmlns'){
6729: if(preg_match('/^http:\/\/www.w3.org\/[0-9]{4}\/XMLSchema$/',$value)){
6730: $this->XMLSchemaVersion = $value;
6731: $this->namespaces['xsd'] = $this->XMLSchemaVersion;
6732: $this->namespaces['xsi'] = $this->XMLSchemaVersion.'-instance';
6733: }
6734: $this->namespaces[$key_localpart] = $value;
6735:
6736: if($name == $this->root_struct_name){
6737: $this->methodNamespace = $value;
6738: }
6739:
6740: } elseif($key_localpart == 'type'){
6741: if (isset($this->message[$pos]['type']) && $this->message[$pos]['type'] == 'array') {
6742:
6743: } else {
6744: $value_prefix = $this->getPrefix($value);
6745: $value_localpart = $this->getLocalPart($value);
6746: $this->message[$pos]['type'] = $value_localpart;
6747: $this->message[$pos]['typePrefix'] = $value_prefix;
6748: if(isset($this->namespaces[$value_prefix])){
6749: $this->message[$pos]['type_namespace'] = $this->namespaces[$value_prefix];
6750: } else if(isset($attrs['xmlns:'.$value_prefix])) {
6751: $this->message[$pos]['type_namespace'] = $attrs['xmlns:'.$value_prefix];
6752: }
6753:
6754: }
6755: } elseif($key_localpart == 'arrayType'){
6756: $this->message[$pos]['type'] = 'array';
6757: 6758: 6759: 6760: 6761: 6762: 6763: 6764:
6765: $expr = '/([A-Za-z0-9_]+):([A-Za-z]+[A-Za-z0-9_]+)\[([0-9]+),?([0-9]*)\]/';
6766: if(preg_match($expr,$value,$regs)){
6767: $this->message[$pos]['typePrefix'] = $regs[1];
6768: $this->message[$pos]['arrayTypePrefix'] = $regs[1];
6769: if (isset($this->namespaces[$regs[1]])) {
6770: $this->message[$pos]['arrayTypeNamespace'] = $this->namespaces[$regs[1]];
6771: } else if (isset($attrs['xmlns:'.$regs[1]])) {
6772: $this->message[$pos]['arrayTypeNamespace'] = $attrs['xmlns:'.$regs[1]];
6773: }
6774: $this->message[$pos]['arrayType'] = $regs[2];
6775: $this->message[$pos]['arraySize'] = $regs[3];
6776: $this->message[$pos]['arrayCols'] = $regs[4];
6777: }
6778:
6779: } elseif ($key_localpart == 'nil'){
6780: $this->message[$pos]['nil'] = ($value == 'true' || $value == '1');
6781:
6782: } elseif ($key != 'href' && $key != 'xmlns' && $key_localpart != 'encodingStyle' && $key_localpart != 'root') {
6783: $this->message[$pos]['xattrs']['!' . $key] = $value;
6784: }
6785:
6786: if ($key == 'xmlns') {
6787: $this->default_namespace = $value;
6788: }
6789:
6790: if($key == 'id'){
6791: $this->ids[$value] = $pos;
6792: }
6793:
6794: if($key_localpart == 'root' && $value == 1){
6795: $this->status = 'method';
6796: $this->root_struct_name = $name;
6797: $this->root_struct = $pos;
6798: $this->debug("found root struct $this->root_struct_name, pos $pos");
6799: }
6800:
6801: $attstr .= " $key=\"$value\"";
6802: }
6803:
6804: if(isset($prefix)){
6805: $this->message[$pos]['namespace'] = $this->namespaces[$prefix];
6806: $this->default_namespace = $this->namespaces[$prefix];
6807: } else {
6808: $this->message[$pos]['namespace'] = $this->default_namespace;
6809: }
6810: if($this->status == 'header'){
6811: if ($this->root_header != $pos) {
6812: $this->responseHeaders .= "<" . (isset($prefix) ? $prefix . ':' : '') . "$name$attstr>";
6813: }
6814: } elseif($this->root_struct_name != ''){
6815: $this->document .= "<" . (isset($prefix) ? $prefix . ':' : '') . "$name$attstr>";
6816: }
6817: }
6818:
6819: 6820: 6821: 6822: 6823: 6824: 6825:
6826: function end_element($parser, $name) {
6827:
6828: $pos = $this->depth_array[$this->depth--];
6829:
6830:
6831: if(strpos($name,':')){
6832:
6833: $prefix = substr($name,0,strpos($name,':'));
6834:
6835: $name = substr(strstr($name,':'),1);
6836: }
6837:
6838:
6839: if(isset($this->body_position) && $pos > $this->body_position){
6840:
6841: if(isset($this->message[$pos]['attrs']['href'])){
6842:
6843: $id = substr($this->message[$pos]['attrs']['href'],1);
6844:
6845: $this->multirefs[$id][$pos] = 'placeholder';
6846:
6847: $this->message[$pos]['result'] =& $this->multirefs[$id][$pos];
6848:
6849: } elseif($this->message[$pos]['children'] != ''){
6850:
6851: if(!isset($this->message[$pos]['result'])){
6852: $this->message[$pos]['result'] = $this->buildVal($pos);
6853: }
6854:
6855: } elseif (isset($this->message[$pos]['xattrs'])) {
6856: if (isset($this->message[$pos]['nil']) && $this->message[$pos]['nil']) {
6857: $this->message[$pos]['xattrs']['!'] = null;
6858: } elseif (isset($this->message[$pos]['cdata']) && trim($this->message[$pos]['cdata']) != '') {
6859: if (isset($this->message[$pos]['type'])) {
6860: $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'] : '');
6861: } else {
6862: $parent = $this->message[$pos]['parent'];
6863: if (isset($this->message[$parent]['type']) && ($this->message[$parent]['type'] == 'array') && isset($this->message[$parent]['arrayType'])) {
6864: $this->message[$pos]['xattrs']['!'] = $this->decodeSimple($this->message[$pos]['cdata'], $this->message[$parent]['arrayType'], isset($this->message[$parent]['arrayTypeNamespace']) ? $this->message[$parent]['arrayTypeNamespace'] : '');
6865: } else {
6866: $this->message[$pos]['xattrs']['!'] = $this->message[$pos]['cdata'];
6867: }
6868: }
6869: }
6870: $this->message[$pos]['result'] = $this->message[$pos]['xattrs'];
6871:
6872: } else {
6873:
6874: if (isset($this->message[$pos]['nil']) && $this->message[$pos]['nil']) {
6875: $this->message[$pos]['xattrs']['!'] = null;
6876: } elseif (isset($this->message[$pos]['type'])) {
6877: $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'] : '');
6878: } else {
6879: $parent = $this->message[$pos]['parent'];
6880: if (isset($this->message[$parent]['type']) && ($this->message[$parent]['type'] == 'array') && isset($this->message[$parent]['arrayType'])) {
6881: $this->message[$pos]['result'] = $this->decodeSimple($this->message[$pos]['cdata'], $this->message[$parent]['arrayType'], isset($this->message[$parent]['arrayTypeNamespace']) ? $this->message[$parent]['arrayTypeNamespace'] : '');
6882: } else {
6883: $this->message[$pos]['result'] = $this->message[$pos]['cdata'];
6884: }
6885: }
6886:
6887: 6888: 6889: 6890: 6891: 6892: 6893: 6894: 6895: 6896:
6897: }
6898: }
6899:
6900:
6901: if($this->status == 'header'){
6902: if ($this->root_header != $pos) {
6903: $this->responseHeaders .= "</" . (isset($prefix) ? $prefix . ':' : '') . "$name>";
6904: }
6905: } elseif($pos >= $this->root_struct){
6906: $this->document .= "</" . (isset($prefix) ? $prefix . ':' : '') . "$name>";
6907: }
6908:
6909: if ($pos == $this->root_struct){
6910: $this->status = 'body';
6911: $this->root_struct_namespace = $this->message[$pos]['namespace'];
6912: } elseif ($pos == $this->root_header) {
6913: $this->status = 'envelope';
6914: } elseif ($name == 'Body' && $this->status == 'body') {
6915: $this->status = 'envelope';
6916: } elseif ($name == 'Header' && $this->status == 'header') {
6917: $this->status = 'envelope';
6918: } elseif ($name == 'Envelope' && $this->status == 'envelope') {
6919: $this->status = '';
6920: }
6921:
6922: $this->parent = $this->message[$pos]['parent'];
6923: }
6924:
6925: 6926: 6927: 6928: 6929: 6930: 6931:
6932: function character_data($parser, $data){
6933: $pos = $this->depth_array[$this->depth];
6934: if ($this->xml_encoding=='UTF-8'){
6935:
6936:
6937:
6938: if($this->decode_utf8){
6939: $data = utf8_decode($data);
6940: }
6941: }
6942: $this->message[$pos]['cdata'] .= $data;
6943:
6944: if($this->status == 'header'){
6945: $this->responseHeaders .= $data;
6946: } else {
6947: $this->document .= $data;
6948: }
6949: }
6950:
6951: 6952: 6953: 6954: 6955: 6956: 6957:
6958: function get_response(){
6959: return $this->soapresponse;
6960: }
6961:
6962: 6963: 6964: 6965: 6966: 6967:
6968: function get_soapbody(){
6969: return $this->soapresponse;
6970: }
6971:
6972: 6973: 6974: 6975: 6976: 6977:
6978: function get_soapheader(){
6979: return $this->soapheader;
6980: }
6981:
6982: 6983: 6984: 6985: 6986: 6987:
6988: function getHeaders(){
6989: return $this->responseHeaders;
6990: }
6991:
6992: 6993: 6994: 6995: 6996: 6997: 6998: 6999: 7000:
7001: function decodeSimple($value, $type, $typens) {
7002:
7003: if ((!isset($type)) || $type == 'string' || $type == 'long' || $type == 'unsignedLong') {
7004: return (string) $value;
7005: }
7006: if ($type == 'int' || $type == 'integer' || $type == 'short' || $type == 'byte') {
7007: return (int) $value;
7008: }
7009: if ($type == 'float' || $type == 'double' || $type == 'decimal') {
7010: return (double) $value;
7011: }
7012: if ($type == 'boolean') {
7013: if (strtolower($value) == 'false' || strtolower($value) == 'f') {
7014: return false;
7015: }
7016: return (boolean) $value;
7017: }
7018: if ($type == 'base64' || $type == 'base64Binary') {
7019: $this->debug('Decode base64 value');
7020: return base64_decode($value);
7021: }
7022:
7023: if ($type == 'nonPositiveInteger' || $type == 'negativeInteger'
7024: || $type == 'nonNegativeInteger' || $type == 'positiveInteger'
7025: || $type == 'unsignedInt'
7026: || $type == 'unsignedShort' || $type == 'unsignedByte') {
7027: return (int) $value;
7028: }
7029:
7030: if ($type == 'array') {
7031: return array();
7032: }
7033:
7034: return (string) $value;
7035: }
7036:
7037: 7038: 7039: 7040: 7041: 7042: 7043: 7044:
7045: function buildVal($pos){
7046: if(!isset($this->message[$pos]['type'])){
7047: $this->message[$pos]['type'] = '';
7048: }
7049: $this->debug('in buildVal() for '.$this->message[$pos]['name']."(pos $pos) of type ".$this->message[$pos]['type']);
7050:
7051: if($this->message[$pos]['children'] != ''){
7052: $this->debug('in buildVal, there are children');
7053: $children = explode('|',$this->message[$pos]['children']);
7054: array_shift($children);
7055:
7056: if(isset($this->message[$pos]['arrayCols']) && $this->message[$pos]['arrayCols'] != ''){
7057: $r=0;
7058: $c=0;
7059: foreach($children as $child_pos){
7060: $this->debug("in buildVal, got an MD array element: $r, $c");
7061: $params[$r][] = $this->message[$child_pos]['result'];
7062: $c++;
7063: if($c == $this->message[$pos]['arrayCols']){
7064: $c = 0;
7065: $r++;
7066: }
7067: }
7068:
7069: } elseif($this->message[$pos]['type'] == 'array' || $this->message[$pos]['type'] == 'Array'){
7070: $this->debug('in buildVal, adding array '.$this->message[$pos]['name']);
7071: foreach($children as $child_pos){
7072: $params[] = &$this->message[$child_pos]['result'];
7073: }
7074:
7075: } elseif($this->message[$pos]['type'] == 'Map' && $this->message[$pos]['type_namespace'] == 'http://xml.apache.org/xml-soap'){
7076: $this->debug('in buildVal, Java Map '.$this->message[$pos]['name']);
7077: foreach($children as $child_pos){
7078: $kv = explode("|",$this->message[$child_pos]['children']);
7079: $params[$this->message[$kv[1]]['result']] = &$this->message[$kv[2]]['result'];
7080: }
7081:
7082:
7083: } else {
7084:
7085: $this->debug('in buildVal, adding Java Vector or generic compound type '.$this->message[$pos]['name']);
7086: if ($this->message[$pos]['type'] == 'Vector' && $this->message[$pos]['type_namespace'] == 'http://xml.apache.org/xml-soap') {
7087: $notstruct = 1;
7088: } else {
7089: $notstruct = 0;
7090: }
7091:
7092: foreach($children as $child_pos){
7093: if($notstruct){
7094: $params[] = &$this->message[$child_pos]['result'];
7095: } else {
7096: if (isset($params[$this->message[$child_pos]['name']])) {
7097:
7098: if ((!is_array($params[$this->message[$child_pos]['name']])) || (!isset($params[$this->message[$child_pos]['name']][0]))) {
7099: $params[$this->message[$child_pos]['name']] = array($params[$this->message[$child_pos]['name']]);
7100: }
7101: $params[$this->message[$child_pos]['name']][] = &$this->message[$child_pos]['result'];
7102: } else {
7103: $params[$this->message[$child_pos]['name']] = &$this->message[$child_pos]['result'];
7104: }
7105: }
7106: }
7107: }
7108: if (isset($this->message[$pos]['xattrs'])) {
7109: $this->debug('in buildVal, handling attributes');
7110: foreach ($this->message[$pos]['xattrs'] as $n => $v) {
7111: $params[$n] = $v;
7112: }
7113: }
7114:
7115: if (isset($this->message[$pos]['cdata']) && trim($this->message[$pos]['cdata']) != '') {
7116: $this->debug('in buildVal, handling simpleContent');
7117: if (isset($this->message[$pos]['type'])) {
7118: $params['!'] = $this->decodeSimple($this->message[$pos]['cdata'], $this->message[$pos]['type'], isset($this->message[$pos]['type_namespace']) ? $this->message[$pos]['type_namespace'] : '');
7119: } else {
7120: $parent = $this->message[$pos]['parent'];
7121: if (isset($this->message[$parent]['type']) && ($this->message[$parent]['type'] == 'array') && isset($this->message[$parent]['arrayType'])) {
7122: $params['!'] = $this->decodeSimple($this->message[$pos]['cdata'], $this->message[$parent]['arrayType'], isset($this->message[$parent]['arrayTypeNamespace']) ? $this->message[$parent]['arrayTypeNamespace'] : '');
7123: } else {
7124: $params['!'] = $this->message[$pos]['cdata'];
7125: }
7126: }
7127: }
7128: $ret = is_array($params) ? $params : array();
7129: $this->debug('in buildVal, return:');
7130: $this->appendDebug($this->varDump($ret));
7131: return $ret;
7132: } else {
7133: $this->debug('in buildVal, no children, building scalar');
7134: $cdata = isset($this->message[$pos]['cdata']) ? $this->message[$pos]['cdata'] : '';
7135: if (isset($this->message[$pos]['type'])) {
7136: $ret = $this->decodeSimple($cdata, $this->message[$pos]['type'], isset($this->message[$pos]['type_namespace']) ? $this->message[$pos]['type_namespace'] : '');
7137: $this->debug("in buildVal, return: $ret");
7138: return $ret;
7139: }
7140: $parent = $this->message[$pos]['parent'];
7141: if (isset($this->message[$parent]['type']) && ($this->message[$parent]['type'] == 'array') && isset($this->message[$parent]['arrayType'])) {
7142: $ret = $this->decodeSimple($cdata, $this->message[$parent]['arrayType'], isset($this->message[$parent]['arrayTypeNamespace']) ? $this->message[$parent]['arrayTypeNamespace'] : '');
7143: $this->debug("in buildVal, return: $ret");
7144: return $ret;
7145: }
7146: $ret = $this->message[$pos]['cdata'];
7147: $this->debug("in buildVal, return: $ret");
7148: return $ret;
7149: }
7150: }
7151: }
7152:
7153: 7154: 7155:
7156: class soap_parser extends nusoap_parser {
7157: }
7158:
7159: ?><?php
7160:
7161:
7162:
7163: 7164: 7165: 7166: 7167: 7168: 7169: 7170: 7171: 7172: 7173: 7174: 7175: 7176: 7177: 7178: 7179: 7180: 7181: 7182:
7183: class nusoap_client extends nusoap_base {
7184:
7185: var $username = '';
7186: var $password = '';
7187: var $authtype = '';
7188: var $certRequest = array();
7189: var $requestHeaders = false;
7190: var $responseHeaders = '';
7191: var $responseHeader = NULL;
7192: var $document = '';
7193: var $endpoint;
7194: var $forceEndpoint = '';
7195: var $proxyhost = '';
7196: var $proxyport = '';
7197: var $proxyusername = '';
7198: var $proxypassword = '';
7199: var $portName = '';
7200: var $xml_encoding = '';
7201: var $http_encoding = false;
7202: var $timeout = 0;
7203: var $response_timeout = 30;
7204: var $endpointType = '';
7205: var $persistentConnection = false;
7206: var $defaultRpcParams = false;
7207: var $request = '';
7208: var $response = '';
7209: var $responseData = '';
7210: var $cookies = array();
7211: var $decode_utf8 = true;
7212: var $operations = array();
7213: var $curl_options = array();
7214: var $bindingType = '';
7215: var $use_curl = false;
7216:
7217: 7218: 7219:
7220: 7221: 7222: 7223:
7224: var $fault;
7225: 7226: 7227: 7228:
7229: var $faultcode;
7230: 7231: 7232: 7233:
7234: var $faultstring;
7235: 7236: 7237: 7238:
7239: var $faultdetail;
7240:
7241: 7242: 7243: 7244: 7245: 7246: 7247: 7248: 7249: 7250: 7251: 7252: 7253: 7254:
7255: function nusoap_client($endpoint,$wsdl = false,$proxyhost = false,$proxyport = false,$proxyusername = false, $proxypassword = false, $timeout = 0, $response_timeout = 30, $portName = ''){
7256: parent::nusoap_base();
7257: $this->endpoint = $endpoint;
7258: $this->proxyhost = $proxyhost;
7259: $this->proxyport = $proxyport;
7260: $this->proxyusername = $proxyusername;
7261: $this->proxypassword = $proxypassword;
7262: $this->timeout = $timeout;
7263: $this->response_timeout = $response_timeout;
7264: $this->portName = $portName;
7265:
7266: $this->debug("ctor wsdl=$wsdl timeout=$timeout response_timeout=$response_timeout");
7267: $this->appendDebug('endpoint=' . $this->varDump($endpoint));
7268:
7269:
7270: if($wsdl){
7271: if (is_object($endpoint) && (get_class($endpoint) == 'wsdl')) {
7272: $this->wsdl = $endpoint;
7273: $this->endpoint = $this->wsdl->wsdl;
7274: $this->wsdlFile = $this->endpoint;
7275: $this->debug('existing wsdl instance created from ' . $this->endpoint);
7276: $this->checkWSDL();
7277: } else {
7278: $this->wsdlFile = $this->endpoint;
7279: $this->wsdl = null;
7280: $this->debug('will use lazy evaluation of wsdl from ' . $this->endpoint);
7281: }
7282: $this->endpointType = 'wsdl';
7283: } else {
7284: $this->debug("instantiate SOAP with endpoint at $endpoint");
7285: $this->endpointType = 'soap';
7286: }
7287: }
7288:
7289: 7290: 7291: 7292: 7293: 7294: 7295: 7296: 7297: 7298: 7299: 7300: 7301: 7302: 7303: 7304: 7305: 7306: 7307: 7308: 7309: 7310: 7311: 7312: 7313:
7314: function call($operation,$params=array(),$namespace='http://tempuri.org',$soapAction='',$headers=false,$rpcParams=null,$style='rpc',$use='encoded'){
7315: $this->operation = $operation;
7316: $this->fault = false;
7317: $this->setError('');
7318: $this->request = '';
7319: $this->response = '';
7320: $this->responseData = '';
7321: $this->faultstring = '';
7322: $this->faultcode = '';
7323: $this->opData = array();
7324:
7325: $this->debug("call: operation=$operation, namespace=$namespace, soapAction=$soapAction, rpcParams=$rpcParams, style=$style, use=$use, endpointType=$this->endpointType");
7326: $this->appendDebug('params=' . $this->varDump($params));
7327: $this->appendDebug('headers=' . $this->varDump($headers));
7328: if ($headers) {
7329: $this->requestHeaders = $headers;
7330: }
7331: if ($this->endpointType == 'wsdl' && is_null($this->wsdl)) {
7332: $this->loadWSDL();
7333: if ($this->getError())
7334: return false;
7335: }
7336:
7337: if($this->endpointType == 'wsdl' && $opData = $this->getOperationData($operation)){
7338:
7339: $this->opData = $opData;
7340: $this->debug("found operation");
7341: $this->appendDebug('opData=' . $this->varDump($opData));
7342: if (isset($opData['soapAction'])) {
7343: $soapAction = $opData['soapAction'];
7344: }
7345: if (! $this->forceEndpoint) {
7346: $this->endpoint = $opData['endpoint'];
7347: } else {
7348: $this->endpoint = $this->forceEndpoint;
7349: }
7350: $namespace = isset($opData['input']['namespace']) ? $opData['input']['namespace'] : $namespace;
7351: $style = $opData['style'];
7352: $use = $opData['input']['use'];
7353:
7354: if($namespace != '' && !isset($this->wsdl->namespaces[$namespace])){
7355: $nsPrefix = 'ns' . rand(1000, 9999);
7356: $this->wsdl->namespaces[$nsPrefix] = $namespace;
7357: }
7358: $nsPrefix = $this->wsdl->getPrefixFromNamespace($namespace);
7359:
7360: if (is_string($params)) {
7361: $this->debug("serializing param string for WSDL operation $operation");
7362: $payload = $params;
7363: } elseif (is_array($params)) {
7364: $this->debug("serializing param array for WSDL operation $operation");
7365: $payload = $this->wsdl->serializeRPCParameters($operation,'input',$params,$this->bindingType);
7366: } else {
7367: $this->debug('params must be array or string');
7368: $this->setError('params must be array or string');
7369: return false;
7370: }
7371: $usedNamespaces = $this->wsdl->usedNamespaces;
7372: if (isset($opData['input']['encodingStyle'])) {
7373: $encodingStyle = $opData['input']['encodingStyle'];
7374: } else {
7375: $encodingStyle = '';
7376: }
7377: $this->appendDebug($this->wsdl->getDebug());
7378: $this->wsdl->clearDebug();
7379: if ($errstr = $this->wsdl->getError()) {
7380: $this->debug('got wsdl error: '.$errstr);
7381: $this->setError('wsdl error: '.$errstr);
7382: return false;
7383: }
7384: } elseif($this->endpointType == 'wsdl') {
7385:
7386: $this->appendDebug($this->wsdl->getDebug());
7387: $this->wsdl->clearDebug();
7388: $this->setError('operation '.$operation.' not present in WSDL.');
7389: $this->debug("operation '$operation' not present in WSDL.");
7390: return false;
7391: } else {
7392:
7393:
7394: $nsPrefix = 'ns' . rand(1000, 9999);
7395:
7396: $payload = '';
7397: if (is_string($params)) {
7398: $this->debug("serializing param string for operation $operation");
7399: $payload = $params;
7400: } elseif (is_array($params)) {
7401: $this->debug("serializing param array for operation $operation");
7402: foreach($params as $k => $v){
7403: $payload .= $this->serialize_val($v,$k,false,false,false,false,$use);
7404: }
7405: } else {
7406: $this->debug('params must be array or string');
7407: $this->setError('params must be array or string');
7408: return false;
7409: }
7410: $usedNamespaces = array();
7411: if ($use == 'encoded') {
7412: $encodingStyle = 'http://schemas.xmlsoap.org/soap/encoding/';
7413: } else {
7414: $encodingStyle = '';
7415: }
7416: }
7417:
7418: if ($style == 'rpc') {
7419: if ($use == 'literal') {
7420: $this->debug("wrapping RPC request with literal method element");
7421: if ($namespace) {
7422:
7423: $payload = "<$nsPrefix:$operation xmlns:$nsPrefix=\"$namespace\">" .
7424: $payload .
7425: "</$nsPrefix:$operation>";
7426: } else {
7427: $payload = "<$operation>" . $payload . "</$operation>";
7428: }
7429: } else {
7430: $this->debug("wrapping RPC request with encoded method element");
7431: if ($namespace) {
7432: $payload = "<$nsPrefix:$operation xmlns:$nsPrefix=\"$namespace\">" .
7433: $payload .
7434: "</$nsPrefix:$operation>";
7435: } else {
7436: $payload = "<$operation>" .
7437: $payload .
7438: "</$operation>";
7439: }
7440: }
7441: }
7442:
7443: $soapmsg = $this->serializeEnvelope($payload,$this->requestHeaders,$usedNamespaces,$style,$use,$encodingStyle);
7444: $this->debug("endpoint=$this->endpoint, soapAction=$soapAction, namespace=$namespace, style=$style, use=$use, encodingStyle=$encodingStyle");
7445: $this->debug('SOAP message length=' . strlen($soapmsg) . ' contents (max 1000 bytes)=' . substr($soapmsg, 0, 1000));
7446:
7447: $return = $this->send($this->getHTTPBody($soapmsg),$soapAction,$this->timeout,$this->response_timeout);
7448: if($errstr = $this->getError()){
7449: $this->debug('Error: '.$errstr);
7450: return false;
7451: } else {
7452: $this->return = $return;
7453: $this->debug('sent message successfully and got a(n) '.gettype($return));
7454: $this->appendDebug('return=' . $this->varDump($return));
7455:
7456:
7457: if(is_array($return) && isset($return['faultcode'])){
7458: $this->debug('got fault');
7459: $this->setError($return['faultcode'].': '.$return['faultstring']);
7460: $this->fault = true;
7461: foreach($return as $k => $v){
7462: $this->$k = $v;
7463: $this->debug("$k = $v<br>");
7464: }
7465: return $return;
7466: } elseif ($style == 'document') {
7467:
7468:
7469: return $return;
7470: } else {
7471:
7472: if(is_array($return)){
7473:
7474:
7475: if(sizeof($return) > 1){
7476: return $return;
7477: }
7478:
7479: $return = array_shift($return);
7480: $this->debug('return shifted value: ');
7481: $this->appendDebug($this->varDump($return));
7482: return $return;
7483:
7484: } else {
7485: return "";
7486: }
7487: }
7488: }
7489: }
7490:
7491: 7492: 7493: 7494: 7495:
7496: function checkWSDL() {
7497: $this->appendDebug($this->wsdl->getDebug());
7498: $this->wsdl->clearDebug();
7499: $this->debug('checkWSDL');
7500:
7501: if ($errstr = $this->wsdl->getError()) {
7502: $this->appendDebug($this->wsdl->getDebug());
7503: $this->wsdl->clearDebug();
7504: $this->debug('got wsdl error: '.$errstr);
7505: $this->setError('wsdl error: '.$errstr);
7506: } elseif ($this->operations = $this->wsdl->getOperations($this->portName, 'soap')) {
7507: $this->appendDebug($this->wsdl->getDebug());
7508: $this->wsdl->clearDebug();
7509: $this->bindingType = 'soap';
7510: $this->debug('got '.count($this->operations).' operations from wsdl '.$this->wsdlFile.' for binding type '.$this->bindingType);
7511: } elseif ($this->operations = $this->wsdl->getOperations($this->portName, 'soap12')) {
7512: $this->appendDebug($this->wsdl->getDebug());
7513: $this->wsdl->clearDebug();
7514: $this->bindingType = 'soap12';
7515: $this->debug('got '.count($this->operations).' operations from wsdl '.$this->wsdlFile.' for binding type '.$this->bindingType);
7516: $this->debug('**************** WARNING: SOAP 1.2 BINDING *****************');
7517: } else {
7518: $this->appendDebug($this->wsdl->getDebug());
7519: $this->wsdl->clearDebug();
7520: $this->debug('getOperations returned false');
7521: $this->setError('no operations defined in the WSDL document!');
7522: }
7523: }
7524:
7525: 7526: 7527: 7528: 7529:
7530: function loadWSDL() {
7531: $this->debug('instantiating wsdl class with doc: '.$this->wsdlFile);
7532: $this->wsdl = new wsdl('',$this->proxyhost,$this->proxyport,$this->proxyusername,$this->proxypassword,$this->timeout,$this->response_timeout,$this->curl_options,$this->use_curl);
7533: $this->wsdl->setCredentials($this->username, $this->password, $this->authtype, $this->certRequest);
7534: $this->wsdl->fetchWSDL($this->wsdlFile);
7535: $this->checkWSDL();
7536: }
7537:
7538: 7539: 7540: 7541: 7542: 7543: 7544:
7545: function getOperationData($operation){
7546: if ($this->endpointType == 'wsdl' && is_null($this->wsdl)) {
7547: $this->loadWSDL();
7548: if ($this->getError())
7549: return false;
7550: }
7551: if(isset($this->operations[$operation])){
7552: return $this->operations[$operation];
7553: }
7554: $this->debug("No data for operation: $operation");
7555: }
7556:
7557: 7558: 7559: 7560: 7561: 7562: 7563: 7564: 7565: 7566: 7567: 7568: 7569: 7570:
7571: function send($msg, $soapaction = '', $timeout=0, $response_timeout=30) {
7572: $this->checkCookies();
7573:
7574: switch(true){
7575:
7576: case preg_match('/^http/',$this->endpoint):
7577: $this->debug('transporting via HTTP');
7578: if($this->persistentConnection == true && is_object($this->persistentConnection)){
7579: $http =& $this->persistentConnection;
7580: } else {
7581: $http = new soap_transport_http($this->endpoint, $this->curl_options, $this->use_curl);
7582: if ($this->persistentConnection) {
7583: $http->usePersistentConnection();
7584: }
7585: }
7586: $http->setContentType($this->getHTTPContentType(), $this->getHTTPContentTypeCharset());
7587: $http->setSOAPAction($soapaction);
7588: if($this->proxyhost && $this->proxyport){
7589: $http->setProxy($this->proxyhost,$this->proxyport,$this->proxyusername,$this->proxypassword);
7590: }
7591: if($this->authtype != '') {
7592: $http->setCredentials($this->username, $this->password, $this->authtype, array(), $this->certRequest);
7593: }
7594: if($this->http_encoding != ''){
7595: $http->setEncoding($this->http_encoding);
7596: }
7597: $this->debug('sending message, length='.strlen($msg));
7598: if(preg_match('/^http:/',$this->endpoint)){
7599:
7600: $this->responseData = $http->send($msg,$timeout,$response_timeout,$this->cookies);
7601: } elseif(preg_match('/^https/',$this->endpoint)){
7602:
7603:
7604:
7605:
7606:
7607:
7608: $this->responseData = $http->sendHTTPS($msg,$timeout,$response_timeout,$this->cookies);
7609: } else {
7610: $this->setError('no http/s in endpoint url');
7611: }
7612: $this->request = $http->outgoing_payload;
7613: $this->response = $http->incoming_payload;
7614: $this->appendDebug($http->getDebug());
7615: $this->UpdateCookies($http->incoming_cookies);
7616:
7617:
7618: if ($this->persistentConnection) {
7619: $http->clearDebug();
7620: if (!is_object($this->persistentConnection)) {
7621: $this->persistentConnection = $http;
7622: }
7623: }
7624:
7625: if($err = $http->getError()){
7626: $this->setError('HTTP Error: '.$err);
7627: return false;
7628: } elseif($this->getError()){
7629: return false;
7630: } else {
7631: $this->debug('got response, length='. strlen($this->responseData).' type='.$http->incoming_headers['content-type']);
7632: return $this->parseResponse($http->incoming_headers, $this->responseData);
7633: }
7634: break;
7635: default:
7636: $this->setError('no transport found, or selected transport is not yet supported!');
7637: return false;
7638: break;
7639: }
7640: }
7641:
7642: 7643: 7644: 7645: 7646: 7647: 7648: 7649:
7650: function parseResponse($headers, $data) {
7651: $this->debug('Entering parseResponse() for data of length ' . strlen($data) . ' headers:');
7652: $this->appendDebug($this->varDump($headers));
7653: if (!isset($headers['content-type'])) {
7654: $this->setError('Response not of type text/xml (no content-type header)');
7655: return false;
7656: }
7657: if (!strstr($headers['content-type'], 'text/xml')) {
7658: $this->setError('Response not of type text/xml: ' . $headers['content-type']);
7659: return false;
7660: }
7661: if (strpos($headers['content-type'], '=')) {
7662: $enc = str_replace('"', '', substr(strstr($headers["content-type"], '='), 1));
7663: $this->debug('Got response encoding: ' . $enc);
7664: if(preg_match('/^(ISO-8859-1|US-ASCII|UTF-8)$/i',$enc)){
7665: $this->xml_encoding = strtoupper($enc);
7666: } else {
7667: $this->xml_encoding = 'US-ASCII';
7668: }
7669: } else {
7670:
7671: $this->xml_encoding = 'ISO-8859-1';
7672: }
7673: $this->debug('Use encoding: ' . $this->xml_encoding . ' when creating nusoap_parser');
7674: $parser = new nusoap_parser($data,$this->xml_encoding,$this->operation,$this->decode_utf8);
7675:
7676: $this->appendDebug($parser->getDebug());
7677:
7678: if($errstr = $parser->getError()){
7679: $this->setError( $errstr);
7680:
7681: unset($parser);
7682: return false;
7683: } else {
7684:
7685: $this->responseHeaders = $parser->getHeaders();
7686:
7687: $this->responseHeader = $parser->get_soapheader();
7688:
7689: $return = $parser->get_soapbody();
7690:
7691: $this->document = $parser->document;
7692:
7693: unset($parser);
7694:
7695: return $return;
7696: }
7697: }
7698:
7699: 7700: 7701: 7702: 7703: 7704: 7705:
7706: function setCurlOption($option, $value) {
7707: $this->debug("setCurlOption option=$option, value=");
7708: $this->appendDebug($this->varDump($value));
7709: $this->curl_options[$option] = $value;
7710: }
7711:
7712: 7713: 7714: 7715: 7716: 7717:
7718: function setEndpoint($endpoint) {
7719: $this->debug("setEndpoint(\"$endpoint\")");
7720: $this->forceEndpoint = $endpoint;
7721: }
7722:
7723: 7724: 7725: 7726: 7727: 7728:
7729: function setHeaders($headers){
7730: $this->debug("setHeaders headers=");
7731: $this->appendDebug($this->varDump($headers));
7732: $this->requestHeaders = $headers;
7733: }
7734:
7735: 7736: 7737: 7738: 7739: 7740:
7741: function getHeaders(){
7742: return $this->responseHeaders;
7743: }
7744:
7745: 7746: 7747: 7748: 7749: 7750:
7751: function getHeader(){
7752: return $this->responseHeader;
7753: }
7754:
7755: 7756: 7757: 7758: 7759: 7760: 7761: 7762: 7763:
7764: function setHTTPProxy($proxyhost, $proxyport, $proxyusername = '', $proxypassword = '') {
7765: $this->proxyhost = $proxyhost;
7766: $this->proxyport = $proxyport;
7767: $this->proxyusername = $proxyusername;
7768: $this->proxypassword = $proxypassword;
7769: }
7770:
7771: 7772: 7773: 7774: 7775: 7776: 7777: 7778: 7779:
7780: function setCredentials($username, $password, $authtype = 'basic', $certRequest = array()) {
7781: $this->debug("setCredentials username=$username authtype=$authtype certRequest=");
7782: $this->appendDebug($this->varDump($certRequest));
7783: $this->username = $username;
7784: $this->password = $password;
7785: $this->authtype = $authtype;
7786: $this->certRequest = $certRequest;
7787: }
7788:
7789: 7790: 7791: 7792: 7793: 7794:
7795: function setHTTPEncoding($enc='gzip, deflate'){
7796: $this->debug("setHTTPEncoding(\"$enc\")");
7797: $this->http_encoding = $enc;
7798: }
7799:
7800: 7801: 7802: 7803: 7804: 7805:
7806: function setUseCURL($use) {
7807: $this->debug("setUseCURL($use)");
7808: $this->use_curl = $use;
7809: }
7810:
7811: 7812: 7813: 7814: 7815:
7816: function useHTTPPersistentConnection(){
7817: $this->debug("useHTTPPersistentConnection");
7818: $this->persistentConnection = true;
7819: }
7820:
7821: 7822: 7823: 7824: 7825: 7826: 7827: 7828: 7829: 7830: 7831:
7832: function getDefaultRpcParams() {
7833: return $this->defaultRpcParams;
7834: }
7835:
7836: 7837: 7838: 7839: 7840: 7841: 7842: 7843: 7844: 7845: 7846:
7847: function setDefaultRpcParams($rpcParams) {
7848: $this->defaultRpcParams = $rpcParams;
7849: }
7850:
7851: 7852: 7853: 7854: 7855: 7856: 7857:
7858: function getProxy() {
7859: $r = rand();
7860: $evalStr = $this->_getProxyClassCode($r);
7861:
7862: if ($this->getError()) {
7863: $this->debug("Error from _getProxyClassCode, so return NULL");
7864: return null;
7865: }
7866:
7867: eval($evalStr);
7868:
7869: eval("\$proxy = new nusoap_proxy_$r('');");
7870:
7871: $proxy->endpointType = 'wsdl';
7872: $proxy->wsdlFile = $this->wsdlFile;
7873: $proxy->wsdl = $this->wsdl;
7874: $proxy->operations = $this->operations;
7875: $proxy->defaultRpcParams = $this->defaultRpcParams;
7876:
7877: $proxy->soap_defencoding = $this->soap_defencoding;
7878: $proxy->username = $this->username;
7879: $proxy->password = $this->password;
7880: $proxy->authtype = $this->authtype;
7881: $proxy->certRequest = $this->certRequest;
7882: $proxy->requestHeaders = $this->requestHeaders;
7883: $proxy->endpoint = $this->endpoint;
7884: $proxy->forceEndpoint = $this->forceEndpoint;
7885: $proxy->proxyhost = $this->proxyhost;
7886: $proxy->proxyport = $this->proxyport;
7887: $proxy->proxyusername = $this->proxyusername;
7888: $proxy->proxypassword = $this->proxypassword;
7889: $proxy->http_encoding = $this->http_encoding;
7890: $proxy->timeout = $this->timeout;
7891: $proxy->response_timeout = $this->response_timeout;
7892: $proxy->persistentConnection = &$this->persistentConnection;
7893: $proxy->decode_utf8 = $this->decode_utf8;
7894: $proxy->curl_options = $this->curl_options;
7895: $proxy->bindingType = $this->bindingType;
7896: $proxy->use_curl = $this->use_curl;
7897: return $proxy;
7898: }
7899:
7900: 7901: 7902: 7903: 7904: 7905:
7906: function _getProxyClassCode($r) {
7907: $this->debug("in getProxy endpointType=$this->endpointType");
7908: $this->appendDebug("wsdl=" . $this->varDump($this->wsdl));
7909: if ($this->endpointType != 'wsdl') {
7910: $evalStr = 'A proxy can only be created for a WSDL client';
7911: $this->setError($evalStr);
7912: $evalStr = "echo \"$evalStr\";";
7913: return $evalStr;
7914: }
7915: if ($this->endpointType == 'wsdl' && is_null($this->wsdl)) {
7916: $this->loadWSDL();
7917: if ($this->getError()) {
7918: return "echo \"" . $this->getError() . "\";";
7919: }
7920: }
7921: $evalStr = '';
7922: foreach ($this->operations as $operation => $opData) {
7923: if ($operation != '') {
7924:
7925: if (sizeof($opData['input']['parts']) > 0) {
7926: $paramStr = '';
7927: $paramArrayStr = '';
7928: $paramCommentStr = '';
7929: foreach ($opData['input']['parts'] as $name => $type) {
7930: $paramStr .= "\$$name, ";
7931: $paramArrayStr .= "'$name' => \$$name, ";
7932: $paramCommentStr .= "$type \$$name, ";
7933: }
7934: $paramStr = substr($paramStr, 0, strlen($paramStr)-2);
7935: $paramArrayStr = substr($paramArrayStr, 0, strlen($paramArrayStr)-2);
7936: $paramCommentStr = substr($paramCommentStr, 0, strlen($paramCommentStr)-2);
7937: } else {
7938: $paramStr = '';
7939: $paramArrayStr = '';
7940: $paramCommentStr = 'void';
7941: }
7942: $opData['namespace'] = !isset($opData['namespace']) ? 'http://testuri.com' : $opData['namespace'];
7943: $evalStr .= "// $paramCommentStr
7944: function " . str_replace('.', '__', $operation) . "($paramStr) {
7945: \$params = array($paramArrayStr);
7946: return \$this->call('$operation', \$params, '".$opData['namespace']."', '".(isset($opData['soapAction']) ? $opData['soapAction'] : '')."');
7947: }
7948: ";
7949: unset($paramStr);
7950: unset($paramCommentStr);
7951: }
7952: }
7953: $evalStr = 'class nusoap_proxy_'.$r.' extends nusoap_client {
7954: '.$evalStr.'
7955: }';
7956: return $evalStr;
7957: }
7958:
7959: 7960: 7961: 7962: 7963: 7964:
7965: function getProxyClassCode() {
7966: $r = rand();
7967: return $this->_getProxyClassCode($r);
7968: }
7969:
7970: 7971: 7972: 7973: 7974: 7975: 7976:
7977: function getHTTPBody($soapmsg) {
7978: return $soapmsg;
7979: }
7980:
7981: 7982: 7983: 7984: 7985: 7986: 7987: 7988:
7989: function getHTTPContentType() {
7990: return 'text/xml';
7991: }
7992:
7993: 7994: 7995: 7996: 7997: 7998: 7999: 8000: 8001:
8002: function getHTTPContentTypeCharset() {
8003: return $this->soap_defencoding;
8004: }
8005:
8006: 8007: 8008: 8009: 8010: 8011:
8012: function decodeUTF8($bool){
8013: $this->decode_utf8 = $bool;
8014: return true;
8015: }
8016:
8017: 8018: 8019: 8020: 8021: 8022: 8023: 8024:
8025: function setCookie($name, $value) {
8026: if (strlen($name) == 0) {
8027: return false;
8028: }
8029: $this->cookies[] = array('name' => $name, 'value' => $value);
8030: return true;
8031: }
8032:
8033: 8034: 8035: 8036: 8037: 8038:
8039: function getCookies() {
8040: return $this->cookies;
8041: }
8042:
8043: 8044: 8045: 8046: 8047: 8048:
8049: function checkCookies() {
8050: if (sizeof($this->cookies) == 0) {
8051: return true;
8052: }
8053: $this->debug('checkCookie: check ' . sizeof($this->cookies) . ' cookies');
8054: $curr_cookies = $this->cookies;
8055: $this->cookies = array();
8056: foreach ($curr_cookies as $cookie) {
8057: if (! is_array($cookie)) {
8058: $this->debug('Remove cookie that is not an array');
8059: continue;
8060: }
8061: if ((isset($cookie['expires'])) && (! empty($cookie['expires']))) {
8062: if (strtotime($cookie['expires']) > time()) {
8063: $this->cookies[] = $cookie;
8064: } else {
8065: $this->debug('Remove expired cookie ' . $cookie['name']);
8066: }
8067: } else {
8068: $this->cookies[] = $cookie;
8069: }
8070: }
8071: $this->debug('checkCookie: '.sizeof($this->cookies).' cookies left in array');
8072: return true;
8073: }
8074:
8075: 8076: 8077: 8078: 8079: 8080: 8081:
8082: function UpdateCookies($cookies) {
8083: if (sizeof($this->cookies) == 0) {
8084:
8085: if (sizeof($cookies) > 0) {
8086: $this->debug('Setting new cookie(s)');
8087: $this->cookies = $cookies;
8088: }
8089: return true;
8090: }
8091: if (sizeof($cookies) == 0) {
8092:
8093: return true;
8094: }
8095:
8096: foreach ($cookies as $newCookie) {
8097: if (!is_array($newCookie)) {
8098: continue;
8099: }
8100: if ((!isset($newCookie['name'])) || (!isset($newCookie['value']))) {
8101: continue;
8102: }
8103: $newName = $newCookie['name'];
8104:
8105: $found = false;
8106: for ($i = 0; $i < count($this->cookies); $i++) {
8107: $cookie = $this->cookies[$i];
8108: if (!is_array($cookie)) {
8109: continue;
8110: }
8111: if (!isset($cookie['name'])) {
8112: continue;
8113: }
8114: if ($newName != $cookie['name']) {
8115: continue;
8116: }
8117: $newDomain = isset($newCookie['domain']) ? $newCookie['domain'] : 'NODOMAIN';
8118: $domain = isset($cookie['domain']) ? $cookie['domain'] : 'NODOMAIN';
8119: if ($newDomain != $domain) {
8120: continue;
8121: }
8122: $newPath = isset($newCookie['path']) ? $newCookie['path'] : 'NOPATH';
8123: $path = isset($cookie['path']) ? $cookie['path'] : 'NOPATH';
8124: if ($newPath != $path) {
8125: continue;
8126: }
8127: $this->cookies[$i] = $newCookie;
8128: $found = true;
8129: $this->debug('Update cookie ' . $newName . '=' . $newCookie['value']);
8130: break;
8131: }
8132: if (! $found) {
8133: $this->debug('Add cookie ' . $newName . '=' . $newCookie['value']);
8134: $this->cookies[] = $newCookie;
8135: }
8136: }
8137: return true;
8138: }
8139: }
8140:
8141: if (!extension_loaded('soap')) {
8142: 8143: 8144:
8145: class soapclient extends nusoap_client {
8146: }
8147: }
8148: ?>
8149: