source: pro-violet-viettel/sourcecode/application/libraries/nusoap/class.nusoap_base.php @ 789

Last change on this file since 789 was 419, checked in by dungnv, 11 years ago
File size: 29.5 KB
Line 
1<?php
2
3/*
4$Id: class.nusoap_base.php,v 1.56 2010/04/26 20:15:08 snichol Exp $
5
6NuSOAP - Web Services Toolkit for PHP
7
8Copyright (c) 2002 NuSphere Corporation
9
10This library is free software; you can redistribute it and/or
11modify it under the terms of the GNU Lesser General Public
12License as published by the Free Software Foundation; either
13version 2.1 of the License, or (at your option) any later version.
14
15This library is distributed in the hope that it will be useful,
16but WITHOUT ANY WARRANTY; without even the implied warranty of
17MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
18Lesser General Public License for more details.
19
20You should have received a copy of the GNU Lesser General Public
21License along with this library; if not, write to the Free Software
22Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
23
24The NuSOAP project home is:
25http://sourceforge.net/projects/nusoap/
26
27The primary support for NuSOAP is the Help forum on the project home page.
28
29If you have any questions or comments, please email:
30
31Dietrich Ayala
32dietrich@ganx4.com
33http://dietrich.ganx4.com/nusoap
34
35NuSphere Corporation
36http://www.nusphere.com
37
38*/
39
40/*
41 *      Some of the standards implmented in whole or part by NuSOAP:
42 *
43 *      SOAP 1.1 (http://www.w3.org/TR/2000/NOTE-SOAP-20000508/)
44 *      WSDL 1.1 (http://www.w3.org/TR/2001/NOTE-wsdl-20010315)
45 *      SOAP Messages With Attachments (http://www.w3.org/TR/SOAP-attachments)
46 *      XML 1.0 (http://www.w3.org/TR/2006/REC-xml-20060816/)
47 *      Namespaces in XML 1.0 (http://www.w3.org/TR/2006/REC-xml-names-20060816/)
48 *      XML Schema 1.0 (http://www.w3.org/TR/xmlschema-0/)
49 *      RFC 2045 Multipurpose Internet Mail Extensions (MIME) Part One: Format of Internet Message Bodies
50 *      RFC 2068 Hypertext Transfer Protocol -- HTTP/1.1
51 *      RFC 2617 HTTP Authentication: Basic and Digest Access Authentication
52 */
53
54/* load classes
55
56// necessary classes
57require_once('class.soapclient.php');
58require_once('class.soap_val.php');
59require_once('class.soap_parser.php');
60require_once('class.soap_fault.php');
61
62// transport classes
63require_once('class.soap_transport_http.php');
64
65// optional add-on classes
66require_once('class.xmlschema.php');
67require_once('class.wsdl.php');
68
69// server class
70require_once('class.soap_server.php');*/
71
72// class variable emulation
73// cf. http://www.webkreator.com/php/techniques/php-static-class-variables.html
74$GLOBALS['_transient']['static']['nusoap_base']['globalDebugLevel'] = 9;
75
76/**
77*
78* nusoap_base
79*
80* @author   Dietrich Ayala <dietrich@ganx4.com>
81* @author   Scott Nichol <snichol@users.sourceforge.net>
82* @version  $Id: class.nusoap_base.php,v 1.56 2010/04/26 20:15:08 snichol Exp $
83* @access   public
84*/
85class nusoap_base {
86        /**
87         * Identification for HTTP headers.
88         *
89         * @var string
90         * @access private
91         */
92        var $title = 'NuSOAP';
93        /**
94         * Version for HTTP headers.
95         *
96         * @var string
97         * @access private
98         */
99        var $version = '0.9.5';
100        /**
101         * CVS revision for HTTP headers.
102         *
103         * @var string
104         * @access private
105         */
106        var $revision = '$Revision: 1.56 $';
107    /**
108     * Current error string (manipulated by getError/setError)
109         *
110         * @var string
111         * @access private
112         */
113        var $error_str = '';
114    /**
115     * Current debug string (manipulated by debug/appendDebug/clearDebug/getDebug/getDebugAsXMLComment)
116         *
117         * @var string
118         * @access private
119         */
120    var $debug_str = '';
121    /**
122         * toggles automatic encoding of special characters as entities
123         * (should always be true, I think)
124         *
125         * @var boolean
126         * @access private
127         */
128        var $charencoding = true;
129        /**
130         * the debug level for this instance
131         *
132         * @var integer
133         * @access private
134         */
135        var $debugLevel;
136
137    /**
138        * set schema version
139        *
140        * @var      string
141        * @access   public
142        */
143        var $XMLSchemaVersion = 'http://www.w3.org/2001/XMLSchema';
144       
145    /**
146        * charset encoding for outgoing messages
147        *
148        * @var      string
149        * @access   public
150        */
151    var $soap_defencoding = 'ISO-8859-1';
152        //var $soap_defencoding = 'UTF-8';
153
154        /**
155        * namespaces in an array of prefix => uri
156        *
157        * this is "seeded" by a set of constants, but it may be altered by code
158        *
159        * @var      array
160        * @access   public
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        * namespaces used in the current context, e.g. during serialization
171        *
172        * @var      array
173        * @access   private
174        */
175        var $usedNamespaces = array();
176
177        /**
178        * XML Schema types in an array of uri => (array of xml type => php type)
179        * is this legacy yet?
180        * no, this is used by the nusoap_xmlschema class to verify type => namespace mappings.
181        * @var      array
182        * @access   public
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                // abstract "any" types
190                'anyType'=>'string','anySimpleType'=>'string',
191                // derived datatypes
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        * XML entities to convert
211        *
212        * @var      array
213        * @access   public
214        * @deprecated
215        * @see  expandEntities
216        */
217        var $xmlEntities = array('quot' => '"','amp' => '&',
218                'lt' => '<','gt' => '>','apos' => "'");
219
220        /**
221        * constructor
222        *
223        * @access       public
224        */
225        function nusoap_base() {
226                $this->debugLevel = $GLOBALS['_transient']['static']['nusoap_base']['globalDebugLevel'];
227        }
228
229        /**
230        * gets the global debug level, which applies to future instances
231        *
232        * @return       integer Debug level 0-9, where 0 turns off
233        * @access       public
234        */
235        function getGlobalDebugLevel() {
236                return $GLOBALS['_transient']['static']['nusoap_base']['globalDebugLevel'];
237        }
238
239        /**
240        * sets the global debug level, which applies to future instances
241        *
242        * @param        int     $level  Debug level 0-9, where 0 turns off
243        * @access       public
244        */
245        function setGlobalDebugLevel($level) {
246                $GLOBALS['_transient']['static']['nusoap_base']['globalDebugLevel'] = $level;
247        }
248
249        /**
250        * gets the debug level for this instance
251        *
252        * @return       int     Debug level 0-9, where 0 turns off
253        * @access       public
254        */
255        function getDebugLevel() {
256                return $this->debugLevel;
257        }
258
259        /**
260        * sets the debug level for this instance
261        *
262        * @param        int     $level  Debug level 0-9, where 0 turns off
263        * @access       public
264        */
265        function setDebugLevel($level) {
266                $this->debugLevel = $level;
267        }
268
269        /**
270        * adds debug data to the instance debug string with formatting
271        *
272        * @param    string $string debug data
273        * @access   private
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        * adds debug data to the instance debug string without formatting
283        *
284        * @param    string $string debug data
285        * @access   public
286        */
287        function appendDebug($string){
288                if ($this->debugLevel > 0) {
289                        // it would be nice to use a memory stream here to use
290                        // memory more efficiently
291                        $this->debug_str .= $string;
292                }
293        }
294
295        /**
296        * clears the current debug data for this instance
297        *
298        * @access   public
299        */
300        function clearDebug() {
301                // it would be nice to use a memory stream here to use
302                // memory more efficiently
303                $this->debug_str = '';
304        }
305
306        /**
307        * gets the current debug data for this instance
308        *
309        * @return   debug data
310        * @access   public
311        */
312        function &getDebug() {
313                // it would be nice to use a memory stream here to use
314                // memory more efficiently
315                return $this->debug_str;
316        }
317
318        /**
319        * gets the current debug data for this instance as an XML comment
320        * this may change the contents of the debug data
321        *
322        * @return   debug data as an XML comment
323        * @access   public
324        */
325        function &getDebugAsXMLComment() {
326                // it would be nice to use a memory stream here to use
327                // memory more efficiently
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        * expands entities, e.g. changes '<' to '&lt;'.
337        *
338        * @param        string  $val    The string in which to expand entities.
339        * @access       private
340        */
341        function expandEntities($val) {
342                if ($this->charencoding) {
343                $val = str_replace('&', '&amp;', $val);
344                $val = str_replace("'", '&apos;', $val);
345                $val = str_replace('"', '&quot;', $val);
346                $val = str_replace('<', '&lt;', $val);
347                $val = str_replace('>', '&gt;', $val);
348            }
349            return $val;
350        }
351
352        /**
353        * returns error string if present
354        *
355        * @return   mixed error string or false
356        * @access   public
357        */
358        function getError(){
359                if($this->error_str != ''){
360                        return $this->error_str;
361                }
362                return false;
363        }
364
365        /**
366        * sets error string
367        *
368        * @return   boolean $string error string
369        * @access   private
370        */
371        function setError($str){
372                $this->error_str = $str;
373        }
374
375        /**
376        * detect if array is a simple array or a struct (associative array)
377        *
378        * @param        mixed   $val    The PHP array
379        * @return       string  (arraySimple|arrayStruct)
380        * @access       private
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        * serializes PHP values in accordance w/ section 5. Type information is
394        * not serialized if $use == 'literal'.
395        *
396        * @param        mixed   $val    The value to serialize
397        * @param        string  $name   The name (local part) of the XML element
398        * @param        string  $type   The XML schema type (local part) for the element
399        * @param        string  $name_ns        The namespace for the name of the XML element
400        * @param        string  $type_ns        The namespace for the type of the element
401        * @param        array   $attributes     The attributes to serialize as name=>value pairs
402        * @param        string  $use    The WSDL "use" (encoded|literal)
403        * @param        boolean $soapval        Whether this is called from soapval.
404        * @return       string  The serialized element, possibly with child elements
405    * @access   public
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                // force valid name if necessary
421                if (is_numeric($name)) {
422                        $name = '__numeric_' . $name;
423                } elseif (! $name) {
424                        $name = 'noname';
425                }
426                // if name has ns, add ns prefix to name
427                $xmlns = '';
428        if($name_ns){
429                        $prefix = 'nu'.rand(1000,9999);
430                        $name = $prefix.':'.$name;
431                        $xmlns .= " xmlns:$prefix=\"$name_ns\"";
432                }
433                // if type is prefixed, create type prefix
434                if($type_ns != '' && $type_ns == $this->namespaces['xsd']){
435                        // need to fix this. shouldn't default to xsd if no ns specified
436                    // w/o checking against typemap
437                        $type_prefix = 'xsd';
438                } elseif($type_ns){
439                        $type_prefix = 'ns'.rand(1000,9999);
440                        $xmlns .= " xmlns:$type_prefix=\"$type_ns\"";
441                }
442                // serialize attributes if present
443                $atts = '';
444                if($attributes){
445                        foreach($attributes as $k => $v){
446                                $atts .= " $k=\"".$this->expandEntities($v).'"';
447                        }
448                }
449                // serialize null value
450                if (is_null($val)) {
451                $this->debug("serialize_val: serialize null");
452                        if ($use == 'literal') {
453                                // TODO: depends on minOccurs
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        // serialize if an xsd built-in primitive type
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                // detect type and serialize
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                                // detect if struct or array
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                                                        // TODO: for literal, the name should be $name
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                                                        // if type is prefixed, create type prefix
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                                        // empty array
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                                        // TODO: for array in literal, there is no wrapper here
624                                        $xml = "<$name$xmlns$type_str$atts>".$xml."</$name>";
625                                } else {
626                                        // got a struct
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                                                // Apache Map
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    * serializes a message
663    *
664    * @param string $body the XML of the SOAP body
665    * @param mixed $headers optional string of XML with SOAP header content, or array of soapval objects for SOAP headers, or associative array
666    * @param array $namespaces optional the namespaces used in generating the body and headers
667    * @param string $style optional (rpc|document)
668    * @param string $use optional (encoded|literal)
669    * @param string $encodingStyle optional (usually 'http://schemas.xmlsoap.org/soap/encoding/' for encoded)
670    * @return string the message
671    * @access public
672    */
673    function serializeEnvelope($body,$headers=false,$namespaces=array(),$style='rpc',$use='encoded',$encodingStyle='http://schemas.xmlsoap.org/soap/encoding/'){
674    // TODO: add an option to automatically run utf8_encode on $body and $headers
675    // if $this->soap_defencoding is UTF-8.  Not doing this automatically allows
676    // one to send arbitrary UTF-8 characters, not just characters that map to ISO-8859-1
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        // serialize namespaces
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        // serialize headers
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        // serialize envelope
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         * formats a string to be inserted into an HTML stream
722         *
723         * @param string $str The string to format
724         * @return string The formatted string
725         * @access public
726         * @deprecated
727         */
728    function formatDump($str){
729                $str = htmlspecialchars($str);
730                return nl2br($str);
731    }
732
733        /**
734        * contracts (changes namespace to prefix) a qualified name
735        *
736        * @param    string $qname qname
737        * @return       string contracted qname
738        * @access   private
739        */
740        function contractQname($qname){
741                // get element namespace
742                //$this->xdebug("Contract $qname");
743                if (strrpos($qname, ':')) {
744                        // get unqualified name
745                        $name = substr($qname, strrpos($qname, ':') + 1);
746                        // get ns
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        * expands (changes prefix to namespace) a qualified name
760        *
761        * @param    string $qname qname
762        * @return       string expanded qname
763        * @access   private
764        */
765        function expandQname($qname){
766                // get element prefix
767                if(strpos($qname,':') && !preg_match('/^http:\/\//',$qname)){
768                        // get unqualified name
769                        $name = substr(strstr($qname,':'),1);
770                        // get ns prefix
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    * returns the local part of a prefixed string
784    * returns the original string, if not prefixed
785    *
786    * @param string $str The prefixed string
787    * @return string The local part
788    * @access public
789    */
790        function getLocalPart($str){
791                if($sstr = strrchr($str,':')){
792                        // get unqualified name
793                        return substr( $sstr, 1 );
794                } else {
795                        return $str;
796                }
797        }
798
799        /**
800    * returns the prefix part of a prefixed string
801    * returns false, if not prefixed
802    *
803    * @param string $str The prefixed string
804    * @return mixed The prefix or false if there is no prefix
805    * @access public
806    */
807        function getPrefix($str){
808                if($pos = strrpos($str,':')){
809                        // get prefix
810                        return substr($str,0,$pos);
811                }
812                return false;
813        }
814
815        /**
816    * pass it a prefix, it returns a namespace
817    *
818    * @param string $prefix The prefix
819    * @return mixed The namespace, false if no namespace has the specified prefix
820    * @access public
821    */
822        function getNamespaceFromPrefix($prefix){
823                if (isset($this->namespaces[$prefix])) {
824                        return $this->namespaces[$prefix];
825                }
826                //$this->setError("No namespace registered for prefix '$prefix'");
827                return false;
828        }
829
830        /**
831    * returns the prefix for a given namespace (or prefix)
832    * or false if no prefixes registered for the given namespace
833    *
834    * @param string $ns The namespace
835    * @return mixed The prefix, false if the namespace has no prefixes
836    * @access public
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    * returns the time in ODBC canonical form with microseconds
850    *
851    * @return string The time in ODBC canonical form with microseconds
852    * @access public
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         * Returns a string with the output of var_dump
868         *
869         * @param mixed $data The variable to var_dump
870         * @return string The output of var_dump
871         * @access public
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        * represents the object as a string
883        *
884        * @return       string
885        * @access   public
886        */
887        function __toString() {
888                return $this->varDump($this);
889        }
890}
891
892// XML Schema Datatype Helper Functions
893
894//xsd:dateTime helpers
895
896/**
897* convert unix timestamp to ISO 8601 compliant date string
898*
899* @param    int $timestamp Unix time stamp
900* @param        boolean $utc Whether the time stamp is UTC or local
901* @return       mixed ISO 8601 date string or false
902* @access   public
903*/
904function 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})-'.  // centuries & years CCYY-
918                '([0-9]{2})-'.  // months MM-
919                '([0-9]{2})'.   // days DD
920                'T'.                    // separator T
921                '([0-9]{2}):'.  // hours hh:
922                '([0-9]{2}):'.  // minutes mm:
923                '([0-9]{2})(\.[0-9]*)?'. // seconds ss.ss...
924                '(Z|[+\-][0-9]{2}:?[0-9]{2})?'. // Z to indicate UTC, -/+HH:MM:SS.SS... for local tz's
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* convert ISO 8601 compliant date string to unix timestamp
938*
939* @param    string $datestr ISO 8601 compliant date string
940* @return       mixed Unix timestamp (int) or false
941* @access   public
942*/
943function iso8601_to_timestamp($datestr){
944        $pattern = '/'.
945        '([0-9]{4})-'.  // centuries & years CCYY-
946        '([0-9]{2})-'.  // months MM-
947        '([0-9]{2})'.   // days DD
948        'T'.                    // separator T
949        '([0-9]{2}):'.  // hours hh:
950        '([0-9]{2}):'.  // minutes mm:
951        '([0-9]{2})(\.[0-9]+)?'. // seconds ss.ss...
952        '(Z|[+\-][0-9]{2}:?[0-9]{2})?'. // Z to indicate UTC, -/+HH:MM:SS.SS... for local tz's
953        '/';
954        if(preg_match($pattern,$datestr,$regs)){
955                // not utc
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//              return strtotime("$regs[1]-$regs[2]-$regs[3] $regs[4]:$regs[5]:$regs[6]Z");
970        } else {
971                return false;
972        }
973}
974
975/**
976* sleeps some number of microseconds
977*
978* @param    string $usec the number of microseconds to sleep
979* @access   public
980* @deprecated
981*/
982function 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
996?>
Note: See TracBrowser for help on using the repository browser.