1 | <?php |
---|
2 | /** |
---|
3 | * This file loads all required libraries, defines constants used across the |
---|
4 | * SOAP package, and defines the base classes that most other classes of this |
---|
5 | * package extend. |
---|
6 | * |
---|
7 | * PHP versions 4 and 5 |
---|
8 | * |
---|
9 | * LICENSE: This source file is subject to version 2.02 of the PHP license, |
---|
10 | * that is bundled with this package in the file LICENSE, and is available at |
---|
11 | * through the world-wide-web at http://www.php.net/license/2_02.txt. If you |
---|
12 | * did not receive a copy of the PHP license and are unable to obtain it |
---|
13 | * through the world-wide-web, please send a note to license@php.net so we can |
---|
14 | * mail you a copy immediately. |
---|
15 | * |
---|
16 | * @category Web Services |
---|
17 | * @package SOAP |
---|
18 | * @author Dietrich Ayala <dietrich@ganx4.com> Original Author |
---|
19 | * @author Shane Caraveo <Shane@Caraveo.com> Port to PEAR and more |
---|
20 | * @author Chuck Hagenbuch <chuck@horde.org> Maintenance |
---|
21 | * @author Jan Schneider <jan@horde.org> Maintenance |
---|
22 | * @copyright 2003-2007 The PHP Group |
---|
23 | * @license http://www.php.net/license/2_02.txt PHP License 2.02 |
---|
24 | * @link http://pear.php.net/package/SOAP |
---|
25 | */ |
---|
26 | |
---|
27 | /** Define linebreak sequence for the Mail_Mime package. */ |
---|
28 | define('MAIL_MIMEPART_CRLF', "\r\n"); |
---|
29 | |
---|
30 | require_once 'PEAR.php'; |
---|
31 | |
---|
32 | if (!defined('INF')) { |
---|
33 | define('INF', 1.8e307); |
---|
34 | } |
---|
35 | if (!defined('NAN')) { |
---|
36 | define('NAN', 0.0); |
---|
37 | } |
---|
38 | |
---|
39 | define('SOAP_LIBRARY_VERSION', '@version@'); |
---|
40 | define('SOAP_LIBRARY_NAME', 'PEAR-SOAP @version@-beta'); |
---|
41 | |
---|
42 | // Set schema version. |
---|
43 | define('SOAP_XML_SCHEMA_VERSION', 'http://www.w3.org/2001/XMLSchema'); |
---|
44 | define('SOAP_XML_SCHEMA_INSTANCE', 'http://www.w3.org/2001/XMLSchema-instance'); |
---|
45 | define('SOAP_XML_SCHEMA_1999', 'http://www.w3.org/1999/XMLSchema'); |
---|
46 | define('SOAP_SCHEMA', 'http://schemas.xmlsoap.org/wsdl/soap/'); |
---|
47 | define('SOAP_SCHEMA_ENCODING', 'http://schemas.xmlsoap.org/soap/encoding/'); |
---|
48 | define('SOAP_ENVELOP', 'http://schemas.xmlsoap.org/soap/envelope/'); |
---|
49 | |
---|
50 | define('SCHEMA_DISCO', 'http://schemas.xmlsoap.org/disco/'); |
---|
51 | define('SCHEMA_DISCO_SCL', 'http://schemas.xmlsoap.org/disco/scl/'); |
---|
52 | |
---|
53 | define('SCHEMA_SOAP', 'http://schemas.xmlsoap.org/wsdl/soap/'); |
---|
54 | define('SCHEMA_SOAP12', 'http://schemas.xmlsoap.org/wsdl/soap12/'); |
---|
55 | define('SCHEMA_SOAP_HTTP', 'http://schemas.xmlsoap.org/soap/http'); |
---|
56 | define('SCHEMA_WSDL_HTTP', 'http://schemas.xmlsoap.org/wsdl/http/'); |
---|
57 | define('SCHEMA_MIME', 'http://schemas.xmlsoap.org/wsdl/mime/'); |
---|
58 | define('SCHEMA_WSDL', 'http://schemas.xmlsoap.org/wsdl/'); |
---|
59 | define('SCHEMA_DIME', 'http://schemas.xmlsoap.org/ws/2002/04/dime/wsdl/'); |
---|
60 | define('SCHEMA_CONTENT', 'http://schemas.xmlsoap.org/ws/2002/04/content-type/'); |
---|
61 | define('SCHEMA_REF', 'http://schemas.xmlsoap.org/ws/2002/04/reference/'); |
---|
62 | |
---|
63 | define('SOAP_DEFAULT_ENCODING', 'UTF-8'); |
---|
64 | |
---|
65 | /** |
---|
66 | * @package SOAP |
---|
67 | */ |
---|
68 | class SOAP_Base_Object extends PEAR |
---|
69 | { |
---|
70 | /** |
---|
71 | * Supported encodings, limited by XML extension. |
---|
72 | * |
---|
73 | * @var array $_encodings |
---|
74 | */ |
---|
75 | var $_encodings = array('ISO-8859-1', 'US-ASCII', 'UTF-8'); |
---|
76 | |
---|
77 | /** |
---|
78 | * Fault code. |
---|
79 | * |
---|
80 | * @var string $_myfaultcode |
---|
81 | */ |
---|
82 | var $_myfaultcode = ''; |
---|
83 | |
---|
84 | /** |
---|
85 | * Recent PEAR_Error object. |
---|
86 | * |
---|
87 | * @var PEAR_Error $fault |
---|
88 | */ |
---|
89 | var $fault = null; |
---|
90 | |
---|
91 | /** |
---|
92 | * Constructor. |
---|
93 | * |
---|
94 | * @param string $faultcode Error code. |
---|
95 | */ |
---|
96 | function SOAP_Base_Object($faultcode = 'Client') |
---|
97 | { |
---|
98 | $this->_myfaultcode = $faultcode; |
---|
99 | parent::PEAR('SOAP_Fault'); |
---|
100 | } |
---|
101 | |
---|
102 | /** |
---|
103 | * Raises a SOAP error. |
---|
104 | * |
---|
105 | * Please refer to the SOAP definition for an impression of what a certain |
---|
106 | * parameter stands for. |
---|
107 | * |
---|
108 | * @param string|object $str Error message or object. |
---|
109 | * @param string $detail Detailed error message. |
---|
110 | * @param string $actorURI |
---|
111 | * @param mixed $code |
---|
112 | * @param mixed $mode |
---|
113 | * @param mixed $options |
---|
114 | * @param boolean $skipmsg |
---|
115 | */ |
---|
116 | function &_raiseSoapFault($str, $detail = '', $actorURI = '', $code = null, |
---|
117 | $mode = null, $options = null, $skipmsg = false) |
---|
118 | { |
---|
119 | // Pass through previous faults. |
---|
120 | $is_instance = isset($this) && is_a($this, 'SOAP_Base_Object'); |
---|
121 | if (is_object($str)) { |
---|
122 | $fault = $str; |
---|
123 | } else { |
---|
124 | if (!$code) { |
---|
125 | $code = $is_instance ? $this->_myfaultcode : 'Client'; |
---|
126 | } |
---|
127 | require_once 'SOAP/Fault.php'; |
---|
128 | $fault = new SOAP_Fault($str, $code, $actorURI, $detail, $mode, |
---|
129 | $options); |
---|
130 | } |
---|
131 | if ($is_instance) { |
---|
132 | $this->fault = $fault; |
---|
133 | } |
---|
134 | |
---|
135 | return $fault; |
---|
136 | } |
---|
137 | |
---|
138 | function _isfault() |
---|
139 | { |
---|
140 | return $this->fault != null; |
---|
141 | } |
---|
142 | |
---|
143 | function &_getfault() |
---|
144 | { |
---|
145 | return $this->fault; |
---|
146 | } |
---|
147 | |
---|
148 | } |
---|
149 | |
---|
150 | /** |
---|
151 | * Common base class of all SOAP classes. |
---|
152 | * |
---|
153 | * @access public |
---|
154 | * @package SOAP |
---|
155 | * @author Shane Caraveo <shane@php.net> Conversion to PEAR and updates |
---|
156 | */ |
---|
157 | class SOAP_Base extends SOAP_Base_Object |
---|
158 | { |
---|
159 | var $_XMLSchema = array('http://www.w3.org/2001/XMLSchema', |
---|
160 | 'http://www.w3.org/1999/XMLSchema'); |
---|
161 | var $_XMLSchemaVersion = 'http://www.w3.org/2001/XMLSchema'; |
---|
162 | |
---|
163 | // load types into typemap array |
---|
164 | var $_typemap = array( |
---|
165 | 'http://www.w3.org/2001/XMLSchema' => array( |
---|
166 | 'string' => 'string', |
---|
167 | 'boolean' => 'boolean', |
---|
168 | 'float' => 'float', |
---|
169 | 'double' => 'float', |
---|
170 | 'decimal' => 'float', |
---|
171 | 'duration' => 'integer', |
---|
172 | 'dateTime' => 'string', |
---|
173 | 'time' => 'string', |
---|
174 | 'date' => 'string', |
---|
175 | 'gYearMonth' => 'integer', |
---|
176 | 'gYear' => 'integer', |
---|
177 | 'gMonthDay' => 'integer', |
---|
178 | 'gDay' => 'integer', |
---|
179 | 'gMonth' => 'integer', |
---|
180 | 'hexBinary' => 'string', |
---|
181 | 'base64Binary' => 'string', |
---|
182 | // derived datatypes |
---|
183 | 'normalizedString' => 'string', |
---|
184 | 'token' => 'string', |
---|
185 | 'language' => 'string', |
---|
186 | 'NMTOKEN' => 'string', |
---|
187 | 'NMTOKENS' => 'string', |
---|
188 | 'Name' => 'string', |
---|
189 | 'NCName' => 'string', |
---|
190 | 'ID' => 'string', |
---|
191 | 'IDREF' => 'string', |
---|
192 | 'IDREFS' => 'string', |
---|
193 | 'ENTITY' => 'string', |
---|
194 | 'ENTITIES' => 'string', |
---|
195 | 'integer' => 'integer', |
---|
196 | 'nonPositiveInteger' => 'integer', |
---|
197 | 'negativeInteger' => 'integer', |
---|
198 | // longs (64bit ints) are not supported cross-platform. |
---|
199 | 'long' => 'string', |
---|
200 | 'int' => 'integer', |
---|
201 | 'short' => 'integer', |
---|
202 | 'byte' => 'string', |
---|
203 | 'nonNegativeInteger' => 'integer', |
---|
204 | 'unsignedLong' => 'integer', |
---|
205 | 'unsignedInt' => 'integer', |
---|
206 | 'unsignedShort' => 'integer', |
---|
207 | 'unsignedByte' => 'integer', |
---|
208 | 'positiveInteger' => 'integer', |
---|
209 | 'anyType' => 'string', |
---|
210 | 'anyURI' => 'string', |
---|
211 | 'QName' => 'string' |
---|
212 | ), |
---|
213 | 'http://www.w3.org/1999/XMLSchema' => array( |
---|
214 | 'i4' => 'integer', |
---|
215 | 'int' => 'integer', |
---|
216 | 'boolean' => 'boolean', |
---|
217 | 'string' => 'string', |
---|
218 | 'double' => 'float', |
---|
219 | 'float' => 'float', |
---|
220 | 'dateTime' => 'string', |
---|
221 | 'timeInstant' => 'string', |
---|
222 | 'base64Binary' => 'string', |
---|
223 | 'base64' => 'string', |
---|
224 | 'ur-type' => 'string' |
---|
225 | ), |
---|
226 | 'http://schemas.xmlsoap.org/soap/encoding/' => array( |
---|
227 | 'base64' => 'string', |
---|
228 | 'array' => 'array', |
---|
229 | 'Array' => 'array', |
---|
230 | 'Struct' => 'array') |
---|
231 | ); |
---|
232 | |
---|
233 | /** |
---|
234 | * Default class name to use for decoded response objects. |
---|
235 | * |
---|
236 | * @var string $_defaultObjectClassname |
---|
237 | */ |
---|
238 | var $_defaultObjectClassname = 'stdClass'; |
---|
239 | |
---|
240 | /** |
---|
241 | * Hash with used namespaces. |
---|
242 | * |
---|
243 | * @var array |
---|
244 | */ |
---|
245 | var $_namespaces; |
---|
246 | |
---|
247 | /** |
---|
248 | * The default namespace. |
---|
249 | * |
---|
250 | * @var string |
---|
251 | */ |
---|
252 | var $_namespace; |
---|
253 | |
---|
254 | var $_xmlEntities = array('&' => '&', |
---|
255 | '<' => '<', |
---|
256 | '>' => '>', |
---|
257 | "'" => ''', |
---|
258 | '"' => '"'); |
---|
259 | |
---|
260 | var $_doconversion = false; |
---|
261 | |
---|
262 | var $_attachments = array(); |
---|
263 | |
---|
264 | var $_wsdl = null; |
---|
265 | |
---|
266 | /** |
---|
267 | * True if we use section 5 encoding, or false if this is literal. |
---|
268 | * |
---|
269 | * @var boolean $_section5 |
---|
270 | */ |
---|
271 | var $_section5 = true; |
---|
272 | |
---|
273 | // Handle type to class mapping. |
---|
274 | var $_auto_translation = false; |
---|
275 | var $_type_translation = array(); |
---|
276 | |
---|
277 | /** |
---|
278 | * Constructor. |
---|
279 | * |
---|
280 | * @param string $faultcode Error code. |
---|
281 | */ |
---|
282 | function SOAP_Base($faultcode = 'Client') |
---|
283 | { |
---|
284 | parent::SOAP_Base_Object($faultcode); |
---|
285 | $this->_resetNamespaces(); |
---|
286 | } |
---|
287 | |
---|
288 | /** |
---|
289 | * Sets the SOAP-ENV prefix and returns the current value. |
---|
290 | * |
---|
291 | * @access public |
---|
292 | * |
---|
293 | * @param string SOAP-ENV prefix |
---|
294 | * |
---|
295 | * @return string current SOAP-ENV prefix. |
---|
296 | */ |
---|
297 | function SOAPENVPrefix($prefix = null) |
---|
298 | { |
---|
299 | static $_soapenv_prefix = 'SOAP-ENV'; |
---|
300 | if (!is_null($prefix)) { |
---|
301 | $_soapenv_prefix = $prefix; |
---|
302 | } |
---|
303 | return $_soapenv_prefix; |
---|
304 | } |
---|
305 | |
---|
306 | /** |
---|
307 | * Sets the SOAP-ENC prefix and returns the current value. |
---|
308 | * |
---|
309 | * @access public |
---|
310 | * |
---|
311 | * @param string SOAP-ENC prefix |
---|
312 | * |
---|
313 | * @return string current SOAP-ENC prefix. |
---|
314 | */ |
---|
315 | function SOAPENCPrefix($prefix = null) |
---|
316 | { |
---|
317 | static $_soapenv_prefix = 'SOAP-ENC'; |
---|
318 | if (!is_null($prefix)) { |
---|
319 | $_soapenv_prefix = $prefix; |
---|
320 | } |
---|
321 | return $_soapenv_prefix; |
---|
322 | } |
---|
323 | |
---|
324 | /** |
---|
325 | * Sets the default namespace. |
---|
326 | * |
---|
327 | * @param string $namespace The default namespace. |
---|
328 | */ |
---|
329 | function setDefaultNamespace($namespace) |
---|
330 | { |
---|
331 | $this->_namespace = $namespace; |
---|
332 | } |
---|
333 | |
---|
334 | function _resetNamespaces() |
---|
335 | { |
---|
336 | $this->_namespaces = array( |
---|
337 | 'http://schemas.xmlsoap.org/soap/envelope/' => SOAP_BASE::SOAPENVPrefix(), |
---|
338 | 'http://www.w3.org/2001/XMLSchema' => 'xsd', |
---|
339 | 'http://www.w3.org/2001/XMLSchema-instance' => 'xsi', |
---|
340 | 'http://schemas.xmlsoap.org/soap/encoding/' => SOAP_BASE::SOAPENCPrefix()); |
---|
341 | } |
---|
342 | |
---|
343 | /** |
---|
344 | * Sets the schema version used in the SOAP message. |
---|
345 | * |
---|
346 | * @access private |
---|
347 | * @see $_XMLSchema |
---|
348 | * |
---|
349 | * @param string $schemaVersion The schema version. |
---|
350 | */ |
---|
351 | function _setSchemaVersion($schemaVersion) |
---|
352 | { |
---|
353 | if (!in_array($schemaVersion, $this->_XMLSchema)) { |
---|
354 | return $this->_raiseSoapFault("unsuported XMLSchema $schemaVersion"); |
---|
355 | } |
---|
356 | $this->_XMLSchemaVersion = $schemaVersion; |
---|
357 | $tmpNS = array_flip($this->_namespaces); |
---|
358 | $tmpNS['xsd'] = $this->_XMLSchemaVersion; |
---|
359 | $tmpNS['xsi'] = $this->_XMLSchemaVersion . '-instance'; |
---|
360 | $this->_namespaces = array_flip($tmpNS); |
---|
361 | } |
---|
362 | |
---|
363 | function _getNamespacePrefix($ns) |
---|
364 | { |
---|
365 | if ($this->_namespace && $ns == $this->_namespace) { |
---|
366 | return ''; |
---|
367 | } |
---|
368 | if (isset($this->_namespaces[$ns])) { |
---|
369 | return $this->_namespaces[$ns]; |
---|
370 | } |
---|
371 | $prefix = 'ns' . count($this->_namespaces); |
---|
372 | $this->_namespaces[$ns] = $prefix; |
---|
373 | return $prefix; |
---|
374 | } |
---|
375 | |
---|
376 | function _getNamespaceForPrefix($prefix) |
---|
377 | { |
---|
378 | $flipped = array_flip($this->_namespaces); |
---|
379 | if (isset($flipped[$prefix])) { |
---|
380 | return $flipped[$prefix]; |
---|
381 | } |
---|
382 | return null; |
---|
383 | } |
---|
384 | |
---|
385 | /** |
---|
386 | * Serializes a value, array or object according to the rules set by this |
---|
387 | * object. |
---|
388 | * |
---|
389 | * @see SOAP_Value |
---|
390 | * |
---|
391 | * @param mixed $value The actual value. |
---|
392 | * @param QName $name The value name. |
---|
393 | * @param QName $type The value type. |
---|
394 | * @param array $options A list of encoding and serialization options. |
---|
395 | * @param array $attributes A hash of additional attributes. |
---|
396 | * @param string $artype The type of any array elements. |
---|
397 | */ |
---|
398 | function _serializeValue($value, $name = null, $type = null, |
---|
399 | $options = array(), $attributes = array(), |
---|
400 | $artype = '') |
---|
401 | { |
---|
402 | $namespaces = array(); |
---|
403 | $arrayType = $array_depth = $xmlout_value = null; |
---|
404 | $typePrefix = $elPrefix = $xmlout_arrayType = ''; |
---|
405 | $xmlout_type = $xmlns = $ptype = $array_type_ns = ''; |
---|
406 | |
---|
407 | if (!$name->name || is_numeric($name->name)) { |
---|
408 | $name->name = 'item'; |
---|
409 | } |
---|
410 | |
---|
411 | if ($this->_wsdl) { |
---|
412 | list($ptype, $arrayType, $array_type_ns, $array_depth) |
---|
413 | = $this->_wsdl->getSchemaType($type, $name); |
---|
414 | } |
---|
415 | |
---|
416 | if (!$arrayType) { |
---|
417 | $arrayType = $artype; |
---|
418 | } |
---|
419 | if (!$ptype) { |
---|
420 | $ptype = $this->_getType($value); |
---|
421 | } |
---|
422 | if (!$type) { |
---|
423 | $type = new QName($ptype); |
---|
424 | } |
---|
425 | |
---|
426 | if (strcasecmp($ptype, 'Struct') == 0 || |
---|
427 | strcasecmp($type->name, 'Struct') == 0) { |
---|
428 | // Struct |
---|
429 | $vars = is_object($value) ? get_object_vars($value) : $value; |
---|
430 | if (is_array($vars)) { |
---|
431 | foreach (array_keys($vars) as $k) { |
---|
432 | // Hide private vars. |
---|
433 | if ($k[0] == '_') { |
---|
434 | continue; |
---|
435 | } |
---|
436 | |
---|
437 | if (is_object($vars[$k])) { |
---|
438 | if (is_a($vars[$k], 'SOAP_Value')) { |
---|
439 | $xmlout_value .= $vars[$k]->serialize($this); |
---|
440 | } else { |
---|
441 | // XXX get the members and serialize them instead |
---|
442 | // converting to an array is more overhead than we |
---|
443 | // should really do. |
---|
444 | $xmlout_value .= $this->_serializeValue(get_object_vars($vars[$k]), new QName($k, $this->_section5 ? null : $name->namepace), null, $options); |
---|
445 | } |
---|
446 | } else { |
---|
447 | $xmlout_value .= $this->_serializeValue($vars[$k], new QName($k, $this->_section5 ? null : $name->namespace), false, $options); |
---|
448 | } |
---|
449 | } |
---|
450 | } |
---|
451 | } elseif (strcasecmp($ptype, 'Array') == 0 || |
---|
452 | strcasecmp($type->name, 'Array') == 0) { |
---|
453 | // Array. |
---|
454 | $type = new QName('Array', SOAP_SCHEMA_ENCODING); |
---|
455 | $numtypes = 0; |
---|
456 | $value = (array)$value; |
---|
457 | // XXX this will be slow on larger arrays. Basically, it flattens |
---|
458 | // arrays to allow us to serialize multi-dimensional arrays. We |
---|
459 | // only do this if arrayType is set, which will typically only |
---|
460 | // happen if we are using WSDL |
---|
461 | if (isset($options['flatten']) || |
---|
462 | ($arrayType && |
---|
463 | (strchr($arrayType, ',') || strstr($arrayType, '][')))) { |
---|
464 | $numtypes = $this->_multiArrayType($value, $arrayType, |
---|
465 | $ar_size, $xmlout_value); |
---|
466 | } |
---|
467 | |
---|
468 | $array_type = $array_type_prefix = ''; |
---|
469 | if ($numtypes != 1) { |
---|
470 | $arrayTypeQName = new QName($arrayType); |
---|
471 | $arrayType = $arrayTypeQName->name; |
---|
472 | $array_types = array(); |
---|
473 | $array_val = null; |
---|
474 | |
---|
475 | // Serialize each array element. |
---|
476 | $ar_size = count($value); |
---|
477 | foreach ($value as $array_val) { |
---|
478 | if (is_a($array_val, 'SOAP_Value')) { |
---|
479 | $array_type = $array_val->type; |
---|
480 | $array_types[$array_type] = 1; |
---|
481 | $array_type_ns = $array_val->type_namespace; |
---|
482 | $xmlout_value .= $array_val->serialize($this); |
---|
483 | } else { |
---|
484 | $array_type = $this->_getType($array_val); |
---|
485 | $array_types[$array_type] = 1; |
---|
486 | if (empty($options['keep_arrays_flat'])) { |
---|
487 | $xmlout_value .= $this->_serializeValue($array_val, new QName('item', $this->_section5 ? null : $name->namespace), new QName($array_type), $options); |
---|
488 | } else { |
---|
489 | $xmlout_value .= $this->_serializeValue($array_val, $name, new QName($array_type), $options, $attributes); |
---|
490 | } |
---|
491 | } |
---|
492 | } |
---|
493 | |
---|
494 | if (!$arrayType) { |
---|
495 | $numtypes = count($array_types); |
---|
496 | if ($numtypes == 1) { |
---|
497 | $arrayType = $array_type; |
---|
498 | } |
---|
499 | // Using anyType is more interoperable. |
---|
500 | if ($array_type == 'Struct') { |
---|
501 | $array_type = ''; |
---|
502 | } elseif ($array_type == 'Array') { |
---|
503 | $arrayType = 'anyType'; |
---|
504 | $array_type_prefix = 'xsd'; |
---|
505 | } else { |
---|
506 | if (!$arrayType) { |
---|
507 | $arrayType = $array_type; |
---|
508 | } |
---|
509 | } |
---|
510 | } |
---|
511 | } |
---|
512 | if (!$arrayType || $numtypes > 1) { |
---|
513 | // Should reference what schema we're using. |
---|
514 | $arrayType = 'xsd:anyType'; |
---|
515 | } else { |
---|
516 | if ($array_type_ns) { |
---|
517 | $array_type_prefix = $this->_getNamespacePrefix($array_type_ns); |
---|
518 | } elseif (isset($this->_typemap[$this->_XMLSchemaVersion][$arrayType])) { |
---|
519 | $array_type_prefix = $this->_namespaces[$this->_XMLSchemaVersion]; |
---|
520 | } elseif (isset($this->_typemap[SOAP_SCHEMA_ENCODING][$arrayType])) { |
---|
521 | $array_type_prefix = SOAP_BASE::SOAPENCPrefix(); |
---|
522 | } |
---|
523 | if ($array_type_prefix) { |
---|
524 | $arrayType = $array_type_prefix . ':' . $arrayType; |
---|
525 | } |
---|
526 | } |
---|
527 | |
---|
528 | $xmlout_arrayType = ' ' . SOAP_BASE::SOAPENCPrefix() |
---|
529 | . ':arrayType="' . $arrayType; |
---|
530 | if ($array_depth != null) { |
---|
531 | for ($i = 0; $i < $array_depth; $i++) { |
---|
532 | $xmlout_arrayType .= '[]'; |
---|
533 | } |
---|
534 | } |
---|
535 | $xmlout_arrayType .= "[$ar_size]\""; |
---|
536 | } elseif (is_a($value, 'SOAP_Value')) { |
---|
537 | $xmlout_value = $value->serialize($this); |
---|
538 | } elseif ($type->name == 'string') { |
---|
539 | $xmlout_value = htmlspecialchars($value); |
---|
540 | } elseif ($type->name == 'rawstring') { |
---|
541 | $xmlout_value = $value; |
---|
542 | } elseif ($type->name == 'boolean') { |
---|
543 | $xmlout_value = $value ? 'true' : 'false'; |
---|
544 | } else { |
---|
545 | $xmlout_value = $value; |
---|
546 | } |
---|
547 | |
---|
548 | // Add namespaces. |
---|
549 | if ($name->namespace) { |
---|
550 | $elPrefix = $this->_getNamespacePrefix($name->namespace); |
---|
551 | if ($elPrefix) { |
---|
552 | $xmlout_name = $elPrefix . ':' . $name->name; |
---|
553 | } else { |
---|
554 | $xmlout_name = $name->name; |
---|
555 | } |
---|
556 | } else { |
---|
557 | $xmlout_name = $name->name; |
---|
558 | } |
---|
559 | |
---|
560 | if ($type->namespace) { |
---|
561 | $typePrefix = false; |
---|
562 | if (empty($options['no_type_prefix'])) { |
---|
563 | $typePrefix = $this->_getNamespacePrefix($type->namespace); |
---|
564 | } |
---|
565 | if ($typePrefix) { |
---|
566 | $xmlout_type = $typePrefix . ':' . $type->name; |
---|
567 | } else { |
---|
568 | $xmlout_type = $type->name; |
---|
569 | } |
---|
570 | } elseif ($type->name && |
---|
571 | isset($this->_typemap[$this->_XMLSchemaVersion][$type->name])) { |
---|
572 | $typePrefix = $this->_namespaces[$this->_XMLSchemaVersion]; |
---|
573 | if ($typePrefix) { |
---|
574 | $xmlout_type = $typePrefix . ':' . $type->name; |
---|
575 | } else { |
---|
576 | $xmlout_type = $type->name; |
---|
577 | } |
---|
578 | } |
---|
579 | |
---|
580 | // Handle additional attributes. |
---|
581 | $xml_attr = ''; |
---|
582 | if (count($attributes)) { |
---|
583 | foreach ($attributes as $k => $v) { |
---|
584 | $kqn = new QName($k); |
---|
585 | $vqn = new QName($v); |
---|
586 | $xml_attr .= ' ' . $kqn->fqn() . '="' . $vqn->fqn() . '"'; |
---|
587 | } |
---|
588 | } |
---|
589 | |
---|
590 | // Store the attachment for mime encoding. |
---|
591 | if (isset($options['attachment']) && |
---|
592 | !PEAR::isError($options['attachment'])) { |
---|
593 | $this->_attachments[] = $options['attachment']; |
---|
594 | } |
---|
595 | |
---|
596 | if ($this->_section5) { |
---|
597 | if ($xmlout_type) { |
---|
598 | $xmlout_type = " xsi:type=\"$xmlout_type\""; |
---|
599 | } |
---|
600 | if (is_null($xmlout_value)) { |
---|
601 | $xml = "\r\n<$xmlout_name$xmlout_type$xmlns$xmlout_arrayType" . |
---|
602 | "$xml_attr xsi:nil=\"true\"/>"; |
---|
603 | } else { |
---|
604 | $xml = "\r\n<$xmlout_name$xmlout_type$xmlns$xmlout_arrayType" . |
---|
605 | "$xml_attr>$xmlout_value</$xmlout_name>"; |
---|
606 | } |
---|
607 | } elseif ($type->name == 'Array' && !empty($options['keep_arrays_flat'])) { |
---|
608 | $xml = $xmlout_value; |
---|
609 | } else { |
---|
610 | if (is_null($xmlout_value)) { |
---|
611 | $xml = "\r\n<$xmlout_name$xmlns$xml_attr/>"; |
---|
612 | } else { |
---|
613 | $xml = "\r\n<$xmlout_name$xmlns$xml_attr>" . |
---|
614 | $xmlout_value . "</$xmlout_name>"; |
---|
615 | } |
---|
616 | } |
---|
617 | |
---|
618 | return $xml; |
---|
619 | } |
---|
620 | |
---|
621 | /** |
---|
622 | * Converts a PHP type to a SOAP type. |
---|
623 | * |
---|
624 | * @param mixed $value The value to inspect. |
---|
625 | * |
---|
626 | * @return string The value's SOAP type. |
---|
627 | */ |
---|
628 | function _getType($value) |
---|
629 | { |
---|
630 | $type = gettype($value); |
---|
631 | switch ($type) { |
---|
632 | case 'object': |
---|
633 | if (is_a($value, 'soap_value')) { |
---|
634 | $type = $value->type; |
---|
635 | } else { |
---|
636 | $type = 'Struct'; |
---|
637 | } |
---|
638 | break; |
---|
639 | |
---|
640 | case 'array': |
---|
641 | // Hashes are always handled as structs. |
---|
642 | if ($this->_isHash($value)) { |
---|
643 | $type = 'Struct'; |
---|
644 | break; |
---|
645 | } |
---|
646 | if (count($value) > 1) { |
---|
647 | // For non-wsdl structs that are all the same type |
---|
648 | reset($value); |
---|
649 | $value1 = next($value); |
---|
650 | $value2 = next($value); |
---|
651 | if (is_a($value1, 'SOAP_Value') && |
---|
652 | is_a($value2, 'SOAP_Value') && |
---|
653 | $value1->name != $value2->name) { |
---|
654 | // This is a struct, not an array. |
---|
655 | $type = 'Struct'; |
---|
656 | break; |
---|
657 | } |
---|
658 | } |
---|
659 | $type = 'Array'; |
---|
660 | break; |
---|
661 | |
---|
662 | case 'integer': |
---|
663 | case 'long': |
---|
664 | $type = 'int'; |
---|
665 | break; |
---|
666 | |
---|
667 | case 'boolean': |
---|
668 | break; |
---|
669 | |
---|
670 | case 'double': |
---|
671 | // double is deprecated in PHP 4.2 and later. |
---|
672 | $type = 'float'; |
---|
673 | break; |
---|
674 | |
---|
675 | case 'null': |
---|
676 | $type = ''; |
---|
677 | break; |
---|
678 | |
---|
679 | case 'string': |
---|
680 | default: |
---|
681 | break; |
---|
682 | } |
---|
683 | |
---|
684 | return $type; |
---|
685 | } |
---|
686 | |
---|
687 | function _multiArrayType($value, &$type, &$size, &$xml) |
---|
688 | { |
---|
689 | if (is_array($value)) { |
---|
690 | // Seems we have a multi dimensional array, figure it out if we |
---|
691 | // do. |
---|
692 | for ($i = 0, $c = count($value); $i < $c; ++$i) { |
---|
693 | $this->_multiArrayType($value[$i], $type, $size, $xml); |
---|
694 | } |
---|
695 | |
---|
696 | $sz = count($value); |
---|
697 | if ($size) { |
---|
698 | $size = $sz . ',' . $size; |
---|
699 | } else { |
---|
700 | $size = $sz; |
---|
701 | } |
---|
702 | return 1; |
---|
703 | } elseif (is_object($value)) { |
---|
704 | $type = $value->type; |
---|
705 | $xml .= $value->serialize($this); |
---|
706 | } else { |
---|
707 | $type = $this->_getType($value); |
---|
708 | $xml .= $this->_serializeValue($value, new QName('item'), new QName($type)); |
---|
709 | } |
---|
710 | $size = null; |
---|
711 | |
---|
712 | return 1; |
---|
713 | } |
---|
714 | |
---|
715 | /** |
---|
716 | * Returns whether a type is a base64 type. |
---|
717 | * |
---|
718 | * @param string $type A type name. |
---|
719 | * |
---|
720 | * @return boolean True if the type name is a base64 type. |
---|
721 | */ |
---|
722 | function _isBase64Type($type) |
---|
723 | { |
---|
724 | return $type == 'base64' || $type == 'base64Binary'; |
---|
725 | } |
---|
726 | |
---|
727 | /** |
---|
728 | * Returns whether an array is a hash. |
---|
729 | * |
---|
730 | * @param array $a An array to check. |
---|
731 | * |
---|
732 | * @return boolean True if the specified array is a hash. |
---|
733 | */ |
---|
734 | function _isHash($a) |
---|
735 | { |
---|
736 | foreach (array_keys($a) as $k) { |
---|
737 | // Checking the type is faster than regexp. |
---|
738 | if (!is_int($k)) { |
---|
739 | return true; |
---|
740 | } |
---|
741 | } |
---|
742 | return false; |
---|
743 | } |
---|
744 | |
---|
745 | function _un_htmlentities($string) |
---|
746 | { |
---|
747 | $trans_tbl = get_html_translation_table(HTML_ENTITIES); |
---|
748 | $trans_tbl = array_flip($trans_tbl); |
---|
749 | return strtr($string, $trans_tbl); |
---|
750 | } |
---|
751 | |
---|
752 | /** |
---|
753 | * Converts a SOAP_Value object into a PHP value. |
---|
754 | */ |
---|
755 | function _decode($soapval) |
---|
756 | { |
---|
757 | if (!is_a($soapval, 'SOAP_Value')) { |
---|
758 | return $soapval; |
---|
759 | } |
---|
760 | |
---|
761 | if (is_array($soapval->value)) { |
---|
762 | $isstruct = $soapval->type != 'Array'; |
---|
763 | if ($isstruct) { |
---|
764 | $classname = $this->_defaultObjectClassname; |
---|
765 | if (isset($this->_type_translation[$soapval->tqn->fqn()])) { |
---|
766 | // This will force an error in PHP if the class does not |
---|
767 | // exist. |
---|
768 | $classname = $this->_type_translation[$soapval->tqn->fqn()]; |
---|
769 | } elseif (isset($this->_type_translation[$soapval->type])) { |
---|
770 | // This will force an error in PHP if the class does not |
---|
771 | // exist. |
---|
772 | $classname = $this->_type_translation[$soapval->type]; |
---|
773 | } elseif ($this->_auto_translation) { |
---|
774 | if (class_exists($soapval->type)) { |
---|
775 | $classname = $soapval->type; |
---|
776 | } elseif ($this->_wsdl) { |
---|
777 | $t = $this->_wsdl->getComplexTypeNameForElement($soapval->name, $soapval->namespace); |
---|
778 | if ($t && class_exists($t)) { |
---|
779 | $classname = $t; |
---|
780 | } |
---|
781 | } |
---|
782 | } |
---|
783 | $return = new $classname; |
---|
784 | } else { |
---|
785 | $return = array(); |
---|
786 | } |
---|
787 | |
---|
788 | foreach ($soapval->value as $item) { |
---|
789 | if ($isstruct) { |
---|
790 | if ($this->_wsdl) { |
---|
791 | // Get this child's WSDL information. |
---|
792 | // /$soapval->prefix/$soapval->type/$item->prefix/$item->name |
---|
793 | $child_type = $this->_wsdl->getComplexTypeChildType( |
---|
794 | $soapval->namespace, |
---|
795 | $soapval->name, |
---|
796 | $item->namespace, |
---|
797 | $item->name); |
---|
798 | if ($child_type) { |
---|
799 | $item->type = $child_type; |
---|
800 | } |
---|
801 | } |
---|
802 | if ($item->type == 'Array') { |
---|
803 | if (isset($return->{$item->name}) && |
---|
804 | is_object($return->{$item->name})) { |
---|
805 | $return->{$item->name} = $this->_decode($item); |
---|
806 | } elseif (isset($return->{$item->name}) && |
---|
807 | is_array($return->{$item->name})) { |
---|
808 | $return->{$item->name}[] = $this->_decode($item); |
---|
809 | } elseif (isset($return->{$item->name})) { |
---|
810 | $return->{$item->name} = array( |
---|
811 | $return->{$item->name}, |
---|
812 | $this->_decode($item) |
---|
813 | ); |
---|
814 | } elseif (is_array($return)) { |
---|
815 | $return[] = $this->_decode($item); |
---|
816 | } else { |
---|
817 | $return->{$item->name} = $this->_decode($item); |
---|
818 | } |
---|
819 | } elseif (isset($return->{$item->name})) { |
---|
820 | $d = $this->_decode($item); |
---|
821 | if (count(get_object_vars($return)) == 1) { |
---|
822 | $isstruct = false; |
---|
823 | $return = array($return->{$item->name}, $d); |
---|
824 | } else { |
---|
825 | if (is_array($return->{$item->name})) { |
---|
826 | $return->{$item->name} = array_merge($return->{$item->name}, array($d)); |
---|
827 | } else { |
---|
828 | $return->{$item->name} = array($return->{$item->name}, $d); |
---|
829 | } |
---|
830 | } |
---|
831 | } else { |
---|
832 | $return->{$item->name} = $this->_decode($item); |
---|
833 | } |
---|
834 | // Set the attributes as members in the class. |
---|
835 | if (method_exists($return, '__set_attribute')) { |
---|
836 | foreach ($soapval->attributes as $key => $value) { |
---|
837 | call_user_func_array(array(&$return, |
---|
838 | '__set_attribute'), |
---|
839 | array($key, $value)); |
---|
840 | } |
---|
841 | } |
---|
842 | } else { |
---|
843 | if ($soapval->arrayType && is_a($item, 'SOAP_Value')) { |
---|
844 | if ($this->_isBase64Type($item->type) && |
---|
845 | !$this->_isBase64Type($soapval->arrayType)) { |
---|
846 | // Decode the value if we're losing the base64 |
---|
847 | // type information. |
---|
848 | $item->value = base64_decode($item->value); |
---|
849 | } |
---|
850 | $item->type = $soapval->arrayType; |
---|
851 | } |
---|
852 | $return[] = $this->_decode($item); |
---|
853 | } |
---|
854 | } |
---|
855 | |
---|
856 | return $return; |
---|
857 | } |
---|
858 | |
---|
859 | if ($soapval->type == 'boolean') { |
---|
860 | if ($soapval->value != '0' && |
---|
861 | strcasecmp($soapval->value, 'false') != 0) { |
---|
862 | $soapval->value = true; |
---|
863 | } else { |
---|
864 | $soapval->value = false; |
---|
865 | } |
---|
866 | } elseif ($soapval->type && |
---|
867 | isset($this->_typemap[SOAP_XML_SCHEMA_VERSION][$soapval->type])) { |
---|
868 | // If we can, set variable type. |
---|
869 | settype($soapval->value, |
---|
870 | $this->_typemap[SOAP_XML_SCHEMA_VERSION][$soapval->type]); |
---|
871 | } elseif ($soapval->type == 'Struct') { |
---|
872 | $soapval->value = null; |
---|
873 | } |
---|
874 | |
---|
875 | return $soapval->value; |
---|
876 | } |
---|
877 | |
---|
878 | /** |
---|
879 | * Creates the SOAP envelope with the SOAP envelop data. |
---|
880 | * |
---|
881 | * @param SOAP_Value $method SOAP_Value instance with the method name as |
---|
882 | * the name, and the method arguments as the |
---|
883 | * value. |
---|
884 | * @param array $headers A list of additional SOAP_Header objects. |
---|
885 | * @param string $encoding The charset of the SOAP message. |
---|
886 | * @param array $options A list of encoding/serialization options. |
---|
887 | * |
---|
888 | * @return string The complete SOAP message. |
---|
889 | */ |
---|
890 | function makeEnvelope($method, $headers, $encoding = SOAP_DEFAULT_ENCODING, |
---|
891 | $options = array()) |
---|
892 | { |
---|
893 | $smsg = $header_xml = $ns_string = ''; |
---|
894 | |
---|
895 | if ($headers) { |
---|
896 | for ($i = 0, $c = count($headers); $i < $c; $i++) { |
---|
897 | $header_xml .= $headers[$i]->serialize($this); |
---|
898 | } |
---|
899 | $header_xml = sprintf("<%s:Header>\r\n%s\r\n</%s:Header>\r\n", |
---|
900 | SOAP_BASE::SOAPENVPrefix(), $header_xml, |
---|
901 | SOAP_BASE::SOAPENVPrefix()); |
---|
902 | } |
---|
903 | |
---|
904 | if (!isset($options['input']) || $options['input'] == 'parse') { |
---|
905 | if (is_array($method)) { |
---|
906 | for ($i = 0, $c = count($method); $i < $c; $i++) { |
---|
907 | $smsg .= $method[$i]->serialize($this); |
---|
908 | } |
---|
909 | } else { |
---|
910 | $smsg = $method->serialize($this); |
---|
911 | } |
---|
912 | } else { |
---|
913 | $smsg = $method; |
---|
914 | } |
---|
915 | $body = sprintf("<%s:Body>%s\r\n</%s:Body>\r\n", |
---|
916 | SOAP_BASE::SOAPENVPrefix(), $smsg, |
---|
917 | SOAP_BASE::SOAPENVPrefix()); |
---|
918 | |
---|
919 | foreach ($this->_namespaces as $k => $v) { |
---|
920 | $ns_string .= "\r\n " . sprintf('xmlns:%s="%s"', $v, $k); |
---|
921 | } |
---|
922 | if ($this->_namespace) { |
---|
923 | $ns_string .= "\r\n " . sprintf('xmlns="%s"', $this->_namespace); |
---|
924 | } |
---|
925 | |
---|
926 | /* If 'use' == 'literal', do not put in the encodingStyle. This is |
---|
927 | * denoted by $this->_section5 being false. 'use' can be defined at a |
---|
928 | * more granular level than we are dealing with here, so this does not |
---|
929 | * work for all services. */ |
---|
930 | $xml = sprintf('<?xml version="1.0" encoding="%s"?>%s<%s:Envelope%s', |
---|
931 | $encoding, "\r\n", SOAP_BASE::SOAPENVPrefix(), |
---|
932 | $ns_string); |
---|
933 | if ($this->_section5) { |
---|
934 | $xml .= "\r\n " . sprintf('%s:encodingStyle="%s"', |
---|
935 | SOAP_BASE::SOAPENVPrefix(), |
---|
936 | SOAP_SCHEMA_ENCODING); |
---|
937 | } |
---|
938 | $xml .= sprintf('>%s%s%s</%s:Envelope>' . "\r\n", |
---|
939 | "\r\n", $header_xml, $body, SOAP_BASE::SOAPENVPrefix()); |
---|
940 | |
---|
941 | return $xml; |
---|
942 | } |
---|
943 | |
---|
944 | function _makeMimeMessage($xml, $encoding = SOAP_DEFAULT_ENCODING) |
---|
945 | { |
---|
946 | if (!@include_once 'Mail/mimePart.php') { |
---|
947 | return $this->_raiseSoapFault('MIME messages are unsupported, the Mail_Mime package is not installed'); |
---|
948 | } |
---|
949 | |
---|
950 | // Encode any attachments. See http://www.w3.org/TR/SOAP-attachments |
---|
951 | // Now we have to mime encode the message. |
---|
952 | $params = array('content_type' => 'multipart/related; type="text/xml"'); |
---|
953 | $msg = new Mail_mimePart('', $params); |
---|
954 | |
---|
955 | // Add the xml part. |
---|
956 | $params['content_type'] = 'text/xml'; |
---|
957 | $params['charset'] = $encoding; |
---|
958 | $msg->addSubPart($xml, $params); |
---|
959 | |
---|
960 | // Add the attachements |
---|
961 | for ($i = 0, $c = count($this->_attachments); $i < $c; ++$i) { |
---|
962 | $msg->addSubPart($this->_attachments[$i]['body'], |
---|
963 | $this->_attachments[$i]); |
---|
964 | } |
---|
965 | |
---|
966 | return $msg->encode(); |
---|
967 | } |
---|
968 | |
---|
969 | // TODO: this needs to be used from the Transport system. |
---|
970 | function _makeDIMEMessage($xml) |
---|
971 | { |
---|
972 | if (!@include_once 'Net/DIME.php') { |
---|
973 | return $this->_raiseSoapFault('DIME messages are unsupported, the Net_DIME package is not installed'); |
---|
974 | } |
---|
975 | |
---|
976 | // Encode any attachments. See |
---|
977 | // http://search.ietf.org/internet-drafts/draft-nielsen-dime-soap-00.txt |
---|
978 | // Now we have to DIME encode the message |
---|
979 | $dime = new Net_DIME_Message(); |
---|
980 | $msg = $dime->encodeData($xml, SOAP_ENVELOP, null, NET_DIME_TYPE_URI); |
---|
981 | |
---|
982 | // Add the attachments. |
---|
983 | $c = count($this->_attachments); |
---|
984 | for ($i = 0; $i < $c; $i++) { |
---|
985 | $msg .= $dime->encodeData($this->_attachments[$i]['body'], |
---|
986 | $this->_attachments[$i]['content_type'], |
---|
987 | $this->_attachments[$i]['cid'], |
---|
988 | NET_DIME_TYPE_MEDIA); |
---|
989 | } |
---|
990 | $msg .= $dime->endMessage(); |
---|
991 | |
---|
992 | return $msg; |
---|
993 | } |
---|
994 | |
---|
995 | function _decodeMimeMessage(&$data, &$headers, &$attachments) |
---|
996 | { |
---|
997 | if (!@include_once 'Mail/mimeDecode.php') { |
---|
998 | return $this->_raiseSoapFault('MIME messages are unsupported, the Mail_Mime package is not installed'); |
---|
999 | } |
---|
1000 | |
---|
1001 | $params['include_bodies'] = true; |
---|
1002 | $params['decode_bodies'] = true; |
---|
1003 | $params['decode_headers'] = true; |
---|
1004 | |
---|
1005 | // Lame thing to have to do for decoding. |
---|
1006 | $decoder = new Mail_mimeDecode($data); |
---|
1007 | $structure = $decoder->decode($params); |
---|
1008 | |
---|
1009 | if (isset($structure->body)) { |
---|
1010 | $data = $structure->body; |
---|
1011 | $headers = $structure->headers; |
---|
1012 | unset($headers['']); |
---|
1013 | return; |
---|
1014 | } elseif (isset($structure->parts)) { |
---|
1015 | $data = $structure->parts[0]->body; |
---|
1016 | $headers = array_merge($structure->headers, |
---|
1017 | $structure->parts[0]->headers); |
---|
1018 | unset($headers['']); |
---|
1019 | if (count($structure->parts) <= 1) { |
---|
1020 | return; |
---|
1021 | } |
---|
1022 | |
---|
1023 | $mime_parts = array_splice($structure->parts, 1); |
---|
1024 | // Prepare the parts for the SOAP parser. |
---|
1025 | for ($i = 0, $c = count($mime_parts); $i < $c; $i++) { |
---|
1026 | $p = $mime_parts[$i]; |
---|
1027 | if (isset($p->headers['content-location'])) { |
---|
1028 | // TODO: modify location per SwA note section 3 |
---|
1029 | // http://www.w3.org/TR/SOAP-attachments |
---|
1030 | $attachments[$p->headers['content-location']] = $p->body; |
---|
1031 | } else { |
---|
1032 | $cid = 'cid:' . substr($p->headers['content-id'], 1, -1); |
---|
1033 | $attachments[$cid] = $p->body; |
---|
1034 | } |
---|
1035 | } |
---|
1036 | |
---|
1037 | return; |
---|
1038 | } |
---|
1039 | |
---|
1040 | $this->_raiseSoapFault('Mime parsing error', '', '', 'Server'); |
---|
1041 | } |
---|
1042 | |
---|
1043 | function _decodeDIMEMessage(&$data, &$headers, &$attachments) |
---|
1044 | { |
---|
1045 | if (!@include_once 'Net/DIME.php') { |
---|
1046 | return $this->_raiseSoapFault('DIME messages are unsupported, the Net_DIME package is not installed'); |
---|
1047 | } |
---|
1048 | |
---|
1049 | // This SHOULD be moved to the transport layer, e.g. PHP itself should |
---|
1050 | // handle parsing DIME ;) |
---|
1051 | $dime = new Net_DIME_Message(); |
---|
1052 | $err = $dime->decodeData($data); |
---|
1053 | if (PEAR::isError($err)) { |
---|
1054 | $this->_raiseSoapFault('Failed to decode the DIME message!', '', '', 'Server'); |
---|
1055 | return; |
---|
1056 | } |
---|
1057 | if (strcasecmp($dime->parts[0]['type'], SOAP_ENVELOP) != 0) { |
---|
1058 | $this->_raiseSoapFault('DIME record 1 is not a SOAP envelop!', '', '', 'Server'); |
---|
1059 | return; |
---|
1060 | } |
---|
1061 | |
---|
1062 | $data = $dime->parts[0]['data']; |
---|
1063 | // Fake it for now. |
---|
1064 | $headers['content-type'] = 'text/xml'; |
---|
1065 | $c = count($dime->parts); |
---|
1066 | for ($i = 0; $i < $c; $i++) { |
---|
1067 | $part =& $dime->parts[$i]; |
---|
1068 | // We need to handle URI's better. |
---|
1069 | $id = strncmp($part['id'], 'cid:', 4) |
---|
1070 | ? 'cid:' . $part['id'] |
---|
1071 | : $part['id']; |
---|
1072 | $attachments[$id] = $part['data']; |
---|
1073 | } |
---|
1074 | } |
---|
1075 | |
---|
1076 | /** |
---|
1077 | * Explicitly sets the translation for a specific class. |
---|
1078 | * |
---|
1079 | * Auto translation works for all cases, but opens ANY class in the script |
---|
1080 | * to be used as a data type, and may not be desireable. |
---|
1081 | * |
---|
1082 | * @param string $type A SOAP type. |
---|
1083 | * @param string $class A PHP class name. |
---|
1084 | */ |
---|
1085 | function setTypeTranslation($type, $class = null) |
---|
1086 | { |
---|
1087 | $tq = new QName($type); |
---|
1088 | if (!$class) { |
---|
1089 | $class = $tq->name; |
---|
1090 | } |
---|
1091 | $this->_type_translation[$type]=$class; |
---|
1092 | } |
---|
1093 | |
---|
1094 | } |
---|
1095 | |
---|
1096 | /** |
---|
1097 | * Class used to handle QNAME values in XML. |
---|
1098 | * |
---|
1099 | * @package SOAP |
---|
1100 | * @author Shane Caraveo <shane@php.net> Conversion to PEAR and updates |
---|
1101 | */ |
---|
1102 | class QName |
---|
1103 | { |
---|
1104 | var $name = ''; |
---|
1105 | var $prefix = ''; |
---|
1106 | var $namespace = ''; |
---|
1107 | |
---|
1108 | function QName($name, $namespace = '') |
---|
1109 | { |
---|
1110 | if ($name && $name[0] == '{') { |
---|
1111 | preg_match('/\{(.*?)\}(.*)/', $name, $m); |
---|
1112 | $this->name = $m[2]; |
---|
1113 | $this->namespace = $m[1]; |
---|
1114 | } elseif (substr_count($name, ':') == 1) { |
---|
1115 | $s = explode(':', $name); |
---|
1116 | $this->prefix = $s[0]; |
---|
1117 | $this->name = $s[1]; |
---|
1118 | $this->namespace = $namespace; |
---|
1119 | } else { |
---|
1120 | $this->name = $name; |
---|
1121 | $this->namespace = $namespace; |
---|
1122 | } |
---|
1123 | |
---|
1124 | // A little more magic than should be in a qname. |
---|
1125 | $p = strpos($this->name, '['); |
---|
1126 | if ($p) { |
---|
1127 | // TODO: Need to re-examine this logic later. |
---|
1128 | // Chop off []. |
---|
1129 | $this->arraySize = explode(',', substr($this->name, $p + 1, -$p - 2)); |
---|
1130 | $this->arrayInfo = substr($this->name, $p); |
---|
1131 | $this->name = substr($this->name, 0, $p); |
---|
1132 | } |
---|
1133 | } |
---|
1134 | |
---|
1135 | function fqn() |
---|
1136 | { |
---|
1137 | if ($this->namespace) { |
---|
1138 | return '{' . $this->namespace . '}' . $this->name; |
---|
1139 | } elseif ($this->prefix) { |
---|
1140 | return $this->prefix . ':' . $this->name; |
---|
1141 | } |
---|
1142 | return $this->name; |
---|
1143 | } |
---|
1144 | |
---|
1145 | } |
---|