ILIAS  release_5-1 Revision 5.0.0-5477-g43f3e3fab5f
class.ilBMFBase.php
Go to the documentation of this file.
1<?php
35$GLOBALS['SOAP_OBJECT_STRUCT'] = true;
36
45$GLOBALS['SOAP_RAW_CONVERT'] = false;
46
47require_once 'PEAR.php';
48require_once dirname(__FILE__).'/Type/class.ilBMFType_dateTime.php';
49require_once dirname(__FILE__).'/Type/class.ilBMFType_hexBinary.php';
50
51// optional features
52$GLOBALS['SOAP_options'] = array();
53
54@include_once 'Mail/mimePart.php';
55@include_once 'Mail/mimeDecode.php';
56if (class_exists('Mail_mimePart')) {
57 $GLOBALS['SOAP_options']['Mime'] = 1;
58 define('MAIL_MIMEPART_CRLF', "\r\n");
59}
60
61@include_once 'Net/DIME.php';
62if (class_exists('Net_DIME_Message')) {
63 $GLOBALS['SOAP_options']['DIME'] = 1;
64}
65
72$GLOBALS['SOAP_DEBUG'] = false;
73
74if (!function_exists('version_compare') ||
75 version_compare(phpversion(), '4.1', '<')) {
76 die("requires PHP 4.1 or higher\n");
77}
78if (version_compare(phpversion(), '4.1', '>=') &&
79 version_compare(phpversion(), '4.2', '<')) {
80 define('FLOAT', 'double');
81} else {
82 define('FLOAT', 'float');
83}
84
85if (!defined('INF')) {
86 define('INF', 1.8e307);
87}
88if (!defined('NAN')) {
89 define('NAN', 0.0);
90}
91
92define('SOAP_LIBRARY_VERSION', '0.8.0RC4');
93define('SOAP_LIBRARY_NAME', 'PEAR-SOAP 0.8.0RC4-devel');
94
95// Set schema version.
96define('SOAP_XML_SCHEMA_VERSION', 'http://www.w3.org/2001/XMLSchema');
97define('SOAP_XML_SCHEMA_INSTANCE', 'http://www.w3.org/2001/XMLSchema-instance');
98define('SOAP_XML_SCHEMA_1999', 'http://www.w3.org/1999/XMLSchema');
99define('SOAP_SCHEMA', 'http://schemas.xmlsoap.org/wsdl/soap/');
100define('SOAP_SCHEMA_ENCODING', 'http://schemas.xmlsoap.org/soap/encoding/');
101define('SOAP_ENVELOP', 'http://schemas.xmlsoap.org/soap/envelope/');
102
103define('SCHEMA_DISCO', 'http://schemas.xmlsoap.org/disco/');
104define('SCHEMA_DISCO_SCL', 'http://schemas.xmlsoap.org/disco/scl/');
105
106define('SCHEMA_SOAP', 'http://schemas.xmlsoap.org/wsdl/soap/');
107define('SCHEMA_SOAP_HTTP', 'http://schemas.xmlsoap.org/soap/http');
108define('SCHEMA_WSDL_HTTP', 'http://schemas.xmlsoap.org/wsdl/http/');
109define('SCHEMA_MIME', 'http://schemas.xmlsoap.org/wsdl/mime/');
110define('SCHEMA_WSDL', 'http://schemas.xmlsoap.org/wsdl/');
111define('SCHEMA_DIME', 'http://schemas.xmlsoap.org/ws/2002/04/dime/wsdl/');
112define('SCHEMA_CONTENT', 'http://schemas.xmlsoap.org/ws/2002/04/content-type/');
113define('SCHEMA_REF', 'http://schemas.xmlsoap.org/ws/2002/04/reference/');
114
115/* Databay: Changes for BMF */
116#define('SOAP_DEFAULT_ENCODING', 'UTF-8');
117define('SOAP_DEFAULT_ENCODING', 'ISO-8859-1');
118
120{
127 var $_debug_flag = false;
128
136 var $_debug_data = '';
137
143 var $_encodings = array('ISO-8859-1', 'US-ASCII', 'UTF-8');
144
151
157 var $fault = null;
158
166 function ilBMFBase_Object($faultcode = 'Client')
167 {
168 $this->_myfaultcode = $faultcode;
169 $this->_debug_flag = $GLOBALS['SOAP_DEBUG'];
170 parent::PEAR('ilBMFFault');
171 }
172
191 function &_raiseSoapFault($str, $detail = '', $actorURI = '', $code = null,
192 $mode = null, $options = null, $skipmsg = false)
193 {
194 // Pass through previous faults.
195 $is_instance = isset($this);
196 if (is_object($str)) {
197 $fault =& $str;
198 } else {
199 if (!$code) {
200 $code = $is_instance ? $this->_myfaultcode : 'Client';
201 }
202 $fault =& new ilBMFFault($str,
203 $code,
204 $actorURI,
205 $detail,
206 $mode,
207 $options);
208 }
209 if ($is_instance) {
210 $this->fault =& $fault;
211 }
212
213 return $fault;
214 }
215
216 function __isfault()
217 {
218 return $this->fault != null;
219 }
220
221 function &__getfault()
222 {
223 return $this->fault;
224 }
225
231 function _debug($string)
232 {
233 if ($this->_debug_flag) {
234 $this->_debug_data .= get_class($this) . ': ' .
235 str_replace('>', ">\r\n", $string) . "\n";
236 }
237 }
238
239}
240
249{
250 var $_XMLSchema = array('http://www.w3.org/2001/XMLSchema',
251 'http://www.w3.org/1999/XMLSchema');
252 var $_XMLSchemaVersion = 'http://www.w3.org/2001/XMLSchema';
253
254 // load types into typemap array
255 var $_typemap = array(
256 'http://www.w3.org/2001/XMLSchema' => array(
257 'string' => 'string',
258 'boolean' => 'boolean',
259 'float' => FLOAT,
260 'double' => FLOAT,
261 'decimal' => FLOAT,
262 'duration' => 'integer',
263 'dateTime' => 'string',
264 'time' => 'string',
265 'date' => 'string',
266 'gYearMonth' => 'integer',
267 'gYear' => 'integer',
268 'gMonthDay' => 'integer',
269 'gDay' => 'integer',
270 'gMonth' => 'integer',
271 'hexBinary' => 'string',
272 'base64Binary' => 'string',
273 // derived datatypes
274 'normalizedString' => 'string',
275 'token' => 'string',
276 'language' => 'string',
277 'NMTOKEN' => 'string',
278 'NMTOKENS' => 'string',
279 'Name' => 'string',
280 'NCName' => 'string',
281 'ID' => 'string',
282 'IDREF' => 'string',
283 'IDREFS' => 'string',
284 'ENTITY' => 'string',
285 'ENTITIES' => 'string',
286 'integer' => 'integer',
287 'nonPositiveInteger' => 'integer',
288 'negativeInteger' => 'integer',
289 'long' => 'integer',
290 'int' => 'integer',
291 'short' => 'integer',
292 'byte' => 'string',
293 'nonNegativeInteger' => 'integer',
294 'unsignedLong' => 'integer',
295 'unsignedInt' => 'integer',
296 'unsignedShort' => 'integer',
297 'unsignedByte' => 'integer',
298 'positiveInteger' => 'integer',
299 'anyType' => 'string',
300 'anyURI' => 'string',
301 'QName' => 'string'
302 ),
303 'http://www.w3.org/1999/XMLSchema' => array(
304 'i4' => 'integer',
305 'int' => 'integer',
306 'boolean' => 'boolean',
307 'string' => 'string',
308 'double' => FLOAT,
309 'float' => FLOAT,
310 'dateTime' => 'string',
311 'timeInstant' => 'string',
312 'base64Binary' => 'string',
313 'base64' => 'string',
314 'ur-type' => 'string'
315 ),
316 'http://schemas.xmlsoap.org/soap/encoding/' => array(
317 'base64' => 'string',
318 'array' => 'array',
319 'Array' => 'array',
320 'Struct' => 'array')
321 );
322
328 var $_defaultObjectClassname = 'stdClass';
329
330 // Load namespace URIs into an array of URI => prefix.
333
334 var $_xmlEntities = array('&' => '&amp;',
335 '<' => '&lt;',
336 '>' => '&gt;',
337 "'" => '&apos;',
338 '"' => '&quot;');
339
340 var $_doconversion = false;
341
342 var $__attachments = array();
343
344 var $_wsdl = null;
345
351 var $_section5 = true;
352
353 // Handle type to class mapping.
355 var $_type_translation = array();
356
364 function ilBMFBase($faultcode = 'Client')
365 {
366 parent::ilBMFBase_Object($faultcode);
367 $this->_resetNamespaces();
368 }
369
371 {
372 $this->_namespaces = array(
373 'http://schemas.xmlsoap.org/soap/envelope/' => 'SOAP-ENV',
374 'http://www.w3.org/2001/XMLSchema' => 'xsd',
375 'http://www.w3.org/2001/XMLSchema-instance' => 'xsi',
376 'http://schemas.xmlsoap.org/soap/encoding/' => 'SOAP-ENC');
377 }
378
387 function _setSchemaVersion($schemaVersion)
388 {
389 if (!in_array($schemaVersion, $this->_XMLSchema)) {
390 return $this->_raiseSoapFault("unsuported XMLSchema $schemaVersion");
391 }
392 $this->_XMLSchemaVersion = $schemaVersion;
393 $tmpNS = array_flip($this->_namespaces);
394 $tmpNS['xsd'] = $this->_XMLSchemaVersion;
395 $tmpNS['xsi'] = $this->_XMLSchemaVersion . '-instance';
396 $this->_namespaces = array_flip($tmpNS);
397 }
398
400 {
401 if ($this->_namespace && $ns == $this->_namespace) {
402 return '';
403 }
404 if (isset($this->_namespaces[$ns])) {
405 return $this->_namespaces[$ns];
406 }
407 $prefix = 'ns' . count($this->_namespaces);
408 $this->_namespaces[$ns] = $prefix;
409 return $prefix;
410 }
411
412 function _getNamespaceForPrefix($prefix)
413 {
414 $flipped = array_flip($this->_namespaces);
415 if (isset($flipped[$prefix])) {
416 return $flipped[$prefix];
417 }
418 return null;
419 }
420
421 function _isSoapValue(&$value)
422 {
423 return is_a($value, 'ilBMFValue');
424 }
425
426 function _serializeValue(&$value, $name = '', $type = false, $elNamespace = NULL, $typeNamespace=NULL, $options=array(), $attributes = array(), $artype='', $OBJTypeNS = array())
427 {
428 $namespaces = array();
429 $arrayType = $array_depth = $xmlout_value = null;
430 $typePrefix = $elPrefix = $xmlout_offset = $xmlout_arrayType = $xmlout_type = $xmlns = '';
431 $ptype = $array_type_ns = '';
432
433 if (!$name || is_numeric($name)) {
434 $name = 'item';
435 }
436
437 if ($this->_wsdl)
438 list($ptype, $arrayType, $array_type_ns, $array_depth)
439 = $this->_wsdl->getSchemaType($type, $name, $typeNamespace);
440
441 if (!$arrayType) $arrayType = $artype;
442 if (!$ptype) $ptype = $this->_getType($value);
443 if (!$type) $type = $ptype;
444
445 if (strcasecmp($ptype,'Struct') == 0 || strcasecmp($type,'Struct') == 0) {
446 // struct
447 $vars = NULL;
448 if (is_object($value)) {
449 $vars = get_object_vars($value);
450 } else {
451 $vars = &$value;
452 }
453 if (is_array($vars)) {
454 foreach (array_keys($vars) as $k) {
455 if ($k[0]=='_') continue; // hide private vars
456 if (is_object($vars[$k])) {
457 if (is_a($vars[$k],'ilbmfvalue')) {
458 $xmlout_value .= $vars[$k]->serialize($this);
459 } else {
460 // XXX get the members and serialize them instead
461 // converting to an array is more overhead than we
462 // should realy do, but php-soap is on it's way.
463 $objarr = get_object_vars ( $vars[$k] );
464 if (!isset ($objarr['OBJTypeNS'])) {
465 $xmlout_value .= $this->_serializeValue(get_object_vars($vars[$k]), $k, false, $this->_section5?NULL:$elNamespace, NULL, NULL, NULL, NULL);
466 } else {
467 $xmlout_value .= $this->_serializeValue(get_object_vars($vars[$k]), $k, false, $this->_section5?NULL:$elNamespace, NULL, NULL, NULL, NULL, $objarr['OBJTypeNS']);
468 }
469 }
470 } else {
471 if ($k != 'OBJTypeNS') {
472 $xmlout_value .= $this->_serializeValue($vars[$k],$k, false, $this->_section5?NULL:$elNamespace);
473 }
474 }
475 }
476 }
477 } else if (strcasecmp($ptype,'Array')==0 || strcasecmp($type,'Array')==0) {
478 // array
479 $typeNamespace = SOAP_SCHEMA_ENCODING;
480 $orig_type = $type;
481 $type = 'Array';
482 $numtypes = 0;
483 // XXX this will be slow on larger array's. Basicly, it flattens array's to allow us
484 // to serialize multi-dimensional array's. We only do this if arrayType is set,
485 // which will typicaly only happen if we are using WSDL
486 if (isset($options['flatten']) || ($arrayType && (strchr($arrayType,',') || strstr($arrayType,'][')))) {
487 $numtypes = $this->_multiArrayType($value, $arrayType, $ar_size, $xmlout_value);
488 }
489
490 $array_type = $array_type_prefix = '';
491 if ($numtypes != 1) {
492 $arrayTypeQName =& new QName($arrayType);
493 $arrayType = $arrayTypeQName->name;
494 $array_types = array();
495 $array_val = NULL;
496
497 // serialize each array element
498 $ar_size = count($value);
499 foreach ($value as $array_val) {
500 if ($this->_isSoapValue($array_val)) {
501 $array_type = $array_val->type;
502 $array_types[$array_type] = 1;
503 $array_type_ns = $array_val->type_namespace;
504 $xmlout_value .= $array_val->serialize($this);
505 } else {
506 $array_type = $this->_getType($array_val);
507 $array_types[$array_type] = 1;
508 $objarr = get_object_vars ( $array_val );
509 if (isset($objarr['OBJTypeNS'])) {
510 $tmp_arr['item'] = $objarr['OBJTypeNS']['item'];
511 $xmlout_value .= $this->_serializeValue($array_val,'item', $array_type, $elNamespace, NULL, NULL, NULL, NULL, $tmp_arr);
512 } else {
513 $xmlout_value .= $this->_serializeValue($array_val,'item', $array_type, $elNamespace);
514 }
515 }
516 }
517
518 $xmlout_offset = " SOAP-ENC:offset=\"[0]\"";
519 if (!$arrayType) {
520 $numtypes = count($array_types);
521 if ($numtypes == 1) $arrayType = $array_type;
522 // using anyType is more interoperable
523 if ($array_type == 'Struct') {
524 $array_type = '';
525 } else if ($array_type == 'Array') {
526 $arrayType = 'anyType';
527 $array_type_prefix = 'xsd';
528 } else
529 if (!$arrayType) $arrayType = $array_type;
530 }
531 }
532 if (!$arrayType || $numtypes > 1) {
533 $arrayType = 'xsd:anyType'; // should reference what schema we're using
534 } else {
535 if ($array_type_ns) {
536 $array_type_prefix = $this->_getNamespacePrefix($array_type_ns);
537 } else if (array_key_exists($arrayType, $this->_typemap[$this->_XMLSchemaVersion])) {
538 $array_type_prefix = $this->_namespaces[$this->_XMLSchemaVersion];
539 }
540 if ($array_type_prefix)
541 $arrayType = $array_type_prefix.':'.$arrayType;
542 }
543
544 if (isset($value[0]->OBJTypeNS)) {
545 $xmlout_arrayType = ' xmlns:' . $value[0]->OBJTypeNS['nsPrefix'] . '="' . $value[0]->OBJTypeNS['namespace'] . '" xsi:type="' . $value[0]->OBJTypeNS['nsPrefix'] . ':Array" ' . $value[0]->OBJTypeNS['nsPrefix'] . ':arrayType="' . $value[0]->OBJTypeNS['pnsPrefix'] . ':' . get_class($value[0]);
546 $xmlout_type = $xmlns = $xmlout_offset = $xml_attr = $arrayType = '';
547 } else {
548 $xmlout_arrayType = " SOAP-ENC:arrayType=\"" . $arrayType;
549 }
550 if ($array_depth != null) {
551 for ($i = 0; $i < $array_depth; $i++) {
552 $xmlout_arrayType .= '[]';
553 }
554 }
555 $xmlout_arrayType .= "[$ar_size]\"";
556 } else if ($this->_isSoapValue($value)) {
557 $xmlout_value =& $value->serialize($this);
558 } else if ($type == 'string') {
559 $xmlout_value = htmlspecialchars($value);
560 } else if ($type == 'rawstring') {
561 $xmlout_value =& $value;
562 } else if ($type == 'boolean') {
563 $xmlout_value = $value?'true':'false';
564 } else {
565 $xmlout_value =& $value;
566 }
567
568 // add namespaces
569 if ($elNamespace) {
570 $elPrefix = $this->_getNamespacePrefix($elNamespace);
571 $xmlout_name = "$elPrefix:$name";
572 } else {
573 $xmlout_name = $name;
574 }
575
576 if ($typeNamespace) {
577 $typePrefix = $this->_getNamespacePrefix($typeNamespace);
578 $xmlout_type = "$typePrefix:$type";
579 } else if ($type && array_key_exists($type, $this->_typemap[$this->_XMLSchemaVersion])) {
580 $typePrefix = $this->_namespaces[$this->_XMLSchemaVersion];
581 $xmlout_type = "$typePrefix:$type";
582 }
583
584 // handle additional attributes
585 $xml_attr = '';
586 if (count($attributes) > 0) {
587 foreach ($attributes as $k => $v) {
588 $kqn =& new QName($k);
589 $vqn =& new QName($v);
590 $xml_attr .= ' '.$kqn->fqn().'="'.$vqn->fqn().'"';
591 }
592 }
593
594 // store the attachement for mime encoding
595 if (isset($options['attachment']))
596 $this->__attachments[] = $options['attachment'];
597
598 if ($this->_section5) {
599 if ($name == 'item' && isset($OBJTypeNS['item'])) {
600 $xmlout_type = $OBJTypeNS['item'];
601 }
602
603 if ($xmlout_type) $xmlout_type = " xsi:type=\"$xmlout_type\"";
604 if (is_null($xmlout_value)) {
605 $xml = "";
606 } else {
607 if (is_array($value) && isset ($value[0]->OBJTypeNS)) {
608 $xmlout_type = '';
609 }
610 $xml = "\r\n<$xmlout_name$xmlout_type$xmlns$xmlout_arrayType$xmlout_offset$xml_attr ";
611 if (isset($OBJTypeNS['namespace']) && isset($OBJTypeNS['type'])) {
612 if (trim($OBJTypeNS['namespace']) != '' || trim($OBJTypeNS['type']) != '') {
613 if (isset($OBJTypeNS['namespace']) && $OBJTypeNS['namespace'] != '') {
614 $xml .= ' xmlns:';
615 if ( isset($OBJTypeNS['nsPrefix']))
616 $xml .= $OBJTypeNS['nsPrefix'];
617 else
618 $xml .= 'intf';
619 $xml .= '="' . $OBJTypeNS['namespace'] . '"';
620 }
621 if (isset($OBJTypeNS['type']) && $OBJTypeNS['type'] != '') {
622 $xml .= ' xsi:type="';
623 if (strpos($OBJTypeNS['type'], "xsd:") === false){
624 if (isset($OBJTypeNS['nsPrefix']))
625 $xml .= $OBJTypeNS['nsPrefix'] . ':';
626 else
627 $xml .= 'intf:';
628 }
629 $xml .= $OBJTypeNS['type'] . '"';
630 }
631 }
632 }
633 $xml .= ">" . $xmlout_value . "</$xmlout_name>";
634 }
635 } else {
636 if (is_null($xmlout_value)) {
637 $xml = "";
638 } else {
639 $xml = "\r\n<$xmlout_name$xmlns$xml_attr>".
640 $xmlout_value."</$xmlout_name>";
641 }
642 }
643 return $xml;
644 }
645
646
647/* Databay: Changes for BMF */
648/* function _serializeValue(&$value, $name = '', $type = false,
649 $elNamespace = null, $typeNamespace = null,
650 $options = array(), $attributes = array(),
651 $artype = '')
652 {
653 $namespaces = array();
654 $arrayType = $array_depth = $xmlout_value = null;
655 $typePrefix = $elPrefix = $xmlout_offset = $xmlout_arrayType = '';
656 $xmlout_type = $xmlns = $ptype = $array_type_ns = '';
657
658 if (!$name || is_numeric($name)) {
659 $name = 'item';
660 }
661
662 if ($this->_wsdl) {
663 list($ptype, $arrayType, $array_type_ns, $array_depth)
664 = $this->_wsdl->getSchemaType($type, $name, $typeNamespace);
665 }
666
667 if (!$arrayType) {
668 $arrayType = $artype;
669 }
670 if (!$ptype) {
671 $ptype = $this->_getType($value);
672 }
673 if (!$type) {
674 $type = $ptype;
675 }
676
677 if (strcasecmp($ptype, 'Struct') == 0 ||
678 strcasecmp($type, 'Struct') == 0) {
679 // Struct
680 $vars = null;
681 if (is_object($value)) {
682 $vars = get_object_vars($value);
683 } else {
684 $vars = &$value;
685 }
686 if (is_array($vars)) {
687 foreach (array_keys($vars) as $k) {
688 // Hide private vars.
689 if ($k[0] == '_') continue;
690 if (is_object($vars[$k])) {
691 if (is_a($vars[$k], 'ilBMFValue')) {
692 $xmlout_value .= $vars[$k]->serialize($this);
693 } else {
694 // XXX get the members and serialize them instead
695 // converting to an array is more overhead than we
696 // should really do.
697 $xmlout_value .= $this->_serializeValue(get_object_vars($vars[$k]), $k, false, $this->_section5 ? null : $elNamespace);
698 }
699 } else {
700 $xmlout_value .= $this->_serializeValue($vars[$k], $k, false, $this->_section5 ? null : $elNamespace);
701 }
702 }
703 }
704 } elseif (strcasecmp($ptype, 'Array') == 0 ||
705 strcasecmp($type, 'Array') == 0) {
706 // Array.
707 $typeNamespace = SOAP_SCHEMA_ENCODING;
708 $orig_type = $type;
709 $type = 'Array';
710 $numtypes = 0;
711 // XXX this will be slow on larger arrays. Basically, it flattens
712 // arrays to allow us to serialize multi-dimensional arrays. We
713 // only do this if arrayType is set, which will typically only
714 // happen if we are using WSDL
715 if (isset($options['flatten']) ||
716 ($arrayType &&
717 (strchr($arrayType, ',') || strstr($arrayType, '][')))) {
718 $numtypes = $this->_multiArrayType($value, $arrayType,
719 $ar_size, $xmlout_value);
720 }
721
722 $array_type = $array_type_prefix = '';
723 if ($numtypes != 1) {
724 $arrayTypeQName =& new QName($arrayType);
725 $arrayType = $arrayTypeQName->name;
726 $array_types = array();
727 $array_val = null;
728
729 // Serialize each array element.
730 $ar_size = count($value);
731 foreach ($value as $array_val) {
732 if ($this->_isSoapValue($array_val)) {
733 $array_type = $array_val->type;
734 $array_types[$array_type] = 1;
735 $array_type_ns = $array_val->type_namespace;
736 $xmlout_value .= $array_val->serialize($this);
737 } else {
738 $array_type = $this->_getType($array_val);
739 $array_types[$array_type] = 1;
740 $xmlout_value .= $this->_serializeValue($array_val, 'item', $array_type, $this->_section5 ? null : $elNamespace);
741 }
742 }
743
744 $xmlout_offset = ' SOAP-ENC:offset="[0]"';
745 if (!$arrayType) {
746 $numtypes = count($array_types);
747 if ($numtypes == 1) {
748 $arrayType = $array_type;
749 }
750 // Using anyType is more interoperable.
751 if ($array_type == 'Struct') {
752 $array_type = '';
753 } elseif ($array_type == 'Array') {
754 $arrayType = 'anyType';
755 $array_type_prefix = 'xsd';
756 } else {
757 if (!$arrayType) {
758 $arrayType = $array_type;
759 }
760 }
761 }
762 }
763 if (!$arrayType || $numtypes > 1) {
764 // Should reference what schema we're using.
765 $arrayType = 'xsd:anyType';
766 } else {
767 if ($array_type_ns) {
768 $array_type_prefix = $this->_getNamespacePrefix($array_type_ns);
769 } elseif (isset($this->_typemap[$this->_XMLSchemaVersion][$arrayType])) {
770 $array_type_prefix = $this->_namespaces[$this->_XMLSchemaVersion];
771 }
772 if ($array_type_prefix) {
773 $arrayType = $array_type_prefix . ':' . $arrayType;
774 }
775 }
776
777 $xmlout_arrayType = ' SOAP-ENC:arrayType="' . $arrayType;
778 if ($array_depth != null) {
779 for ($i = 0; $i < $array_depth; $i++) {
780 $xmlout_arrayType .= '[]';
781 }
782 }
783 $xmlout_arrayType .= "[$ar_size]\"";
784 } elseif ($this->_isSoapValue($value)) {
785 $xmlout_value = $value->serialize($this);
786 } elseif ($type == 'string') {
787 $xmlout_value = htmlspecialchars($value);
788 } elseif ($type == 'rawstring') {
789 $xmlout_value =& $value;
790 } elseif ($type == 'boolean') {
791 $xmlout_value = $value ? 'true' : 'false';
792 } else {
793 $xmlout_value =& $value;
794 }
795
796 // Add namespaces.
797 if ($elNamespace) {
798 $elPrefix = $this->_getNamespacePrefix($elNamespace);
799 if ($elPrefix) {
800 $xmlout_name = "$elPrefix:$name";
801 } else {
802 $xmlout_name = $name;
803 }
804 } else {
805 $xmlout_name = $name;
806 }
807
808 if ($typeNamespace) {
809 $typePrefix = $this->_getNamespacePrefix($typeNamespace);
810 if ($typePrefix) {
811 $xmlout_type = "$typePrefix:$type";
812 } else {
813 $xmlout_type = $type;
814 }
815 } elseif ($type &&
816 isset($this->_typemap[$this->_XMLSchemaVersion][$type])) {
817 $typePrefix = $this->_namespaces[$this->_XMLSchemaVersion];
818 if ($typePrefix) {
819 $xmlout_type = "$typePrefix:$type";
820 } else {
821 $xmlout_type = $type;
822 }
823 }
824
825 // Handle additional attributes.
826 $xml_attr = '';
827 if (count($attributes)) {
828 foreach ($attributes as $k => $v) {
829 $kqn =& new QName($k);
830 $vqn =& new QName($v);
831 $xml_attr .= ' ' . $kqn->fqn() . '="' . $vqn->fqn() . '"';
832 }
833 }
834
835 // Store the attachment for mime encoding.
836 if (isset($options['attachment']) &&
837 !PEAR::isError($options['attachment'])) {
838 $this->__attachments[] = $options['attachment'];
839 }
840
841 if ($this->_section5) {
842 if ($xmlout_type) {
843 $xmlout_type = " xsi:type=\"$xmlout_type\"";
844 }
845 if (is_null($xmlout_value)) {
846 $xml = "\r\n<$xmlout_name$xmlout_type$xmlns$xmlout_arrayType" .
847 "$xml_attr xsi:nil=\"true\"/>";
848 } else {
849 $xml = "\r\n<$xmlout_name$xmlout_type$xmlns$xmlout_arrayType" .
850 "$xmlout_offset$xml_attr>$xmlout_value</$xmlout_name>";
851 }
852 } else {
853 if (is_null($xmlout_value)) {
854 $xml = "\r\n<$xmlout_name$xmlns$xml_attr/>";
855 } else {
856 $xml = "\r\n<$xmlout_name$xmlns$xml_attr>" .
857 $xmlout_value . "</$xmlout_name>";
858 }
859 }
860
861 return $xml;
862 }
863*/
873 function _getType(&$value)
874 {
875 global $SOAP_OBJECT_STRUCT, $SOAP_RAW_CONVERT;
876
877 $type = gettype($value);
878 switch ($type) {
879 case 'object':
880 if (is_a($value, 'ilbmfvalue')) {
881 $type = $value->type;
882 } else {
883 $type = 'Struct';
884 }
885 break;
886
887 case 'array':
888 // Hashes are always handled as structs.
889 if ($this->_isHash($value)) {
890 $type = 'Struct';
891 } else {
892 $ar_size = count($value);
893 reset($value);
894 $key1 = key($value);
895 if ($ar_size > 0 && is_a($key1, 'ilBMFValue')) {
896 // FIXME: for non-wsdl structs that are all the same type
897 $key2 = key($value);
898 if ($ar_size > 1 &&
899 $this->_isSoapValue($key1) &&
900 $this->_isSoapValue($key2) &&
901 $key1->name != $key2->name) {
902 // This is a struct, not an array.
903 $type = 'Struct';
904 } else {
905 $type = 'Array';
906 }
907 } else {
908 $type = 'Array';
909 }
910 }
911 break;
912
913 case 'integer':
914 case 'long':
915 $type = 'int';
916 break;
917
918 case 'boolean':
919 break;
920
921 case 'double':
922 // double is deprecated in PHP 4.2 and later.
923 $type = 'decimal';
924 break;
925
926 case 'null':
927 $type = '';
928 break;
929
930 case 'string':
931/* Databay: Changes for BMF */
932/* if ($SOAP_RAW_CONVERT) {
933 if (is_numeric($value)) {
934 if (strstr($value, '.')) {
935 $type = 'float';
936 } else {
937 $type = 'int';
938 }
939 } else {
940 if (ilBMFType_hexBinary::is_hexbin($value)) {
941 $type = 'hexBinary';
942 } else {
943 if ($this->_isBase64($value)) {
944 $type = 'base64Binary';
945 } else {
946 $dt =& new ilBMFType_dateTime($value);
947 if ($dt->toUnixtime() != -1) {
948 $type = 'dateTime';
949 }
950 }
951 }
952 }
953 }
954 break;*/
955 if ($SOAP_RAW_CONVERT) {
956 if (is_numeric($value)) {
957 if (strstr($value,'.')) $type = 'float';
958 else $type = 'int';
959 } else
960 if (ilBMFType_hexBinary::is_hexbin($value)) {
961 $type = 'hexBinary';
962 } else
963 if ($this->_isBase64($value)) {
964 $type = 'base64Binary';
965 } else {
966 $dt =& new ilBMFType_dateTime($value);
967 if ($dt->toUnixtime() != -1) {
968 $type = 'dateTime';
969 #$value = $dt->toSOAP();
970 }
971 }
972 } else {
973 $dt =& new ilBMFType_dateTime($value);
974 if ($dt->toUnixtime() != -1) {
975 $type = 'dateTime';
976 #$value = $dt->toSOAP();
977 }
978 }
979
980 default:
981 break;
982 }
983
984 return $type;
985 }
986
987 function _multiArrayType(&$value, &$type, &$size, &$xml)
988 {
989 $sz = count($value);
990 if (is_array($value)) {
991 // Seems we have a multi dimensional array, figure it out if we
992 // do.
993 $c = count($value);
994 for ($i = 0; $i < $c; $i++) {
995 $this->_multiArrayType($value[$i], $type, $size, $xml);
996 }
997
998 if ($size) {
999 $size = $sz. ',' . $size;
1000 } else {
1001 $size = $sz;
1002 }
1003
1004 return 1;
1005 } else {
1006 if (is_object($value)) {
1007 $type = $value->type;
1008 $xml .= $value->serialize($this);
1009 } else {
1010 $type = $this->_getType($value);
1011 $xml .= $this->_serializeValue($value, 'item', $type);
1012 }
1013 }
1014 $size = null;
1015
1016 return 1;
1017 }
1018
1026 function _isBase64(&$value)
1027 {
1028 $l = strlen($value);
1029 if ($l) {
1030 return $value[$l - 1] == '=' &&
1031 preg_match('/[A-Za-z=\/\+]+/', $value);
1032 }
1033 return false;
1034 }
1035
1043 function _isBase64Type($type)
1044 {
1045 return $type == 'base64' || $type == 'base64Binary';
1046 }
1047
1055 function _isHash(&$a)
1056 {
1057 // I really dislike having to loop through this in PHP code, really
1058 // large arrays will be slow. We need a C function to do this.
1059 $names = array();
1060 $it = 0;
1061 foreach ($a as $k => $v) {
1062 // Checking the type is faster than regexp.
1063 $t = gettype($k);
1064 if ($t != 'integer') {
1065 return true;
1066 } elseif ($this->_isSoapValue($v)) {
1067 $names[$v->name] = 1;
1068 }
1069 // If someone has a large hash they should really be defining the
1070 // type.
1071 if ($it++ > 10) {
1072 return false;
1073 }
1074 }
1075 return count($names)>1;
1076 }
1077
1078 function _un_htmlentities($string)
1079 {
1080 $trans_tbl = get_html_translation_table(HTML_ENTITIES);
1081 $trans_tbl = array_flip($trans_tbl);
1082 return strtr($string, $trans_tbl);
1083 }
1084
1085 function &_decode(&$soapval)
1086 {
1087 global $SOAP_OBJECT_STRUCT;
1088
1089 if (!$this->_isSoapValue($soapval)) {
1090 return $soapval;
1091 } elseif (is_array($soapval->value)) {
1092 if ($SOAP_OBJECT_STRUCT && $soapval->type != 'Array') {
1093 $classname = $this->_defaultObjectClassname;
1094 if (isset($this->_type_translation[$soapval->tqn->fqn()])) {
1095 // This will force an error in PHP if the class does not
1096 // exist.
1097 $classname = $this->_type_translation[$soapval->tqn->fqn()];
1098 } elseif (isset($this->_type_translation[$soapval->type])) {
1099 // This will force an error in PHP if the class does not
1100 // exist.
1101 $classname = $this->_type_translation[$soapval->type];
1102 } elseif ($this->_auto_translation) {
1103 if (class_exists($soapval->type)) {
1104 $classname = $soapval->type;
1105 } elseif ($this->_wsdl) {
1106 $t = $this->_wsdl->getComplexTypeNameForElement($soapval->name, $soapval->namespace);
1107 if ($t && class_exists($t)) {
1108 $classname = $t;
1109 }
1110 }
1111 }
1112 $return =& new $classname;
1113 } else {
1114 $return = array();
1115 }
1116
1117 $counter = 1;
1118 $isstruct = !$SOAP_OBJECT_STRUCT || !is_array($return);
1119 foreach ($soapval->value as $item) {
1120 if (is_object($return)) {
1121 if ($this->_wsdl) {
1122 // Get this child's WSDL information.
1123 // /$soapval->ns/$soapval->type/$item->ns/$item->name
1124 $child_type = $this->_wsdl->getComplexTypeChildType(
1125 $soapval->namespace,
1126 $soapval->name,
1127 $item->namespace,
1128 $item->name);
1129 if ($child_type) {
1130 $item->type = $child_type;
1131 }
1132 }
1133 if (!$isstruct || $item->type == 'Array') {
1134 if (isset($return->{$item->name}) &&
1135 is_object($return->{$item->name})) {
1136 $return->{$item->name} =& $this->_decode($item);
1137 } elseif (isset($return->{$item->name}) &&
1138 is_array($return->{$item->name})) {
1139 $return->{$item->name}[] = $this->_decode($item);
1140 } elseif (is_array($return)) {
1141 $return[] =& $this->_decode($item);
1142 } else {
1143 $return->{$item->name} =& $this->_decode($item);
1144 }
1145 } elseif (isset($return->{$item->name})) {
1146 $isstruct = false;
1147 if (count(get_object_vars($return)) == 1) {
1148 $d =& $this->_decode($item);
1149 $return = array($return->{$item->name}, $d);
1150 } else {
1151 $d =& $this->_decode($item);
1152 $return->{$item->name} = array($return->{$item->name}, $d);
1153 }
1154 } else {
1155 $return->{$item->name} =& $this->_decode($item);
1156 }
1157 // Set the attributes as members in the class.
1158 if (method_exists($return, '__set_attribute')) {
1159 foreach ($soapval->attributes as $key => $value) {
1160 call_user_func_array(array(&$return,
1161 '__set_attribute'),
1162 array($key, $value));
1163 }
1164 }
1165 } else {
1166 if ($soapval->arrayType && $this->_isSoapValue($item)) {
1167 if ($this->_isBase64Type($item->type) &&
1168 !$this->_isBase64Type($soapval->arrayType)) {
1169 // Decode the value if we're losing the base64
1170 // type information.
1171 $item->value = base64_decode($item->value);
1172 }
1173 $item->type = $soapval->arrayType;
1174 }
1175 if (!$isstruct) {
1176 $return[] = $this->_decode($item);
1177 } elseif (isset($return[$item->name])) {
1178 $isstruct = false;
1179 $d =& $this->_decode($item);
1180 $return = array($return[$item->name], $d);
1181 } else {
1182 $return[$item->name] = $this->_decode($item);
1183 }
1184 }
1185 }
1186
1187 return $return;
1188 }
1189
1190 if ($soapval->type == 'boolean') {
1191 if ($soapval->value != '0' &&
1192 strcasecmp($soapval->value, 'false') != 0) {
1193 $soapval->value = true;
1194 } else {
1195 $soapval->value = false;
1196 }
1197 } elseif ($soapval->type &&
1198 isset($this->_typemap[SOAP_XML_SCHEMA_VERSION][$soapval->type])) {
1199 // If we can, set variable type.
1200 settype($soapval->value,
1201 $this->_typemap[SOAP_XML_SCHEMA_VERSION][$soapval->type]);
1202 }
1203
1204 if ($this->_isBase64Type($soapval->type)) {
1205 return base64_decode($soapval->value);
1206 } else {
1207 return $soapval->value;
1208 }
1209 }
1210
1223 function _makeEnvelope(&$method, &$headers,
1224 $encoding = SOAP_DEFAULT_ENCODING,
1225 $options = array())
1226 {
1227 $smsg = $header_xml = $ns_string = '';
1228
1229 if ($headers) {
1230 $c = count($headers);
1231 for ($i = 0; $i < $c; $i++) {
1232 $header_xml .= $headers[$i]->serialize($this);
1233 }
1234 $header_xml = "<SOAP-ENV:Header>\r\n$header_xml\r\n</SOAP-ENV:Header>\r\n";
1235 }
1236
1237 if (!isset($options['input']) || $options['input'] == 'parse') {
1238 if (is_array($method)) {
1239 $c = count($method);
1240 for ($i = 0; $i < $c; $i++) {
1241 $smsg .= $method[$i]->serialize($this);
1242 }
1243 } else {
1244 $smsg = $method->serialize($this);
1245 }
1246 } else {
1247 $smsg = $method;
1248 }
1249 $body = "<SOAP-ENV:Body>\r\n" . $smsg . "\r\n</SOAP-ENV:Body>\r\n";
1250
1251 foreach ($this->_namespaces as $k => $v) {
1252 $ns_string .= " xmlns:$v=\"$k\"\r\n";
1253 }
1254 if ($this->_namespace) {
1255 $ns_string .= " xmlns=\"{$this->_namespace}\"\r\n";
1256 }
1257
1258 /* If 'use' == 'literal', we do not put in the encodingStyle. This is
1259 * denoted by $this->_section5 being false. 'use' can be defined at a
1260 * more granular level than we are dealing with here, so this does not
1261 * work for all services. */
1262 $xml = "<?xml version=\"1.0\" encoding=\"$encoding\"?>\r\n\r\n".
1263 "<SOAP-ENV:Envelope $ns_string".
1264 ($this->_section5 ? ' SOAP-ENV:encodingStyle="' . SOAP_SCHEMA_ENCODING . '"' : '').
1265 ">\r\n".
1266 "$header_xml$body</SOAP-ENV:Envelope>\r\n";
1267
1268 return $xml;
1269 }
1270
1271 function _makeMimeMessage(&$xml, $encoding = SOAP_DEFAULT_ENCODING)
1272 {
1273 global $SOAP_options;
1274
1275 if (!isset($SOAP_options['Mime'])) {
1276 return $this->_raiseSoapFault('Mime is not installed');
1277 }
1278
1279 // Encode any attachments.
1280 // See http://www.w3.org/TR/SOAP-attachments
1281 // Now we have to mime encode the message.
1282 $params = array('content_type' => 'multipart/related; type=text/xml');
1283 $msg =& new Mail_mimePart('', $params);
1284
1285 // Add the xml part.
1286 $params['content_type'] = 'text/xml';
1287 $params['charset'] = $encoding;
1288 $params['encoding'] = 'base64';
1289 $msg->addSubPart($xml, $params);
1290
1291 // Add the attachements
1292 $c = count($this->__attachments);
1293 for ($i = 0; $i < $c; $i++) {
1294 $attachment =& $this->__attachments[$i];
1295 $msg->addSubPart($attachment['body'], $attachment);
1296 }
1297
1298 return $msg->encode();
1299 }
1300
1301 // TODO: this needs to be used from the Transport system.
1302 function _makeDIMEMessage($xml)
1303 {
1304 global $SOAP_options;
1305
1306 if (!isset($SOAP_options['DIME'])) {
1307 return $this->_raiseSoapFault('DIME is not installed');
1308 }
1309
1310 // Encode any attachments.
1311 // See http://search.ietf.org/internet-drafts/draft-nielsen-dime-soap-00.txt
1312 // Now we have to DIME encode the message
1313 $dime =& new Net_DIME_Message();
1314 $msg = $dime->encodeData($xml, SOAP_ENVELOP, null, NET_DIME_TYPE_URI);
1315
1316 // Add the attachments.
1317 $c = count($this->__attachments);
1318 for ($i = 0; $i < $c; $i++) {
1319 $attachment =& $this->__attachments[$i];
1320 $msg .= $dime->encodeData($attachment['body'],
1321 $attachment['content_type'],
1322 $attachment['cid'],
1323 NET_DIME_TYPE_MEDIA);
1324 }
1325 $msg .= $dime->endMessage();
1326
1327 return $msg;
1328 }
1329
1330 function _decodeMimeMessage(&$data, &$headers, &$attachments)
1331 {
1332 global $SOAP_options;
1333
1334 if (!isset($SOAP_options['Mime'])) {
1335 $this->_raiseSoapFault('Mime Unsupported, install PEAR::Mail::Mime', '', '', 'Server');
1336 return;
1337 }
1338
1339 $params['include_bodies'] = true;
1340 $params['decode_bodies'] = true;
1341 $params['decode_headers'] = true;
1342
1343 // Lame thing to have to do for decoding.
1344 $decoder =& new Mail_mimeDecode($data);
1345 $structure = $decoder->decode($params);
1346
1347 if (isset($structure->body)) {
1348 $data = $structure->body;
1349 $headers = $structure->headers;
1350
1351 return;
1352 } elseif (isset($structure->parts)) {
1353 $data = $structure->parts[0]->body;
1354 $headers = array_merge($structure->headers,
1355 $structure->parts[0]->headers);
1356 if (count($structure->parts) > 1) {
1357 $mime_parts = array_splice($structure->parts,1);
1358 // Prepare the parts for the SOAP parser.
1359
1360 $c = count($mime_parts);
1361 for ($i = 0; $i < $c; $i++) {
1362 $p =& $mime_parts[$i];
1363 if (isset($p->headers['content-location'])) {
1364 // TODO: modify location per SwA note section 3
1365 // http://www.w3.org/TR/SOAP-attachments
1366 $attachments[$p->headers['content-location']] = $p->body;
1367 } else {
1368 $cid = 'cid:' . substr($p->headers['content-id'], 1, -1);
1369 $attachments[$cid] = $p->body;
1370 }
1371 }
1372 }
1373
1374 return;
1375 }
1376
1377 $this->_raiseSoapFault('Mime parsing error', '', '', 'Server');
1378 }
1379
1380 function _decodeDIMEMessage(&$data, &$headers, &$attachments)
1381 {
1382 global $SOAP_options;
1383
1384 if (!isset($SOAP_options['DIME'])) {
1385 $this->_raiseSoapFault('DIME Unsupported, install PEAR::Net::DIME', '', '', 'Server');
1386 return;
1387 }
1388
1389 // This SHOULD be moved to the transport layer, e.g. PHP itself should
1390 // handle parsing DIME ;)
1391 $dime =& new Net_DIME_Message();
1392 $err = $dime->decodeData($data);
1393 if (PEAR::isError($err)) {
1394 $this->_raiseSoapFault('Failed to decode the DIME message!', '', '', 'Server');
1395 return;
1396 }
1397 if (strcasecmp($dime->parts[0]['type'], SOAP_ENVELOP) != 0) {
1398 $this->_raiseSoapFault('DIME record 1 is not a SOAP envelop!', '', '', 'Server');
1399 return;
1400 }
1401
1402 $data = $dime->parts[0]['data'];
1403 // Fake it for now.
1404 $headers['content-type'] = 'text/xml';
1405 $c = count($dime->parts);
1406 for ($i = 0; $i < $c; $i++) {
1407 $part =& $dime->parts[$i];
1408 // We need to handle URI's better.
1409 $id = strncmp($part['id'], 'cid:', 4)
1410 ? 'cid:' . $part['id']
1411 : $part['id'];
1412 $attachments[$id] = $part['data'];
1413 }
1414 }
1415
1416 function __set_type_translation($type, $class = null)
1417 {
1418 $tq =& new QName($type);
1419 if (!$class) {
1420 $class = $tq->name;
1421 }
1422 $this->_type_translation[$type]=$class;
1423 }
1424
1425}
1426
1435{
1436 var $name = '';
1437 var $ns = '';
1439
1440 function QName($name, $namespace = '')
1441 {
1442 if ($name && $name[0] == '{') {
1443 preg_match('/\{(.*?)\}(.*)/', $name, $m);
1444 $this->name = $m[2];
1445 $this->namespace = $m[1];
1446 } elseif (substr_count($name, ':') == 1) {
1447 $s = explode(':', $name);
1448 $s = array_reverse($s);
1449 $this->name = $s[0];
1450 $this->ns = $s[1];
1451 $this->namespace = $namespace;
1452 } else {
1453 $this->name = $name;
1454 $this->namespace = $namespace;
1455 }
1456
1457 // A little more magic than should be in a qname.
1458 $p = strpos($this->name, '[');
1459 if ($p) {
1460 // TODO: Need to re-examine this logic later.
1461 // Chop off [].
1462 $this->arraySize = explode(',', substr($this->name, $p + 1, -$p - 2));
1463 $this->arrayInfo = substr($this->name, $p);
1464 $this->name = substr($this->name, 0, $p);
1465 }
1466 }
1467
1468 function fqn()
1469 {
1470 if ($this->namespace) {
1471 return '{' . $this->namespace . '}' . $this->name;
1472 } elseif ($this->ns) {
1473 return $this->ns . ':' . $this->name;
1474 }
1475 return $this->name;
1476 }
1477
1478}
$size
Definition: RandomTest.php:79
global $l
Definition: afr.php:30
isError($data, $code=null)
Tell whether a value is a PEAR error.
Definition: PEAR.php:279
QName($name, $namespace='')
$GLOBALS['SOAP_OBJECT_STRUCT']
SOAP_OBJECT_STRUCT makes PEAR::SOAP use objects for SOAP structures rather than arrays.
const SOAP_ENVELOP
const SOAP_XML_SCHEMA_VERSION
const SOAP_SCHEMA_ENCODING
const SOAP_DEFAULT_ENCODING
_debug($string)
Adds a string to the debug data.
$_debug_data
String containing debugging information if $_debug_flag is true.
ilBMFBase_Object($faultcode='Client')
Constructor.
$fault
Recent PEAR_Error object.
$_myfaultcode
Fault code.
$_debug_flag
Store debugging information in $_debug_data?
$_encodings
Supported encodings, limited by XML extension.
& _raiseSoapFault($str, $detail='', $actorURI='', $code=null, $mode=null, $options=null, $skipmsg=false)
Raises a SOAP error.
_un_htmlentities($string)
_isBase64Type($type)
Returns whether a type is a base64 type.
_makeDIMEMessage($xml)
_isBase64(&$value)
Returns whether a string is base64 encoded data.
_getNamespaceForPrefix($prefix)
_decodeDIMEMessage(&$data, &$headers, &$attachments)
_setSchemaVersion($schemaVersion)
Sets the schema version used in the SOAP message.
_getNamespacePrefix($ns)
ilBMFBase($faultcode='Client')
Constructor.
$_defaultObjectClassname
Default class name to use for decoded response objects.
_isHash(&$a)
Returns whether an array is a hash.
__set_type_translation($type, $class=null)
$_section5
True if we use section 5 encoding, or false if this is literal.
_serializeValue(&$value, $name='', $type=false, $elNamespace=NULL, $typeNamespace=NULL, $options=array(), $attributes=array(), $artype='', $OBJTypeNS=array())
_getType(&$value)
Converts a PHP type to a SOAP type.
_decodeMimeMessage(&$data, &$headers, &$attachments)
_multiArrayType(&$value, &$type, &$size, &$xml)
_makeMimeMessage(&$xml, $encoding=SOAP_DEFAULT_ENCODING)
_makeEnvelope(&$method, &$headers, $encoding=SOAP_DEFAULT_ENCODING, $options=array())
Creates the SOAP envelope with the SOAP envelop data.
_isSoapValue(&$value)
& _decode(&$soapval)
$data
$params
Definition: example_049.php:96
$code
Definition: example_050.php:99
if(!is_array($argv)) $options