/[drupal]/contributions/sandbox/stevemckenzie/salesforce/includes/nusoap.orig.php
ViewVC logotype

Contents of /contributions/sandbox/stevemckenzie/salesforce/includes/nusoap.orig.php

Parent Directory Parent Directory | Revision Log Revision Log | View Revision Graph Revision Graph


Revision 1.1 - (show annotations) (download) (as text)
Mon Oct 16 20:24:05 2006 UTC (3 years, 1 month ago) by stevemckenzie
Branch: MAIN
CVS Tags: HEAD
File MIME type: text/x-php
checkin of salesforce.module - ahhhh the madness
<
1 <?php
2
3 /*
4 $Id: nusoap.orig.php,v 1.1 2005/10/13 06:10:09 ryankicks Exp $
5
6 NuSOAP - Web Services Toolkit for PHP
7
8 Copyright (c) 2002 NuSphere Corporation
9
10 This library is free software; you can redistribute it and/or
11 modify it under the terms of the GNU Lesser General Public
12 License as published by the Free Software Foundation; either
13 version 2.1 of the License, or (at your option) any later version.
14
15 This library is distributed in the hope that it will be useful,
16 but WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18 Lesser General Public License for more details.
19
20 You should have received a copy of the GNU Lesser General Public
21 License along with this library; if not, write to the Free Software
22 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
23
24 If you have any questions or comments, please email:
25
26 Dietrich Ayala
27 dietrich@ganx4.com
28 http://dietrich.ganx4.com/nusoap
29
30 NuSphere Corporation
31 http://www.nusphere.com
32
33 */
34
35 /* load classes
36
37 // necessary classes
38 require_once('class.soapclient.php');
39 require_once('class.soap_val.php');
40 require_once('class.soap_parser.php');
41 require_once('class.soap_fault.php');
42
43 // transport classes
44 require_once('class.soap_transport_http.php');
45
46 // optional add-on classes
47 require_once('class.xmlschema.php');
48 require_once('class.wsdl.php');
49
50 // server class
51 require_once('class.soap_server.php');*/
52
53 // class variable emulation
54 // cf. http://www.webkreator.com/php/techniques/php-static-class-variables.html
55 $GLOBALS['_transient']['static']['nusoap_base']->globalDebugLevel = 9;
56
57 /**
58 *
59 * nusoap_base
60 *
61 * @author Dietrich Ayala <dietrich@ganx4.com>
62 * @version $Id: nusoap.orig.php,v 1.1 2005/10/13 06:10:09 ryankicks Exp $
63 * @access public
64 */
65 class nusoap_base {
66 /**
67 * Identification for HTTP headers.
68 *
69 * @var string
70 * @access private
71 */
72 var $title = 'NuSOAP';
73 /**
74 * Version for HTTP headers.
75 *
76 * @var string
77 * @access private
78 */
79 var $version = '0.7.2';
80 /**
81 * CVS revision for HTTP headers.
82 *
83 * @var string
84 * @access private
85 */
86 var $revision = '$Revision: 1.1 $';
87 /**
88 * Current error string (manipulated by getError/setError)
89 *
90 * @var string
91 * @access private
92 */
93 var $error_str = '';
94 /**
95 * Current debug string (manipulated by debug/appendDebug/clearDebug/getDebug/getDebugAsXMLComment)
96 *
97 * @var string
98 * @access private
99 */
100 var $debug_str = '';
101 /**
102 * toggles automatic encoding of special characters as entities
103 * (should always be true, I think)
104 *
105 * @var boolean
106 * @access private
107 */
108 var $charencoding = true;
109 /**
110 * the debug level for this instance
111 *
112 * @var integer
113 * @access private
114 */
115 var $debugLevel;
116
117 /**
118 * set schema version
119 *
120 * @var string
121 * @access public
122 */
123 var $XMLSchemaVersion = 'http://www.w3.org/2001/XMLSchema';
124
125 /**
126 * charset encoding for outgoing messages
127 *
128 * @var string
129 * @access public
130 */
131 var $soap_defencoding = 'ISO-8859-1';
132 //var $soap_defencoding = 'UTF-8';
133
134 /**
135 * namespaces in an array of prefix => uri
136 *
137 * this is "seeded" by a set of constants, but it may be altered by code
138 *
139 * @var array
140 * @access public
141 */
142 var $namespaces = array(
143 'SOAP-ENV' => 'http://schemas.xmlsoap.org/soap/envelope/',
144 'xsd' => 'http://www.w3.org/2001/XMLSchema',
145 'xsi' => 'http://www.w3.org/2001/XMLSchema-instance',
146 'SOAP-ENC' => 'http://schemas.xmlsoap.org/soap/encoding/'
147 );
148
149 /**
150 * namespaces used in the current context, e.g. during serialization
151 *
152 * @var array
153 * @access private
154 */
155 var $usedNamespaces = array();
156
157 /**
158 * XML Schema types in an array of uri => (array of xml type => php type)
159 * is this legacy yet?
160 * no, this is used by the xmlschema class to verify type => namespace mappings.
161 * @var array
162 * @access public
163 */
164 var $typemap = array(
165 'http://www.w3.org/2001/XMLSchema' => array(
166 'string'=>'string','boolean'=>'boolean','float'=>'double','double'=>'double','decimal'=>'double',
167 'duration'=>'','dateTime'=>'string','time'=>'string','date'=>'string','gYearMonth'=>'',
168 'gYear'=>'','gMonthDay'=>'','gDay'=>'','gMonth'=>'','hexBinary'=>'string','base64Binary'=>'string',
169 // abstract "any" types
170 'anyType'=>'string','anySimpleType'=>'string',
171 // derived datatypes
172 'normalizedString'=>'string','token'=>'string','language'=>'','NMTOKEN'=>'','NMTOKENS'=>'','Name'=>'','NCName'=>'','ID'=>'',
173 'IDREF'=>'','IDREFS'=>'','ENTITY'=>'','ENTITIES'=>'','integer'=>'integer','nonPositiveInteger'=>'integer',
174 'negativeInteger'=>'integer','long'=>'integer','int'=>'integer','short'=>'integer','byte'=>'integer','nonNegativeInteger'=>'integer',
175 'unsignedLong'=>'','unsignedInt'=>'','unsignedShort'=>'','unsignedByte'=>'','positiveInteger'=>''),
176 'http://www.w3.org/2000/10/XMLSchema' => array(
177 'i4'=>'','int'=>'integer','boolean'=>'boolean','string'=>'string','double'=>'double',
178 'float'=>'double','dateTime'=>'string',
179 'timeInstant'=>'string','base64Binary'=>'string','base64'=>'string','ur-type'=>'array'),
180 'http://www.w3.org/1999/XMLSchema' => array(
181 'i4'=>'','int'=>'integer','boolean'=>'boolean','string'=>'string','double'=>'double',
182 'float'=>'double','dateTime'=>'string',
183 'timeInstant'=>'string','base64Binary'=>'string','base64'=>'string','ur-type'=>'array'),
184 'http://soapinterop.org/xsd' => array('SOAPStruct'=>'struct'),
185 'http://schemas.xmlsoap.org/soap/encoding/' => array('base64'=>'string','array'=>'array','Array'=>'array'),
186 'http://xml.apache.org/xml-soap' => array('Map')
187 );
188
189 /**
190 * XML entities to convert
191 *
192 * @var array
193 * @access public
194 * @deprecated
195 * @see expandEntities
196 */
197 var $xmlEntities = array('quot' => '"','amp' => '&',
198 'lt' => '<','gt' => '>','apos' => "'");
199
200 /**
201 * constructor
202 *
203 * @access public
204 */
205 function nusoap_base() {
206 $this->debugLevel = $GLOBALS['_transient']['static']['nusoap_base']->globalDebugLevel;
207 }
208
209 /**
210 * gets the global debug level, which applies to future instances
211 *
212 * @return integer Debug level 0-9, where 0 turns off
213 * @access public
214 */
215 function getGlobalDebugLevel() {
216 return $GLOBALS['_transient']['static']['nusoap_base']->globalDebugLevel;
217 }
218
219 /**
220 * sets the global debug level, which applies to future instances
221 *
222 * @param int $level Debug level 0-9, where 0 turns off
223 * @access public
224 */
225 function setGlobalDebugLevel($level) {
226 $GLOBALS['_transient']['static']['nusoap_base']->globalDebugLevel = $level;
227 }
228
229 /**
230 * gets the debug level for this instance
231 *
232 * @return int Debug level 0-9, where 0 turns off
233 * @access public
234 */
235 function getDebugLevel() {
236 return $this->debugLevel;
237 }
238
239 /**
240 * sets the debug level for this instance
241 *
242 * @param int $level Debug level 0-9, where 0 turns off
243 * @access public
244 */
245 function setDebugLevel($level) {
246 $this->debugLevel = $level;
247 }
248
249 /**
250 * adds debug data to the instance debug string with formatting
251 *
252 * @param string $string debug data
253 * @access private
254 */
255 function debug($string){
256 if ($this->debugLevel > 0) {
257 $this->appendDebug($this->getmicrotime().' '.get_class($this).": $string\n");
258 }
259 }
260
261 /**
262 * adds debug data to the instance debug string without formatting
263 *
264 * @param string $string debug data
265 * @access public
266 */
267 function appendDebug($string){
268 if ($this->debugLevel > 0) {
269 // it would be nice to use a memory stream here to use
270 // memory more efficiently
271 $this->debug_str .= $string;
272 }
273 }
274
275 /**
276 * clears the current debug data for this instance
277 *
278 * @access public
279 */
280 function clearDebug() {
281 // it would be nice to use a memory stream here to use
282 // memory more efficiently
283 $this->debug_str = '';
284 }
285
286 /**
287 * gets the current debug data for this instance
288 *
289 * @return debug data
290 * @access public
291 */
292 function &getDebug() {
293 // it would be nice to use a memory stream here to use
294 // memory more efficiently
295 return $this->debug_str;
296 }
297
298 /**
299 * gets the current debug data for this instance as an XML comment
300 * this may change the contents of the debug data
301 *
302 * @return debug data as an XML comment
303 * @access public
304 */
305 function &getDebugAsXMLComment() {
306 // it would be nice to use a memory stream here to use
307 // memory more efficiently
308 while (strpos($this->debug_str, '--')) {
309 $this->debug_str = str_replace('--', '- -', $this->debug_str);
310 }
311 return "<!--\n" . $this->debug_str . "\n-->";
312 }
313
314 /**
315 * expands entities, e.g. changes '<' to '&lt;'.
316 *
317 * @param string $val The string in which to expand entities.
318 * @access private
319 */
320 function expandEntities($val) {
321 if ($this->charencoding) {
322 $val = str_replace('&', '&amp;', $val);
323 $val = str_replace("'", '&apos;', $val);
324 $val = str_replace('"', '&quot;', $val);
325 $val = str_replace('<', '&lt;', $val);
326 $val = str_replace('>', '&gt;', $val);
327 }
328 return $val;
329 }
330
331 /**
332 * returns error string if present
333 *
334 * @return mixed error string or false
335 * @access public
336 */
337 function getError(){
338 if($this->error_str != ''){
339 return $this->error_str;
340 }
341 return false;
342 }
343
344 /**
345 * sets error string
346 *
347 * @return boolean $string error string
348 * @access private
349 */
350 function setError($str){
351 $this->error_str = $str;
352 }
353
354 /**
355 * detect if array is a simple array or a struct (associative array)
356 *
357 * @param mixed $val The PHP array
358 * @return string (arraySimple|arrayStruct)
359 * @access private
360 */
361 function isArraySimpleOrStruct($val) {
362 $keyList = array_keys($val);
363 foreach ($keyList as $keyListValue) {
364 if (!is_int($keyListValue)) {
365 return 'arrayStruct';
366 }
367 }
368 return 'arraySimple';
369 }
370
371 /**
372 * serializes PHP values in accordance w/ section 5. Type information is
373 * not serialized if $use == 'literal'.
374 *
375 * @param mixed $val The value to serialize
376 * @param string $name The name (local part) of the XML element
377 * @param string $type The XML schema type (local part) for the element
378 * @param string $name_ns The namespace for the name of the XML element
379 * @param string $type_ns The namespace for the type of the element
380 * @param array $attributes The attributes to serialize as name=>value pairs
381 * @param string $use The WSDL "use" (encoded|literal)
382 * @return string The serialized element, possibly with child elements
383 * @access public
384 */
385 function serialize_val($val,$name=false,$type=false,$name_ns=false,$type_ns=false,$attributes=false,$use='encoded'){
386 $this->debug("in serialize_val: name=$name, type=$type, name_ns=$name_ns, type_ns=$type_ns, use=$use");
387 $this->appendDebug('value=' . $this->varDump($val));
388 $this->appendDebug('attributes=' . $this->varDump($attributes));
389
390 if(is_object($val) && get_class($val) == 'soapval'){
391 return $val->serialize($use);
392 }
393 // force valid name if necessary
394 if (is_numeric($name)) {
395 $name = '__numeric_' . $name;
396 } elseif (! $name) {
397 $name = 'noname';
398 }
399 // if name has ns, add ns prefix to name
400 $xmlns = '';
401 if($name_ns){
402 $prefix = 'nu'.rand(1000,9999);
403 $name = $prefix.':'.$name;
404 $xmlns .= " xmlns:$prefix=\"$name_ns\"";
405 }
406 // if type is prefixed, create type prefix
407 if($type_ns != '' && $type_ns == $this->namespaces['xsd']){
408 // need to fix this. shouldn't default to xsd if no ns specified
409 // w/o checking against typemap
410 $type_prefix = 'xsd';
411 } elseif($type_ns){
412 $type_prefix = 'ns'.rand(1000,9999);
413 $xmlns .= " xmlns:$type_prefix=\"$type_ns\"";
414 }
415 // serialize attributes if present
416 $atts = '';
417 if($attributes){
418 foreach($attributes as $k => $v){
419 $atts .= " $k=\"".$this->expandEntities($v).'"';
420 }
421 }
422 // serialize null value
423 if (is_null($val)) {
424 if ($use == 'literal') {
425 // TODO: depends on minOccurs
426 return "<$name$xmlns $atts/>";
427 } else {
428 if (isset($type) && isset($type_prefix)) {
429 $type_str = " xsi:type=\"$type_prefix:$type\"";
430 } else {
431 $type_str = '';
432 }
433 return "<$name$xmlns$type_str $atts xsi:nil=\"true\"/>";
434 }
435 }
436 // serialize if an xsd built-in primitive type
437 if($type != '' && isset($this->typemap[$this->XMLSchemaVersion][$type])){
438 if (is_bool($val)) {
439 if ($type == 'boolean') {
440 $val = $val ? 'true' : 'false';
441 } elseif (! $val) {
442 $val = 0;
443 }
444 } else if (is_string($val)) {
445 $val = $this->expandEntities($val);
446 }
447 if ($use == 'literal') {
448 return "<$name$xmlns $atts>$val</$name>";
449 } else {
450 return "<$name$xmlns $atts xsi:type=\"xsd:$type\">$val</$name>";
451 }
452 }
453 // detect type and serialize
454 $xml = '';
455 switch(true) {
456 case (is_bool($val) || $type == 'boolean'):
457 if ($type == 'boolean') {
458 $val = $val ? 'true' : 'false';
459 } elseif (! $val) {
460 $val = 0;
461 }
462 if ($use == 'literal') {
463 $xml .= "<$name$xmlns $atts>$val</$name>";
464 } else {
465 $xml .= "<$name$xmlns xsi:type=\"xsd:boolean\"$atts>$val</$name>";
466 }
467 break;
468 case (is_int($val) || is_long($val) || $type == 'int'):
469 if ($use == 'literal') {
470 $xml .= "<$name$xmlns $atts>$val</$name>";
471 } else {
472 $xml .= "<$name$xmlns xsi:type=\"xsd:int\"$atts>$val</$name>";
473 }
474 break;
475 case (is_float($val)|| is_double($val) || $type == 'float'):
476 if ($use == 'literal') {
477 $xml .= "<$name$xmlns $atts>$val</$name>";
478 } else {
479 $xml .= "<$name$xmlns xsi:type=\"xsd:float\"$atts>$val</$name>";
480 }
481 break;
482 case (is_string($val) || $type == 'string'):
483 $val = $this->expandEntities($val);
484 if ($use == 'literal') {
485 $xml .= "<$name$xmlns $atts>$val</$name>";
486 } else {
487 $xml .= "<$name$xmlns xsi:type=\"xsd:string\"$atts>$val</$name>";
488 }
489 break;
490 case is_object($val):
491 if (! $name) {
492 $name = get_class($val);
493 $this->debug("In serialize_val, used class name $name as element name");
494 } else {
495 $this->debug("In serialize_val, do not override name $name for element name for class " . get_class($val));
496 }
497 foreach(get_object_vars($val) as $k => $v){
498 $pXml = isset($pXml) ? $pXml.$this->serialize_val($v,$k,false,false,false,false,$use) : $this->serialize_val($v,$k,false,false,false,false,$use);
499 }
500 $xml .= '<'.$name.'>'.$pXml.'</'.$name.'>';
501 break;
502 break;
503 case (is_array($val) || $type):
504 // detect if struct or array
505 $valueType = $this->isArraySimpleOrStruct($val);
506 if($valueType=='arraySimple' || ereg('^ArrayOf',$type)){
507 $i = 0;
508 if(is_array($val) && count($val)> 0){
509 foreach($val as $v){
510 if(is_object($v) && get_class($v) == 'soapval'){
511 $tt_ns = $v->type_ns;
512 $tt = $v->type;
513 } elseif (is_array($v)) {
514 $tt = $this->isArraySimpleOrStruct($v);
515 } else {
516 $tt = gettype($v);
517 }
518 $array_types[$tt] = 1;
519 // TODO: for literal, the name should be $name
520 $xml .= $this->serialize_val($v,'item',false,false,false,false,$use);
521 ++$i;
522 }
523 if(count($array_types) > 1){
524 $array_typename = 'xsd:anyType';
525 } elseif(isset($tt) && isset($this->typemap[$this->XMLSchemaVersion][$tt])) {
526 if ($tt == 'integer') {
527 $tt = 'int';
528 }
529 $array_typename = 'xsd:'.$tt;
530 } elseif(isset($tt) && $tt == 'arraySimple'){
531 $array_typename = 'SOAP-ENC:Array';
532 } elseif(isset($tt) && $tt == 'arrayStruct'){
533 $array_typename = 'unnamed_struct_use_soapval';
534 } else {
535 // if type is prefixed, create type prefix
536 if ($tt_ns != '' && $tt_ns == $this->namespaces['xsd']){
537 $array_typename = 'xsd:' . $tt;
538 } elseif ($tt_ns) {
539 $tt_prefix = 'ns' . rand(1000, 9999);
540 $array_typename = "$tt_prefix:$tt";
541 $xmlns .= " xmlns:$tt_prefix=\"$tt_ns\"";
542 } else {
543 $array_typename = $tt;
544 }
545 }
546 $array_type = $i;
547 if ($use == 'literal') {
548 $type_str = '';
549 } else if (isset($type) && isset($type_prefix)) {
550 $type_str = " xsi:type=\"$type_prefix:$type\"";
551 } else {
552 $type_str = " xsi:type=\"SOAP-ENC:Array\" SOAP-ENC:arrayType=\"".$array_typename."[$array_type]\"";
553 }
554 // empty array
555 } else {
556 if ($use == 'literal') {
557 $type_str = '';
558 } else if (isset($type) && isset($type_prefix)) {
559 $type_str = " xsi:type=\"$type_prefix:$type\"";
560 } else {
561 $type_str = " xsi:type=\"SOAP-ENC:Array\" SOAP-ENC:arrayType=\"xsd:anyType[0]\"";
562 }
563 }
564 // TODO: for array in literal, there is no wrapper here
565 $xml = "<$name$xmlns$type_str$atts>".$xml."</$name>";
566 } else {
567 // got a struct
568 if(isset($type) && isset($type_prefix)){
569 $type_str = " xsi:type=\"$type_prefix:$type\"";
570 } else {
571 $type_str = '';
572 }
573 if ($use == 'literal') {
574 $xml .= "<$name$xmlns $atts>";
575 } else {
576 $xml .= "<$name$xmlns$type_str$atts>";
577 }
578 foreach($val as $k => $v){
579 // Apache Map
580 if ($type == 'Map' && $type_ns == 'http://xml.apache.org/xml-soap') {
581 $xml .= '<item>';
582 $xml .= $this->serialize_val($k,'key',false,false,false,false,$use);
583 $xml .= $this->serialize_val($v,'value',false,false,false,false,$use);
584 $xml .= '</item>';
585 } else {
586 $xml .= $this->serialize_val($v,$k,false,false,false,false,$use);
587 }
588 }
589 $xml .= "</$name>";
590 }
591 break;
592 default:
593 $xml .= 'not detected, got '.gettype($val).' for '.$val;
594 break;
595 }
596 return $xml;
597 }
598
599 /**
600 * serializes a message
601 *
602 * @param string $body the XML of the SOAP body
603 * @param mixed $headers optional string of XML with SOAP header content, or array of soapval objects for SOAP headers
604 * @param array $namespaces optional the namespaces used in generating the body and headers
605 * @param string $style optional (rpc|document)
606 * @param string $use optional (encoded|literal)
607 * @param string $encodingStyle optional (usually 'http://schemas.xmlsoap.org/soap/encoding/' for encoded)
608 * @return string the message
609 * @access public
610 */
611 function serializeEnvelope($body,$headers=false,$namespaces=array(),$style='rpc',$use='encoded',$encodingStyle='http://schemas.xmlsoap.org/soap/encoding/'){
612 // TODO: add an option to automatically run utf8_encode on $body and $headers
613 // if $this->soap_defencoding is UTF-8. Not doing this automatically allows
614 // one to send arbitrary UTF-8 characters, not just characters that map to ISO-8859-1
615
616 $this->debug("In serializeEnvelope length=" . strlen($body) . " body (max 1000 characters)=" . substr($body, 0, 1000) . " style=$style use=$use encodingStyle=$encodingStyle");
617 $this->debug("headers:");
618 $this->appendDebug($this->varDump($headers));
619 $this->debug("namespaces:");
620 $this->appendDebug($this->varDump($namespaces));
621
622 // serialize namespaces
623 $ns_string = '';
624 foreach(array_merge($this->namespaces,$namespaces) as $k => $v){
625 $ns_string .= " xmlns:$k=\"$v\"";
626 }
627 if($encodingStyle) {
628 $ns_string = " SOAP-ENV:encodingStyle=\"$encodingStyle\"$ns_string";
629 }
630
631 // serialize headers
632 if($headers){
633 if (is_array($headers)) {
634 $xml = '';
635 foreach ($headers as $header) {
636 $xml .= $this->serialize_val($header, false, false, false, false, false, $use);
637 }
638 $headers = $xml;
639 $this->debug("In serializeEnvelope, serialzied array of headers to $headers");
640 }
641 $headers = "<SOAP-ENV:Header>".$headers."</SOAP-ENV:Header>";
642 }
643 // serialize envelope
644 return
645 '<?xml version="1.0" encoding="'.$this->soap_defencoding .'"?'.">".
646 '<SOAP-ENV:Envelope'.$ns_string.">".
647 $headers.
648 "<SOAP-ENV:Body>".
649 $body.
650 "</SOAP-ENV:Body>".
651 "</SOAP-ENV:Envelope>";
652 }
653
654 /**
655 * formats a string to be inserted into an HTML stream
656 *
657 * @param string $str The string to format
658 * @return string The formatted string
659 * @access public
660 * @deprecated
661 */
662 function formatDump($str){
663 $str = htmlspecialchars($str);
664 return nl2br($str);
665 }
666
667 /**
668 * contracts (changes namespace to prefix) a qualified name
669 *
670 * @param string $qname qname
671 * @return string contracted qname
672 * @access private
673 */
674 function contractQname($qname){
675 // get element namespace
676 //$this->xdebug("Contract $qname");
677 if (strrpos($qname, ':')) {
678 // get unqualified name
679 $name = substr($qname, strrpos($qname, ':') + 1);
680 // get ns
681 $ns = substr($qname, 0, strrpos($qname, ':'));
682 $p = $this->getPrefixFromNamespace($ns);
683 if ($p) {
684 return $p . ':' . $name;
685 }
686 return $qname;
687 } else {
688 return $qname;
689 }
690 }
691
692 /**
693 * expands (changes prefix to namespace) a qualified name
694 *
695 * @param string $string qname
696 * @return string expanded qname
697 * @access private
698 */
699 function expandQname($qname){
700 // get element prefix
701 if(strpos($qname,':') && !ereg('^http://',$qname)){
702 // get unqualified name
703 $name = substr(strstr($qname,':'),1);
704 // get ns prefix
705 $prefix = substr($qname,0,strpos($qname,':'));
706 if(isset($this->namespaces[$prefix])){
707 return $this->namespaces[$prefix].':'.$name;
708 } else {
709 return $qname;
710 }
711 } else {
712 return $qname;
713 }
714 }
715
716 /**
717 * returns the local part of a prefixed string
718 * returns the original string, if not prefixed
719 *
720 * @param string $str The prefixed string
721 * @return string The local part
722 * @access public
723 */
724 function getLocalPart($str){
725 if($sstr = strrchr($str,':')){
726 // get unqualified name
727 return substr( $sstr, 1 );
728 } else {
729 return $str;
730 }
731 }
732
733 /**
734 * returns the prefix part of a prefixed string
735 * returns false, if not prefixed
736 *
737 * @param string $str The prefixed string
738 * @return mixed The prefix or false if there is no prefix
739 * @access public
740 */
741 function getPrefix($str){
742 if($pos = strrpos($str,':')){
743 // get prefix
744 return substr($str,0,$pos);
745 }
746 return false;
747 }
748
749 /**
750 * pass it a prefix, it returns a namespace
751 *
752 * @param string $prefix The prefix
753 * @return mixed The namespace, false if no namespace has the specified prefix
754 * @access public
755 */
756 function getNamespaceFromPrefix($prefix){
757 if (isset($this->namespaces[$prefix])) {
758 return $this->namespaces[$prefix];
759 }
760 //$this->setError("No namespace registered for prefix '$prefix'");
761 return false;
762 }
763
764 /**
765 * returns the prefix for a given namespace (or prefix)
766 * or false if no prefixes registered for the given namespace
767 *
768 * @param string $ns The namespace
769 * @return mixed The prefix, false if the namespace has no prefixes
770 * @access public
771 */
772 function getPrefixFromNamespace($ns) {
773 foreach ($this->namespaces as $p => $n) {
774 if ($ns == $n || $ns == $p) {
775 $this->usedNamespaces[$p] = $n;
776 return $p;
777 }
778 }
779 return false;
780 }
781
782 /**
783 * returns the time in ODBC canonical form with microseconds
784 *
785 * @return string The time in ODBC canonical form with microseconds
786 * @access public
787 */
788 function getmicrotime() {
789 if (function_exists('gettimeofday')) {
790 $tod = gettimeofday();
791 $sec = $tod['sec'];
792 $usec = $tod['usec'];
793 } else {
794 $sec = time();
795 $usec = 0;
796 }
797 return strftime('%Y-%m-%d %H:%M:%S', $sec) . '.' . sprintf('%06d', $usec);
798 }
799
800 /**
801 * Returns a string with the output of var_dump
802 *
803 * @param mixed $data The variable to var_dump
804 * @return string The output of var_dump
805 * @access public
806 */
807 function varDump($data) {
808 ob_start();
809 var_dump($data);
810 $ret_val = ob_get_contents();
811 ob_end_clean();
812 return $ret_val;
813 }
814 }
815
816 // XML Schema Datatype Helper Functions
817
818 //xsd:dateTime helpers
819
820 /**
821 * convert unix timestamp to ISO 8601 compliant date string
822 *
823 * @param string $timestamp Unix time stamp
824 * @access public
825 */
826 function timestamp_to_iso8601($timestamp,$utc=true){
827 $datestr = date('Y-m-d\TH:i:sO',$timestamp);
828 if($utc){
829 $eregStr =
830 '([0-9]{4})-'. // centuries & years CCYY-
831 '([0-9]{2})-'. // months MM-
832 '([0-9]{2})'. // days DD
833 'T'. // separator T
834 '([0-9]{2}):'. // hours hh:
835 '([0-9]{2}):'. // minutes mm:
836 '([0-9]{2})(\.[0-9]*)?'. // seconds ss.ss...
837 '(Z|[+\-][0-9]{2}:?[0-9]{2})?'; // Z to indicate UTC, -/+HH:MM:SS.SS... for local tz's
838
839 if(ereg($eregStr,$datestr,$regs)){
840 return sprintf('%04d-%02d-%02dT%02d:%02d:%02dZ',$regs[1],$regs[2],$regs[3],$regs[4],$regs[5],$regs[6]);
841 }
842 return false;
843 } else {
844 return $datestr;
845 }
846 }
847
848 /**
849 * convert ISO 8601 compliant date string to unix timestamp
850 *
851 * @param string $datestr ISO 8601 compliant date string
852 * @access public
853 */
854 function iso8601_to_timestamp($datestr){
855 $eregStr =
856 '([0-9]{4})-'. // centuries & years CCYY-
857 '([0-9]{2})-'. // months MM-
858 '([0-9]{2})'. // days DD
859 'T'. // separator T
860 '([0-9]{2}):'. // hours hh:
861 '([0-9]{2}):'. // minutes mm:
862 '([0-9]{2})(\.[0-9]+)?'. // seconds ss.ss...
863 '(Z|[+\-][0-9]{2}:?[0-9]{2})?'; // Z to indicate UTC, -/+HH:MM:SS.SS... for local tz's
864 if(ereg($eregStr,$datestr,$regs)){
865 // not utc
866 if($regs[8] != 'Z'){
867 $op = substr($regs[8],0,1);
868 $h = substr($regs[8],1,2);
869 $m = substr($regs[8],strlen($regs[8])-2,2);
870 if($op == '-'){
871 $regs[4] = $regs[4] + $h;
872 $regs[5] = $regs[5] + $m;
873 } elseif($op == '+'){
874 $regs[4] = $regs[4] - $h;
875 $regs[5] = $regs[5] - $m;
876 }
877 }
878 return strtotime("$regs[1]-$regs[2]-$regs[3] $regs[4]:$regs[5]:$regs[6]Z");
879 } else {
880 return false;
881 }
882 }
883
884 /**
885 * sleeps some number of microseconds
886 *
887 * @param string $usec the number of microseconds to sleep
888 * @access public
889 * @deprecated
890 */
891 function usleepWindows($usec)
892 {
893 $start = gettimeofday();
894
895 do
896 {
897 $stop = gettimeofday();
898 $timePassed = 1000000 * ($stop['sec'] - $start['sec'])
899 + $stop['usec'] - $start['usec'];
900 }
901 while ($timePassed < $usec);
902 }
903
904 ?><?php
905
906
907
908 /**
909 * Contains information for a SOAP fault.
910 * Mainly used for returning faults from deployed functions
911 * in a server instance.
912 * @author Dietrich Ayala <dietrich@ganx4.com>
913 * @version $Id: nusoap.orig.php,v 1.1 2005/10/13 06:10:09 ryankicks Exp $
914 * @access public
915 */
916 class soap_fault extends nusoap_base {
917 /**
918 * The fault code (client|server)
919 * @var string
920 * @access private
921 */
922 var $faultcode;
923 /**
924 * The fault actor
925 * @var string
926 * @access private
927 */
928 var $faultactor;
929 /**
930 * The fault string, a description of the fault
931 * @var string
932 * @access private
933 */
934 var $faultstring;
935 /**
936 * The fault detail, typically a string or array of string
937 * @var mixed
938 * @access private
939 */
940 var $faultdetail;
941
942 /**
943 * constructor
944 *
945 * @param string $faultcode (client | server)
946 * @param string $faultactor only used when msg routed between multiple actors
947 * @param string $faultstring human readable error message
948 * @param mixed $faultdetail detail, typically a string or array of string
949 */
950 function soap_fault($faultcode,$faultactor='',$faultstring='',$faultdetail=''){
951 parent::nusoap_base();
952 $this->faultcode = $faultcode;
953 $this->faultactor = $faultactor;
954 $this->faultstring = $faultstring;
955 $this->faultdetail = $faultdetail;
956 }
957
958 /**
959 * serialize a fault
960 *
961 * @return string The serialization of the fault instance.
962 * @access public
963 */
964 function serialize(){
965 $ns_string = '';
966 foreach($this->namespaces as $k => $v){
967 $ns_string .= "\n xmlns:$k=\"$v\"";
968 }
969 $return_msg =
970 '<?xml version="1.0" encoding="'.$this->soap_defencoding.'"?>'.
971 '<SOAP-ENV:Envelope SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"'.$ns_string.">\n".
972 '<SOAP-ENV:Body>'.
973 '<SOAP-ENV:Fault>'.
974 $this->serialize_val($this->faultcode, 'faultcode').
975 $this->serialize_val($this->faultactor, 'faultactor').
976 $this->serialize_val($this->faultstring, 'faultstring').
977 $this->serialize_val($this->faultdetail, 'detail').
978 '</SOAP-ENV:Fault>'.
979 '</SOAP-ENV:Body>'.
980 '</SOAP-ENV:Envelope>';
981 return $return_msg;
982 }
983 }
984
985
986
987 ?><?php
988
989
990
991 /**
992 * parses an XML Schema, allows access to it's data, other utility methods
993 * no validation... yet.
994 * very experimental and limited. As is discussed on XML-DEV, I'm one of the people
995 * that just doesn't have time to read the spec(s) thoroughly, and just have a couple of trusty
996 * tutorials I refer to :)
997 *
998 * @author Dietrich Ayala <dietrich@ganx4.com>
999 * @version $Id: nusoap.orig.php,v 1.1 2005/10/13 06:10:09 ryankicks Exp $
1000 * @access public
1001 */
1002 class XMLSchema extends nusoap_base {
1003
1004 // files
1005 var $schema = '';
1006 var $xml = '';
1007 // namespaces
1008 var $enclosingNamespaces;
1009 // schema info
1010 var $schemaInfo = array();
1011 var $schemaTargetNamespace = '';
1012 // types, elements, attributes defined by the schema
1013 var $attributes = array();
1014 var $complexTypes = array();
1015 var $complexTypeStack = array();
1016 var $currentComplexType = null;
1017 var $elements = array();
1018 var $elementStack = array();
1019 var $currentElement = null;
1020 var $simpleTypes = array();
1021 var $simpleTypeStack = array();
1022 var $currentSimpleType = null;
1023 // imports
1024 var $imports = array();
1025 // parser vars
1026 var $parser;
1027 var $position = 0;
1028 var $depth = 0;
1029 var $depth_array = array();
1030 var $message = array();
1031 var $defaultNamespace = array();
1032
1033 /**
1034 * constructor
1035 *
1036 * @param string $schema schema document URI
1037 * @param string $xml xml document URI
1038 * @param string $namespaces namespaces defined in enclosing XML
1039 * @access public
1040 */
1041 function XMLSchema($schema='',$xml='',$namespaces=array()){
1042 parent::nusoap_base();
1043 $this->debug('xmlschema class instantiated, inside constructor');
1044 // files
1045 $this->schema = $schema;
1046 $this->xml = $xml;
1047
1048 // namespaces
1049 $this->enclosingNamespaces = $namespaces;
1050 $this->namespaces = array_merge($this->namespaces, $namespaces);
1051
1052 // parse schema file
1053 if($schema != ''){
1054 $this->debug('initial schema file: '.$schema);
1055 $this->parseFile($schema, 'schema');
1056 }
1057
1058 // parse xml file
1059 if($xml != ''){
1060 $this->debug('initial xml file: '.$xml);
1061 $this->parseFile($xml, 'xml');
1062 }
1063
1064 }
1065
1066 /**
1067 * parse an XML file
1068 *
1069 * @param string $xml, path/URL to XML file
1070 * @param string $type, (schema | xml)
1071 * @return boolean
1072 * @access public
1073 */
1074 function parseFile($xml,$type){
1075 // parse xml file
1076 if($xml != ""){
1077 $xmlStr = @join("",@file($xml));
1078 if($xmlStr == ""){
1079 $msg = 'Error reading XML from '.$xml;
1080 $this->setError($msg);
1081 $this->debug($msg);
1082 return false;
1083 } else {
1084 $this->debug("parsing $xml");
1085 $this->parseString($xmlStr,$type);
1086 $this->debug("done parsing $xml");
1087 return true;
1088 }
1089 }
1090 return false;
1091 }
1092
1093 /**
1094 * parse an XML string
1095 *
1096 * @param string $xml path or URL
1097 * @param string $type, (schema|xml)
1098 * @access private
1099 */
1100 function parseString($xml,$type){
1101 // parse xml string
1102 if($xml != ""){
1103
1104 // Create an XML parser.
1105 $this->parser = xml_parser_create();
1106 // Set the options for parsing the XML data.
1107 xml_parser_set_option($this->parser, XML_OPTION_CASE_FOLDING, 0);
1108
1109 // Set the object for the parser.
1110 xml_set_object($this->parser, $this);
1111
1112 // Set the element handlers for the parser.
1113 if($type == "schema"){
1114 xml_set_element_handler($this->parser, 'schemaStartElement','schemaEndElement');
1115 xml_set_character_data_handler($this->parser,'schemaCharacterData');
1116 } elseif($type == "xml"){
1117 xml_set_element_handler($this->parser, 'xmlStartElement','xmlEndElement');
1118 xml_set_character_data_handler($this->parser,'xmlCharacterData');
1119 }
1120
1121 // Parse the XML file.
1122 if(!xml_parse($this->parser,$xml,true)){
1123 // Display an error message.
1124 $errstr = sprintf('XML error parsing XML schema on line %d: %s',
1125 xml_get_current_line_number($this->parser),
1126 xml_error_string(xml_get_error_code($this->parser))
1127 );
1128 $this->debug($errstr);
1129 $this->debug("XML payload:\n" . $xml);
1130 $this->setError($errstr);
1131 }
1132
1133 xml_parser_free($this->parser);
1134 } else{
1135 $this->debug('no xml passed to parseString()!!');
1136 $this->setError('no xml passed to parseString()!!');
1137 }
1138 }
1139
1140 /**
1141 * start-element handler
1142 *
1143 * @param string $parser XML parser object
1144 * @param string $name element name
1145 * @param string $attrs associative array of attributes
1146 * @access private
1147 */
1148 function schemaStartElement($parser, $name, $attrs) {
1149
1150 // position in the total number of elements, starting from 0
1151 $pos = $this->position++;
1152 $depth = $this->depth++;
1153 // set self as current value for this depth
1154 $this->depth_array[$depth] = $pos;
1155 $this->message[$pos] = array('cdata' => '');
1156 if ($depth > 0) {
1157 $this->defaultNamespace[$pos] = $this->defaultNamespace[$this->depth_array[$depth - 1]];
1158 } else {
1159 $this->defaultNamespace[$pos] = false;
1160 }
1161
1162 // get element prefix
1163 if($prefix = $this->getPrefix($name)){
1164 // get unqualified name
1165 $name = $this->getLocalPart($name);
1166 } else {
1167 $prefix = '';
1168 }
1169
1170 // loop thru attributes, expanding, and registering namespace declarations
1171 if(count($attrs) > 0){
1172 foreach($attrs as $k => $v){
1173 // if ns declarations, add to class level array of valid namespaces
1174 if(ereg("^xmlns",$k)){
1175 //$this->xdebug("$k: $v");
1176 //$this->xdebug('ns_prefix: '.$this->getPrefix($k));
1177 if($ns_prefix = substr(strrchr($k,':'),1)){
1178 //$this->xdebug("Add namespace[$ns_prefix] = $v");
1179 $this->namespaces[$ns_prefix] = $v;
1180 } else {
1181 $this->defaultNamespace[$pos] = $v;
1182 if (! $this->getPrefixFromNamespace($v)) {
1183 $this->namespaces['ns'.(count($this->namespaces)+1)] = $v;
1184 }
1185 }
1186 if($v == 'http://www.w3.org/2001/XMLSchema' || $v == 'http://www.w3.org/1999/XMLSchema' || $v == 'http://www.w3.org/2000/10/XMLSchema'){
1187 $this->XMLSchemaVersion = $v;
1188 $this->namespaces['xsi'] = $v.'-instance';
1189 }
1190 }
1191 }
1192 foreach($attrs as $k => $v){
1193 // expand each attribute
1194 $k = strpos($k,':') ? $this->expandQname($k) : $k;
1195 $v = strpos($v,':') ? $this->expandQname($v) : $v;
1196 $eAttrs[$k] = $v;
1197 }
1198 $attrs = $eAttrs;
1199 } else {
1200 $attrs = array();
1201 }
1202 // find status, register data
1203 switch($name){
1204 case 'all': // (optional) compositor content for a complexType
1205 case 'choice':
1206 case 'group':
1207 case 'sequence':
1208 //$this->xdebug("compositor $name for currentComplexType: $this->currentComplexType and currentElement: $this->currentElement");
1209 $this->complexTypes[$this->currentComplexType]['compositor'] = $name;
1210 //if($name == 'all' || $name == 'sequence'){
1211 // $this->complexTypes[$this->currentComplexType]['phpType'] = 'struct';
1212 //}
1213 break;
1214 case 'attribute': // complexType attribute
1215 //$this->xdebug("parsing attribute $attrs[name] $attrs[ref] of value: ".$attrs['http://schemas.xmlsoap.org/wsdl/:arrayType']);
1216 $this->xdebug("parsing attribute:");
1217 $this->appendDebug($this->varDump($attrs));
1218 if (!isset($attrs['form'])) {
1219 $attrs['form'] = $this->schemaInfo['attributeFormDefault'];
1220 }
1221 if (isset($attrs['http://schemas.xmlsoap.org/wsdl/:arrayType'])) {
1222 $v = $attrs['http://schemas.xmlsoap.org/wsdl/:arrayType'];
1223 if (!strpos($v, ':')) {
1224 // no namespace in arrayType attribute value...
1225 if ($this->defaultNamespace[$pos]) {
1226 // ...so use the default
1227 $attrs['http://schemas.xmlsoap.org/wsdl/:arrayType'] = $this->defaultNamespace[$pos] . ':' . $attrs['http://schemas.xmlsoap.org/wsdl/:arrayType'];
1228 }
1229 }
1230 }
1231 if(isset($attrs['name'])){
1232 $this->attributes[$attrs['name']] = $attrs;
1233 $aname = $attrs['name'];
1234 } elseif(isset($attrs['ref']) && $attrs['ref'] == 'http://schemas.xmlsoap.org/soap/encoding/:arrayType'){
1235 if (isset($attrs['http://schemas.xmlsoap.org/wsdl/:arrayType'])) {
1236 $aname = $attrs['http://schemas.xmlsoap.org/wsdl/:arrayType'];
1237 } else {
1238 $aname = '';
1239 }
1240 } elseif(isset($attrs['ref'])){
1241 $aname = $attrs['ref'];
1242 $this->attributes[$attrs['ref']] = $attrs;
1243 }
1244
1245 if($this->currentComplexType){ // This should *always* be
1246 $this->complexTypes[$this->currentComplexType]['attrs'][$aname] = $attrs;
1247 }
1248 // arrayType attribute
1249 if(isset($attrs['http://schemas.xmlsoap.org/wsdl/:arrayType']) || $this->getLocalPart($aname) == 'arrayType'){
1250 $this->complexTypes[$this->currentComplexType]['phpType'] = 'array';
1251 $prefix = $this->getPrefix($aname);
1252 if(isset($attrs['http://schemas.xmlsoap.org/wsdl/:arrayType'])){
1253 $v = $attrs['http://schemas.xmlsoap.org/wsdl/:arrayType'];
1254 } else {
1255 $v = '';
1256 }
1257 if(strpos($v,'[,]')){