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('MAIL_MIMEPART_CRLF', "\r\n"); |
---|
28 | require_once 'PEAR.php'; |
---|
29 | |
---|
30 | if (!defined('INF')) { |
---|
31 | define('INF', 1.8e307); |
---|
32 | } |
---|
33 | if (!defined('NAN')) { |
---|
34 | define('NAN', 0.0); |
---|
35 | } |
---|
36 | |
---|
37 | define('SOAP_LIBRARY_VERSION', '0.11.0'); |
---|
38 | define('SOAP_LIBRARY_NAME', 'PEAR-SOAP 0.11.0-beta'); |
---|
39 | |
---|
40 | // Set schema version. |
---|
41 | define('SOAP_XML_SCHEMA_VERSION', 'http://www.w3.org/2001/XMLSchema'); |
---|
42 | define('SOAP_XML_SCHEMA_INSTANCE', 'http://www.w3.org/2001/XMLSchema-instance'); |
---|
43 | define('SOAP_XML_SCHEMA_1999', 'http://www.w3.org/1999/XMLSchema'); |
---|
44 | define('SOAP_SCHEMA', 'http://schemas.xmlsoap.org/wsdl/soap/'); |
---|
45 | define('SOAP_SCHEMA_ENCODING', 'http://schemas.xmlsoap.org/soap/encoding/'); |
---|
46 | define('SOAP_ENVELOP', 'http://schemas.xmlsoap.org/soap/envelope/'); |
---|
47 | |
---|
48 | define('SCHEMA_DISCO', 'http://schemas.xmlsoap.org/disco/'); |
---|
49 | define('SCHEMA_DISCO_SCL', 'http://schemas.xmlsoap.org/disco/scl/'); |
---|
50 | |
---|
51 | define('SCHEMA_SOAP', 'http://schemas.xmlsoap.org/wsdl/soap/'); |
---|
52 | define('SCHEMA_SOAP12', 'http://schemas.xmlsoap.org/wsdl/soap12/'); |
---|
53 | define('SCHEMA_SOAP_HTTP', 'http://schemas.xmlsoap.org/soap/http'); |
---|
54 | define('SCHEMA_WSDL_HTTP', 'http://schemas.xmlsoap.org/wsdl/http/'); |
---|
55 | define('SCHEMA_MIME', 'http://schemas.xmlsoap.org/wsdl/mime/'); |
---|
56 | define('SCHEMA_WSDL', 'http://schemas.xmlsoap.org/wsdl/'); |
---|
57 | define('SCHEMA_DIME', 'http://schemas.xmlsoap.org/ws/2002/04/dime/wsdl/'); |
---|
58 | define('SCHEMA_CONTENT', 'http://schemas.xmlsoap.org/ws/2002/04/content-type/'); |
---|
59 | define('SCHEMA_REF', 'http://schemas.xmlsoap.org/ws/2002/04/reference/'); |
---|
60 | |
---|
61 | define('SOAP_DEFAULT_ENCODING', 'UTF-8'); |
---|
62 | |
---|
63 | class SOAP_Base_Object extends PEAR |
---|
64 | { |
---|
65 | |
---|
66 | /** |
---|
67 | * Supported encodings, limited by XML extension. |
---|
68 | * |
---|
69 | * @var array $_encodings |
---|
70 | */ |
---|
71 | var $_encodings = array('ISO-8859-1', 'US-ASCII', 'UTF-8'); |
---|
72 | |
---|
73 | /** |
---|
74 | * Fault code. |
---|
75 | * |
---|
76 | * @var string $_myfaultcode |
---|
77 | */ |
---|
78 | var $_myfaultcode = ''; |
---|
79 | |
---|
80 | /** |
---|
81 | * Recent PEAR_Error object. |
---|
82 | * |
---|
83 | * @var PEAR_Error $fault |
---|
84 | */ |
---|
85 | var $fault = null; |
---|
86 | |
---|
87 | /** |
---|
88 | * Constructor. |
---|
89 | * |
---|
90 | * @param string $faultcode Error code. |
---|
91 | */ |
---|
92 | function SOAP_Base_Object($faultcode = 'Client') |
---|
93 | { |
---|
94 | $this->_myfaultcode = $faultcode; |
---|
95 | parent::PEAR('SOAP_Fault'); |
---|
96 | } |
---|
97 | |
---|
98 | /** |
---|
99 | * Raises a SOAP error. |
---|
100 | * |
---|
101 | * Please refer to the SOAP definition for an impression of what a certain |
---|
102 | * parameter stands for. |
---|
103 | * |
---|
104 | * @param string|object $str Error message or object. |
---|
105 | * @param string $detail Detailed error message. |
---|
106 | * @param string $actorURI |
---|
107 | * @param mixed $code |
---|
108 | * @param mixed $mode |
---|
109 | * @param mixed $options |
---|
110 | * @param boolean $skipmsg |
---|
111 | */ |
---|
112 | function &_raiseSoapFault($str, $detail = '', $actorURI = '', $code = null, |
---|
113 | $mode = null, $options = null, $skipmsg = false) |
---|
114 | { |
---|
115 | // Pass through previous faults. |
---|
116 | $is_instance = isset($this) && is_a($this, 'SOAP_Base_Object'); |
---|
117 | if (is_object($str)) { |
---|
118 | $fault =& $str; |
---|
119 | } else { |
---|
120 | if (!$code) { |
---|
121 | $code = $is_instance ? $this->_myfaultcode : 'Client'; |
---|
122 | } |
---|
123 | require_once 'SOAP/Fault.php'; |
---|
124 | $fault =& new SOAP_Fault($str, |
---|
125 | $code, |
---|
126 | $actorURI, |
---|
127 | $detail, |
---|
128 | $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 | * @array |
---|
244 | */ |
---|
245 | var $_namespaces; |
---|
246 | |
---|
247 | /** |
---|
248 | * The default namespace. |
---|
249 | * |
---|
250 | * @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 default namespace. |
---|
290 | * |
---|
291 | * @param string $namespace The default namespace. |
---|
292 | */ |
---|
293 | function setDefaultNamespace($namespace) |
---|
294 | { |
---|
295 | $this->_namespace = $namespace; |
---|
296 | } |
---|
297 | |
---|
298 | function _resetNamespaces() |
---|
299 | { |
---|
300 | $this->_namespaces = array( |
---|
301 | 'http://schemas.xmlsoap.org/soap/envelope/' => 'SOAP-ENV', |
---|
302 | 'http://www.w3.org/2001/XMLSchema' => 'xsd', |
---|
303 | 'http://www.w3.org/2001/XMLSchema-instance' => 'xsi', |
---|
304 | 'http://schemas.xmlsoap.org/soap/encoding/' => 'SOAP-ENC'); |
---|
305 | } |
---|
306 | |
---|
307 | /** |
---|
308 | * Sets the schema version used in the SOAP message. |
---|
309 | * |
---|
310 | * @access private |
---|
311 | * @see $_XMLSchema |
---|
312 | * |
---|
313 | * @param string $schemaVersion The schema version. |
---|
314 | */ |
---|
315 | function _setSchemaVersion($schemaVersion) |
---|
316 | { |
---|
317 | if (!in_array($schemaVersion, $this->_XMLSchema)) { |
---|
318 | return $this->_raiseSoapFault("unsuported XMLSchema $schemaVersion"); |
---|
319 | } |
---|
320 | $this->_XMLSchemaVersion = $schemaVersion; |
---|
321 | $tmpNS = array_flip($this->_namespaces); |
---|
322 | $tmpNS['xsd'] = $this->_XMLSchemaVersion; |
---|
323 | $tmpNS['xsi'] = $this->_XMLSchemaVersion . '-instance'; |
---|
324 | $this->_namespaces = array_flip($tmpNS); |
---|
325 | } |
---|
326 | |
---|
327 | function _getNamespacePrefix($ns) |
---|
328 | { |
---|
329 | if ($this->_namespace && $ns == $this->_namespace) { |
---|
330 | return ''; |
---|
331 | } |
---|
332 | if (isset($this->_namespaces[$ns])) { |
---|
333 | return $this->_namespaces[$ns]; |
---|
334 | } |
---|
335 | $prefix = 'ns' . count($this->_namespaces); |
---|
336 | $this->_namespaces[$ns] = $prefix; |
---|
337 | return $prefix; |
---|
338 | } |
---|
339 | |
---|
340 | function _getNamespaceForPrefix($prefix) |
---|
341 | { |
---|
342 | $flipped = array_flip($this->_namespaces); |
---|
343 | if (isset($flipped[$prefix])) { |
---|
344 | return $flipped[$prefix]; |
---|
345 | } |
---|
346 | return null; |
---|
347 | } |
---|
348 | |
---|
349 | function _isSoapValue(&$value) |
---|
350 | { |
---|
351 | return is_a($value, 'SOAP_Value'); |
---|
352 | } |
---|
353 | |
---|
354 | function _serializeValue(&$value, $name = '', $type = false, |
---|
355 | $elNamespace = null, $typeNamespace = null, |
---|
356 | $options = array(), $attributes = array(), |
---|
357 | $artype = '') |
---|
358 | { |
---|
359 | $namespaces = array(); |
---|
360 | $arrayType = $array_depth = $xmlout_value = null; |
---|
361 | $typePrefix = $elPrefix = $xmlout_offset = $xmlout_arrayType = ''; |
---|
362 | $xmlout_type = $xmlns = $ptype = $array_type_ns = ''; |
---|
363 | |
---|
364 | if (!$name || is_numeric($name)) { |
---|
365 | $name = 'item'; |
---|
366 | } |
---|
367 | |
---|
368 | if ($this->_wsdl) { |
---|
369 | list($ptype, $arrayType, $array_type_ns, $array_depth) |
---|
370 | = $this->_wsdl->getSchemaType($type, $name, $typeNamespace); |
---|
371 | } |
---|
372 | |
---|
373 | if (!$arrayType) { |
---|
374 | $arrayType = $artype; |
---|
375 | } |
---|
376 | if (!$ptype) { |
---|
377 | $ptype = $this->_getType($value); |
---|
378 | } |
---|
379 | if (!$type) { |
---|
380 | $type = $ptype; |
---|
381 | } |
---|
382 | |
---|
383 | if (strcasecmp($ptype, 'Struct') == 0 || |
---|
384 | strcasecmp($type, 'Struct') == 0) { |
---|
385 | // Struct |
---|
386 | $vars = null; |
---|
387 | if (is_object($value)) { |
---|
388 | $vars = get_object_vars($value); |
---|
389 | } else { |
---|
390 | $vars = &$value; |
---|
391 | } |
---|
392 | if (is_array($vars)) { |
---|
393 | foreach (array_keys($vars) as $k) { |
---|
394 | // Hide private vars. |
---|
395 | if ($k[0] == '_') { |
---|
396 | continue; |
---|
397 | } |
---|
398 | if (is_object($vars[$k])) { |
---|
399 | if (is_a($vars[$k], 'SOAP_Value')) { |
---|
400 | $xmlout_value .= $vars[$k]->serialize($this); |
---|
401 | } else { |
---|
402 | // XXX get the members and serialize them instead |
---|
403 | // converting to an array is more overhead than we |
---|
404 | // should really do. |
---|
405 | $xmlout_value .= $this->_serializeValue(get_object_vars($vars[$k]), $k, false, $this->_section5 ? null : $elNamespace); |
---|
406 | } |
---|
407 | } else { |
---|
408 | $xmlout_value .= $this->_serializeValue($vars[$k], $k, false, $this->_section5 ? null : $elNamespace); |
---|
409 | } |
---|
410 | } |
---|
411 | } |
---|
412 | } elseif (strcasecmp($ptype, 'Array') == 0 || |
---|
413 | strcasecmp($type, 'Array') == 0) { |
---|
414 | // Array. |
---|
415 | $typeNamespace = SOAP_SCHEMA_ENCODING; |
---|
416 | $orig_type = $type; |
---|
417 | $type = 'Array'; |
---|
418 | $numtypes = 0; |
---|
419 | $value = (array)$value; |
---|
420 | // XXX this will be slow on larger arrays. Basically, it flattens |
---|
421 | // arrays to allow us to serialize multi-dimensional arrays. We |
---|
422 | // only do this if arrayType is set, which will typically only |
---|
423 | // happen if we are using WSDL |
---|
424 | if (isset($options['flatten']) || |
---|
425 | ($arrayType && |
---|
426 | (strchr($arrayType, ',') || strstr($arrayType, '][')))) { |
---|
427 | $numtypes = $this->_multiArrayType($value, $arrayType, |
---|
428 | $ar_size, $xmlout_value); |
---|
429 | } |
---|
430 | |
---|
431 | $array_type = $array_type_prefix = ''; |
---|
432 | if ($numtypes != 1) { |
---|
433 | $arrayTypeQName = new QName($arrayType); |
---|
434 | $arrayType = $arrayTypeQName->name; |
---|
435 | $array_types = array(); |
---|
436 | $array_val = null; |
---|
437 | |
---|
438 | // Serialize each array element. |
---|
439 | $ar_size = count($value); |
---|
440 | foreach ($value as $array_val) { |
---|
441 | if ($this->_isSoapValue($array_val)) { |
---|
442 | $array_type = $array_val->type; |
---|
443 | $array_types[$array_type] = 1; |
---|
444 | $array_type_ns = $array_val->type_namespace; |
---|
445 | $xmlout_value .= $array_val->serialize($this); |
---|
446 | } else { |
---|
447 | $array_type = $this->_getType($array_val); |
---|
448 | $array_types[$array_type] = 1; |
---|
449 | $xmlout_value .= $this->_serializeValue($array_val, 'item', $array_type, $this->_section5 ? null : $elNamespace); |
---|
450 | } |
---|
451 | } |
---|
452 | |
---|
453 | $xmlout_offset = ' SOAP-ENC:offset="[0]"'; |
---|
454 | if (!$arrayType) { |
---|
455 | $numtypes = count($array_types); |
---|
456 | if ($numtypes == 1) { |
---|
457 | $arrayType = $array_type; |
---|
458 | } |
---|
459 | // Using anyType is more interoperable. |
---|
460 | if ($array_type == 'Struct') { |
---|
461 | $array_type = ''; |
---|
462 | } elseif ($array_type == 'Array') { |
---|
463 | $arrayType = 'anyType'; |
---|
464 | $array_type_prefix = 'xsd'; |
---|
465 | } else { |
---|
466 | if (!$arrayType) { |
---|
467 | $arrayType = $array_type; |
---|
468 | } |
---|
469 | } |
---|
470 | } |
---|
471 | } |
---|
472 | if (!$arrayType || $numtypes > 1) { |
---|
473 | // Should reference what schema we're using. |
---|
474 | $arrayType = 'xsd:anyType'; |
---|
475 | } else { |
---|
476 | if ($array_type_ns) { |
---|
477 | $array_type_prefix = $this->_getNamespacePrefix($array_type_ns); |
---|
478 | } elseif (isset($this->_typemap[$this->_XMLSchemaVersion][$arrayType])) { |
---|
479 | $array_type_prefix = $this->_namespaces[$this->_XMLSchemaVersion]; |
---|
480 | } |
---|
481 | if ($array_type_prefix) { |
---|
482 | $arrayType = $array_type_prefix . ':' . $arrayType; |
---|
483 | } |
---|
484 | } |
---|
485 | |
---|
486 | $xmlout_arrayType = ' SOAP-ENC:arrayType="' . $arrayType; |
---|
487 | if ($array_depth != null) { |
---|
488 | for ($i = 0; $i < $array_depth; $i++) { |
---|
489 | $xmlout_arrayType .= '[]'; |
---|
490 | } |
---|
491 | } |
---|
492 | $xmlout_arrayType .= "[$ar_size]\""; |
---|
493 | } elseif ($this->_isSoapValue($value)) { |
---|
494 | $xmlout_value = $value->serialize($this); |
---|
495 | } elseif ($type == 'string') { |
---|
496 | $xmlout_value = htmlspecialchars($value); |
---|
497 | } elseif ($type == 'rawstring') { |
---|
498 | $xmlout_value =& $value; |
---|
499 | } elseif ($type == 'boolean') { |
---|
500 | $xmlout_value = $value ? 'true' : 'false'; |
---|
501 | } else { |
---|
502 | $xmlout_value =& $value; |
---|
503 | } |
---|
504 | |
---|
505 | // Add namespaces. |
---|
506 | if ($elNamespace) { |
---|
507 | $elPrefix = $this->_getNamespacePrefix($elNamespace); |
---|
508 | if ($elPrefix) { |
---|
509 | $xmlout_name = "$elPrefix:$name"; |
---|
510 | } else { |
---|
511 | $xmlout_name = $name; |
---|
512 | } |
---|
513 | } else { |
---|
514 | $xmlout_name = $name; |
---|
515 | } |
---|
516 | |
---|
517 | if ($typeNamespace) { |
---|
518 | $typePrefix = $this->_getNamespacePrefix($typeNamespace); |
---|
519 | if ($typePrefix) { |
---|
520 | $xmlout_type = "$typePrefix:$type"; |
---|
521 | } else { |
---|
522 | $xmlout_type = $type; |
---|
523 | } |
---|
524 | } elseif ($type && |
---|
525 | isset($this->_typemap[$this->_XMLSchemaVersion][$type])) { |
---|
526 | $typePrefix = $this->_namespaces[$this->_XMLSchemaVersion]; |
---|
527 | if ($typePrefix) { |
---|
528 | $xmlout_type = "$typePrefix:$type"; |
---|
529 | } else { |
---|
530 | $xmlout_type = $type; |
---|
531 | } |
---|
532 | } |
---|
533 | |
---|
534 | // Handle additional attributes. |
---|
535 | $xml_attr = ''; |
---|
536 | if (count($attributes)) { |
---|
537 | foreach ($attributes as $k => $v) { |
---|
538 | $kqn = new QName($k); |
---|
539 | $vqn = new QName($v); |
---|
540 | $xml_attr .= ' ' . $kqn->fqn() . '="' . $vqn->fqn() . '"'; |
---|
541 | } |
---|
542 | } |
---|
543 | |
---|
544 | // Store the attachment for mime encoding. |
---|
545 | if (isset($options['attachment']) && |
---|
546 | !PEAR::isError($options['attachment'])) { |
---|
547 | $this->_attachments[] = $options['attachment']; |
---|
548 | } |
---|
549 | |
---|
550 | if ($this->_section5) { |
---|
551 | if ($xmlout_type) { |
---|
552 | $xmlout_type = " xsi:type=\"$xmlout_type\""; |
---|
553 | } |
---|
554 | if (is_null($xmlout_value)) { |
---|
555 | $xml = "\r\n<$xmlout_name$xmlout_type$xmlns$xmlout_arrayType" . |
---|
556 | "$xml_attr xsi:nil=\"true\"/>"; |
---|
557 | } else { |
---|
558 | $xml = "\r\n<$xmlout_name$xmlout_type$xmlns$xmlout_arrayType" . |
---|
559 | "$xmlout_offset$xml_attr>$xmlout_value</$xmlout_name>"; |
---|
560 | } |
---|
561 | } else { |
---|
562 | if (is_null($xmlout_value)) { |
---|
563 | $xml = "\r\n<$xmlout_name$xmlns$xml_attr/>"; |
---|
564 | } else { |
---|
565 | $xml = "\r\n<$xmlout_name$xmlns$xml_attr>" . |
---|
566 | $xmlout_value . "</$xmlout_name>"; |
---|
567 | } |
---|
568 | } |
---|
569 | |
---|
570 | return $xml; |
---|
571 | } |
---|
572 | |
---|
573 | /** |
---|
574 | * Converts a PHP type to a SOAP type. |
---|
575 | * |
---|
576 | * @access private |
---|
577 | * |
---|
578 | * @param string $value The value to inspect. |
---|
579 | * |
---|
580 | * @return string The value's SOAP type. |
---|
581 | */ |
---|
582 | function _getType(&$value) |
---|
583 | { |
---|
584 | $type = gettype($value); |
---|
585 | switch ($type) { |
---|
586 | case 'object': |
---|
587 | if (is_a($value, 'soap_value')) { |
---|
588 | $type = $value->type; |
---|
589 | } else { |
---|
590 | $type = 'Struct'; |
---|
591 | } |
---|
592 | break; |
---|
593 | |
---|
594 | case 'array': |
---|
595 | // Hashes are always handled as structs. |
---|
596 | if ($this->_isHash($value)) { |
---|
597 | $type = 'Struct'; |
---|
598 | } else { |
---|
599 | $ar_size = count($value); |
---|
600 | reset($value); |
---|
601 | $key1 = key($value); |
---|
602 | if ($ar_size > 0 && is_a($key1, 'SOAP_Value')) { |
---|
603 | // FIXME: for non-wsdl structs that are all the same type |
---|
604 | $key2 = key($value); |
---|
605 | if ($ar_size > 1 && |
---|
606 | $this->_isSoapValue($key1) && |
---|
607 | $this->_isSoapValue($key2) && |
---|
608 | $key1->name != $key2->name) { |
---|
609 | // This is a struct, not an array. |
---|
610 | $type = 'Struct'; |
---|
611 | } else { |
---|
612 | $type = 'Array'; |
---|
613 | } |
---|
614 | } else { |
---|
615 | $type = 'Array'; |
---|
616 | } |
---|
617 | } |
---|
618 | break; |
---|
619 | |
---|
620 | case 'integer': |
---|
621 | case 'long': |
---|
622 | $type = 'int'; |
---|
623 | break; |
---|
624 | |
---|
625 | case 'boolean': |
---|
626 | break; |
---|
627 | |
---|
628 | case 'double': |
---|
629 | // double is deprecated in PHP 4.2 and later. |
---|
630 | $type = 'float'; |
---|
631 | break; |
---|
632 | |
---|
633 | case 'null': |
---|
634 | $type = ''; |
---|
635 | break; |
---|
636 | |
---|
637 | case 'string': |
---|
638 | default: |
---|
639 | break; |
---|
640 | } |
---|
641 | |
---|
642 | return $type; |
---|
643 | } |
---|
644 | |
---|
645 | function _multiArrayType($value, &$type, &$size, &$xml) |
---|
646 | { |
---|
647 | if (is_array($value)) { |
---|
648 | // Seems we have a multi dimensional array, figure it out if we |
---|
649 | // do. |
---|
650 | for ($i = 0, $c = count($value); $i < $c; ++$i) { |
---|
651 | $this->_multiArrayType($value[$i], $type, $size, $xml); |
---|
652 | } |
---|
653 | |
---|
654 | $sz = count($value); |
---|
655 | if ($size) { |
---|
656 | $size = $sz . ',' . $size; |
---|
657 | } else { |
---|
658 | $size = $sz; |
---|
659 | } |
---|
660 | return 1; |
---|
661 | } elseif (is_object($value)) { |
---|
662 | $type = $value->type; |
---|
663 | $xml .= $value->serialize($this); |
---|
664 | } else { |
---|
665 | $type = $this->_getType($value); |
---|
666 | $xml .= $this->_serializeValue($value, 'item', $type); |
---|
667 | } |
---|
668 | $size = null; |
---|
669 | |
---|
670 | return 1; |
---|
671 | } |
---|
672 | |
---|
673 | /** |
---|
674 | * Returns whether a type is a base64 type. |
---|
675 | * |
---|
676 | * @param string $type A type name. |
---|
677 | * |
---|
678 | * @return boolean True if the type name is a base64 type. |
---|
679 | */ |
---|
680 | function _isBase64Type($type) |
---|
681 | { |
---|
682 | return $type == 'base64' || $type == 'base64Binary'; |
---|
683 | } |
---|
684 | |
---|
685 | /** |
---|
686 | * Returns whether an array is a hash. |
---|
687 | * |
---|
688 | * @param array $a An array to check. |
---|
689 | * |
---|
690 | * @return boolean True if the specified array is a hash. |
---|
691 | */ |
---|
692 | function _isHash(&$a) |
---|
693 | { |
---|
694 | // I really dislike having to loop through this in PHP code, really |
---|
695 | // large arrays will be slow. We need a C function to do this. |
---|
696 | $it = 0; |
---|
697 | foreach ($a as $k => $v) { |
---|
698 | // Checking the type is faster than regexp. |
---|
699 | if (!is_int($k)) { |
---|
700 | return true; |
---|
701 | } |
---|
702 | // If someone has a large hash they should really be defining the |
---|
703 | // type. |
---|
704 | if ($it++ > 10) { |
---|
705 | $this->_raiseSoapFault('Large associative array passed where a SOAP_Value was expected'); |
---|
706 | return false; |
---|
707 | } |
---|
708 | } |
---|
709 | return false; |
---|
710 | } |
---|
711 | |
---|
712 | function _un_htmlentities($string) |
---|
713 | { |
---|
714 | $trans_tbl = get_html_translation_table(HTML_ENTITIES); |
---|
715 | $trans_tbl = array_flip($trans_tbl); |
---|
716 | return strtr($string, $trans_tbl); |
---|
717 | } |
---|
718 | |
---|
719 | /** |
---|
720 | * Converts a SOAP_Value object into a StdClass PHP object |
---|
721 | */ |
---|
722 | function &_decode(&$soapval) |
---|
723 | { |
---|
724 | if (!$this->_isSoapValue($soapval)) { |
---|
725 | return $soapval; |
---|
726 | } elseif (is_array($soapval->value)) { |
---|
727 | if ($soapval->type != 'Array') { |
---|
728 | $classname = $this->_defaultObjectClassname; |
---|
729 | if (isset($this->_type_translation[$soapval->tqn->fqn()])) { |
---|
730 | // This will force an error in PHP if the class does not |
---|
731 | // exist. |
---|
732 | $classname = $this->_type_translation[$soapval->tqn->fqn()]; |
---|
733 | } elseif (isset($this->_type_translation[$soapval->type])) { |
---|
734 | // This will force an error in PHP if the class does not |
---|
735 | // exist. |
---|
736 | $classname = $this->_type_translation[$soapval->type]; |
---|
737 | } elseif ($this->_auto_translation) { |
---|
738 | if (class_exists($soapval->type)) { |
---|
739 | $classname = $soapval->type; |
---|
740 | } elseif ($this->_wsdl) { |
---|
741 | $t = $this->_wsdl->getComplexTypeNameForElement($soapval->name, $soapval->namespace); |
---|
742 | if ($t && class_exists($t)) { |
---|
743 | $classname = $t; |
---|
744 | } |
---|
745 | } |
---|
746 | } |
---|
747 | $return =& new $classname; |
---|
748 | } else { |
---|
749 | $return = array(); |
---|
750 | } |
---|
751 | |
---|
752 | $counter = 1; |
---|
753 | $isstruct = !is_array($return); |
---|
754 | foreach ($soapval->value as $item) { |
---|
755 | if (is_object($return)) { |
---|
756 | if ($this->_wsdl) { |
---|
757 | // Get this child's WSDL information. |
---|
758 | // /$soapval->ns/$soapval->type/$item->ns/$item->name |
---|
759 | $child_type = $this->_wsdl->getComplexTypeChildType( |
---|
760 | $soapval->namespace, |
---|
761 | $soapval->name, |
---|
762 | $item->namespace, |
---|
763 | $item->name); |
---|
764 | if ($child_type) { |
---|
765 | $item->type = $child_type; |
---|
766 | } |
---|
767 | } |
---|
768 | if (!$isstruct || $item->type == 'Array') { |
---|
769 | if (isset($return->{$item->name}) && |
---|
770 | is_object($return->{$item->name})) { |
---|
771 | $return->{$item->name} =& $this->_decode($item); |
---|
772 | } elseif (isset($return->{$item->name}) && |
---|
773 | is_array($return->{$item->name})) { |
---|
774 | $return->{$item->name}[] = $this->_decode($item); |
---|
775 | } elseif (isset($return->{$item->name})) { |
---|
776 | $return->{$item->name} = array( |
---|
777 | $return->{$item->name}, |
---|
778 | $this->_decode($item) |
---|
779 | ); |
---|
780 | } elseif (is_array($return)) { |
---|
781 | $return[] =& $this->_decode($item); |
---|
782 | } else { |
---|
783 | $return->{$item->name} =& $this->_decode($item); |
---|
784 | } |
---|
785 | } elseif (isset($return->{$item->name})) { |
---|
786 | //$isstruct = false; |
---|
787 | if (count(get_object_vars($return)) == 1) { |
---|
788 | $d =& $this->_decode($item); |
---|
789 | $return = array($return->{$item->name}, $d); |
---|
790 | } else { |
---|
791 | $d =& $this->_decode($item); |
---|
792 | $return->{$item->name} = array($return->{$item->name}, $d); |
---|
793 | } |
---|
794 | } else { |
---|
795 | $return->{$item->name} =& $this->_decode($item); |
---|
796 | } |
---|
797 | // Set the attributes as members in the class. |
---|
798 | if (method_exists($return, '__set_attribute')) { |
---|
799 | foreach ($soapval->attributes as $key => $value) { |
---|
800 | call_user_func_array(array(&$return, |
---|
801 | '__set_attribute'), |
---|
802 | array($key, $value)); |
---|
803 | } |
---|
804 | } |
---|
805 | } else { |
---|
806 | if ($soapval->arrayType && $this->_isSoapValue($item)) { |
---|
807 | if ($this->_isBase64Type($item->type) && |
---|
808 | !$this->_isBase64Type($soapval->arrayType)) { |
---|
809 | // Decode the value if we're losing the base64 |
---|
810 | // type information. |
---|
811 | $item->value = base64_decode($item->value); |
---|
812 | } |
---|
813 | $item->type = $soapval->arrayType; |
---|
814 | } |
---|
815 | if (!$isstruct) { |
---|
816 | $return[] = $this->_decode($item); |
---|
817 | } elseif (isset($return[$item->name])) { |
---|
818 | $isstruct = false; |
---|
819 | $d =& $this->_decode($item); |
---|
820 | $return = array($return[$item->name], $d); |
---|
821 | } else { |
---|
822 | $return[$item->name] = $this->_decode($item); |
---|
823 | } |
---|
824 | } |
---|
825 | } |
---|
826 | |
---|
827 | return $return; |
---|
828 | } |
---|
829 | |
---|
830 | if ($soapval->type == 'boolean') { |
---|
831 | if ($soapval->value != '0' && |
---|
832 | strcasecmp($soapval->value, 'false') != 0) { |
---|
833 | $soapval->value = true; |
---|
834 | } else { |
---|
835 | $soapval->value = false; |
---|
836 | } |
---|
837 | } elseif ($soapval->type && |
---|
838 | isset($this->_typemap[SOAP_XML_SCHEMA_VERSION][$soapval->type])) { |
---|
839 | // If we can, set variable type. |
---|
840 | settype($soapval->value, |
---|
841 | $this->_typemap[SOAP_XML_SCHEMA_VERSION][$soapval->type]); |
---|
842 | } |
---|
843 | |
---|
844 | return $soapval->value; |
---|
845 | } |
---|
846 | |
---|
847 | /** |
---|
848 | * Creates the SOAP envelope with the SOAP envelop data. |
---|
849 | * |
---|
850 | * @param mixed $method |
---|
851 | * @param array $headers |
---|
852 | * @param string $encoding |
---|
853 | * @param array $options |
---|
854 | * |
---|
855 | * @return string |
---|
856 | */ |
---|
857 | function makeEnvelope(&$method, &$headers, |
---|
858 | $encoding = SOAP_DEFAULT_ENCODING, |
---|
859 | $options = array()) |
---|
860 | { |
---|
861 | $smsg = $header_xml = $ns_string = ''; |
---|
862 | |
---|
863 | if ($headers) { |
---|
864 | $c = count($headers); |
---|
865 | for ($i = 0; $i < $c; $i++) { |
---|
866 | $header_xml .= $headers[$i]->serialize($this); |
---|
867 | } |
---|
868 | $header_xml = "<SOAP-ENV:Header>\r\n$header_xml\r\n</SOAP-ENV:Header>\r\n"; |
---|
869 | } |
---|
870 | |
---|
871 | if (!isset($options['input']) || $options['input'] == 'parse') { |
---|
872 | if (is_array($method)) { |
---|
873 | $c = count($method); |
---|
874 | for ($i = 0; $i < $c; $i++) { |
---|
875 | $smsg .= $method[$i]->serialize($this); |
---|
876 | } |
---|
877 | } else { |
---|
878 | $smsg = $method->serialize($this); |
---|
879 | } |
---|
880 | } else { |
---|
881 | $smsg = $method; |
---|
882 | } |
---|
883 | $body = "<SOAP-ENV:Body>\r\n" . $smsg . "\r\n</SOAP-ENV:Body>\r\n"; |
---|
884 | |
---|
885 | foreach ($this->_namespaces as $k => $v) { |
---|
886 | $ns_string .= " xmlns:$v=\"$k\"\r\n"; |
---|
887 | } |
---|
888 | if ($this->_namespace) { |
---|
889 | $ns_string .= " xmlns=\"{$this->_namespace}\"\r\n"; |
---|
890 | } |
---|
891 | |
---|
892 | /* If 'use' == 'literal', we do not put in the encodingStyle. This is |
---|
893 | * denoted by $this->_section5 being false. 'use' can be defined at a |
---|
894 | * more granular level than we are dealing with here, so this does not |
---|
895 | * work for all services. */ |
---|
896 | $xml = "<?xml version=\"1.0\" encoding=\"$encoding\"?>\r\n\r\n". |
---|
897 | "<SOAP-ENV:Envelope $ns_string". |
---|
898 | ($this->_section5 ? ' SOAP-ENV:encodingStyle="' . SOAP_SCHEMA_ENCODING . '"' : ''). |
---|
899 | ">\r\n". |
---|
900 | "$header_xml$body</SOAP-ENV:Envelope>\r\n"; |
---|
901 | |
---|
902 | return $xml; |
---|
903 | } |
---|
904 | |
---|
905 | function _makeMimeMessage($xml, $encoding = SOAP_DEFAULT_ENCODING) |
---|
906 | { |
---|
907 | if (!@include_once 'Mail/mimePart.php') { |
---|
908 | return $this->_raiseSoapFault('MIME messages are unsupported, the Mail_Mime package is not installed'); |
---|
909 | } |
---|
910 | |
---|
911 | // Encode any attachments. See http://www.w3.org/TR/SOAP-attachments |
---|
912 | // Now we have to mime encode the message. |
---|
913 | $params = array('content_type' => 'multipart/related; type="text/xml"'); |
---|
914 | $msg = new Mail_mimePart('', $params); |
---|
915 | |
---|
916 | // Add the xml part. |
---|
917 | $params['content_type'] = 'text/xml'; |
---|
918 | $params['charset'] = $encoding; |
---|
919 | $params['encoding'] = 'base64'; |
---|
920 | $msg->addSubPart($xml, $params); |
---|
921 | |
---|
922 | // Add the attachements |
---|
923 | for ($i = 0, $c = count($this->_attachments); $i < $c; ++$i) { |
---|
924 | $msg->addSubPart($this->_attachments[$i]['body'], |
---|
925 | $this->_attachments[$i]); |
---|
926 | } |
---|
927 | |
---|
928 | return $msg->encode(); |
---|
929 | } |
---|
930 | |
---|
931 | // TODO: this needs to be used from the Transport system. |
---|
932 | function _makeDIMEMessage($xml) |
---|
933 | { |
---|
934 | if (!@include_once 'Net/DIME.php') { |
---|
935 | return $this->_raiseSoapFault('DIME messages are unsupported, the Net_DIME package is not installed'); |
---|
936 | } |
---|
937 | |
---|
938 | // Encode any attachments. See |
---|
939 | // http://search.ietf.org/internet-drafts/draft-nielsen-dime-soap-00.txt |
---|
940 | // Now we have to DIME encode the message |
---|
941 | $dime = new Net_DIME_Message(); |
---|
942 | $msg = $dime->encodeData($xml, SOAP_ENVELOP, null, NET_DIME_TYPE_URI); |
---|
943 | |
---|
944 | // Add the attachments. |
---|
945 | $c = count($this->_attachments); |
---|
946 | for ($i = 0; $i < $c; $i++) { |
---|
947 | $msg .= $dime->encodeData($this->_attachments[$i]['body'], |
---|
948 | $this->_attachments[$i]['content_type'], |
---|
949 | $this->_attachments[$i]['cid'], |
---|
950 | NET_DIME_TYPE_MEDIA); |
---|
951 | } |
---|
952 | $msg .= $dime->endMessage(); |
---|
953 | |
---|
954 | return $msg; |
---|
955 | } |
---|
956 | |
---|
957 | function _decodeMimeMessage(&$data, &$headers, &$attachments) |
---|
958 | { |
---|
959 | if (!@include_once 'Mail/mimeDecode.php') { |
---|
960 | return $this->_raiseSoapFault('MIME messages are unsupported, the Mail_Mime package is not installed'); |
---|
961 | } |
---|
962 | |
---|
963 | $params['include_bodies'] = true; |
---|
964 | $params['decode_bodies'] = true; |
---|
965 | $params['decode_headers'] = true; |
---|
966 | |
---|
967 | // Lame thing to have to do for decoding. |
---|
968 | $decoder =& new Mail_mimeDecode($data); |
---|
969 | $structure = $decoder->decode($params); |
---|
970 | |
---|
971 | if (isset($structure->body)) { |
---|
972 | $data = $structure->body; |
---|
973 | $headers = $structure->headers; |
---|
974 | |
---|
975 | return; |
---|
976 | } elseif (isset($structure->parts)) { |
---|
977 | $data = $structure->parts[0]->body; |
---|
978 | $headers = array_merge($structure->headers, |
---|
979 | $structure->parts[0]->headers); |
---|
980 | if (count($structure->parts) > 1) { |
---|
981 | $mime_parts = array_splice($structure->parts,1); |
---|
982 | // Prepare the parts for the SOAP parser. |
---|
983 | |
---|
984 | $c = count($mime_parts); |
---|
985 | for ($i = 0; $i < $c; $i++) { |
---|
986 | $p =& $mime_parts[$i]; |
---|
987 | if (isset($p->headers['content-location'])) { |
---|
988 | // TODO: modify location per SwA note section 3 |
---|
989 | // http://www.w3.org/TR/SOAP-attachments |
---|
990 | $attachments[$p->headers['content-location']] = $p->body; |
---|
991 | } else { |
---|
992 | $cid = 'cid:' . substr($p->headers['content-id'], 1, -1); |
---|
993 | $attachments[$cid] = $p->body; |
---|
994 | } |
---|
995 | } |
---|
996 | } |
---|
997 | |
---|
998 | return; |
---|
999 | } |
---|
1000 | |
---|
1001 | $this->_raiseSoapFault('Mime parsing error', '', '', 'Server'); |
---|
1002 | } |
---|
1003 | |
---|
1004 | function _decodeDIMEMessage(&$data, &$headers, &$attachments) |
---|
1005 | { |
---|
1006 | if (!@include_once 'Net/DIME.php') { |
---|
1007 | return $this->_raiseSoapFault('DIME messages are unsupported, the Net_DIME package is not installed'); |
---|
1008 | } |
---|
1009 | |
---|
1010 | // This SHOULD be moved to the transport layer, e.g. PHP itself should |
---|
1011 | // handle parsing DIME ;) |
---|
1012 | $dime =& new Net_DIME_Message(); |
---|
1013 | $err = $dime->decodeData($data); |
---|
1014 | if (PEAR::isError($err)) { |
---|
1015 | $this->_raiseSoapFault('Failed to decode the DIME message!', '', '', 'Server'); |
---|
1016 | return; |
---|
1017 | } |
---|
1018 | if (strcasecmp($dime->parts[0]['type'], SOAP_ENVELOP) != 0) { |
---|
1019 | $this->_raiseSoapFault('DIME record 1 is not a SOAP envelop!', '', '', 'Server'); |
---|
1020 | return; |
---|
1021 | } |
---|
1022 | |
---|
1023 | $data = $dime->parts[0]['data']; |
---|
1024 | // Fake it for now. |
---|
1025 | $headers['content-type'] = 'text/xml'; |
---|
1026 | $c = count($dime->parts); |
---|
1027 | for ($i = 0; $i < $c; $i++) { |
---|
1028 | $part =& $dime->parts[$i]; |
---|
1029 | // We need to handle URI's better. |
---|
1030 | $id = strncmp($part['id'], 'cid:', 4) |
---|
1031 | ? 'cid:' . $part['id'] |
---|
1032 | : $part['id']; |
---|
1033 | $attachments[$id] = $part['data']; |
---|
1034 | } |
---|
1035 | } |
---|
1036 | |
---|
1037 | /** |
---|
1038 | * @deprecated Use setTypeTranslation(). |
---|
1039 | */ |
---|
1040 | function __set_type_translation($type, $class = null) |
---|
1041 | { |
---|
1042 | $this->setTypeTranslation($type, $class); |
---|
1043 | } |
---|
1044 | |
---|
1045 | /** |
---|
1046 | * Explicitly sets the translation for a specific class. |
---|
1047 | * |
---|
1048 | * Auto translation works for all cases, but opens ANY class in the script |
---|
1049 | * to be used as a data type, and may not be desireable. |
---|
1050 | * |
---|
1051 | * @param string $type A SOAP type. |
---|
1052 | * @param string $class A PHP class name. |
---|
1053 | */ |
---|
1054 | function setTypeTranslation($type, $class = null) |
---|
1055 | { |
---|
1056 | $tq = new QName($type); |
---|
1057 | if (!$class) { |
---|
1058 | $class = $tq->name; |
---|
1059 | } |
---|
1060 | $this->_type_translation[$type]=$class; |
---|
1061 | } |
---|
1062 | |
---|
1063 | } |
---|
1064 | |
---|
1065 | /** |
---|
1066 | * Class used to handle QNAME values in XML. |
---|
1067 | * |
---|
1068 | * @access public |
---|
1069 | * @package SOAP |
---|
1070 | * @author Shane Caraveo <shane@php.net> Conversion to PEAR and updates |
---|
1071 | */ |
---|
1072 | class QName |
---|
1073 | { |
---|
1074 | var $name = ''; |
---|
1075 | var $ns = ''; |
---|
1076 | var $namespace=''; |
---|
1077 | |
---|
1078 | function QName($name, $namespace = '') |
---|
1079 | { |
---|
1080 | if ($name && $name[0] == '{') { |
---|
1081 | preg_match('/\{(.*?)\}(.*)/', $name, $m); |
---|
1082 | $this->name = $m[2]; |
---|
1083 | $this->namespace = $m[1]; |
---|
1084 | } elseif (substr_count($name, ':') == 1) { |
---|
1085 | $s = explode(':', $name); |
---|
1086 | $s = array_reverse($s); |
---|
1087 | $this->name = $s[0]; |
---|
1088 | $this->ns = $s[1]; |
---|
1089 | $this->namespace = $namespace; |
---|
1090 | } else { |
---|
1091 | $this->name = $name; |
---|
1092 | $this->namespace = $namespace; |
---|
1093 | } |
---|
1094 | |
---|
1095 | // A little more magic than should be in a qname. |
---|
1096 | $p = strpos($this->name, '['); |
---|
1097 | if ($p) { |
---|
1098 | // TODO: Need to re-examine this logic later. |
---|
1099 | // Chop off []. |
---|
1100 | $this->arraySize = explode(',', substr($this->name, $p + 1, -$p - 2)); |
---|
1101 | $this->arrayInfo = substr($this->name, $p); |
---|
1102 | $this->name = substr($this->name, 0, $p); |
---|
1103 | } |
---|
1104 | } |
---|
1105 | |
---|
1106 | function fqn() |
---|
1107 | { |
---|
1108 | if ($this->namespace) { |
---|
1109 | return '{' . $this->namespace . '}' . $this->name; |
---|
1110 | } elseif ($this->ns) { |
---|
1111 | return $this->ns . ':' . $this->name; |
---|
1112 | } |
---|
1113 | return $this->name; |
---|
1114 | } |
---|
1115 | |
---|
1116 | } |
---|