~alexharrington/xibo/pyclient-1.1.0a22

« back to all changes in this revision

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

  • Committer: Dan Garner
  • Date: 2008-12-14 14:42:52 UTC
  • mto: (1.1.80 Xibo)
  • mto: This revision was merged to the branch mainline in revision 2.
  • Revision ID: mail@dangarner.co.uk-20081214144252-8dosaegtfwvv0dsl
Moved 3rd Party libraries to their own folder.
Updated jQuery to the latest revision and now use jQuery UI instead of individual plugins.

Tabs are not currently working

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
<?php
2
 
 
3
 
 
4
 
 
5
 
 
6
 
/**
7
 
* parses a WSDL file, allows access to it's data, other utility methods.
8
 
* also builds WSDL structures programmatically.
9
 
10
 
* @author   Dietrich Ayala <dietrich@ganx4.com>
11
 
* @author   Scott Nichol <snichol@users.sourceforge.net>
12
 
* @version  $Id: class.wsdl.php,v 1.69 2007/11/06 15:17:46 snichol Exp $
13
 
* @access public 
14
 
*/
15
 
class wsdl extends nusoap_base {
16
 
        // URL or filename of the root of this WSDL
17
 
    var $wsdl; 
18
 
    // define internal arrays of bindings, ports, operations, messages, etc.
19
 
    var $schemas = array();
20
 
    var $currentSchema;
21
 
    var $message = array();
22
 
    var $complexTypes = array();
23
 
    var $messages = array();
24
 
    var $currentMessage;
25
 
    var $currentOperation;
26
 
    var $portTypes = array();
27
 
    var $currentPortType;
28
 
    var $bindings = array();
29
 
    var $currentBinding;
30
 
    var $ports = array();
31
 
    var $currentPort;
32
 
    var $opData = array();
33
 
    var $status = '';
34
 
    var $documentation = false;
35
 
    var $endpoint = ''; 
36
 
    // array of wsdl docs to import
37
 
    var $import = array(); 
38
 
    // parser vars
39
 
    var $parser;
40
 
    var $position = 0;
41
 
    var $depth = 0;
42
 
    var $depth_array = array();
43
 
        // for getting wsdl
44
 
        var $proxyhost = '';
45
 
    var $proxyport = '';
46
 
        var $proxyusername = '';
47
 
        var $proxypassword = '';
48
 
        var $timeout = 0;
49
 
        var $response_timeout = 30;
50
 
        var $curl_options = array();    // User-specified cURL options
51
 
        var $use_curl = false;                  // whether to always try to use cURL
52
 
        // for HTTP authentication
53
 
        var $username = '';                             // Username for HTTP authentication
54
 
        var $password = '';                             // Password for HTTP authentication
55
 
        var $authtype = '';                             // Type of HTTP authentication
56
 
        var $certRequest = array();             // Certificate for HTTP SSL authentication
57
 
 
58
 
    /**
59
 
     * constructor
60
 
     * 
61
 
     * @param string $wsdl WSDL document URL
62
 
         * @param string $proxyhost
63
 
         * @param string $proxyport
64
 
         * @param string $proxyusername
65
 
         * @param string $proxypassword
66
 
         * @param integer $timeout set the connection timeout
67
 
         * @param integer $response_timeout set the response timeout
68
 
         * @param array $curl_options user-specified cURL options
69
 
         * @param boolean $use_curl try to use cURL
70
 
     * @access public 
71
 
     */
72
 
    function wsdl($wsdl = '',$proxyhost=false,$proxyport=false,$proxyusername=false,$proxypassword=false,$timeout=0,$response_timeout=30,$curl_options=null,$use_curl=false){
73
 
                parent::nusoap_base();
74
 
                $this->debug("ctor wsdl=$wsdl timeout=$timeout response_timeout=$response_timeout");
75
 
        $this->proxyhost = $proxyhost;
76
 
        $this->proxyport = $proxyport;
77
 
                $this->proxyusername = $proxyusername;
78
 
                $this->proxypassword = $proxypassword;
79
 
                $this->timeout = $timeout;
80
 
                $this->response_timeout = $response_timeout;
81
 
                if (is_array($curl_options))
82
 
                        $this->curl_options = $curl_options;
83
 
                $this->use_curl = $use_curl;
84
 
                $this->fetchWSDL($wsdl);
85
 
    }
86
 
 
87
 
        /**
88
 
         * fetches the WSDL document and parses it
89
 
         *
90
 
         * @access public
91
 
         */
92
 
        function fetchWSDL($wsdl) {
93
 
                $this->debug("parse and process WSDL path=$wsdl");
94
 
                $this->wsdl = $wsdl;
95
 
        // parse wsdl file
96
 
        if ($this->wsdl != "") {
97
 
            $this->parseWSDL($this->wsdl);
98
 
        }
99
 
        // imports
100
 
        // TODO: handle imports more properly, grabbing them in-line and nesting them
101
 
        $imported_urls = array();
102
 
        $imported = 1;
103
 
        while ($imported > 0) {
104
 
                $imported = 0;
105
 
                // Schema imports
106
 
                foreach ($this->schemas as $ns => $list) {
107
 
                        foreach ($list as $xs) {
108
 
                                        $wsdlparts = parse_url($this->wsdl);    // this is bogusly simple!
109
 
                            foreach ($xs->imports as $ns2 => $list2) {
110
 
                                for ($ii = 0; $ii < count($list2); $ii++) {
111
 
                                        if (! $list2[$ii]['loaded']) {
112
 
                                                $this->schemas[$ns]->imports[$ns2][$ii]['loaded'] = true;
113
 
                                                $url = $list2[$ii]['location'];
114
 
                                                                if ($url != '') {
115
 
                                                                        $urlparts = parse_url($url);
116
 
                                                                        if (!isset($urlparts['host'])) {
117
 
                                                                                $url = $wsdlparts['scheme'] . '://' . $wsdlparts['host'] . (isset($wsdlparts['port']) ? ':' .$wsdlparts['port'] : '') .
118
 
                                                                                                substr($wsdlparts['path'],0,strrpos($wsdlparts['path'],'/') + 1) .$urlparts['path'];
119
 
                                                                        }
120
 
                                                                        if (! in_array($url, $imported_urls)) {
121
 
                                                                $this->parseWSDL($url);
122
 
                                                                $imported++;
123
 
                                                                $imported_urls[] = $url;
124
 
                                                        }
125
 
                                                                } else {
126
 
                                                                        $this->debug("Unexpected scenario: empty URL for unloaded import");
127
 
                                                                }
128
 
                                                        }
129
 
                                                }
130
 
                            } 
131
 
                        }
132
 
                }
133
 
                // WSDL imports
134
 
                        $wsdlparts = parse_url($this->wsdl);    // this is bogusly simple!
135
 
            foreach ($this->import as $ns => $list) {
136
 
                for ($ii = 0; $ii < count($list); $ii++) {
137
 
                        if (! $list[$ii]['loaded']) {
138
 
                                $this->import[$ns][$ii]['loaded'] = true;
139
 
                                $url = $list[$ii]['location'];
140
 
                                                if ($url != '') {
141
 
                                                        $urlparts = parse_url($url);
142
 
                                                        if (!isset($urlparts['host'])) {
143
 
                                                                $url = $wsdlparts['scheme'] . '://' . $wsdlparts['host'] . (isset($wsdlparts['port']) ? ':' . $wsdlparts['port'] : '') .
144
 
                                                                                substr($wsdlparts['path'],0,strrpos($wsdlparts['path'],'/') + 1) .$urlparts['path'];
145
 
                                                        }
146
 
                                                        if (! in_array($url, $imported_urls)) {
147
 
                                                $this->parseWSDL($url);
148
 
                                                $imported++;
149
 
                                                $imported_urls[] = $url;
150
 
                                        }
151
 
                                                } else {
152
 
                                                        $this->debug("Unexpected scenario: empty URL for unloaded import");
153
 
                                                }
154
 
                                        }
155
 
                                }
156
 
            } 
157
 
                }
158
 
        // add new data to operation data
159
 
        foreach($this->bindings as $binding => $bindingData) {
160
 
            if (isset($bindingData['operations']) && is_array($bindingData['operations'])) {
161
 
                foreach($bindingData['operations'] as $operation => $data) {
162
 
                    $this->debug('post-parse data gathering for ' . $operation);
163
 
                    $this->bindings[$binding]['operations'][$operation]['input'] = 
164
 
                                                isset($this->bindings[$binding]['operations'][$operation]['input']) ? 
165
 
                                                array_merge($this->bindings[$binding]['operations'][$operation]['input'], $this->portTypes[ $bindingData['portType'] ][$operation]['input']) :
166
 
                                                $this->portTypes[ $bindingData['portType'] ][$operation]['input'];
167
 
                    $this->bindings[$binding]['operations'][$operation]['output'] = 
168
 
                                                isset($this->bindings[$binding]['operations'][$operation]['output']) ?
169
 
                                                array_merge($this->bindings[$binding]['operations'][$operation]['output'], $this->portTypes[ $bindingData['portType'] ][$operation]['output']) :
170
 
                                                $this->portTypes[ $bindingData['portType'] ][$operation]['output'];
171
 
                    if(isset($this->messages[ $this->bindings[$binding]['operations'][$operation]['input']['message'] ])){
172
 
                                                $this->bindings[$binding]['operations'][$operation]['input']['parts'] = $this->messages[ $this->bindings[$binding]['operations'][$operation]['input']['message'] ];
173
 
                                        }
174
 
                                        if(isset($this->messages[ $this->bindings[$binding]['operations'][$operation]['output']['message'] ])){
175
 
                                $this->bindings[$binding]['operations'][$operation]['output']['parts'] = $this->messages[ $this->bindings[$binding]['operations'][$operation]['output']['message'] ];
176
 
                    }
177
 
                    // Set operation style if necessary, but do not override one already provided
178
 
                                        if (isset($bindingData['style']) && !isset($this->bindings[$binding]['operations'][$operation]['style'])) {
179
 
                        $this->bindings[$binding]['operations'][$operation]['style'] = $bindingData['style'];
180
 
                    }
181
 
                    $this->bindings[$binding]['operations'][$operation]['transport'] = isset($bindingData['transport']) ? $bindingData['transport'] : '';
182
 
                    $this->bindings[$binding]['operations'][$operation]['documentation'] = isset($this->portTypes[ $bindingData['portType'] ][$operation]['documentation']) ? $this->portTypes[ $bindingData['portType'] ][$operation]['documentation'] : '';
183
 
                    $this->bindings[$binding]['operations'][$operation]['endpoint'] = isset($bindingData['endpoint']) ? $bindingData['endpoint'] : '';
184
 
                } 
185
 
            } 
186
 
        }
187
 
        }
188
 
 
189
 
    /**
190
 
     * parses the wsdl document
191
 
     * 
192
 
     * @param string $wsdl path or URL
193
 
     * @access private 
194
 
     */
195
 
    function parseWSDL($wsdl = '') {
196
 
                $this->debug("parse WSDL at path=$wsdl");
197
 
 
198
 
        if ($wsdl == '') {
199
 
            $this->debug('no wsdl passed to parseWSDL()!!');
200
 
            $this->setError('no wsdl passed to parseWSDL()!!');
201
 
            return false;
202
 
        }
203
 
        
204
 
        // parse $wsdl for url format
205
 
        $wsdl_props = parse_url($wsdl);
206
 
 
207
 
        if (isset($wsdl_props['scheme']) && ($wsdl_props['scheme'] == 'http' || $wsdl_props['scheme'] == 'https')) {
208
 
            $this->debug('getting WSDL http(s) URL ' . $wsdl);
209
 
                // get wsdl
210
 
                $tr = new soap_transport_http($wsdl, $this->curl_options, $this->use_curl);
211
 
                        $tr->request_method = 'GET';
212
 
                        $tr->useSOAPAction = false;
213
 
                        if($this->proxyhost && $this->proxyport){
214
 
                                $tr->setProxy($this->proxyhost,$this->proxyport,$this->proxyusername,$this->proxypassword);
215
 
                        }
216
 
                        if ($this->authtype != '') {
217
 
                                $tr->setCredentials($this->username, $this->password, $this->authtype, array(), $this->certRequest);
218
 
                        }
219
 
                        $tr->setEncoding('gzip, deflate');
220
 
                        $wsdl_string = $tr->send('', $this->timeout, $this->response_timeout);
221
 
                        //$this->debug("WSDL request\n" . $tr->outgoing_payload);
222
 
                        //$this->debug("WSDL response\n" . $tr->incoming_payload);
223
 
                        $this->appendDebug($tr->getDebug());
224
 
                        // catch errors
225
 
                        if($err = $tr->getError() ){
226
 
                                $errstr = 'HTTP ERROR: '.$err;
227
 
                                $this->debug($errstr);
228
 
                    $this->setError($errstr);
229
 
                                unset($tr);
230
 
                    return false;
231
 
                        }
232
 
                        unset($tr);
233
 
                        $this->debug("got WSDL URL");
234
 
        } else {
235
 
            // $wsdl is not http(s), so treat it as a file URL or plain file path
236
 
                if (isset($wsdl_props['scheme']) && ($wsdl_props['scheme'] == 'file') && isset($wsdl_props['path'])) {
237
 
                        $path = isset($wsdl_props['host']) ? ($wsdl_props['host'] . ':' . $wsdl_props['path']) : $wsdl_props['path'];
238
 
                } else {
239
 
                        $path = $wsdl;
240
 
                }
241
 
            $this->debug('getting WSDL file ' . $path);
242
 
            if ($fp = @fopen($path, 'r')) {
243
 
                $wsdl_string = '';
244
 
                while ($data = fread($fp, 32768)) {
245
 
                    $wsdl_string .= $data;
246
 
                } 
247
 
                fclose($fp);
248
 
            } else {
249
 
                $errstr = "Bad path to WSDL file $path";
250
 
                $this->debug($errstr);
251
 
                $this->setError($errstr);
252
 
                return false;
253
 
            } 
254
 
        }
255
 
        $this->debug('Parse WSDL');
256
 
        // end new code added
257
 
        // Create an XML parser.
258
 
        $this->parser = xml_parser_create(); 
259
 
        // Set the options for parsing the XML data.
260
 
        // xml_parser_set_option($parser, XML_OPTION_SKIP_WHITE, 1);
261
 
        xml_parser_set_option($this->parser, XML_OPTION_CASE_FOLDING, 0); 
262
 
        // Set the object for the parser.
263
 
        xml_set_object($this->parser, $this); 
264
 
        // Set the element handlers for the parser.
265
 
        xml_set_element_handler($this->parser, 'start_element', 'end_element');
266
 
        xml_set_character_data_handler($this->parser, 'character_data');
267
 
        // Parse the XML file.
268
 
        if (!xml_parse($this->parser, $wsdl_string, true)) {
269
 
            // Display an error message.
270
 
            $errstr = sprintf(
271
 
                                'XML error parsing WSDL from %s on line %d: %s',
272
 
                                $wsdl,
273
 
                xml_get_current_line_number($this->parser),
274
 
                xml_error_string(xml_get_error_code($this->parser))
275
 
                );
276
 
            $this->debug($errstr);
277
 
                        $this->debug("XML payload:\n" . $wsdl_string);
278
 
            $this->setError($errstr);
279
 
            return false;
280
 
        } 
281
 
                // free the parser
282
 
        xml_parser_free($this->parser);
283
 
        $this->debug('Parsing WSDL done');
284
 
                // catch wsdl parse errors
285
 
                if($this->getError()){
286
 
                        return false;
287
 
                }
288
 
        return true;
289
 
    } 
290
 
 
291
 
    /**
292
 
     * start-element handler
293
 
     * 
294
 
     * @param string $parser XML parser object
295
 
     * @param string $name element name
296
 
     * @param string $attrs associative array of attributes
297
 
     * @access private 
298
 
     */
299
 
    function start_element($parser, $name, $attrs)
300
 
    {
301
 
        if ($this->status == 'schema') {
302
 
            $this->currentSchema->schemaStartElement($parser, $name, $attrs);
303
 
            $this->appendDebug($this->currentSchema->getDebug());
304
 
            $this->currentSchema->clearDebug();
305
 
        } elseif (ereg('schema$', $name)) {
306
 
                $this->debug('Parsing WSDL schema');
307
 
            // $this->debug("startElement for $name ($attrs[name]). status = $this->status (".$this->getLocalPart($name).")");
308
 
            $this->status = 'schema';
309
 
            $this->currentSchema = new nusoap_xmlschema('', '', $this->namespaces);
310
 
            $this->currentSchema->schemaStartElement($parser, $name, $attrs);
311
 
            $this->appendDebug($this->currentSchema->getDebug());
312
 
            $this->currentSchema->clearDebug();
313
 
        } else {
314
 
            // position in the total number of elements, starting from 0
315
 
            $pos = $this->position++;
316
 
            $depth = $this->depth++; 
317
 
            // set self as current value for this depth
318
 
            $this->depth_array[$depth] = $pos;
319
 
            $this->message[$pos] = array('cdata' => ''); 
320
 
            // process attributes
321
 
            if (count($attrs) > 0) {
322
 
                                // register namespace declarations
323
 
                foreach($attrs as $k => $v) {
324
 
                    if (ereg("^xmlns", $k)) {
325
 
                        if ($ns_prefix = substr(strrchr($k, ':'), 1)) {
326
 
                            $this->namespaces[$ns_prefix] = $v;
327
 
                        } else {
328
 
                            $this->namespaces['ns' . (count($this->namespaces) + 1)] = $v;
329
 
                        } 
330
 
                        if ($v == 'http://www.w3.org/2001/XMLSchema' || $v == 'http://www.w3.org/1999/XMLSchema' || $v == 'http://www.w3.org/2000/10/XMLSchema') {
331
 
                            $this->XMLSchemaVersion = $v;
332
 
                            $this->namespaces['xsi'] = $v . '-instance';
333
 
                        } 
334
 
                    }
335
 
                }
336
 
                // expand each attribute prefix to its namespace
337
 
                foreach($attrs as $k => $v) {
338
 
                    $k = strpos($k, ':') ? $this->expandQname($k) : $k;
339
 
                    if ($k != 'location' && $k != 'soapAction' && $k != 'namespace') {
340
 
                        $v = strpos($v, ':') ? $this->expandQname($v) : $v;
341
 
                    } 
342
 
                    $eAttrs[$k] = $v;
343
 
                } 
344
 
                $attrs = $eAttrs;
345
 
            } else {
346
 
                $attrs = array();
347
 
            } 
348
 
            // get element prefix, namespace and name
349
 
            if (ereg(':', $name)) {
350
 
                // get ns prefix
351
 
                $prefix = substr($name, 0, strpos($name, ':')); 
352
 
                // get ns
353
 
                $namespace = isset($this->namespaces[$prefix]) ? $this->namespaces[$prefix] : ''; 
354
 
                // get unqualified name
355
 
                $name = substr(strstr($name, ':'), 1);
356
 
            } 
357
 
                        // process attributes, expanding any prefixes to namespaces
358
 
            // find status, register data
359
 
            switch ($this->status) {
360
 
                case 'message':
361
 
                    if ($name == 'part') {
362
 
                                    if (isset($attrs['type'])) {
363
 
                                    $this->debug("msg " . $this->currentMessage . ": found part (with type) $attrs[name]: " . implode(',', $attrs));
364
 
                                    $this->messages[$this->currentMessage][$attrs['name']] = $attrs['type'];
365
 
                                } 
366
 
                                    if (isset($attrs['element'])) {
367
 
                                    $this->debug("msg " . $this->currentMessage . ": found part (with element) $attrs[name]: " . implode(',', $attrs));
368
 
                                        $this->messages[$this->currentMessage][$attrs['name']] = $attrs['element'] . '^';
369
 
                                    } 
370
 
                                } 
371
 
                                break;
372
 
                            case 'portType':
373
 
                                switch ($name) {
374
 
                                    case 'operation':
375
 
                                        $this->currentPortOperation = $attrs['name'];
376
 
                                        $this->debug("portType $this->currentPortType operation: $this->currentPortOperation");
377
 
                                        if (isset($attrs['parameterOrder'])) {
378
 
                                                $this->portTypes[$this->currentPortType][$attrs['name']]['parameterOrder'] = $attrs['parameterOrder'];
379
 
                                                } 
380
 
                                                break;
381
 
                                            case 'documentation':
382
 
                                                $this->documentation = true;
383
 
                                                break; 
384
 
                                            // merge input/output data
385
 
                                            default:
386
 
                                                $m = isset($attrs['message']) ? $this->getLocalPart($attrs['message']) : '';
387
 
                                                $this->portTypes[$this->currentPortType][$this->currentPortOperation][$name]['message'] = $m;
388
 
                                                break;
389
 
                                        } 
390
 
                                break;
391
 
                                case 'binding':
392
 
                                    switch ($name) {
393
 
                                        case 'binding': 
394
 
                                            // get ns prefix
395
 
                                            if (isset($attrs['style'])) {
396
 
                                            $this->bindings[$this->currentBinding]['prefix'] = $prefix;
397
 
                                                } 
398
 
                                                $this->bindings[$this->currentBinding] = array_merge($this->bindings[$this->currentBinding], $attrs);
399
 
                                                break;
400
 
                                                case 'header':
401
 
                                                    $this->bindings[$this->currentBinding]['operations'][$this->currentOperation][$this->opStatus]['headers'][] = $attrs;
402
 
                                                    break;
403
 
                                                case 'operation':
404
 
                                                    if (isset($attrs['soapAction'])) {
405
 
                                                        $this->bindings[$this->currentBinding]['operations'][$this->currentOperation]['soapAction'] = $attrs['soapAction'];
406
 
                                                    } 
407
 
                                                    if (isset($attrs['style'])) {
408
 
                                                        $this->bindings[$this->currentBinding]['operations'][$this->currentOperation]['style'] = $attrs['style'];
409
 
                                                    } 
410
 
                                                    if (isset($attrs['name'])) {
411
 
                                                        $this->currentOperation = $attrs['name'];
412
 
                                                        $this->debug("current binding operation: $this->currentOperation");
413
 
                                                        $this->bindings[$this->currentBinding]['operations'][$this->currentOperation]['name'] = $attrs['name'];
414
 
                                                        $this->bindings[$this->currentBinding]['operations'][$this->currentOperation]['binding'] = $this->currentBinding;
415
 
                                                        $this->bindings[$this->currentBinding]['operations'][$this->currentOperation]['endpoint'] = isset($this->bindings[$this->currentBinding]['endpoint']) ? $this->bindings[$this->currentBinding]['endpoint'] : '';
416
 
                                                    } 
417
 
                                                    break;
418
 
                                                case 'input':
419
 
                                                    $this->opStatus = 'input';
420
 
                                                    break;
421
 
                                                case 'output':
422
 
                                                    $this->opStatus = 'output';
423
 
                                                    break;
424
 
                                                case 'body':
425
 
                                                    if (isset($this->bindings[$this->currentBinding]['operations'][$this->currentOperation][$this->opStatus])) {
426
 
                                                        $this->bindings[$this->currentBinding]['operations'][$this->currentOperation][$this->opStatus] = array_merge($this->bindings[$this->currentBinding]['operations'][$this->currentOperation][$this->opStatus], $attrs);
427
 
                                                    } else {
428
 
                                                        $this->bindings[$this->currentBinding]['operations'][$this->currentOperation][$this->opStatus] = $attrs;
429
 
                                                    } 
430
 
                                                    break;
431
 
                                        } 
432
 
                                        break;
433
 
                                case 'service':
434
 
                                        switch ($name) {
435
 
                                            case 'port':
436
 
                                                $this->currentPort = $attrs['name'];
437
 
                                                $this->debug('current port: ' . $this->currentPort);
438
 
                                                $this->ports[$this->currentPort]['binding'] = $this->getLocalPart($attrs['binding']);
439
 
                                        
440
 
                                                break;
441
 
                                            case 'address':
442
 
                                                $this->ports[$this->currentPort]['location'] = $attrs['location'];
443
 
                                                $this->ports[$this->currentPort]['bindingType'] = $namespace;
444
 
                                                $this->bindings[ $this->ports[$this->currentPort]['binding'] ]['bindingType'] = $namespace;
445
 
                                                $this->bindings[ $this->ports[$this->currentPort]['binding'] ]['endpoint'] = $attrs['location'];
446
 
                                                break;
447
 
                                        } 
448
 
                                        break;
449
 
                        } 
450
 
                // set status
451
 
                switch ($name) {
452
 
                        case 'import':
453
 
                            if (isset($attrs['location'])) {
454
 
                    $this->import[$attrs['namespace']][] = array('location' => $attrs['location'], 'loaded' => false);
455
 
                    $this->debug('parsing import ' . $attrs['namespace']. ' - ' . $attrs['location'] . ' (' . count($this->import[$attrs['namespace']]).')');
456
 
                                } else {
457
 
                    $this->import[$attrs['namespace']][] = array('location' => '', 'loaded' => true);
458
 
                                        if (! $this->getPrefixFromNamespace($attrs['namespace'])) {
459
 
                                                $this->namespaces['ns'.(count($this->namespaces)+1)] = $attrs['namespace'];
460
 
                                        }
461
 
                    $this->debug('parsing import ' . $attrs['namespace']. ' - [no location] (' . count($this->import[$attrs['namespace']]).')');
462
 
                                }
463
 
                                break;
464
 
                        //wait for schema
465
 
                        //case 'types':
466
 
                        //      $this->status = 'schema';
467
 
                        //      break;
468
 
                        case 'message':
469
 
                                $this->status = 'message';
470
 
                                $this->messages[$attrs['name']] = array();
471
 
                                $this->currentMessage = $attrs['name'];
472
 
                                break;
473
 
                        case 'portType':
474
 
                                $this->status = 'portType';
475
 
                                $this->portTypes[$attrs['name']] = array();
476
 
                                $this->currentPortType = $attrs['name'];
477
 
                                break;
478
 
                        case "binding":
479
 
                                if (isset($attrs['name'])) {
480
 
                                // get binding name
481
 
                                        if (strpos($attrs['name'], ':')) {
482
 
                                        $this->currentBinding = $this->getLocalPart($attrs['name']);
483
 
                                        } else {
484
 
                                        $this->currentBinding = $attrs['name'];
485
 
                                        } 
486
 
                                        $this->status = 'binding';
487
 
                                        $this->bindings[$this->currentBinding]['portType'] = $this->getLocalPart($attrs['type']);
488
 
                                        $this->debug("current binding: $this->currentBinding of portType: " . $attrs['type']);
489
 
                                } 
490
 
                                break;
491
 
                        case 'service':
492
 
                                $this->serviceName = $attrs['name'];
493
 
                                $this->status = 'service';
494
 
                                $this->debug('current service: ' . $this->serviceName);
495
 
                                break;
496
 
                        case 'definitions':
497
 
                                foreach ($attrs as $name => $value) {
498
 
                                        $this->wsdl_info[$name] = $value;
499
 
                                } 
500
 
                                break;
501
 
                        } 
502
 
                } 
503
 
        } 
504
 
 
505
 
        /**
506
 
        * end-element handler
507
 
        * 
508
 
        * @param string $parser XML parser object
509
 
        * @param string $name element name
510
 
        * @access private 
511
 
        */
512
 
        function end_element($parser, $name){ 
513
 
                // unset schema status
514
 
                if (/*ereg('types$', $name) ||*/ ereg('schema$', $name)) {
515
 
                        $this->status = "";
516
 
            $this->appendDebug($this->currentSchema->getDebug());
517
 
            $this->currentSchema->clearDebug();
518
 
                        $this->schemas[$this->currentSchema->schemaTargetNamespace][] = $this->currentSchema;
519
 
                $this->debug('Parsing WSDL schema done');
520
 
                } 
521
 
                if ($this->status == 'schema') {
522
 
                        $this->currentSchema->schemaEndElement($parser, $name);
523
 
                } else {
524
 
                        // bring depth down a notch
525
 
                        $this->depth--;
526
 
                } 
527
 
                // end documentation
528
 
                if ($this->documentation) {
529
 
                        //TODO: track the node to which documentation should be assigned; it can be a part, message, etc.
530
 
                        //$this->portTypes[$this->currentPortType][$this->currentPortOperation]['documentation'] = $this->documentation;
531
 
                        $this->documentation = false;
532
 
                } 
533
 
        } 
534
 
 
535
 
        /**
536
 
         * element content handler
537
 
         * 
538
 
         * @param string $parser XML parser object
539
 
         * @param string $data element content
540
 
         * @access private 
541
 
         */
542
 
        function character_data($parser, $data)
543
 
        {
544
 
                $pos = isset($this->depth_array[$this->depth]) ? $this->depth_array[$this->depth] : 0;
545
 
                if (isset($this->message[$pos]['cdata'])) {
546
 
                        $this->message[$pos]['cdata'] .= $data;
547
 
                } 
548
 
                if ($this->documentation) {
549
 
                        $this->documentation .= $data;
550
 
                } 
551
 
        } 
552
 
        
553
 
        /**
554
 
        * if authenticating, set user credentials here
555
 
        *
556
 
        * @param    string $username
557
 
        * @param    string $password
558
 
        * @param        string $authtype (basic|digest|certificate|ntlm)
559
 
        * @param        array $certRequest (keys must be cainfofile (optional), sslcertfile, sslkeyfile, passphrase, certpassword (optional), verifypeer (optional), verifyhost (optional): see corresponding options in cURL docs)
560
 
        * @access   public
561
 
        */
562
 
        function setCredentials($username, $password, $authtype = 'basic', $certRequest = array()) {
563
 
                $this->debug("setCredentials username=$username authtype=$authtype certRequest=");
564
 
                $this->appendDebug($this->varDump($certRequest));
565
 
                $this->username = $username;
566
 
                $this->password = $password;
567
 
                $this->authtype = $authtype;
568
 
                $this->certRequest = $certRequest;
569
 
        }
570
 
        
571
 
        function getBindingData($binding)
572
 
        {
573
 
                if (is_array($this->bindings[$binding])) {
574
 
                        return $this->bindings[$binding];
575
 
                } 
576
 
        }
577
 
        
578
 
        /**
579
 
         * returns an assoc array of operation names => operation data
580
 
         * 
581
 
         * @param string $bindingType eg: soap, smtp, dime (only soap and soap12 are currently supported)
582
 
         * @return array 
583
 
         * @access public 
584
 
         */
585
 
        function getOperations($bindingType = 'soap') {
586
 
                $ops = array();
587
 
                if ($bindingType == 'soap') {
588
 
                        $bindingType = 'http://schemas.xmlsoap.org/wsdl/soap/';
589
 
                } elseif ($bindingType == 'soap12') {
590
 
                        $bindingType = 'http://schemas.xmlsoap.org/wsdl/soap12/';
591
 
                }
592
 
                // loop thru ports
593
 
                foreach($this->ports as $port => $portData) {
594
 
                        // binding type of port matches parameter
595
 
                        if ($portData['bindingType'] == $bindingType) {
596
 
                                //$this->debug("getOperations for port $port");
597
 
                                //$this->debug("port data: " . $this->varDump($portData));
598
 
                                //$this->debug("bindings: " . $this->varDump($this->bindings[ $portData['binding'] ]));
599
 
                                // merge bindings
600
 
                                if (isset($this->bindings[ $portData['binding'] ]['operations'])) {
601
 
                                        $ops = array_merge ($ops, $this->bindings[ $portData['binding'] ]['operations']);
602
 
                                }
603
 
                        }
604
 
                } 
605
 
                return $ops;
606
 
        } 
607
 
        
608
 
        /**
609
 
         * returns an associative array of data necessary for calling an operation
610
 
         * 
611
 
         * @param string $operation name of operation
612
 
         * @param string $bindingType type of binding eg: soap, soap12
613
 
         * @return array 
614
 
         * @access public 
615
 
         */
616
 
        function getOperationData($operation, $bindingType = 'soap')
617
 
        {
618
 
                if ($bindingType == 'soap') {
619
 
                        $bindingType = 'http://schemas.xmlsoap.org/wsdl/soap/';
620
 
                } elseif ($bindingType == 'soap12') {
621
 
                        $bindingType = 'http://schemas.xmlsoap.org/wsdl/soap12/';
622
 
                }
623
 
                // loop thru ports
624
 
                foreach($this->ports as $port => $portData) {
625
 
                        // binding type of port matches parameter
626
 
                        if ($portData['bindingType'] == $bindingType) {
627
 
                                // get binding
628
 
                                //foreach($this->bindings[ $portData['binding'] ]['operations'] as $bOperation => $opData) {
629
 
                                foreach(array_keys($this->bindings[ $portData['binding'] ]['operations']) as $bOperation) {
630
 
                                        // note that we could/should also check the namespace here
631
 
                                        if ($operation == $bOperation) {
632
 
                                                $opData = $this->bindings[ $portData['binding'] ]['operations'][$operation];
633
 
                                            return $opData;
634
 
                                        } 
635
 
                                } 
636
 
                        }
637
 
                } 
638
 
        }
639
 
        
640
 
        /**
641
 
         * returns an associative array of data necessary for calling an operation
642
 
         * 
643
 
         * @param string $soapAction soapAction for operation
644
 
         * @param string $bindingType type of binding eg: soap, soap12
645
 
         * @return array 
646
 
         * @access public 
647
 
         */
648
 
        function getOperationDataForSoapAction($soapAction, $bindingType = 'soap') {
649
 
                if ($bindingType == 'soap') {
650
 
                        $bindingType = 'http://schemas.xmlsoap.org/wsdl/soap/';
651
 
                } elseif ($bindingType == 'soap12') {
652
 
                        $bindingType = 'http://schemas.xmlsoap.org/wsdl/soap12/';
653
 
                }
654
 
                // loop thru ports
655
 
                foreach($this->ports as $port => $portData) {
656
 
                        // binding type of port matches parameter
657
 
                        if ($portData['bindingType'] == $bindingType) {
658
 
                                // loop through operations for the binding
659
 
                                foreach ($this->bindings[ $portData['binding'] ]['operations'] as $bOperation => $opData) {
660
 
                                        if ($opData['soapAction'] == $soapAction) {
661
 
                                            return $opData;
662
 
                                        } 
663
 
                                } 
664
 
                        }
665
 
                } 
666
 
        }
667
 
        
668
 
        /**
669
 
    * returns an array of information about a given type
670
 
    * returns false if no type exists by the given name
671
 
    *
672
 
        *        typeDef = array(
673
 
        *        'elements' => array(), // refs to elements array
674
 
        *       'restrictionBase' => '',
675
 
        *       'phpType' => '',
676
 
        *       'order' => '(sequence|all)',
677
 
        *       'attrs' => array() // refs to attributes array
678
 
        *       )
679
 
    *
680
 
    * @param string $type the type
681
 
    * @param string $ns namespace (not prefix) of the type
682
 
    * @return mixed
683
 
    * @access public
684
 
    * @see nusoap_xmlschema
685
 
    */
686
 
        function getTypeDef($type, $ns) {
687
 
                $this->debug("in getTypeDef: type=$type, ns=$ns");
688
 
                if ((! $ns) && isset($this->namespaces['tns'])) {
689
 
                        $ns = $this->namespaces['tns'];
690
 
                        $this->debug("in getTypeDef: type namespace forced to $ns");
691
 
                }
692
 
                if (!isset($this->schemas[$ns])) {
693
 
                        foreach ($this->schemas as $ns0 => $schema0) {
694
 
                                if (strcasecmp($ns, $ns0) == 0) {
695
 
                                        $this->debug("in getTypeDef: replacing schema namespace $ns with $ns0");
696
 
                                        $ns = $ns0;
697
 
                                        break;
698
 
                                }
699
 
                        }
700
 
                }
701
 
                if (isset($this->schemas[$ns])) {
702
 
                        $this->debug("in getTypeDef: have schema for namespace $ns");
703
 
                        for ($i = 0; $i < count($this->schemas[$ns]); $i++) {
704
 
                                $xs = &$this->schemas[$ns][$i];
705
 
                                $t = $xs->getTypeDef($type);
706
 
                                //$this->appendDebug($xs->getDebug());
707
 
                                //$xs->clearDebug();
708
 
                                if ($t) {
709
 
                                        if (!isset($t['phpType'])) {
710
 
                                                // get info for type to tack onto the element
711
 
                                                $uqType = substr($t['type'], strrpos($t['type'], ':') + 1);
712
 
                                                $ns = substr($t['type'], 0, strrpos($t['type'], ':'));
713
 
                                                $etype = $this->getTypeDef($uqType, $ns);
714
 
                                                if ($etype) {
715
 
                                                        $this->debug("found type for [element] $type:");
716
 
                                                        $this->debug($this->varDump($etype));
717
 
                                                        if (isset($etype['phpType'])) {
718
 
                                                                $t['phpType'] = $etype['phpType'];
719
 
                                                        }
720
 
                                                        if (isset($etype['elements'])) {
721
 
                                                                $t['elements'] = $etype['elements'];
722
 
                                                        }
723
 
                                                        if (isset($etype['attrs'])) {
724
 
                                                                $t['attrs'] = $etype['attrs'];
725
 
                                                        }
726
 
                                                }
727
 
                                        }
728
 
                                        return $t;
729
 
                                }
730
 
                        }
731
 
                } else {
732
 
                        $this->debug("in getTypeDef: do not have schema for namespace $ns");
733
 
                }
734
 
                return false;
735
 
        }
736
 
 
737
 
    /**
738
 
    * prints html description of services
739
 
    *
740
 
    * @access private
741
 
    */
742
 
    function webDescription(){
743
 
        global $HTTP_SERVER_VARS;
744
 
 
745
 
                if (isset($_SERVER)) {
746
 
                        $PHP_SELF = $_SERVER['PHP_SELF'];
747
 
                } elseif (isset($HTTP_SERVER_VARS)) {
748
 
                        $PHP_SELF = $HTTP_SERVER_VARS['PHP_SELF'];
749
 
                } else {
750
 
                        $this->setError("Neither _SERVER nor HTTP_SERVER_VARS is available");
751
 
                }
752
 
 
753
 
                $b = '
754
 
                <html><head><title>NuSOAP: '.$this->serviceName.'</title>
755
 
                <style type="text/css">
756
 
                    body    { font-family: arial; color: #000000; background-color: #ffffff; margin: 0px 0px 0px 0px; }
757
 
                    p       { font-family: arial; color: #000000; margin-top: 0px; margin-bottom: 12px; }
758
 
                    pre { background-color: silver; padding: 5px; font-family: Courier New; font-size: x-small; color: #000000;}
759
 
                    ul      { margin-top: 10px; margin-left: 20px; }
760
 
                    li      { list-style-type: none; margin-top: 10px; color: #000000; }
761
 
                    .content{
762
 
                        margin-left: 0px; padding-bottom: 2em; }
763
 
                    .nav {
764
 
                        padding-top: 10px; padding-bottom: 10px; padding-left: 15px; font-size: .70em;
765
 
                        margin-top: 10px; margin-left: 0px; color: #000000;
766
 
                        background-color: #ccccff; width: 20%; margin-left: 20px; margin-top: 20px; }
767
 
                    .title {
768
 
                        font-family: arial; font-size: 26px; color: #ffffff;
769
 
                        background-color: #999999; width: 105%; margin-left: 0px;
770
 
                        padding-top: 10px; padding-bottom: 10px; padding-left: 15px;}
771
 
                    .hidden {
772
 
                        position: absolute; visibility: hidden; z-index: 200; left: 250px; top: 100px;
773
 
                        font-family: arial; overflow: hidden; width: 600;
774
 
                        padding: 20px; font-size: 10px; background-color: #999999;
775
 
                        layer-background-color:#FFFFFF; }
776
 
                    a,a:active  { color: charcoal; font-weight: bold; }
777
 
                    a:visited   { color: #666666; font-weight: bold; }
778
 
                    a:hover     { color: cc3300; font-weight: bold; }
779
 
                </style>
780
 
                <script language="JavaScript" type="text/javascript">
781
 
                <!--
782
 
                // POP-UP CAPTIONS...
783
 
                function lib_bwcheck(){ //Browsercheck (needed)
784
 
                    this.ver=navigator.appVersion
785
 
                    this.agent=navigator.userAgent
786
 
                    this.dom=document.getElementById?1:0
787
 
                    this.opera5=this.agent.indexOf("Opera 5")>-1
788
 
                    this.ie5=(this.ver.indexOf("MSIE 5")>-1 && this.dom && !this.opera5)?1:0;
789
 
                    this.ie6=(this.ver.indexOf("MSIE 6")>-1 && this.dom && !this.opera5)?1:0;
790
 
                    this.ie4=(document.all && !this.dom && !this.opera5)?1:0;
791
 
                    this.ie=this.ie4||this.ie5||this.ie6
792
 
                    this.mac=this.agent.indexOf("Mac")>-1
793
 
                    this.ns6=(this.dom && parseInt(this.ver) >= 5) ?1:0;
794
 
                    this.ns4=(document.layers && !this.dom)?1:0;
795
 
                    this.bw=(this.ie6 || this.ie5 || this.ie4 || this.ns4 || this.ns6 || this.opera5)
796
 
                    return this
797
 
                }
798
 
                var bw = new lib_bwcheck()
799
 
                //Makes crossbrowser object.
800
 
                function makeObj(obj){
801
 
                    this.evnt=bw.dom? document.getElementById(obj):bw.ie4?document.all[obj]:bw.ns4?document.layers[obj]:0;
802
 
                    if(!this.evnt) return false
803
 
                    this.css=bw.dom||bw.ie4?this.evnt.style:bw.ns4?this.evnt:0;
804
 
                    this.wref=bw.dom||bw.ie4?this.evnt:bw.ns4?this.css.document:0;
805
 
                    this.writeIt=b_writeIt;
806
 
                    return this
807
 
                }
808
 
                // A unit of measure that will be added when setting the position of a layer.
809
 
                //var px = bw.ns4||window.opera?"":"px";
810
 
                function b_writeIt(text){
811
 
                    if (bw.ns4){this.wref.write(text);this.wref.close()}
812
 
                    else this.wref.innerHTML = text
813
 
                }
814
 
                //Shows the messages
815
 
                var oDesc;
816
 
                function popup(divid){
817
 
                    if(oDesc = new makeObj(divid)){
818
 
                        oDesc.css.visibility = "visible"
819
 
                    }
820
 
                }
821
 
                function popout(){ // Hides message
822
 
                    if(oDesc) oDesc.css.visibility = "hidden"
823
 
                }
824
 
                //-->
825
 
                </script>
826
 
                </head>
827
 
                <body>
828
 
                <div class=content>
829
 
                        <br><br>
830
 
                        <div class=title>'.$this->serviceName.'</div>
831
 
                        <div class=nav>
832
 
                                <p>View the <a href="'.$PHP_SELF.'?wsdl">WSDL</a> for the service.
833
 
                                Click on an operation name to view it&apos;s details.</p>
834
 
                                <ul>';
835
 
                                foreach($this->getOperations() as $op => $data){
836
 
                                    $b .= "<li><a href='#' onclick=\"popout();popup('$op')\">$op</a></li>";
837
 
                                    // create hidden div
838
 
                                    $b .= "<div id='$op' class='hidden'>
839
 
                                    <a href='#' onclick='popout()'><font color='#ffffff'>Close</font></a><br><br>";
840
 
                                    foreach($data as $donnie => $marie){ // loop through opdata
841
 
                                                if($donnie == 'input' || $donnie == 'output'){ // show input/output data
842
 
                                                    $b .= "<font color='white'>".ucfirst($donnie).':</font><br>';
843
 
                                                    foreach($marie as $captain => $tenille){ // loop through data
844
 
                                                                if($captain == 'parts'){ // loop thru parts
845
 
                                                                    $b .= "&nbsp;&nbsp;$captain:<br>";
846
 
                                                        //if(is_array($tenille)){
847
 
                                                                        foreach($tenille as $joanie => $chachi){
848
 
                                                                                        $b .= "&nbsp;&nbsp;&nbsp;&nbsp;$joanie: $chachi<br>";
849
 
                                                                        }
850
 
                                                                //}
851
 
                                                                } else {
852
 
                                                                    $b .= "&nbsp;&nbsp;$captain: $tenille<br>";
853
 
                                                                }
854
 
                                                    }
855
 
                                                } else {
856
 
                                                    $b .= "<font color='white'>".ucfirst($donnie).":</font> $marie<br>";
857
 
                                                }
858
 
                                    }
859
 
                                        $b .= '</div>';
860
 
                                }
861
 
                                $b .= '
862
 
                                <ul>
863
 
                        </div>
864
 
                </div></body></html>';
865
 
                return $b;
866
 
    }
867
 
 
868
 
        /**
869
 
        * serialize the parsed wsdl
870
 
        *
871
 
        * @param mixed $debug whether to put debug=1 in endpoint URL
872
 
        * @return string serialization of WSDL
873
 
        * @access public 
874
 
        */
875
 
        function serialize($debug = 0)
876
 
        {
877
 
                $xml = '<?xml version="1.0" encoding="ISO-8859-1"?>';
878
 
                $xml .= "\n<definitions";
879
 
                foreach($this->namespaces as $k => $v) {
880
 
                        $xml .= " xmlns:$k=\"$v\"";
881
 
                } 
882
 
                // 10.9.02 - add poulter fix for wsdl and tns declarations
883
 
                if (isset($this->namespaces['wsdl'])) {
884
 
                        $xml .= " xmlns=\"" . $this->namespaces['wsdl'] . "\"";
885
 
                } 
886
 
                if (isset($this->namespaces['tns'])) {
887
 
                        $xml .= " targetNamespace=\"" . $this->namespaces['tns'] . "\"";
888
 
                } 
889
 
                $xml .= '>'; 
890
 
                // imports
891
 
                if (sizeof($this->import) > 0) {
892
 
                        foreach($this->import as $ns => $list) {
893
 
                                foreach ($list as $ii) {
894
 
                                        if ($ii['location'] != '') {
895
 
                                                $xml .= '<import location="' . $ii['location'] . '" namespace="' . $ns . '" />';
896
 
                                        } else {
897
 
                                                $xml .= '<import namespace="' . $ns . '" />';
898
 
                                        }
899
 
                                }
900
 
                        } 
901
 
                } 
902
 
                // types
903
 
                if (count($this->schemas)>=1) {
904
 
                        $xml .= "\n<types>\n";
905
 
                        foreach ($this->schemas as $ns => $list) {
906
 
                                foreach ($list as $xs) {
907
 
                                        $xml .= $xs->serializeSchema();
908
 
                                }
909
 
                        }
910
 
                        $xml .= '</types>';
911
 
                } 
912
 
                // messages
913
 
                if (count($this->messages) >= 1) {
914
 
                        foreach($this->messages as $msgName => $msgParts) {
915
 
                                $xml .= "\n<message name=\"" . $msgName . '">';
916
 
                                if(is_array($msgParts)){
917
 
                                        foreach($msgParts as $partName => $partType) {
918
 
                                                // print 'serializing '.$partType.', sv: '.$this->XMLSchemaVersion.'<br>';
919
 
                                                if (strpos($partType, ':')) {
920
 
                                                    $typePrefix = $this->getPrefixFromNamespace($this->getPrefix($partType));
921
 
                                                } elseif (isset($this->typemap[$this->namespaces['xsd']][$partType])) {
922
 
                                                    // print 'checking typemap: '.$this->XMLSchemaVersion.'<br>';
923
 
                                                    $typePrefix = 'xsd';
924
 
                                                } else {
925
 
                                                    foreach($this->typemap as $ns => $types) {
926
 
                                                        if (isset($types[$partType])) {
927
 
                                                            $typePrefix = $this->getPrefixFromNamespace($ns);
928
 
                                                        } 
929
 
                                                    } 
930
 
                                                    if (!isset($typePrefix)) {
931
 
                                                        die("$partType has no namespace!");
932
 
                                                    } 
933
 
                                                }
934
 
                                                $ns = $this->getNamespaceFromPrefix($typePrefix);
935
 
                                                $localPart = $this->getLocalPart($partType);
936
 
                                                $typeDef = $this->getTypeDef($localPart, $ns);
937
 
                                                if ($typeDef['typeClass'] == 'element') {
938
 
                                                        $elementortype = 'element';
939
 
                                                        if (substr($localPart, -1) == '^') {
940
 
                                                                $localPart = substr($localPart, 0, -1);
941
 
                                                        }
942
 
                                                } else {
943
 
                                                        $elementortype = 'type';
944
 
                                                }
945
 
                                                $xml .= "\n" . '  <part name="' . $partName . '" ' . $elementortype . '="' . $typePrefix . ':' . $localPart . '" />';
946
 
                                        }
947
 
                                }
948
 
                                $xml .= '</message>';
949
 
                        } 
950
 
                } 
951
 
                // bindings & porttypes
952
 
                if (count($this->bindings) >= 1) {
953
 
                        $binding_xml = '';
954
 
                        $portType_xml = '';
955
 
                        foreach($this->bindings as $bindingName => $attrs) {
956
 
                                $binding_xml .= "\n<binding name=\"" . $bindingName . '" type="tns:' . $attrs['portType'] . '">';
957
 
                                $binding_xml .= "\n" . '  <soap:binding style="' . $attrs['style'] . '" transport="' . $attrs['transport'] . '"/>';
958
 
                                $portType_xml .= "\n<portType name=\"" . $attrs['portType'] . '">';
959
 
                                foreach($attrs['operations'] as $opName => $opParts) {
960
 
                                        $binding_xml .= "\n" . '  <operation name="' . $opName . '">';
961
 
                                        $binding_xml .= "\n" . '    <soap:operation soapAction="' . $opParts['soapAction'] . '" style="'. $opParts['style'] . '"/>';
962
 
                                        if (isset($opParts['input']['encodingStyle']) && $opParts['input']['encodingStyle'] != '') {
963
 
                                                $enc_style = ' encodingStyle="' . $opParts['input']['encodingStyle'] . '"';
964
 
                                        } else {
965
 
                                                $enc_style = '';
966
 
                                        }
967
 
                                        $binding_xml .= "\n" . '    <input><soap:body use="' . $opParts['input']['use'] . '" namespace="' . $opParts['input']['namespace'] . '"' . $enc_style . '/></input>';
968
 
                                        if (isset($opParts['output']['encodingStyle']) && $opParts['output']['encodingStyle'] != '') {
969
 
                                                $enc_style = ' encodingStyle="' . $opParts['output']['encodingStyle'] . '"';
970
 
                                        } else {
971
 
                                                $enc_style = '';
972
 
                                        }
973
 
                                        $binding_xml .= "\n" . '    <output><soap:body use="' . $opParts['output']['use'] . '" namespace="' . $opParts['output']['namespace'] . '"' . $enc_style . '/></output>';
974
 
                                        $binding_xml .= "\n" . '  </operation>';
975
 
                                        $portType_xml .= "\n" . '  <operation name="' . $opParts['name'] . '"';
976
 
                                        if (isset($opParts['parameterOrder'])) {
977
 
                                            $portType_xml .= ' parameterOrder="' . $opParts['parameterOrder'] . '"';
978
 
                                        } 
979
 
                                        $portType_xml .= '>';
980
 
                                        if(isset($opParts['documentation']) && $opParts['documentation'] != '') {
981
 
                                                $portType_xml .= "\n" . '    <documentation>' . htmlspecialchars($opParts['documentation']) . '</documentation>';
982
 
                                        }
983
 
                                        $portType_xml .= "\n" . '    <input message="tns:' . $opParts['input']['message'] . '"/>';
984
 
                                        $portType_xml .= "\n" . '    <output message="tns:' . $opParts['output']['message'] . '"/>';
985
 
                                        $portType_xml .= "\n" . '  </operation>';
986
 
                                } 
987
 
                                $portType_xml .= "\n" . '</portType>';
988
 
                                $binding_xml .= "\n" . '</binding>';
989
 
                        } 
990
 
                        $xml .= $portType_xml . $binding_xml;
991
 
                } 
992
 
                // services
993
 
                $xml .= "\n<service name=\"" . $this->serviceName . '">';
994
 
                if (count($this->ports) >= 1) {
995
 
                        foreach($this->ports as $pName => $attrs) {
996
 
                                $xml .= "\n" . '  <port name="' . $pName . '" binding="tns:' . $attrs['binding'] . '">';
997
 
                                $xml .= "\n" . '    <soap:address location="' . $attrs['location'] . ($debug ? '?debug=1' : '') . '"/>';
998
 
                                $xml .= "\n" . '  </port>';
999
 
                        } 
1000
 
                } 
1001
 
                $xml .= "\n" . '</service>';
1002
 
                return $xml . "\n</definitions>";
1003
 
        } 
1004
 
 
1005
 
        /**
1006
 
         * determine whether a set of parameters are unwrapped
1007
 
         * when they are expect to be wrapped, Microsoft-style.
1008
 
         *
1009
 
         * @param string $type the type (element name) of the wrapper
1010
 
         * @param array $parameters the parameter values for the SOAP call
1011
 
         * @return boolean whether they parameters are unwrapped (and should be wrapped)
1012
 
         * @access private
1013
 
         */
1014
 
        function parametersMatchWrapped($type, &$parameters) {
1015
 
                $this->debug("in parametersMatchWrapped type=$type, parameters=");
1016
 
                $this->appendDebug($this->varDump($parameters));
1017
 
 
1018
 
                // split type into namespace:unqualified-type
1019
 
                if (strpos($type, ':')) {
1020
 
                        $uqType = substr($type, strrpos($type, ':') + 1);
1021
 
                        $ns = substr($type, 0, strrpos($type, ':'));
1022
 
                        $this->debug("in parametersMatchWrapped: got a prefixed type: $uqType, $ns");
1023
 
                        if ($this->getNamespaceFromPrefix($ns)) {
1024
 
                                $ns = $this->getNamespaceFromPrefix($ns);
1025
 
                                $this->debug("in parametersMatchWrapped: expanded prefixed type: $uqType, $ns");
1026
 
                        }
1027
 
                } else {
1028
 
                        // TODO: should the type be compared to types in XSD, and the namespace
1029
 
                        // set to XSD if the type matches?
1030
 
                        $this->debug("in parametersMatchWrapped: No namespace for type $type");
1031
 
                        $ns = '';
1032
 
                        $uqType = $type;
1033
 
                }
1034
 
 
1035
 
                // get the type information
1036
 
                if (!$typeDef = $this->getTypeDef($uqType, $ns)) {
1037
 
                        $this->debug("in parametersMatchWrapped: $type ($uqType) is not a supported type.");
1038
 
                        return false;
1039
 
                }
1040
 
                $this->debug("in parametersMatchWrapped: found typeDef=");
1041
 
                $this->appendDebug($this->varDump($typeDef));
1042
 
                if (substr($uqType, -1) == '^') {
1043
 
                        $uqType = substr($uqType, 0, -1);
1044
 
                }
1045
 
                $phpType = $typeDef['phpType'];
1046
 
                $arrayType = (isset($typeDef['arrayType']) ? $typeDef['arrayType'] : '');
1047
 
                $this->debug("in parametersMatchWrapped: uqType: $uqType, ns: $ns, phptype: $phpType, arrayType: $arrayType");
1048
 
                
1049
 
                // we expect a complexType or element of complexType
1050
 
                if ($phpType != 'struct') {
1051
 
                        $this->debug("in parametersMatchWrapped: not a struct");
1052
 
                        return false;
1053
 
                }
1054
 
 
1055
 
                // see whether the parameter names match the elements
1056
 
                if (isset($typeDef['elements']) && is_array($typeDef['elements'])) {
1057
 
                        $elements = 0;
1058
 
                        $matches = 0;
1059
 
                        $change = false;
1060
 
                        if ($this->isArraySimpleOrStruct($parameters) == 'arraySimple' && count($parameters) == count($typeDef['elements'])) {
1061
 
                                $this->debug("in parametersMatchWrapped: (wrapped return value kludge) correct number of elements in simple array, so change array and wrap");
1062
 
                                $change = true;
1063
 
                        }
1064
 
                        foreach ($typeDef['elements'] as $name => $attrs) {
1065
 
                                if ($change) {
1066
 
                                        $this->debug("in parametersMatchWrapped: change parameter $element to name $name");
1067
 
                                        $parameters[$name] = $parameters[$elements];
1068
 
                                        unset($parameters[$elements]);
1069
 
                                        $matches++;
1070
 
                                } elseif (isset($parameters[$name])) {
1071
 
                                        $this->debug("in parametersMatchWrapped: have parameter named $name");
1072
 
                                        $matches++;
1073
 
                                } else {
1074
 
                                        $this->debug("in parametersMatchWrapped: do not have parameter named $name");
1075
 
                                }
1076
 
                                $elements++;
1077
 
                        }
1078
 
 
1079
 
                        $this->debug("in parametersMatchWrapped: $matches parameter names match $elements wrapped parameter names");
1080
 
                        if ($matches == 0) {
1081
 
                                return false;
1082
 
                        }
1083
 
                        return true;
1084
 
                }
1085
 
 
1086
 
                // since there are no elements for the type, if the user passed no
1087
 
                // parameters, the parameters match wrapped.
1088
 
                $this->debug("in parametersMatchWrapped: no elements type $ns:$uqType");
1089
 
                return count($parameters) == 0;
1090
 
        }
1091
 
 
1092
 
        /**
1093
 
         * serialize PHP values according to a WSDL message definition
1094
 
         * contrary to the method name, this is not limited to RPC
1095
 
         *
1096
 
         * TODO
1097
 
         * - multi-ref serialization
1098
 
         * - validate PHP values against type definitions, return errors if invalid
1099
 
         * 
1100
 
         * @param string $operation operation name
1101
 
         * @param string $direction (input|output)
1102
 
         * @param mixed $parameters parameter value(s)
1103
 
         * @param string $bindingType (soap|soap12)
1104
 
         * @return mixed parameters serialized as XML or false on error (e.g. operation not found)
1105
 
         * @access public
1106
 
         */
1107
 
        function serializeRPCParameters($operation, $direction, $parameters, $bindingType = 'soap') {
1108
 
                $this->debug("in serializeRPCParameters: operation=$operation, direction=$direction, XMLSchemaVersion=$this->XMLSchemaVersion, bindingType=$bindingType");
1109
 
                $this->appendDebug('parameters=' . $this->varDump($parameters));
1110
 
                
1111
 
                if ($direction != 'input' && $direction != 'output') {
1112
 
                        $this->debug('The value of the \$direction argument needs to be either "input" or "output"');
1113
 
                        $this->setError('The value of the \$direction argument needs to be either "input" or "output"');
1114
 
                        return false;
1115
 
                } 
1116
 
                if (!$opData = $this->getOperationData($operation, $bindingType)) {
1117
 
                        $this->debug('Unable to retrieve WSDL data for operation: ' . $operation . ' bindingType: ' . $bindingType);
1118
 
                        $this->setError('Unable to retrieve WSDL data for operation: ' . $operation . ' bindingType: ' . $bindingType);
1119
 
                        return false;
1120
 
                }
1121
 
                $this->debug('in serializeRPCParameters: opData:');
1122
 
                $this->appendDebug($this->varDump($opData));
1123
 
 
1124
 
                // Get encoding style for output and set to current
1125
 
                $encodingStyle = 'http://schemas.xmlsoap.org/soap/encoding/';
1126
 
                if(($direction == 'input') && isset($opData['output']['encodingStyle']) && ($opData['output']['encodingStyle'] != $encodingStyle)) {
1127
 
                        $encodingStyle = $opData['output']['encodingStyle'];
1128
 
                        $enc_style = $encodingStyle;
1129
 
                }
1130
 
 
1131
 
                // set input params
1132
 
                $xml = '';
1133
 
                if (isset($opData[$direction]['parts']) && sizeof($opData[$direction]['parts']) > 0) {
1134
 
                        $parts = &$opData[$direction]['parts'];
1135
 
                        $part_count = sizeof($parts);
1136
 
                        $style = $opData['style'];
1137
 
                        $use = $opData[$direction]['use'];
1138
 
                        $this->debug("have $part_count part(s) to serialize using $style/$use");
1139
 
                        if (is_array($parameters)) {
1140
 
                                $parametersArrayType = $this->isArraySimpleOrStruct($parameters);
1141
 
                                $parameter_count = count($parameters);
1142
 
                                $this->debug("have $parameter_count parameter(s) provided as $parametersArrayType to serialize");
1143
 
                                // check for Microsoft-style wrapped parameters
1144
 
                                if ($style == 'document' && $use == 'literal' && $part_count == 1 && isset($parts['parameters'])) {
1145
 
                                        $this->debug('check whether the caller has wrapped the parameters');
1146
 
                                        if ((($parametersArrayType == 'arrayStruct' || $parameter_count == 0) && !isset($parameters['parameters'])) || ($direction == 'output' && $parametersArrayType == 'arraySimple' && $parameter_count == 1)) {
1147
 
                                                $this->debug('check whether caller\'s parameters match the wrapped ones');
1148
 
                                                if ($this->parametersMatchWrapped($parts['parameters'], $parameters)) {
1149
 
                                                        $this->debug('wrap the parameters for the caller');
1150
 
                                                        $parameters = array('parameters' => $parameters);
1151
 
                                                        $parameter_count = 1;
1152
 
                                                }
1153
 
                                        }
1154
 
                                }
1155
 
                                foreach ($parts as $name => $type) {
1156
 
                                        $this->debug("serializing part $name of type $type");
1157
 
                                        // Track encoding style
1158
 
                                        if (isset($opData[$direction]['encodingStyle']) && $encodingStyle != $opData[$direction]['encodingStyle']) {
1159
 
                                                $encodingStyle = $opData[$direction]['encodingStyle'];                  
1160
 
                                                $enc_style = $encodingStyle;
1161
 
                                        } else {
1162
 
                                                $enc_style = false;
1163
 
                                        }
1164
 
                                        // NOTE: add error handling here
1165
 
                                        // if serializeType returns false, then catch global error and fault
1166
 
                                        if ($parametersArrayType == 'arraySimple') {
1167
 
                                                $p = array_shift($parameters);
1168
 
                                                $this->debug('calling serializeType w/indexed param');
1169
 
                                                $xml .= $this->serializeType($name, $type, $p, $use, $enc_style);
1170
 
                                        } elseif (isset($parameters[$name])) {
1171
 
                                                $this->debug('calling serializeType w/named param');
1172
 
                                                $xml .= $this->serializeType($name, $type, $parameters[$name], $use, $enc_style);
1173
 
                                        } else {
1174
 
                                                // TODO: only send nillable
1175
 
                                                $this->debug('calling serializeType w/null param');
1176
 
                                                $xml .= $this->serializeType($name, $type, null, $use, $enc_style);
1177
 
                                        }
1178
 
                                }
1179
 
                        } else {
1180
 
                                $this->debug('no parameters passed.');
1181
 
                        }
1182
 
                }
1183
 
                $this->debug("serializeRPCParameters returning: $xml");
1184
 
                return $xml;
1185
 
        } 
1186
 
        
1187
 
        /**
1188
 
         * serialize a PHP value according to a WSDL message definition
1189
 
         * 
1190
 
         * TODO
1191
 
         * - multi-ref serialization
1192
 
         * - validate PHP values against type definitions, return errors if invalid
1193
 
         * 
1194
 
         * @param string $operation operation name
1195
 
         * @param string $direction (input|output)
1196
 
         * @param mixed $parameters parameter value(s)
1197
 
         * @return mixed parameters serialized as XML or false on error (e.g. operation not found)
1198
 
         * @access public
1199
 
         * @deprecated
1200
 
         */
1201
 
        function serializeParameters($operation, $direction, $parameters)
1202
 
        {
1203
 
                $this->debug("in serializeParameters: operation=$operation, direction=$direction, XMLSchemaVersion=$this->XMLSchemaVersion"); 
1204
 
                $this->appendDebug('parameters=' . $this->varDump($parameters));
1205
 
                
1206
 
                if ($direction != 'input' && $direction != 'output') {
1207
 
                        $this->debug('The value of the \$direction argument needs to be either "input" or "output"');
1208
 
                        $this->setError('The value of the \$direction argument needs to be either "input" or "output"');
1209
 
                        return false;
1210
 
                } 
1211
 
                if (!$opData = $this->getOperationData($operation)) {
1212
 
                        $this->debug('Unable to retrieve WSDL data for operation: ' . $operation);
1213
 
                        $this->setError('Unable to retrieve WSDL data for operation: ' . $operation);
1214
 
                        return false;
1215
 
                }
1216
 
                $this->debug('opData:');
1217
 
                $this->appendDebug($this->varDump($opData));
1218
 
                
1219
 
                // Get encoding style for output and set to current
1220
 
                $encodingStyle = 'http://schemas.xmlsoap.org/soap/encoding/';
1221
 
                if(($direction == 'input') && isset($opData['output']['encodingStyle']) && ($opData['output']['encodingStyle'] != $encodingStyle)) {
1222
 
                        $encodingStyle = $opData['output']['encodingStyle'];
1223
 
                        $enc_style = $encodingStyle;
1224
 
                }
1225
 
                
1226
 
                // set input params
1227
 
                $xml = '';
1228
 
                if (isset($opData[$direction]['parts']) && sizeof($opData[$direction]['parts']) > 0) {
1229
 
                        
1230
 
                        $use = $opData[$direction]['use'];
1231
 
                        $this->debug("use=$use");
1232
 
                        $this->debug('got ' . count($opData[$direction]['parts']) . ' part(s)');
1233
 
                        if (is_array($parameters)) {
1234
 
                                $parametersArrayType = $this->isArraySimpleOrStruct($parameters);
1235
 
                                $this->debug('have ' . $parametersArrayType . ' parameters');
1236
 
                                foreach($opData[$direction]['parts'] as $name => $type) {
1237
 
                                        $this->debug('serializing part "'.$name.'" of type "'.$type.'"');
1238
 
                                        // Track encoding style
1239
 
                                        if(isset($opData[$direction]['encodingStyle']) && $encodingStyle != $opData[$direction]['encodingStyle']) {
1240
 
                                                $encodingStyle = $opData[$direction]['encodingStyle'];                  
1241
 
                                                $enc_style = $encodingStyle;
1242
 
                                        } else {
1243
 
                                                $enc_style = false;
1244
 
                                        }
1245
 
                                        // NOTE: add error handling here
1246
 
                                        // if serializeType returns false, then catch global error and fault
1247
 
                                        if ($parametersArrayType == 'arraySimple') {
1248
 
                                                $p = array_shift($parameters);
1249
 
                                                $this->debug('calling serializeType w/indexed param');
1250
 
                                                $xml .= $this->serializeType($name, $type, $p, $use, $enc_style);
1251
 
                                        } elseif (isset($parameters[$name])) {
1252
 
                                                $this->debug('calling serializeType w/named param');
1253
 
                                                $xml .= $this->serializeType($name, $type, $parameters[$name], $use, $enc_style);
1254
 
                                        } else {
1255
 
                                                // TODO: only send nillable
1256
 
                                                $this->debug('calling serializeType w/null param');
1257
 
                                                $xml .= $this->serializeType($name, $type, null, $use, $enc_style);
1258
 
                                        }
1259
 
                                }
1260
 
                        } else {
1261
 
                                $this->debug('no parameters passed.');
1262
 
                        }
1263
 
                }
1264
 
                $this->debug("serializeParameters returning: $xml");
1265
 
                return $xml;
1266
 
        } 
1267
 
        
1268
 
        /**
1269
 
         * serializes a PHP value according a given type definition
1270
 
         * 
1271
 
         * @param string $name name of value (part or element)
1272
 
         * @param string $type XML schema type of value (type or element)
1273
 
         * @param mixed $value a native PHP value (parameter value)
1274
 
         * @param string $use use for part (encoded|literal)
1275
 
         * @param string $encodingStyle SOAP encoding style for the value (if different than the enclosing style)
1276
 
         * @param boolean $unqualified a kludge for what should be XML namespace form handling
1277
 
         * @return string value serialized as an XML string
1278
 
         * @access private
1279
 
         */
1280
 
        function serializeType($name, $type, $value, $use='encoded', $encodingStyle=false, $unqualified=false)
1281
 
        {
1282
 
                $this->debug("in serializeType: name=$name, type=$type, use=$use, encodingStyle=$encodingStyle, unqualified=" . ($unqualified ? "unqualified" : "qualified"));
1283
 
                $this->appendDebug("value=" . $this->varDump($value));
1284
 
                if($use == 'encoded' && $encodingStyle) {
1285
 
                        $encodingStyle = ' SOAP-ENV:encodingStyle="' . $encodingStyle . '"';
1286
 
                }
1287
 
 
1288
 
                // if a soapval has been supplied, let its type override the WSDL
1289
 
        if (is_object($value) && get_class($value) == 'soapval') {
1290
 
                if ($value->type_ns) {
1291
 
                        $type = $value->type_ns . ':' . $value->type;
1292
 
                        $forceType = true;
1293
 
                        $this->debug("in serializeType: soapval overrides type to $type");
1294
 
                } elseif ($value->type) {
1295
 
                        $type = $value->type;
1296
 
                        $forceType = true;
1297
 
                        $this->debug("in serializeType: soapval overrides type to $type");
1298
 
                } else {
1299
 
                        $forceType = false;
1300
 
                        $this->debug("in serializeType: soapval does not override type");
1301
 
                }
1302
 
                $attrs = $value->attributes;
1303
 
                $value = $value->value;
1304
 
                $this->debug("in serializeType: soapval overrides value to $value");
1305
 
                if ($attrs) {
1306
 
                        if (!is_array($value)) {
1307
 
                                $value['!'] = $value;
1308
 
                        }
1309
 
                        foreach ($attrs as $n => $v) {
1310
 
                                $value['!' . $n] = $v;
1311
 
                        }
1312
 
                        $this->debug("in serializeType: soapval provides attributes");
1313
 
                    }
1314
 
        } else {
1315
 
                $forceType = false;
1316
 
        }
1317
 
 
1318
 
                $xml = '';
1319
 
                if (strpos($type, ':')) {
1320
 
                        $uqType = substr($type, strrpos($type, ':') + 1);
1321
 
                        $ns = substr($type, 0, strrpos($type, ':'));
1322
 
                        $this->debug("in serializeType: got a prefixed type: $uqType, $ns");
1323
 
                        if ($this->getNamespaceFromPrefix($ns)) {
1324
 
                                $ns = $this->getNamespaceFromPrefix($ns);
1325
 
                                $this->debug("in serializeType: expanded prefixed type: $uqType, $ns");
1326
 
                        }
1327
 
 
1328
 
                        if($ns == $this->XMLSchemaVersion || $ns == 'http://schemas.xmlsoap.org/soap/encoding/'){
1329
 
                                $this->debug('in serializeType: type namespace indicates XML Schema or SOAP Encoding type');
1330
 
                                if ($unqualified && $use == 'literal') {
1331
 
                                        $elementNS = " xmlns=\"\"";
1332
 
                                } else {
1333
 
                                        $elementNS = '';
1334
 
                                }
1335
 
                                if (is_null($value)) {
1336
 
                                        if ($use == 'literal') {
1337
 
                                                // TODO: depends on minOccurs
1338
 
                                                $xml = "<$name$elementNS/>";
1339
 
                                        } else {
1340
 
                                                // TODO: depends on nillable, which should be checked before calling this method
1341
 
                                                $xml = "<$name$elementNS xsi:nil=\"true\" xsi:type=\"" . $this->getPrefixFromNamespace($ns) . ":$uqType\"/>";
1342
 
                                        }
1343
 
                                        $this->debug("in serializeType: returning: $xml");
1344
 
                                        return $xml;
1345
 
                                }
1346
 
                                if ($uqType == 'Array') {
1347
 
                                        // JBoss/Axis does this sometimes
1348
 
                                        return $this->serialize_val($value, $name, false, false, false, false, $use);
1349
 
                                }
1350
 
                        if ($uqType == 'boolean') {
1351
 
                                if ((is_string($value) && $value == 'false') || (! $value)) {
1352
 
                                                $value = 'false';
1353
 
                                        } else {
1354
 
                                                $value = 'true';
1355
 
                                        }
1356
 
                                } 
1357
 
                                if ($uqType == 'string' && gettype($value) == 'string') {
1358
 
                                        $value = $this->expandEntities($value);
1359
 
                                }
1360
 
                                if (($uqType == 'long' || $uqType == 'unsignedLong') && gettype($value) == 'double') {
1361
 
                                        $value = sprintf("%.0lf", $value);
1362
 
                                }
1363
 
                                // it's a scalar
1364
 
                                // TODO: what about null/nil values?
1365
 
                                // check type isn't a custom type extending xmlschema namespace
1366
 
                                if (!$this->getTypeDef($uqType, $ns)) {
1367
 
                                        if ($use == 'literal') {
1368
 
                                                if ($forceType) {
1369
 
                                                        $xml = "<$name$elementNS xsi:type=\"" . $this->getPrefixFromNamespace($ns) . ":$uqType\">$value</$name>";
1370
 
                                                } else {
1371
 
                                                        $xml = "<$name$elementNS>$value</$name>";
1372
 
                                                }
1373
 
                                        } else {
1374
 
                                                $xml = "<$name$elementNS xsi:type=\"" . $this->getPrefixFromNamespace($ns) . ":$uqType\"$encodingStyle>$value</$name>";
1375
 
                                        }
1376
 
                                        $this->debug("in serializeType: returning: $xml");
1377
 
                                        return $xml;
1378
 
                                }
1379
 
                                $this->debug('custom type extends XML Schema or SOAP Encoding namespace (yuck)');
1380
 
                        } else if ($ns == 'http://xml.apache.org/xml-soap') {
1381
 
                                $this->debug('in serializeType: appears to be Apache SOAP type');
1382
 
                                if ($uqType == 'Map') {
1383
 
                                        $tt_prefix = $this->getPrefixFromNamespace('http://xml.apache.org/xml-soap');
1384
 
                                        if (! $tt_prefix) {
1385
 
                                                $this->debug('in serializeType: Add namespace for Apache SOAP type');
1386
 
                                                $tt_prefix = 'ns' . rand(1000, 9999);
1387
 
                                                $this->namespaces[$tt_prefix] = 'http://xml.apache.org/xml-soap';
1388
 
                                                // force this to be added to usedNamespaces
1389
 
                                                $tt_prefix = $this->getPrefixFromNamespace('http://xml.apache.org/xml-soap');
1390
 
                                        }
1391
 
                                        $contents = '';
1392
 
                                        foreach($value as $k => $v) {
1393
 
                                                $this->debug("serializing map element: key $k, value $v");
1394
 
                                                $contents .= '<item>';
1395
 
                                                $contents .= $this->serialize_val($k,'key',false,false,false,false,$use);
1396
 
                                                $contents .= $this->serialize_val($v,'value',false,false,false,false,$use);
1397
 
                                                $contents .= '</item>';
1398
 
                                        }
1399
 
                                        if ($use == 'literal') {
1400
 
                                                if ($forceType) {
1401
 
                                                        $xml = "<$name xsi:type=\"" . $tt_prefix . ":$uqType\">$contents</$name>";
1402
 
                                                } else {
1403
 
                                                        $xml = "<$name>$contents</$name>";
1404
 
                                                }
1405
 
                                        } else {
1406
 
                                                $xml = "<$name xsi:type=\"" . $tt_prefix . ":$uqType\"$encodingStyle>$contents</$name>";
1407
 
                                        }
1408
 
                                        $this->debug("in serializeType: returning: $xml");
1409
 
                                        return $xml;
1410
 
                                }
1411
 
                                $this->debug('in serializeType: Apache SOAP type, but only support Map');
1412
 
                        }
1413
 
                } else {
1414
 
                        // TODO: should the type be compared to types in XSD, and the namespace
1415
 
                        // set to XSD if the type matches?
1416
 
                        $this->debug("in serializeType: No namespace for type $type");
1417
 
                        $ns = '';
1418
 
                        $uqType = $type;
1419
 
                }
1420
 
                if(!$typeDef = $this->getTypeDef($uqType, $ns)){
1421
 
                        $this->setError("$type ($uqType) is not a supported type.");
1422
 
                        $this->debug("in serializeType: $type ($uqType) is not a supported type.");
1423
 
                        return false;
1424
 
                } else {
1425
 
                        $this->debug("in serializeType: found typeDef");
1426
 
                        $this->appendDebug('typeDef=' . $this->varDump($typeDef));
1427
 
                        if (substr($uqType, -1) == '^') {
1428
 
                                $uqType = substr($uqType, 0, -1);
1429
 
                        }
1430
 
                }
1431
 
                $phpType = $typeDef['phpType'];
1432
 
                $this->debug("in serializeType: uqType: $uqType, ns: $ns, phptype: $phpType, arrayType: " . (isset($typeDef['arrayType']) ? $typeDef['arrayType'] : '') ); 
1433
 
                // if php type == struct, map value to the <all> element names
1434
 
                if ($phpType == 'struct') {
1435
 
                        if (isset($typeDef['typeClass']) && $typeDef['typeClass'] == 'element') {
1436
 
                                $elementName = $uqType;
1437
 
                                if (isset($typeDef['form']) && ($typeDef['form'] == 'qualified')) {
1438
 
                                        $elementNS = " xmlns=\"$ns\"";
1439
 
                                } else {
1440
 
                                        $elementNS = " xmlns=\"\"";
1441
 
                                }
1442
 
                        } else {
1443
 
                                $elementName = $name;
1444
 
                                if ($unqualified) {
1445
 
                                        $elementNS = " xmlns=\"\"";
1446
 
                                } else {
1447
 
                                        $elementNS = '';
1448
 
                                }
1449
 
                        }
1450
 
                        if (is_null($value)) {
1451
 
                                if ($use == 'literal') {
1452
 
                                        // TODO: depends on minOccurs
1453
 
                                        $xml = "<$elementName$elementNS/>";
1454
 
                                } else {
1455
 
                                        $xml = "<$elementName$elementNS xsi:nil=\"true\" xsi:type=\"" . $this->getPrefixFromNamespace($ns) . ":$uqType\"/>";
1456
 
                                }
1457
 
                                $this->debug("in serializeType: returning: $xml");
1458
 
                                return $xml;
1459
 
                        }
1460
 
                        if (is_object($value)) {
1461
 
                                $value = get_object_vars($value);
1462
 
                        }
1463
 
                        if (is_array($value)) {
1464
 
                                $elementAttrs = $this->serializeComplexTypeAttributes($typeDef, $value, $ns, $uqType);
1465
 
                                if ($use == 'literal') {
1466
 
                                        if ($forceType) {
1467
 
                                                $xml = "<$elementName$elementNS$elementAttrs xsi:type=\"" . $this->getPrefixFromNamespace($ns) . ":$uqType\">";
1468
 
                                        } else {
1469
 
                                                $xml = "<$elementName$elementNS$elementAttrs>";
1470
 
                                        }
1471
 
                                } else {
1472
 
                                        $xml = "<$elementName$elementNS$elementAttrs xsi:type=\"" . $this->getPrefixFromNamespace($ns) . ":$uqType\"$encodingStyle>";
1473
 
                                }
1474
 
        
1475
 
                                $xml .= $this->serializeComplexTypeElements($typeDef, $value, $ns, $uqType, $use, $encodingStyle);
1476
 
                                $xml .= "</$elementName>";
1477
 
                        } else {
1478
 
                                $this->debug("in serializeType: phpType is struct, but value is not an array");
1479
 
                                $this->setError("phpType is struct, but value is not an array: see debug output for details");
1480
 
                                $xml = '';
1481
 
                        }
1482
 
                } elseif ($phpType == 'array') {
1483
 
                        if (isset($typeDef['form']) && ($typeDef['form'] == 'qualified')) {
1484
 
                                $elementNS = " xmlns=\"$ns\"";
1485
 
                        } else {
1486
 
                                if ($unqualified) {
1487
 
                                        $elementNS = " xmlns=\"\"";
1488
 
                                } else {
1489
 
                                        $elementNS = '';
1490
 
                                }
1491
 
                        }
1492
 
                        if (is_null($value)) {
1493
 
                                if ($use == 'literal') {
1494
 
                                        // TODO: depends on minOccurs
1495
 
                                        $xml = "<$name$elementNS/>";
1496
 
                                } else {
1497
 
                                        $xml = "<$name$elementNS xsi:nil=\"true\" xsi:type=\"" .
1498
 
                                                $this->getPrefixFromNamespace('http://schemas.xmlsoap.org/soap/encoding/') .
1499
 
                                                ":Array\" " .
1500
 
                                                $this->getPrefixFromNamespace('http://schemas.xmlsoap.org/soap/encoding/') .
1501
 
                                                ':arrayType="' .
1502
 
                                                $this->getPrefixFromNamespace($this->getPrefix($typeDef['arrayType'])) .
1503
 
                                                ':' .
1504
 
                                                $this->getLocalPart($typeDef['arrayType'])."[0]\"/>";
1505
 
                                }
1506
 
                                $this->debug("in serializeType: returning: $xml");
1507
 
                                return $xml;
1508
 
                        }
1509
 
                        if (isset($typeDef['multidimensional'])) {
1510
 
                                $nv = array();
1511
 
                                foreach($value as $v) {
1512
 
                                        $cols = ',' . sizeof($v);
1513
 
                                        $nv = array_merge($nv, $v);
1514
 
                                } 
1515
 
                                $value = $nv;
1516
 
                        } else {
1517
 
                                $cols = '';
1518
 
                        } 
1519
 
                        if (is_array($value) && sizeof($value) >= 1) {
1520
 
                                $rows = sizeof($value);
1521
 
                                $contents = '';
1522
 
                                foreach($value as $k => $v) {
1523
 
                                        $this->debug("serializing array element: $k, $v of type: $typeDef[arrayType]");
1524
 
                                        //if (strpos($typeDef['arrayType'], ':') ) {
1525
 
                                        if (!in_array($typeDef['arrayType'],$this->typemap['http://www.w3.org/2001/XMLSchema'])) {
1526
 
                                            $contents .= $this->serializeType('item', $typeDef['arrayType'], $v, $use);
1527
 
                                        } else {
1528
 
                                            $contents .= $this->serialize_val($v, 'item', $typeDef['arrayType'], null, $this->XMLSchemaVersion, false, $use);
1529
 
                                        } 
1530
 
                                }
1531
 
                        } else {
1532
 
                                $rows = 0;
1533
 
                                $contents = null;
1534
 
                        }
1535
 
                        // TODO: for now, an empty value will be serialized as a zero element
1536
 
                        // array.  Revisit this when coding the handling of null/nil values.
1537
 
                        if ($use == 'literal') {
1538
 
                                $xml = "<$name$elementNS>"
1539
 
                                        .$contents
1540
 
                                        ."</$name>";
1541
 
                        } else {
1542
 
                                $xml = "<$name$elementNS xsi:type=\"".$this->getPrefixFromNamespace('http://schemas.xmlsoap.org/soap/encoding/').':Array" '.
1543
 
                                        $this->getPrefixFromNamespace('http://schemas.xmlsoap.org/soap/encoding/')
1544
 
                                        .':arrayType="'
1545
 
                                        .$this->getPrefixFromNamespace($this->getPrefix($typeDef['arrayType']))
1546
 
                                        .":".$this->getLocalPart($typeDef['arrayType'])."[$rows$cols]\">"
1547
 
                                        .$contents
1548
 
                                        ."</$name>";
1549
 
                        }
1550
 
                } elseif ($phpType == 'scalar') {
1551
 
                        if (isset($typeDef['form']) && ($typeDef['form'] == 'qualified')) {
1552
 
                                $elementNS = " xmlns=\"$ns\"";
1553
 
                        } else {
1554
 
                                if ($unqualified) {
1555
 
                                        $elementNS = " xmlns=\"\"";
1556
 
                                } else {
1557
 
                                        $elementNS = '';
1558
 
                                }
1559
 
                        }
1560
 
                        if ($use == 'literal') {
1561
 
                                if ($forceType) {
1562
 
                                        $xml = "<$name$elementNS xsi:type=\"" . $this->getPrefixFromNamespace($ns) . ":$uqType\">$value</$name>";
1563
 
                                } else {
1564
 
                                        $xml = "<$name$elementNS>$value</$name>";
1565
 
                                }
1566
 
                        } else {
1567
 
                                $xml = "<$name$elementNS xsi:type=\"" . $this->getPrefixFromNamespace($ns) . ":$uqType\"$encodingStyle>$value</$name>";
1568
 
                        }
1569
 
                }
1570
 
                $this->debug("in serializeType: returning: $xml");
1571
 
                return $xml;
1572
 
        }
1573
 
        
1574
 
        /**
1575
 
         * serializes the attributes for a complexType
1576
 
         *
1577
 
         * @param array $typeDef our internal representation of an XML schema type (or element)
1578
 
         * @param mixed $value a native PHP value (parameter value)
1579
 
         * @param string $ns the namespace of the type
1580
 
         * @param string $uqType the local part of the type
1581
 
         * @return string value serialized as an XML string
1582
 
         * @access private
1583
 
         */
1584
 
        function serializeComplexTypeAttributes($typeDef, $value, $ns, $uqType) {
1585
 
                $xml = '';
1586
 
                if (isset($typeDef['attrs']) && is_array($typeDef['attrs'])) {
1587
 
                        $this->debug("serialize attributes for XML Schema type $ns:$uqType");
1588
 
                        if (is_array($value)) {
1589
 
                                $xvalue = $value;
1590
 
                        } elseif (is_object($value)) {
1591
 
                                $xvalue = get_object_vars($value);
1592
 
                        } else {
1593
 
                                $this->debug("value is neither an array nor an object for XML Schema type $ns:$uqType");
1594
 
                                $xvalue = array();
1595
 
                        }
1596
 
                        foreach ($typeDef['attrs'] as $aName => $attrs) {
1597
 
                                if (isset($xvalue['!' . $aName])) {
1598
 
                                        $xname = '!' . $aName;
1599
 
                                        $this->debug("value provided for attribute $aName with key $xname");
1600
 
                                } elseif (isset($xvalue[$aName])) {
1601
 
                                        $xname = $aName;
1602
 
                                        $this->debug("value provided for attribute $aName with key $xname");
1603
 
                                } elseif (isset($attrs['default'])) {
1604
 
                                        $xname = '!' . $aName;
1605
 
                                        $xvalue[$xname] = $attrs['default'];
1606
 
                                        $this->debug('use default value of ' . $xvalue[$aName] . ' for attribute ' . $aName);
1607
 
                                } else {
1608
 
                                        $xname = '';
1609
 
                                        $this->debug("no value provided for attribute $aName");
1610
 
                                }
1611
 
                                if ($xname) {
1612
 
                                        $xml .=  " $aName=\"" . $this->expandEntities($xvalue[$xname]) . "\"";
1613
 
                                }
1614
 
                        } 
1615
 
                } else {
1616
 
                        $this->debug("no attributes to serialize for XML Schema type $ns:$uqType");
1617
 
                }
1618
 
                if (isset($typeDef['extensionBase'])) {
1619
 
                        $ns = $this->getPrefix($typeDef['extensionBase']);
1620
 
                        $uqType = $this->getLocalPart($typeDef['extensionBase']);
1621
 
                        if ($this->getNamespaceFromPrefix($ns)) {
1622
 
                                $ns = $this->getNamespaceFromPrefix($ns);
1623
 
                        }
1624
 
                        if ($typeDef = $this->getTypeDef($uqType, $ns)) {
1625
 
                                $this->debug("serialize attributes for extension base $ns:$uqType");
1626
 
                                $xml .= $this->serializeComplexTypeAttributes($typeDef, $value, $ns, $uqType);
1627
 
                        } else {
1628
 
                                $this->debug("extension base $ns:$uqType is not a supported type");
1629
 
                        }
1630
 
                }
1631
 
                return $xml;
1632
 
        }
1633
 
 
1634
 
        /**
1635
 
         * serializes the elements for a complexType
1636
 
         *
1637
 
         * @param array $typeDef our internal representation of an XML schema type (or element)
1638
 
         * @param mixed $value a native PHP value (parameter value)
1639
 
         * @param string $ns the namespace of the type
1640
 
         * @param string $uqType the local part of the type
1641
 
         * @param string $use use for part (encoded|literal)
1642
 
         * @param string $encodingStyle SOAP encoding style for the value (if different than the enclosing style)
1643
 
         * @return string value serialized as an XML string
1644
 
         * @access private
1645
 
         */
1646
 
        function serializeComplexTypeElements($typeDef, $value, $ns, $uqType, $use='encoded', $encodingStyle=false) {
1647
 
                $xml = '';
1648
 
                if (isset($typeDef['elements']) && is_array($typeDef['elements'])) {
1649
 
                        $this->debug("in serializeComplexTypeElements, serialize elements for XML Schema type $ns:$uqType");
1650
 
                        if (is_array($value)) {
1651
 
                                $xvalue = $value;
1652
 
                        } elseif (is_object($value)) {
1653
 
                                $xvalue = get_object_vars($value);
1654
 
                        } else {
1655
 
                                $this->debug("value is neither an array nor an object for XML Schema type $ns:$uqType");
1656
 
                                $xvalue = array();
1657
 
                        }
1658
 
                        // toggle whether all elements are present - ideally should validate against schema
1659
 
                        if (count($typeDef['elements']) != count($xvalue)){
1660
 
                                $optionals = true;
1661
 
                        }
1662
 
                        foreach ($typeDef['elements'] as $eName => $attrs) {
1663
 
                                if (!isset($xvalue[$eName])) {
1664
 
                                        if (isset($attrs['default'])) {
1665
 
                                                $xvalue[$eName] = $attrs['default'];
1666
 
                                                $this->debug('use default value of ' . $xvalue[$eName] . ' for element ' . $eName);
1667
 
                                        }
1668
 
                                }
1669
 
                                // if user took advantage of a minOccurs=0, then only serialize named parameters
1670
 
                                if (isset($optionals)
1671
 
                                    && (!isset($xvalue[$eName])) 
1672
 
                                        && ( (!isset($attrs['nillable'])) || $attrs['nillable'] != 'true')
1673
 
                                        ){
1674
 
                                        if (isset($attrs['minOccurs']) && $attrs['minOccurs'] <> '0') {
1675
 
                                                $this->debug("apparent error: no value provided for element $eName with minOccurs=" . $attrs['minOccurs']);
1676
 
                                        }
1677
 
                                        // do nothing
1678
 
                                        $this->debug("no value provided for complexType element $eName and element is not nillable, so serialize nothing");
1679
 
                                } else {
1680
 
                                        // get value
1681
 
                                        if (isset($xvalue[$eName])) {
1682
 
                                            $v = $xvalue[$eName];
1683
 
                                        } else {
1684
 
                                            $v = null;
1685
 
                                        }
1686
 
                                        if (isset($attrs['form'])) {
1687
 
                                                $unqualified = ($attrs['form'] == 'unqualified');
1688
 
                                        } else {
1689
 
                                                $unqualified = false;
1690
 
                                        }
1691
 
                                        if (isset($attrs['maxOccurs']) && ($attrs['maxOccurs'] == 'unbounded' || $attrs['maxOccurs'] > 1) && isset($v) && is_array($v) && $this->isArraySimpleOrStruct($v) == 'arraySimple') {
1692
 
                                                $vv = $v;
1693
 
                                                foreach ($vv as $k => $v) {
1694
 
                                                        if (isset($attrs['type']) || isset($attrs['ref'])) {
1695
 
                                                                // serialize schema-defined type
1696
 
                                                            $xml .= $this->serializeType($eName, isset($attrs['type']) ? $attrs['type'] : $attrs['ref'], $v, $use, $encodingStyle, $unqualified);
1697
 
                                                        } else {
1698
 
                                                                // serialize generic type (can this ever really happen?)
1699
 
                                                            $this->debug("calling serialize_val() for $v, $eName, false, false, false, false, $use");
1700
 
                                                            $xml .= $this->serialize_val($v, $eName, false, false, false, false, $use);
1701
 
                                                        }
1702
 
                                                }
1703
 
                                        } else {
1704
 
                                                if (isset($attrs['type']) || isset($attrs['ref'])) {
1705
 
                                                        // serialize schema-defined type
1706
 
                                                    $xml .= $this->serializeType($eName, isset($attrs['type']) ? $attrs['type'] : $attrs['ref'], $v, $use, $encodingStyle, $unqualified);
1707
 
                                                } else {
1708
 
                                                        // serialize generic type (can this ever really happen?)
1709
 
                                                    $this->debug("calling serialize_val() for $v, $eName, false, false, false, false, $use");
1710
 
                                                    $xml .= $this->serialize_val($v, $eName, false, false, false, false, $use);
1711
 
                                                }
1712
 
                                        }
1713
 
                                }
1714
 
                        } 
1715
 
                } else {
1716
 
                        $this->debug("no elements to serialize for XML Schema type $ns:$uqType");
1717
 
                }
1718
 
                if (isset($typeDef['extensionBase'])) {
1719
 
                        $ns = $this->getPrefix($typeDef['extensionBase']);
1720
 
                        $uqType = $this->getLocalPart($typeDef['extensionBase']);
1721
 
                        if ($this->getNamespaceFromPrefix($ns)) {
1722
 
                                $ns = $this->getNamespaceFromPrefix($ns);
1723
 
                        }
1724
 
                        if ($typeDef = $this->getTypeDef($uqType, $ns)) {
1725
 
                                $this->debug("serialize elements for extension base $ns:$uqType");
1726
 
                                $xml .= $this->serializeComplexTypeElements($typeDef, $value, $ns, $uqType, $use, $encodingStyle);
1727
 
                        } else {
1728
 
                                $this->debug("extension base $ns:$uqType is not a supported type");
1729
 
                        }
1730
 
                }
1731
 
                return $xml;
1732
 
        }
1733
 
 
1734
 
        /**
1735
 
        * adds an XML Schema complex type to the WSDL types
1736
 
        *
1737
 
        * @param string $name
1738
 
        * @param string $typeClass (complexType|simpleType|attribute)
1739
 
        * @param string $phpType currently supported are array and struct (php assoc array)
1740
 
        * @param string $compositor (all|sequence|choice)
1741
 
        * @param string $restrictionBase namespace:name (http://schemas.xmlsoap.org/soap/encoding/:Array)
1742
 
        * @param array $elements e.g. array ( name => array(name=>'',type=>'') )
1743
 
        * @param array $attrs e.g. array(array('ref'=>'SOAP-ENC:arrayType','wsdl:arrayType'=>'xsd:string[]'))
1744
 
        * @param string $arrayType as namespace:name (xsd:string)
1745
 
        * @see nusoap_xmlschema
1746
 
        * @access public
1747
 
        */
1748
 
        function addComplexType($name,$typeClass='complexType',$phpType='array',$compositor='',$restrictionBase='',$elements=array(),$attrs=array(),$arrayType='') {
1749
 
                if (count($elements) > 0) {
1750
 
                        $eElements = array();
1751
 
                foreach($elements as $n => $e){
1752
 
                    // expand each element
1753
 
                    $ee = array();
1754
 
                    foreach ($e as $k => $v) {
1755
 
                            $k = strpos($k,':') ? $this->expandQname($k) : $k;
1756
 
                            $v = strpos($v,':') ? $this->expandQname($v) : $v;
1757
 
                            $ee[$k] = $v;
1758
 
                        }
1759
 
                        $eElements[$n] = $ee;
1760
 
                }
1761
 
                $elements = $eElements;
1762
 
                }
1763
 
                
1764
 
                if (count($attrs) > 0) {
1765
 
                foreach($attrs as $n => $a){
1766
 
                    // expand each attribute
1767
 
                    foreach ($a as $k => $v) {
1768
 
                            $k = strpos($k,':') ? $this->expandQname($k) : $k;
1769
 
                            $v = strpos($v,':') ? $this->expandQname($v) : $v;
1770
 
                            $aa[$k] = $v;
1771
 
                        }
1772
 
                        $eAttrs[$n] = $aa;
1773
 
                }
1774
 
                $attrs = $eAttrs;
1775
 
                }
1776
 
 
1777
 
                $restrictionBase = strpos($restrictionBase,':') ? $this->expandQname($restrictionBase) : $restrictionBase;
1778
 
                $arrayType = strpos($arrayType,':') ? $this->expandQname($arrayType) : $arrayType;
1779
 
 
1780
 
                $typens = isset($this->namespaces['types']) ? $this->namespaces['types'] : $this->namespaces['tns'];
1781
 
                $this->schemas[$typens][0]->addComplexType($name,$typeClass,$phpType,$compositor,$restrictionBase,$elements,$attrs,$arrayType);
1782
 
        }
1783
 
 
1784
 
        /**
1785
 
        * adds an XML Schema simple type to the WSDL types
1786
 
        *
1787
 
        * @param string $name
1788
 
        * @param string $restrictionBase namespace:name (http://schemas.xmlsoap.org/soap/encoding/:Array)
1789
 
        * @param string $typeClass (should always be simpleType)
1790
 
        * @param string $phpType (should always be scalar)
1791
 
        * @param array $enumeration array of values
1792
 
        * @see nusoap_xmlschema
1793
 
        * @access public
1794
 
        */
1795
 
        function addSimpleType($name, $restrictionBase='', $typeClass='simpleType', $phpType='scalar', $enumeration=array()) {
1796
 
                $restrictionBase = strpos($restrictionBase,':') ? $this->expandQname($restrictionBase) : $restrictionBase;
1797
 
 
1798
 
                $typens = isset($this->namespaces['types']) ? $this->namespaces['types'] : $this->namespaces['tns'];
1799
 
                $this->schemas[$typens][0]->addSimpleType($name, $restrictionBase, $typeClass, $phpType, $enumeration);
1800
 
        }
1801
 
 
1802
 
        /**
1803
 
        * adds an element to the WSDL types
1804
 
        *
1805
 
        * @param array $attrs attributes that must include name and type
1806
 
        * @see nusoap_xmlschema
1807
 
        * @access public
1808
 
        */
1809
 
        function addElement($attrs) {
1810
 
                $typens = isset($this->namespaces['types']) ? $this->namespaces['types'] : $this->namespaces['tns'];
1811
 
                $this->schemas[$typens][0]->addElement($attrs);
1812
 
        }
1813
 
 
1814
 
        /**
1815
 
        * register an operation with the server
1816
 
        * 
1817
 
        * @param string $name operation (method) name
1818
 
        * @param array $in assoc array of input values: key = param name, value = param type
1819
 
        * @param array $out assoc array of output values: key = param name, value = param type
1820
 
        * @param string $namespace optional The namespace for the operation
1821
 
        * @param string $soapaction optional The soapaction for the operation
1822
 
        * @param string $style (rpc|document) optional The style for the operation Note: when 'document' is specified, parameter and return wrappers are created for you automatically
1823
 
        * @param string $use (encoded|literal) optional The use for the parameters (cannot mix right now)
1824
 
        * @param string $documentation optional The description to include in the WSDL
1825
 
        * @param string $encodingStyle optional (usually 'http://schemas.xmlsoap.org/soap/encoding/' for encoded)
1826
 
        * @access public 
1827
 
        */
1828
 
        function addOperation($name, $in = false, $out = false, $namespace = false, $soapaction = false, $style = 'rpc', $use = 'encoded', $documentation = '', $encodingStyle = ''){
1829
 
                if ($use == 'encoded' && $encodingStyle == '') {
1830
 
                        $encodingStyle = 'http://schemas.xmlsoap.org/soap/encoding/';
1831
 
                }
1832
 
 
1833
 
                if ($style == 'document') {
1834
 
                        $elements = array();
1835
 
                        foreach ($in as $n => $t) {
1836
 
                                $elements[$n] = array('name' => $n, 'type' => $t);
1837
 
                        }
1838
 
                        $this->addComplexType($name . 'RequestType', 'complexType', 'struct', 'all', '', $elements);
1839
 
                        $this->addElement(array('name' => $name, 'type' => $name . 'RequestType'));
1840
 
                        $in = array('parameters' => 'tns:' . $name . '^');
1841
 
 
1842
 
                        $elements = array();
1843
 
                        foreach ($out as $n => $t) {
1844
 
                                $elements[$n] = array('name' => $n, 'type' => $t);
1845
 
                        }
1846
 
                        $this->addComplexType($name . 'ResponseType', 'complexType', 'struct', 'all', '', $elements);
1847
 
                        $this->addElement(array('name' => $name . 'Response', 'type' => $name . 'ResponseType', 'form' => 'qualified'));
1848
 
                        $out = array('parameters' => 'tns:' . $name . 'Response' . '^');
1849
 
                }
1850
 
 
1851
 
                // get binding
1852
 
                $this->bindings[ $this->serviceName . 'Binding' ]['operations'][$name] =
1853
 
                array(
1854
 
                'name' => $name,
1855
 
                'binding' => $this->serviceName . 'Binding',
1856
 
                'endpoint' => $this->endpoint,
1857
 
                'soapAction' => $soapaction,
1858
 
                'style' => $style,
1859
 
                'input' => array(
1860
 
                        'use' => $use,
1861
 
                        'namespace' => $namespace,
1862
 
                        'encodingStyle' => $encodingStyle,
1863
 
                        'message' => $name . 'Request',
1864
 
                        'parts' => $in),
1865
 
                'output' => array(
1866
 
                        'use' => $use,
1867
 
                        'namespace' => $namespace,
1868
 
                        'encodingStyle' => $encodingStyle,
1869
 
                        'message' => $name . 'Response',
1870
 
                        'parts' => $out),
1871
 
                'namespace' => $namespace,
1872
 
                'transport' => 'http://schemas.xmlsoap.org/soap/http',
1873
 
                'documentation' => $documentation); 
1874
 
                // add portTypes
1875
 
                // add messages
1876
 
                if($in)
1877
 
                {
1878
 
                        foreach($in as $pName => $pType)
1879
 
                        {
1880
 
                                if(strpos($pType,':')) {
1881
 
                                        $pType = $this->getNamespaceFromPrefix($this->getPrefix($pType)).":".$this->getLocalPart($pType);
1882
 
                                }
1883
 
                                $this->messages[$name.'Request'][$pName] = $pType;
1884
 
                        }
1885
 
                } else {
1886
 
            $this->messages[$name.'Request']= '0';
1887
 
        }
1888
 
                if($out)
1889
 
                {
1890
 
                        foreach($out as $pName => $pType)
1891
 
                        {
1892
 
                                if(strpos($pType,':')) {
1893
 
                                        $pType = $this->getNamespaceFromPrefix($this->getPrefix($pType)).":".$this->getLocalPart($pType);
1894
 
                                }
1895
 
                                $this->messages[$name.'Response'][$pName] = $pType;
1896
 
                        }
1897
 
                } else {
1898
 
            $this->messages[$name.'Response']= '0';
1899
 
        }
1900
 
                return true;
1901
 
        } 
1902
 
}
1903
 
 
1904
 
?>
 
 
b'\\ No newline at end of file'