~dangarner/xibo/334359

« back to all changes in this revision

Viewing changes to server/3rdparty/nuSoap/class.nusoap_base.php

  • Committer: Alex Harrington
  • Date: 2009-02-23 08:34:26 UTC
  • mfrom: (1.1.85 Xibo)
  • Revision ID: alex@longhill.org.uk-20090223083426-kdq80nu0zucqjyu0
[server] Merged from lp:~dangarner/xibo/xibo-server for 1.0.0-rc1

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
<?php
 
2
 
 
3
/*
 
4
$Id: class.nusoap_base.php,v 1.51 2007/11/06 15:17:46 snichol 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
The NuSOAP project home is:
 
25
http://sourceforge.net/projects/nusoap/
 
26
 
 
27
The primary support for NuSOAP is the mailing list:
 
28
nusoap-general@lists.sourceforge.net
 
29
 
 
30
If you have any questions or comments, please email:
 
31
 
 
32
Dietrich Ayala
 
33
dietrich@ganx4.com
 
34
http://dietrich.ganx4.com/nusoap
 
35
 
 
36
NuSphere Corporation
 
37
http://www.nusphere.com
 
38
 
 
39
*/
 
40
 
 
41
/*
 
42
 *      Some of the standards implmented in whole or part by NuSOAP:
 
43
 *
 
44
 *      SOAP 1.1 (http://www.w3.org/TR/2000/NOTE-SOAP-20000508/)
 
45
 *      WSDL 1.1 (http://www.w3.org/TR/2001/NOTE-wsdl-20010315)
 
46
 *      SOAP Messages With Attachments (http://www.w3.org/TR/SOAP-attachments)
 
47
 *      XML 1.0 (http://www.w3.org/TR/2006/REC-xml-20060816/)
 
48
 *      Namespaces in XML 1.0 (http://www.w3.org/TR/2006/REC-xml-names-20060816/)
 
49
 *      XML Schema 1.0 (http://www.w3.org/TR/xmlschema-0/)
 
50
 *      RFC 2045 Multipurpose Internet Mail Extensions (MIME) Part One: Format of Internet Message Bodies
 
51
 *      RFC 2068 Hypertext Transfer Protocol -- HTTP/1.1
 
52
 *      RFC 2617 HTTP Authentication: Basic and Digest Access Authentication
 
53
 */
 
54
 
 
55
/* load classes
 
56
 
 
57
// necessary classes
 
58
require_once('class.soapclient.php');
 
59
require_once('class.soap_val.php');
 
60
require_once('class.soap_parser.php');
 
61
require_once('class.soap_fault.php');
 
62
 
 
63
// transport classes
 
64
require_once('class.soap_transport_http.php');
 
65
 
 
66
// optional add-on classes
 
67
require_once('class.xmlschema.php');
 
68
require_once('class.wsdl.php');
 
69
 
 
70
// server class
 
71
require_once('class.soap_server.php');*/
 
72
 
 
73
// class variable emulation
 
74
// cf. http://www.webkreator.com/php/techniques/php-static-class-variables.html
 
75
$GLOBALS['_transient']['static']['nusoap_base']->globalDebugLevel = 9;
 
76
 
 
77
/**
 
78
*
 
79
* nusoap_base
 
80
*
 
81
* @author   Dietrich Ayala <dietrich@ganx4.com>
 
82
* @author   Scott Nichol <snichol@users.sourceforge.net>
 
83
* @version  $Id: class.nusoap_base.php,v 1.51 2007/11/06 15:17:46 snichol Exp $
 
84
* @access   public
 
85
*/
 
86
class nusoap_base {
 
87
        /**
 
88
         * Identification for HTTP headers.
 
89
         *
 
90
         * @var string
 
91
         * @access private
 
92
         */
 
93
        var $title = 'NuSOAP';
 
94
        /**
 
95
         * Version for HTTP headers.
 
96
         *
 
97
         * @var string
 
98
         * @access private
 
99
         */
 
100
        var $version = '0.7.3';
 
101
        /**
 
102
         * CVS revision for HTTP headers.
 
103
         *
 
104
         * @var string
 
105
         * @access private
 
106
         */
 
107
        var $revision = '$Revision: 1.51 $';
 
108
    /**
 
109
     * Current error string (manipulated by getError/setError)
 
110
         *
 
111
         * @var string
 
112
         * @access private
 
113
         */
 
114
        var $error_str = '';
 
115
    /**
 
116
     * Current debug string (manipulated by debug/appendDebug/clearDebug/getDebug/getDebugAsXMLComment)
 
117
         *
 
118
         * @var string
 
119
         * @access private
 
120
         */
 
121
    var $debug_str = '';
 
122
    /**
 
123
         * toggles automatic encoding of special characters as entities
 
124
         * (should always be true, I think)
 
125
         *
 
126
         * @var boolean
 
127
         * @access private
 
128
         */
 
129
        var $charencoding = true;
 
130
        /**
 
131
         * the debug level for this instance
 
132
         *
 
133
         * @var integer
 
134
         * @access private
 
135
         */
 
136
        var $debugLevel;
 
137
 
 
138
    /**
 
139
        * set schema version
 
140
        *
 
141
        * @var      string
 
142
        * @access   public
 
143
        */
 
144
        var $XMLSchemaVersion = 'http://www.w3.org/2001/XMLSchema';
 
145
        
 
146
    /**
 
147
        * charset encoding for outgoing messages
 
148
        *
 
149
        * @var      string
 
150
        * @access   public
 
151
        */
 
152
    var $soap_defencoding = 'ISO-8859-1';
 
153
        //var $soap_defencoding = 'UTF-8';
 
154
 
 
155
        /**
 
156
        * namespaces in an array of prefix => uri
 
157
        *
 
158
        * this is "seeded" by a set of constants, but it may be altered by code
 
159
        *
 
160
        * @var      array
 
161
        * @access   public
 
162
        */
 
163
        var $namespaces = array(
 
164
                'SOAP-ENV' => 'http://schemas.xmlsoap.org/soap/envelope/',
 
165
                'xsd' => 'http://www.w3.org/2001/XMLSchema',
 
166
                'xsi' => 'http://www.w3.org/2001/XMLSchema-instance',
 
167
                'SOAP-ENC' => 'http://schemas.xmlsoap.org/soap/encoding/'
 
168
                );
 
169
 
 
170
        /**
 
171
        * namespaces used in the current context, e.g. during serialization
 
172
        *
 
173
        * @var      array
 
174
        * @access   private
 
175
        */
 
176
        var $usedNamespaces = array();
 
177
 
 
178
        /**
 
179
        * XML Schema types in an array of uri => (array of xml type => php type)
 
180
        * is this legacy yet?
 
181
        * no, this is used by the nusoap_xmlschema class to verify type => namespace mappings.
 
182
        * @var      array
 
183
        * @access   public
 
184
        */
 
185
        var $typemap = array(
 
186
        'http://www.w3.org/2001/XMLSchema' => array(
 
187
                'string'=>'string','boolean'=>'boolean','float'=>'double','double'=>'double','decimal'=>'double',
 
188
                'duration'=>'','dateTime'=>'string','time'=>'string','date'=>'string','gYearMonth'=>'',
 
189
                'gYear'=>'','gMonthDay'=>'','gDay'=>'','gMonth'=>'','hexBinary'=>'string','base64Binary'=>'string',
 
190
                // abstract "any" types
 
191
                'anyType'=>'string','anySimpleType'=>'string',
 
192
                // derived datatypes
 
193
                'normalizedString'=>'string','token'=>'string','language'=>'','NMTOKEN'=>'','NMTOKENS'=>'','Name'=>'','NCName'=>'','ID'=>'',
 
194
                'IDREF'=>'','IDREFS'=>'','ENTITY'=>'','ENTITIES'=>'','integer'=>'integer','nonPositiveInteger'=>'integer',
 
195
                'negativeInteger'=>'integer','long'=>'integer','int'=>'integer','short'=>'integer','byte'=>'integer','nonNegativeInteger'=>'integer',
 
196
                'unsignedLong'=>'','unsignedInt'=>'','unsignedShort'=>'','unsignedByte'=>'','positiveInteger'=>''),
 
197
        'http://www.w3.org/2000/10/XMLSchema' => array(
 
198
                'i4'=>'','int'=>'integer','boolean'=>'boolean','string'=>'string','double'=>'double',
 
199
                'float'=>'double','dateTime'=>'string',
 
200
                'timeInstant'=>'string','base64Binary'=>'string','base64'=>'string','ur-type'=>'array'),
 
201
        'http://www.w3.org/1999/XMLSchema' => array(
 
202
                'i4'=>'','int'=>'integer','boolean'=>'boolean','string'=>'string','double'=>'double',
 
203
                'float'=>'double','dateTime'=>'string',
 
204
                'timeInstant'=>'string','base64Binary'=>'string','base64'=>'string','ur-type'=>'array'),
 
205
        'http://soapinterop.org/xsd' => array('SOAPStruct'=>'struct'),
 
206
        'http://schemas.xmlsoap.org/soap/encoding/' => array('base64'=>'string','array'=>'array','Array'=>'array'),
 
207
    'http://xml.apache.org/xml-soap' => array('Map')
 
208
        );
 
209
 
 
210
        /**
 
211
        * XML entities to convert
 
212
        *
 
213
        * @var      array
 
214
        * @access   public
 
215
        * @deprecated
 
216
        * @see  expandEntities
 
217
        */
 
218
        var $xmlEntities = array('quot' => '"','amp' => '&',
 
219
                'lt' => '<','gt' => '>','apos' => "'");
 
220
 
 
221
        /**
 
222
        * constructor
 
223
        *
 
224
        * @access       public
 
225
        */
 
226
        function nusoap_base() {
 
227
                $this->debugLevel = $GLOBALS['_transient']['static']['nusoap_base']->globalDebugLevel;
 
228
        }
 
229
 
 
230
        /**
 
231
        * gets the global debug level, which applies to future instances
 
232
        *
 
233
        * @return       integer Debug level 0-9, where 0 turns off
 
234
        * @access       public
 
235
        */
 
236
        function getGlobalDebugLevel() {
 
237
                return $GLOBALS['_transient']['static']['nusoap_base']->globalDebugLevel;
 
238
        }
 
239
 
 
240
        /**
 
241
        * sets the global debug level, which applies to future instances
 
242
        *
 
243
        * @param        int     $level  Debug level 0-9, where 0 turns off
 
244
        * @access       public
 
245
        */
 
246
        function setGlobalDebugLevel($level) {
 
247
                $GLOBALS['_transient']['static']['nusoap_base']->globalDebugLevel = $level;
 
248
        }
 
249
 
 
250
        /**
 
251
        * gets the debug level for this instance
 
252
        *
 
253
        * @return       int     Debug level 0-9, where 0 turns off
 
254
        * @access       public
 
255
        */
 
256
        function getDebugLevel() {
 
257
                return $this->debugLevel;
 
258
        }
 
259
 
 
260
        /**
 
261
        * sets the debug level for this instance
 
262
        *
 
263
        * @param        int     $level  Debug level 0-9, where 0 turns off
 
264
        * @access       public
 
265
        */
 
266
        function setDebugLevel($level) {
 
267
                $this->debugLevel = $level;
 
268
        }
 
269
 
 
270
        /**
 
271
        * adds debug data to the instance debug string with formatting
 
272
        *
 
273
        * @param    string $string debug data
 
274
        * @access   private
 
275
        */
 
276
        function debug($string){
 
277
                if ($this->debugLevel > 0) {
 
278
                        $this->appendDebug($this->getmicrotime().' '.get_class($this).": $string\n");
 
279
                }
 
280
        }
 
281
 
 
282
        /**
 
283
        * adds debug data to the instance debug string without formatting
 
284
        *
 
285
        * @param    string $string debug data
 
286
        * @access   public
 
287
        */
 
288
        function appendDebug($string){
 
289
                if ($this->debugLevel > 0) {
 
290
                        // it would be nice to use a memory stream here to use
 
291
                        // memory more efficiently
 
292
                        $this->debug_str .= $string;
 
293
                }
 
294
        }
 
295
 
 
296
        /**
 
297
        * clears the current debug data for this instance
 
298
        *
 
299
        * @access   public
 
300
        */
 
301
        function clearDebug() {
 
302
                // it would be nice to use a memory stream here to use
 
303
                // memory more efficiently
 
304
                $this->debug_str = '';
 
305
        }
 
306
 
 
307
        /**
 
308
        * gets the current debug data for this instance
 
309
        *
 
310
        * @return   debug data
 
311
        * @access   public
 
312
        */
 
313
        function &getDebug() {
 
314
                // it would be nice to use a memory stream here to use
 
315
                // memory more efficiently
 
316
                return $this->debug_str;
 
317
        }
 
318
 
 
319
        /**
 
320
        * gets the current debug data for this instance as an XML comment
 
321
        * this may change the contents of the debug data
 
322
        *
 
323
        * @return   debug data as an XML comment
 
324
        * @access   public
 
325
        */
 
326
        function &getDebugAsXMLComment() {
 
327
                // it would be nice to use a memory stream here to use
 
328
                // memory more efficiently
 
329
                while (strpos($this->debug_str, '--')) {
 
330
                        $this->debug_str = str_replace('--', '- -', $this->debug_str);
 
331
                }
 
332
                $ret = "<!--\n" . $this->debug_str . "\n-->";
 
333
        return $ret;
 
334
        }
 
335
 
 
336
        /**
 
337
        * expands entities, e.g. changes '<' to '&lt;'.
 
338
        *
 
339
        * @param        string  $val    The string in which to expand entities.
 
340
        * @access       private
 
341
        */
 
342
        function expandEntities($val) {
 
343
                if ($this->charencoding) {
 
344
                $val = str_replace('&', '&amp;', $val);
 
345
                $val = str_replace("'", '&apos;', $val);
 
346
                $val = str_replace('"', '&quot;', $val);
 
347
                $val = str_replace('<', '&lt;', $val);
 
348
                $val = str_replace('>', '&gt;', $val);
 
349
            }
 
350
            return $val;
 
351
        }
 
352
 
 
353
        /**
 
354
        * returns error string if present
 
355
        *
 
356
        * @return   mixed error string or false
 
357
        * @access   public
 
358
        */
 
359
        function getError(){
 
360
                if($this->error_str != ''){
 
361
                        return $this->error_str;
 
362
                }
 
363
                return false;
 
364
        }
 
365
 
 
366
        /**
 
367
        * sets error string
 
368
        *
 
369
        * @return   boolean $string error string
 
370
        * @access   private
 
371
        */
 
372
        function setError($str){
 
373
                $this->error_str = $str;
 
374
        }
 
375
 
 
376
        /**
 
377
        * detect if array is a simple array or a struct (associative array)
 
378
        *
 
379
        * @param        mixed   $val    The PHP array
 
380
        * @return       string  (arraySimple|arrayStruct)
 
381
        * @access       private
 
382
        */
 
383
        function isArraySimpleOrStruct($val) {
 
384
        $keyList = array_keys($val);
 
385
                foreach ($keyList as $keyListValue) {
 
386
                        if (!is_int($keyListValue)) {
 
387
                                return 'arrayStruct';
 
388
                        }
 
389
                }
 
390
                return 'arraySimple';
 
391
        }
 
392
 
 
393
        /**
 
394
        * serializes PHP values in accordance w/ section 5. Type information is
 
395
        * not serialized if $use == 'literal'.
 
396
        *
 
397
        * @param        mixed   $val    The value to serialize
 
398
        * @param        string  $name   The name (local part) of the XML element
 
399
        * @param        string  $type   The XML schema type (local part) for the element
 
400
        * @param        string  $name_ns        The namespace for the name of the XML element
 
401
        * @param        string  $type_ns        The namespace for the type of the element
 
402
        * @param        array   $attributes     The attributes to serialize as name=>value pairs
 
403
        * @param        string  $use    The WSDL "use" (encoded|literal)
 
404
        * @param        boolean $soapval        Whether this is called from soapval.
 
405
        * @return       string  The serialized element, possibly with child elements
 
406
    * @access   public
 
407
        */
 
408
        function serialize_val($val,$name=false,$type=false,$name_ns=false,$type_ns=false,$attributes=false,$use='encoded',$soapval=false) {
 
409
                $this->debug("in serialize_val: name=$name, type=$type, name_ns=$name_ns, type_ns=$type_ns, use=$use, soapval=$soapval");
 
410
                $this->appendDebug('value=' . $this->varDump($val));
 
411
                $this->appendDebug('attributes=' . $this->varDump($attributes));
 
412
                
 
413
        if (is_object($val) && get_class($val) == 'soapval' && (! $soapval)) {
 
414
                $this->debug("serialize_val: serialize soapval");
 
415
                $xml = $val->serialize($use);
 
416
                        $this->appendDebug($val->getDebug());
 
417
                        $val->clearDebug();
 
418
                        $this->debug("serialize_val of soapval returning $xml");
 
419
                        return $xml;
 
420
        }
 
421
                // force valid name if necessary
 
422
                if (is_numeric($name)) {
 
423
                        $name = '__numeric_' . $name;
 
424
                } elseif (! $name) {
 
425
                        $name = 'noname';
 
426
                }
 
427
                // if name has ns, add ns prefix to name
 
428
                $xmlns = '';
 
429
        if($name_ns){
 
430
                        $prefix = 'nu'.rand(1000,9999);
 
431
                        $name = $prefix.':'.$name;
 
432
                        $xmlns .= " xmlns:$prefix=\"$name_ns\"";
 
433
                }
 
434
                // if type is prefixed, create type prefix
 
435
                if($type_ns != '' && $type_ns == $this->namespaces['xsd']){
 
436
                        // need to fix this. shouldn't default to xsd if no ns specified
 
437
                    // w/o checking against typemap
 
438
                        $type_prefix = 'xsd';
 
439
                } elseif($type_ns){
 
440
                        $type_prefix = 'ns'.rand(1000,9999);
 
441
                        $xmlns .= " xmlns:$type_prefix=\"$type_ns\"";
 
442
                }
 
443
                // serialize attributes if present
 
444
                $atts = '';
 
445
                if($attributes){
 
446
                        foreach($attributes as $k => $v){
 
447
                                $atts .= " $k=\"".$this->expandEntities($v).'"';
 
448
                        }
 
449
                }
 
450
                // serialize null value
 
451
                if (is_null($val)) {
 
452
                $this->debug("serialize_val: serialize null");
 
453
                        if ($use == 'literal') {
 
454
                                // TODO: depends on minOccurs
 
455
                                $xml = "<$name$xmlns$atts/>";
 
456
                                $this->debug("serialize_val returning $xml");
 
457
                        return $xml;
 
458
                } else {
 
459
                                if (isset($type) && isset($type_prefix)) {
 
460
                                        $type_str = " xsi:type=\"$type_prefix:$type\"";
 
461
                                } else {
 
462
                                        $type_str = '';
 
463
                                }
 
464
                                $xml = "<$name$xmlns$type_str$atts xsi:nil=\"true\"/>";
 
465
                                $this->debug("serialize_val returning $xml");
 
466
                        return $xml;
 
467
                }
 
468
                }
 
469
        // serialize if an xsd built-in primitive type
 
470
        if($type != '' && isset($this->typemap[$this->XMLSchemaVersion][$type])){
 
471
                $this->debug("serialize_val: serialize xsd built-in primitive type");
 
472
                if (is_bool($val)) {
 
473
                        if ($type == 'boolean') {
 
474
                                $val = $val ? 'true' : 'false';
 
475
                        } elseif (! $val) {
 
476
                                $val = 0;
 
477
                        }
 
478
                        } else if (is_string($val)) {
 
479
                                $val = $this->expandEntities($val);
 
480
                        }
 
481
                        if ($use == 'literal') {
 
482
                                $xml = "<$name$xmlns$atts>$val</$name>";
 
483
                                $this->debug("serialize_val returning $xml");
 
484
                        return $xml;
 
485
                } else {
 
486
                                $xml = "<$name$xmlns xsi:type=\"xsd:$type\"$atts>$val</$name>";
 
487
                                $this->debug("serialize_val returning $xml");
 
488
                        return $xml;
 
489
                }
 
490
        }
 
491
                // detect type and serialize
 
492
                $xml = '';
 
493
                switch(true) {
 
494
                        case (is_bool($val) || $type == 'boolean'):
 
495
                                $this->debug("serialize_val: serialize boolean");
 
496
                        if ($type == 'boolean') {
 
497
                                $val = $val ? 'true' : 'false';
 
498
                        } elseif (! $val) {
 
499
                                $val = 0;
 
500
                        }
 
501
                                if ($use == 'literal') {
 
502
                                        $xml .= "<$name$xmlns$atts>$val</$name>";
 
503
                                } else {
 
504
                                        $xml .= "<$name$xmlns xsi:type=\"xsd:boolean\"$atts>$val</$name>";
 
505
                                }
 
506
                                break;
 
507
                        case (is_int($val) || is_long($val) || $type == 'int'):
 
508
                                $this->debug("serialize_val: serialize int");
 
509
                                if ($use == 'literal') {
 
510
                                        $xml .= "<$name$xmlns$atts>$val</$name>";
 
511
                                } else {
 
512
                                        $xml .= "<$name$xmlns xsi:type=\"xsd:int\"$atts>$val</$name>";
 
513
                                }
 
514
                                break;
 
515
                        case (is_float($val)|| is_double($val) || $type == 'float'):
 
516
                                $this->debug("serialize_val: serialize float");
 
517
                                if ($use == 'literal') {
 
518
                                        $xml .= "<$name$xmlns$atts>$val</$name>";
 
519
                                } else {
 
520
                                        $xml .= "<$name$xmlns xsi:type=\"xsd:float\"$atts>$val</$name>";
 
521
                                }
 
522
                                break;
 
523
                        case (is_string($val) || $type == 'string'):
 
524
                                $this->debug("serialize_val: serialize string");
 
525
                                $val = $this->expandEntities($val);
 
526
                                if ($use == 'literal') {
 
527
                                        $xml .= "<$name$xmlns$atts>$val</$name>";
 
528
                                } else {
 
529
                                        $xml .= "<$name$xmlns xsi:type=\"xsd:string\"$atts>$val</$name>";
 
530
                                }
 
531
                                break;
 
532
                        case is_object($val):
 
533
                                $this->debug("serialize_val: serialize object");
 
534
                        if (get_class($val) == 'soapval') {
 
535
                                $this->debug("serialize_val: serialize soapval object");
 
536
                                $pXml = $val->serialize($use);
 
537
                                        $this->appendDebug($val->getDebug());
 
538
                                        $val->clearDebug();
 
539
                        } else {
 
540
                                        if (! $name) {
 
541
                                                $name = get_class($val);
 
542
                                                $this->debug("In serialize_val, used class name $name as element name");
 
543
                                        } else {
 
544
                                                $this->debug("In serialize_val, do not override name $name for element name for class " . get_class($val));
 
545
                                        }
 
546
                                        foreach(get_object_vars($val) as $k => $v){
 
547
                                                $pXml = isset($pXml) ? $pXml.$this->serialize_val($v,$k,false,false,false,false,$use) : $this->serialize_val($v,$k,false,false,false,false,$use);
 
548
                                        }
 
549
                                }
 
550
                                if(isset($type) && isset($type_prefix)){
 
551
                                        $type_str = " xsi:type=\"$type_prefix:$type\"";
 
552
                                } else {
 
553
                                        $type_str = '';
 
554
                                }
 
555
                                if ($use == 'literal') {
 
556
                                        $xml .= "<$name$xmlns$atts>$pXml</$name>";
 
557
                                } else {
 
558
                                        $xml .= "<$name$xmlns$type_str$atts>$pXml</$name>";
 
559
                                }
 
560
                                break;
 
561
                        break;
 
562
                        case (is_array($val) || $type):
 
563
                                // detect if struct or array
 
564
                                $valueType = $this->isArraySimpleOrStruct($val);
 
565
                if($valueType=='arraySimple' || ereg('^ArrayOf',$type)){
 
566
                                        $this->debug("serialize_val: serialize array");
 
567
                                        $i = 0;
 
568
                                        if(is_array($val) && count($val)> 0){
 
569
                                                foreach($val as $v){
 
570
                                if(is_object($v) && get_class($v) ==  'soapval'){
 
571
                                                                $tt_ns = $v->type_ns;
 
572
                                                                $tt = $v->type;
 
573
                                                        } elseif (is_array($v)) {
 
574
                                                                $tt = $this->isArraySimpleOrStruct($v);
 
575
                                                        } else {
 
576
                                                                $tt = gettype($v);
 
577
                                }
 
578
                                                        $array_types[$tt] = 1;
 
579
                                                        // TODO: for literal, the name should be $name
 
580
                                                        $xml .= $this->serialize_val($v,'item',false,false,false,false,$use);
 
581
                                                        ++$i;
 
582
                                                }
 
583
                                                if(count($array_types) > 1){
 
584
                                                        $array_typename = 'xsd:anyType';
 
585
                                                } elseif(isset($tt) && isset($this->typemap[$this->XMLSchemaVersion][$tt])) {
 
586
                                                        if ($tt == 'integer') {
 
587
                                                                $tt = 'int';
 
588
                                                        }
 
589
                                                        $array_typename = 'xsd:'.$tt;
 
590
                                                } elseif(isset($tt) && $tt == 'arraySimple'){
 
591
                                                        $array_typename = 'SOAP-ENC:Array';
 
592
                                                } elseif(isset($tt) && $tt == 'arrayStruct'){
 
593
                                                        $array_typename = 'unnamed_struct_use_soapval';
 
594
                                                } else {
 
595
                                                        // if type is prefixed, create type prefix
 
596
                                                        if ($tt_ns != '' && $tt_ns == $this->namespaces['xsd']){
 
597
                                                                 $array_typename = 'xsd:' . $tt;
 
598
                                                        } elseif ($tt_ns) {
 
599
                                                                $tt_prefix = 'ns' . rand(1000, 9999);
 
600
                                                                $array_typename = "$tt_prefix:$tt";
 
601
                                                                $xmlns .= " xmlns:$tt_prefix=\"$tt_ns\"";
 
602
                                                        } else {
 
603
                                                                $array_typename = $tt;
 
604
                                                        }
 
605
                                                }
 
606
                                                $array_type = $i;
 
607
                                                if ($use == 'literal') {
 
608
                                                        $type_str = '';
 
609
                                                } else if (isset($type) && isset($type_prefix)) {
 
610
                                                        $type_str = " xsi:type=\"$type_prefix:$type\"";
 
611
                                                } else {
 
612
                                                        $type_str = " xsi:type=\"SOAP-ENC:Array\" SOAP-ENC:arrayType=\"".$array_typename."[$array_type]\"";
 
613
                                                }
 
614
                                        // empty array
 
615
                                        } else {
 
616
                                                if ($use == 'literal') {
 
617
                                                        $type_str = '';
 
618
                                                } else if (isset($type) && isset($type_prefix)) {
 
619
                                                        $type_str = " xsi:type=\"$type_prefix:$type\"";
 
620
                                                } else {
 
621
                                                        $type_str = " xsi:type=\"SOAP-ENC:Array\" SOAP-ENC:arrayType=\"xsd:anyType[0]\"";
 
622
                                                }
 
623
                                        }
 
624
                                        // TODO: for array in literal, there is no wrapper here
 
625
                                        $xml = "<$name$xmlns$type_str$atts>".$xml."</$name>";
 
626
                                } else {
 
627
                                        // got a struct
 
628
                                        $this->debug("serialize_val: serialize struct");
 
629
                                        if(isset($type) && isset($type_prefix)){
 
630
                                                $type_str = " xsi:type=\"$type_prefix:$type\"";
 
631
                                        } else {
 
632
                                                $type_str = '';
 
633
                                        }
 
634
                                        if ($use == 'literal') {
 
635
                                                $xml .= "<$name$xmlns$atts>";
 
636
                                        } else {
 
637
                                                $xml .= "<$name$xmlns$type_str$atts>";
 
638
                                        }
 
639
                                        foreach($val as $k => $v){
 
640
                                                // Apache Map
 
641
                                                if ($type == 'Map' && $type_ns == 'http://xml.apache.org/xml-soap') {
 
642
                                                        $xml .= '<item>';
 
643
                                                        $xml .= $this->serialize_val($k,'key',false,false,false,false,$use);
 
644
                                                        $xml .= $this->serialize_val($v,'value',false,false,false,false,$use);
 
645
                                                        $xml .= '</item>';
 
646
                                                } else {
 
647
                                                        $xml .= $this->serialize_val($v,$k,false,false,false,false,$use);
 
648
                                                }
 
649
                                        }
 
650
                                        $xml .= "</$name>";
 
651
                                }
 
652
                                break;
 
653
                        default:
 
654
                                $this->debug("serialize_val: serialize unknown");
 
655
                                $xml .= 'not detected, got '.gettype($val).' for '.$val;
 
656
                                break;
 
657
                }
 
658
                $this->debug("serialize_val returning $xml");
 
659
                return $xml;
 
660
        }
 
661
 
 
662
    /**
 
663
    * serializes a message
 
664
    *
 
665
    * @param string $body the XML of the SOAP body
 
666
    * @param mixed $headers optional string of XML with SOAP header content, or array of soapval objects for SOAP headers, or associative array
 
667
    * @param array $namespaces optional the namespaces used in generating the body and headers
 
668
    * @param string $style optional (rpc|document)
 
669
    * @param string $use optional (encoded|literal)
 
670
    * @param string $encodingStyle optional (usually 'http://schemas.xmlsoap.org/soap/encoding/' for encoded)
 
671
    * @return string the message
 
672
    * @access public
 
673
    */
 
674
    function serializeEnvelope($body,$headers=false,$namespaces=array(),$style='rpc',$use='encoded',$encodingStyle='http://schemas.xmlsoap.org/soap/encoding/'){
 
675
    // TODO: add an option to automatically run utf8_encode on $body and $headers
 
676
    // if $this->soap_defencoding is UTF-8.  Not doing this automatically allows
 
677
    // one to send arbitrary UTF-8 characters, not just characters that map to ISO-8859-1
 
678
 
 
679
        $this->debug("In serializeEnvelope length=" . strlen($body) . " body (max 1000 characters)=" . substr($body, 0, 1000) . " style=$style use=$use encodingStyle=$encodingStyle");
 
680
        $this->debug("headers:");
 
681
        $this->appendDebug($this->varDump($headers));
 
682
        $this->debug("namespaces:");
 
683
        $this->appendDebug($this->varDump($namespaces));
 
684
 
 
685
        // serialize namespaces
 
686
    $ns_string = '';
 
687
        foreach(array_merge($this->namespaces,$namespaces) as $k => $v){
 
688
                $ns_string .= " xmlns:$k=\"$v\"";
 
689
        }
 
690
        if($encodingStyle) {
 
691
                $ns_string = " SOAP-ENV:encodingStyle=\"$encodingStyle\"$ns_string";
 
692
        }
 
693
 
 
694
        // serialize headers
 
695
        if($headers){
 
696
                if (is_array($headers)) {
 
697
                        $xml = '';
 
698
                        foreach ($headers as $k => $v) {
 
699
                                if (is_object($v) && get_class($v) == 'soapval') {
 
700
                                        $xml .= $this->serialize_val($v, false, false, false, false, false, $use);
 
701
                                } else {
 
702
                                        $xml .= $this->serialize_val($v, $k, false, false, false, false, $use);
 
703
                                }
 
704
                        }
 
705
                        $headers = $xml;
 
706
                        $this->debug("In serializeEnvelope, serialized array of headers to $headers");
 
707
                }
 
708
                $headers = "<SOAP-ENV:Header>".$headers."</SOAP-ENV:Header>";
 
709
        }
 
710
        // serialize envelope
 
711
        return
 
712
        '<?xml version="1.0" encoding="'.$this->soap_defencoding .'"?'.">".
 
713
        '<SOAP-ENV:Envelope'.$ns_string.">".
 
714
        $headers.
 
715
        "<SOAP-ENV:Body>".
 
716
                $body.
 
717
        "</SOAP-ENV:Body>".
 
718
        "</SOAP-ENV:Envelope>";
 
719
    }
 
720
 
 
721
        /**
 
722
         * formats a string to be inserted into an HTML stream
 
723
         *
 
724
         * @param string $str The string to format
 
725
         * @return string The formatted string
 
726
         * @access public
 
727
         * @deprecated
 
728
         */
 
729
    function formatDump($str){
 
730
                $str = htmlspecialchars($str);
 
731
                return nl2br($str);
 
732
    }
 
733
 
 
734
        /**
 
735
        * contracts (changes namespace to prefix) a qualified name
 
736
        *
 
737
        * @param    string $qname qname
 
738
        * @return       string contracted qname
 
739
        * @access   private
 
740
        */
 
741
        function contractQname($qname){
 
742
                // get element namespace
 
743
                //$this->xdebug("Contract $qname");
 
744
                if (strrpos($qname, ':')) {
 
745
                        // get unqualified name
 
746
                        $name = substr($qname, strrpos($qname, ':') + 1);
 
747
                        // get ns
 
748
                        $ns = substr($qname, 0, strrpos($qname, ':'));
 
749
                        $p = $this->getPrefixFromNamespace($ns);
 
750
                        if ($p) {
 
751
                                return $p . ':' . $name;
 
752
                        }
 
753
                        return $qname;
 
754
                } else {
 
755
                        return $qname;
 
756
                }
 
757
        }
 
758
 
 
759
        /**
 
760
        * expands (changes prefix to namespace) a qualified name
 
761
        *
 
762
        * @param    string $qname qname
 
763
        * @return       string expanded qname
 
764
        * @access   private
 
765
        */
 
766
        function expandQname($qname){
 
767
                // get element prefix
 
768
                if(strpos($qname,':') && !ereg('^http://',$qname)){
 
769
                        // get unqualified name
 
770
                        $name = substr(strstr($qname,':'),1);
 
771
                        // get ns prefix
 
772
                        $prefix = substr($qname,0,strpos($qname,':'));
 
773
                        if(isset($this->namespaces[$prefix])){
 
774
                                return $this->namespaces[$prefix].':'.$name;
 
775
                        } else {
 
776
                                return $qname;
 
777
                        }
 
778
                } else {
 
779
                        return $qname;
 
780
                }
 
781
        }
 
782
 
 
783
    /**
 
784
    * returns the local part of a prefixed string
 
785
    * returns the original string, if not prefixed
 
786
    *
 
787
    * @param string $str The prefixed string
 
788
    * @return string The local part
 
789
    * @access public
 
790
    */
 
791
        function getLocalPart($str){
 
792
                if($sstr = strrchr($str,':')){
 
793
                        // get unqualified name
 
794
                        return substr( $sstr, 1 );
 
795
                } else {
 
796
                        return $str;
 
797
                }
 
798
        }
 
799
 
 
800
        /**
 
801
    * returns the prefix part of a prefixed string
 
802
    * returns false, if not prefixed
 
803
    *
 
804
    * @param string $str The prefixed string
 
805
    * @return mixed The prefix or false if there is no prefix
 
806
    * @access public
 
807
    */
 
808
        function getPrefix($str){
 
809
                if($pos = strrpos($str,':')){
 
810
                        // get prefix
 
811
                        return substr($str,0,$pos);
 
812
                }
 
813
                return false;
 
814
        }
 
815
 
 
816
        /**
 
817
    * pass it a prefix, it returns a namespace
 
818
    *
 
819
    * @param string $prefix The prefix
 
820
    * @return mixed The namespace, false if no namespace has the specified prefix
 
821
    * @access public
 
822
    */
 
823
        function getNamespaceFromPrefix($prefix){
 
824
                if (isset($this->namespaces[$prefix])) {
 
825
                        return $this->namespaces[$prefix];
 
826
                }
 
827
                //$this->setError("No namespace registered for prefix '$prefix'");
 
828
                return false;
 
829
        }
 
830
 
 
831
        /**
 
832
    * returns the prefix for a given namespace (or prefix)
 
833
    * or false if no prefixes registered for the given namespace
 
834
    *
 
835
    * @param string $ns The namespace
 
836
    * @return mixed The prefix, false if the namespace has no prefixes
 
837
    * @access public
 
838
    */
 
839
        function getPrefixFromNamespace($ns) {
 
840
                foreach ($this->namespaces as $p => $n) {
 
841
                        if ($ns == $n || $ns == $p) {
 
842
                            $this->usedNamespaces[$p] = $n;
 
843
                                return $p;
 
844
                        }
 
845
                }
 
846
                return false;
 
847
        }
 
848
 
 
849
        /**
 
850
    * returns the time in ODBC canonical form with microseconds
 
851
    *
 
852
    * @return string The time in ODBC canonical form with microseconds
 
853
    * @access public
 
854
    */
 
855
        function getmicrotime() {
 
856
                if (function_exists('gettimeofday')) {
 
857
                        $tod = gettimeofday();
 
858
                        $sec = $tod['sec'];
 
859
                        $usec = $tod['usec'];
 
860
                } else {
 
861
                        $sec = time();
 
862
                        $usec = 0;
 
863
                }
 
864
                return strftime('%Y-%m-%d %H:%M:%S', $sec) . '.' . sprintf('%06d', $usec);
 
865
        }
 
866
 
 
867
        /**
 
868
         * Returns a string with the output of var_dump
 
869
         *
 
870
         * @param mixed $data The variable to var_dump
 
871
         * @return string The output of var_dump
 
872
         * @access public
 
873
         */
 
874
    function varDump($data) {
 
875
                ob_start();
 
876
                var_dump($data);
 
877
                $ret_val = ob_get_contents();
 
878
                ob_end_clean();
 
879
                return $ret_val;
 
880
        }
 
881
 
 
882
        /**
 
883
        * represents the object as a string
 
884
        *
 
885
        * @return       string
 
886
        * @access   public
 
887
        */
 
888
        function __toString() {
 
889
                return $this->varDump($this);
 
890
        }
 
891
}
 
892
 
 
893
// XML Schema Datatype Helper Functions
 
894
 
 
895
//xsd:dateTime helpers
 
896
 
 
897
/**
 
898
* convert unix timestamp to ISO 8601 compliant date string
 
899
*
 
900
* @param    string $timestamp Unix time stamp
 
901
* @param        boolean $utc Whether the time stamp is UTC or local
 
902
* @access   public
 
903
*/
 
904
function timestamp_to_iso8601($timestamp,$utc=true){
 
905
        $datestr = date('Y-m-d\TH:i:sO',$timestamp);
 
906
        if($utc){
 
907
                $eregStr =
 
908
                '([0-9]{4})-'.  // centuries & years CCYY-
 
909
                '([0-9]{2})-'.  // months MM-
 
910
                '([0-9]{2})'.   // days DD
 
911
                'T'.                    // separator T
 
912
                '([0-9]{2}):'.  // hours hh:
 
913
                '([0-9]{2}):'.  // minutes mm:
 
914
                '([0-9]{2})(\.[0-9]*)?'. // seconds ss.ss...
 
915
                '(Z|[+\-][0-9]{2}:?[0-9]{2})?'; // Z to indicate UTC, -/+HH:MM:SS.SS... for local tz's
 
916
 
 
917
                if(ereg($eregStr,$datestr,$regs)){
 
918
                        return sprintf('%04d-%02d-%02dT%02d:%02d:%02dZ',$regs[1],$regs[2],$regs[3],$regs[4],$regs[5],$regs[6]);
 
919
                }
 
920
                return false;
 
921
        } else {
 
922
                return $datestr;
 
923
        }
 
924
}
 
925
 
 
926
/**
 
927
* convert ISO 8601 compliant date string to unix timestamp
 
928
*
 
929
* @param    string $datestr ISO 8601 compliant date string
 
930
* @access   public
 
931
*/
 
932
function iso8601_to_timestamp($datestr){
 
933
        $eregStr =
 
934
        '([0-9]{4})-'.  // centuries & years CCYY-
 
935
        '([0-9]{2})-'.  // months MM-
 
936
        '([0-9]{2})'.   // days DD
 
937
        'T'.                    // separator T
 
938
        '([0-9]{2}):'.  // hours hh:
 
939
        '([0-9]{2}):'.  // minutes mm:
 
940
        '([0-9]{2})(\.[0-9]+)?'. // seconds ss.ss...
 
941
        '(Z|[+\-][0-9]{2}:?[0-9]{2})?'; // Z to indicate UTC, -/+HH:MM:SS.SS... for local tz's
 
942
        if(ereg($eregStr,$datestr,$regs)){
 
943
                // not utc
 
944
                if($regs[8] != 'Z'){
 
945
                        $op = substr($regs[8],0,1);
 
946
                        $h = substr($regs[8],1,2);
 
947
                        $m = substr($regs[8],strlen($regs[8])-2,2);
 
948
                        if($op == '-'){
 
949
                                $regs[4] = $regs[4] + $h;
 
950
                                $regs[5] = $regs[5] + $m;
 
951
                        } elseif($op == '+'){
 
952
                                $regs[4] = $regs[4] - $h;
 
953
                                $regs[5] = $regs[5] - $m;
 
954
                        }
 
955
                }
 
956
                return gmmktime($regs[4], $regs[5], $regs[6], $regs[2], $regs[3], $regs[1]);
 
957
//              return strtotime("$regs[1]-$regs[2]-$regs[3] $regs[4]:$regs[5]:$regs[6]Z");
 
958
        } else {
 
959
                return false;
 
960
        }
 
961
}
 
962
 
 
963
/**
 
964
* sleeps some number of microseconds
 
965
*
 
966
* @param    string $usec the number of microseconds to sleep
 
967
* @access   public
 
968
* @deprecated
 
969
*/
 
970
function usleepWindows($usec)
 
971
{
 
972
        $start = gettimeofday();
 
973
        
 
974
        do
 
975
        {
 
976
                $stop = gettimeofday();
 
977
                $timePassed = 1000000 * ($stop['sec'] - $start['sec'])
 
978
                + $stop['usec'] - $start['usec'];
 
979
        }
 
980
        while ($timePassed < $usec);
 
981
}
 
982
 
 
983
 
 
984
?>
 
 
b'\\ No newline at end of file'