• Main Page
  • Related Pages
  • Namespaces
  • Data Structures
  • Files
  • File List
  • Globals

payment/bmf/lib/SOAP/class.ilBMFBase.php

Go to the documentation of this file.
00001 <?php
00002 //
00003 // +----------------------------------------------------------------------+
00004 // | PHP Version 4                                                        |
00005 // +----------------------------------------------------------------------+
00006 // | Copyright (c) 1997-2002 The PHP Group                                |
00007 // +----------------------------------------------------------------------+
00008 // | This source file is subject to version 2.02 of the PHP license,      |
00009 // | that is bundled with this package in the file LICENSE, and is        |
00010 // | available at through the world-wide-web at                           |
00011 // | http://www.php.net/license/2_02.txt.                                 |
00012 // | If you did not receive a copy of the PHP license and are unable to   |
00013 // | obtain it through the world-wide-web, please send a note to          |
00014 // | license@php.net so we can mail you a copy immediately.               |
00015 // +----------------------------------------------------------------------+
00016 // | Authors: Shane Caraveo <Shane@Caraveo.com>   Port to PEAR and more   |
00017 // | Authors: Dietrich Ayala <dietrich@ganx4.com> Original Author         |
00018 // +----------------------------------------------------------------------+
00019 //
00020 // $Id: class.ilBMFBase.php 5974 2004-11-24 17:03:42Z smeyer $
00021 //
00022 
00023 /*
00024    SOAP_OBJECT_STRUCT makes pear::soap use objects for soap structures
00025    rather than arrays.  This has been done to provide a closer match to php-soap.
00026    If the old behaviour is needed, set to false.  The old behaviour is depricated.
00027 */
00028 $GLOBALS['SOAP_OBJECT_STRUCT'] = TRUE;
00029 /*
00030    SOAP_RAW_CONVERT makes pear::soap attempt to determine what SOAP type
00031    a php string COULD be.  This may result in slightly better interoperability when
00032    you are not using WSDL, and are being lazy and not using ilBMFValue to define
00033    types for your values.
00034 */
00035 $GLOBALS['SOAP_RAW_CONVERT'] = FALSE;
00036 
00037 require_once 'PEAR.php';
00038 #require_once dirname(__FILE__).'/class.ilBMFFault.php';
00039 require_once dirname(__FILE__).'/Type/class.ilBMFType_dateTime.php';
00040 require_once dirname(__FILE__).'/Type/class.ilBMFType_hexBinary.php';
00041 
00042 // optional features
00043 $GLOBALS['SOAP_options'] = array();
00044 
00045 @include_once 'Mail/mimePart.php';
00046 @include_once 'Mail/mimeDecode.php';
00047 if (class_exists('Mail_mimePart')) {
00048     $GLOBALS['SOAP_options']['Mime'] = 1;
00049     define('MAIL_MIMEPART_CRLF',"\n");
00050 }
00051 
00052 @include_once 'Net/DIME.php';
00053 if (class_exists('Net_DIME_Message')) {
00054     $GLOBALS['SOAP_options']['DIME'] = 1;
00055 }
00056 
00057 #error_reporting(E_ALL);
00058 
00064 $GLOBALS['SOAP_DEBUG']=false;
00065 
00066 if (!function_exists('version_compare') ||
00067     version_compare(phpversion(), '4.1', '<')) {
00068     die("requires PHP 4.1 or higher\n");
00069 }
00070 if (version_compare(phpversion(), '4.1', '>=') &&
00071     version_compare(phpversion(), '4.2', '<')) {
00072     define('FLOAT', 'double');
00073 } else {
00074     define('FLOAT', 'float');
00075 }
00076 
00077 # for float support
00078 # is there a way to calculate INF for the platform?
00079 define('INF',   1.8e307); 
00080 define('NAN',   0.0);
00081 
00082 define('SOAP_LIBRARY_VERSION', '0.7.1');
00083 define('SOAP_LIBRARY_NAME', 'PEAR-SOAP 0.7.1');
00084 // set schema version
00085 define('SOAP_XML_SCHEMA_VERSION',   'http://www.w3.org/2001/XMLSchema');
00086 define('SOAP_XML_SCHEMA_INSTANCE',  'http://www.w3.org/2001/XMLSchema-instance');
00087 define('SOAP_XML_SCHEMA_1999',      'http://www.w3.org/1999/XMLSchema');
00088 define('SOAP_SCHEMA',               'http://schemas.xmlsoap.org/wsdl/soap/');
00089 define('SOAP_SCHEMA_ENCODING',      'http://schemas.xmlsoap.org/soap/encoding/');
00090 define('SOAP_ENVELOP',              'http://schemas.xmlsoap.org/soap/envelope/');
00091 
00092 define('SCHEMA_SOAP',               'http://schemas.xmlsoap.org/wsdl/soap/');
00093 define('SCHEMA_HTTP',               'http://schemas.xmlsoap.org/wsdl/http/');
00094 define('SCHEMA_MIME',               'http://schemas.xmlsoap.org/wsdl/mime/');
00095 define('SCHEMA_WSDL',               'http://schemas.xmlsoap.org/wsdl/');
00096 define('SCHEMA_DIME',               'http://schemas.xmlsoap.org/ws/2002/04/dime/wsdl/');
00097 define('SCHEMA_CONTENT',            'http://schemas.xmlsoap.org/ws/2002/04/content-type/');
00098 define('SCHEMA_REF',                'http://schemas.xmlsoap.org/ws/2002/04/reference/');
00099 
00100 // define('SOAP_DEFAULT_ENCODING',  'UTF-8');
00101 define('SOAP_DEFAULT_ENCODING',  'ISO-8859-1');
00102 
00103 if (!function_exists('is_a'))
00104 {
00105    function is_a(&$object, $class_name)
00106    {
00107       if (get_class($object) == $class_name) return TRUE;
00108       else return is_subclass_of($object, $class_name);
00109    }
00110 }
00111 
00121 class ilBMFBase extends PEAR
00122 {
00123     var $_XMLSchema = array('http://www.w3.org/2001/XMLSchema', 'http://www.w3.org/1999/XMLSchema');
00124     var $_XMLSchemaVersion = 'http://www.w3.org/2001/XMLSchema';
00125     
00126     // load types into typemap array
00127     var $_typemap = array(
00128         'http://www.w3.org/2001/XMLSchema' => array(
00129             'string' => 'string',
00130             'boolean' => 'boolean',
00131             'float' => FLOAT,
00132             'double' => FLOAT,
00133             'decimal' => 'double',
00134             'duration' => 'integer',
00135             'dateTime' => 'string',
00136             'time' => 'string',
00137             'date' => 'string',
00138             'gYearMonth' => 'integer',
00139             'gYear' => 'integer',
00140             'gMonthDay' => 'integer',
00141             'gDay' => 'integer',
00142             'gMonth' => 'integer',
00143             'hexBinary' => 'string',
00144             'base64Binary' => 'string',
00145             // derived datatypes
00146             'normalizedString' => 'string',
00147             'token' => 'string',
00148             'language' => 'string',
00149             'NMTOKEN' => 'string',
00150             'NMTOKENS' => 'string',
00151             'Name' => 'string',
00152             'NCName' => 'string',
00153             'ID' => 'string',
00154             'IDREF' => 'string',
00155             'IDREFS' => 'string',
00156             'ENTITY' => 'string',
00157             'ENTITIES' => 'string',
00158             'integer' => 'integer',
00159             'nonPositiveInteger' => 'integer',
00160             'negativeInteger' => 'integer',
00161             'long' => 'integer',
00162             'int' => 'integer',
00163             'short' => 'integer',
00164             'byte' => 'string',
00165             'nonNegativeInteger' => 'integer',
00166             'unsignedLong' => 'integer',
00167             'unsignedInt' => 'integer',
00168             'unsignedShort' => 'integer',
00169             'unsignedByte' => 'integer',
00170             'positiveInteger'  => 'integer',
00171             'anyType' => 'string',
00172             'anyURI' => 'string',
00173             'QName' => 'string'
00174         ),
00175         'http://www.w3.org/1999/XMLSchema' => array(
00176             'i4' => 'integer',
00177             'int' => 'integer',
00178             'boolean' => 'boolean',
00179             'string' => 'string',
00180             'double' => FLOAT,
00181             'float' => FLOAT,
00182             'dateTime' => 'string',
00183             'timeInstant' => 'string',
00184             'base64Binary' => 'string',
00185             'base64' => 'string',
00186             'ur-type' => 'string'
00187         ),
00188         'http://schemas.xmlsoap.org/soap/encoding/' => array('base64' => 'string','array' => 'array','Array' => 'array', 'Struct'=>'array')
00189     );
00190 
00191     // load namespace uris into an array of uri => prefix
00192     var $_namespaces;
00193     var $_ns_count = 0;
00194     # supported encodings, limited by XML extension
00195     var $_encodings = array('ISO-8859-1','US-ASCII','UTF-8');
00196 
00197     var $_xmlEntities = array ( '&' => '&amp;', '<' => '&lt;', '>' => '&gt;', "'" => '&apos;', '"' => '&quot;' );
00198     
00199     var $_doconversion = FALSE;
00200     
00201     var $__attachments = array();
00202     
00209     var $_debug_flag = false;
00210     
00218     var $_debug_data = '';
00219     
00225     var $_myfaultcode = '';
00226     
00232     var $fault = NULL;
00233     
00234     var $_wsdl = NULL;
00235     
00241     var $_section5 = TRUE;
00242 
00243     // handle type to class mapping 
00244     var $_auto_translation = false;
00245     var $_type_translation = array();
00246     
00247     
00254     function ilBMFBase($faultcode = 'Client')
00255     {
00256         $this->_myfaultcode = $faultcode;
00257         $this->_resetNamespaces();
00258         $this->_debug_flag = $GLOBALS['SOAP_DEBUG'];
00259         parent::PEAR('SOAPfault');
00260     }
00261     
00262     function _resetNamespaces()
00263     {
00264         $this->_namespaces = array(
00265             'http://schemas.xmlsoap.org/soap/envelope/' => 'SOAP-ENV',
00266             'http://www.w3.org/2001/XMLSchema' => 'xsd',
00267             'http://www.w3.org/2001/XMLSchema-instance' => 'xsi',
00268             'http://schemas.xmlsoap.org/soap/encoding/' => 'SOAP-ENC');
00269     }
00270 
00280     function _setSchemaVersion($schemaVersion)
00281     {
00282         if (!in_array($schemaVersion, $this->_XMLSchema)) {
00283             return $this->_raiseSoapFault("unsuported XMLSchema $schemaVersion");
00284         }
00285         $this->_XMLSchemaVersion = $schemaVersion;
00286         $tmpNS = array_flip($this->_namespaces);
00287         $tmpNS['xsd'] = $this->_XMLSchemaVersion;
00288         $tmpNS['xsi'] = $this->_XMLSchemaVersion.'-instance';
00289         $this->_namespaces = array_flip($tmpNS);
00290     }
00291     
00309     function &_raiseSoapFault($str, $detail = '', $actorURI = '', $code = null, $mode = null, $options = null, $skipmsg = false)
00310     {
00311         # pass through previous faults
00312         if (is_object($str)) {
00313             $this->fault = $str;
00314         } else {
00315             if (!$code) $code = $this->_myfaultcode;
00316             $this->fault = new ilBMFFault($str, 
00317                                           $code, 
00318                                           $actorURI,
00319                                           $detail,
00320                                           $mode,
00321                                           $options);
00322         }
00323         return $this->fault;
00324     }
00325 
00326     function __isfault()
00327     {
00328         return $this->fault != NULL;
00329     }
00330     
00331     function &__getfault()
00332     {
00333         return $this->fault;
00334     }
00335     
00341     function _debug($string)
00342     {
00343         if ($this->_debug_flag) {
00344             $this->_debug_data .= get_class($this) . ': ' . preg_replace("/>/", ">\r\n", $string) . "\n";
00345         }
00346     }
00347     
00348     function _getNamespacePrefix($ns)
00349     {
00350         if (array_key_exists($ns,$this->_namespaces)) {
00351             return $this->_namespaces[$ns];
00352         }
00353         $prefix = 'ns'.count($this->_namespaces);
00354         $this->_namespaces[$ns] = $prefix;
00355         return $prefix;
00356         return NULL;
00357     }
00358 
00359     function _getNamespaceForPrefix($prefix)
00360     {
00361         $flipped = array_flip($this->_namespaces);
00362         if (array_key_exists($prefix,$flipped)) {
00363             return $flipped[$prefix];
00364         }
00365         return NULL;
00366     }
00367         
00368     function _isSoapValue(&$value)
00369     {
00370         return is_object($value) &&
00371                 (get_class($value) == 'ilbmfvalue' ||
00372                 is_subclass_of($value,'ilbmfvalue'));
00373     }
00374    
00375     function _serializeValue(&$value, $name = '', $type = false, $elNamespace = NULL, $typeNamespace=NULL, $options=array(), $attributes = array(), $artype='', $OBJTypeNS = array())
00376     {
00377         $namespaces = array();
00378         $arrayType = $xmlout_value = NULL;
00379         $typePrefix = $elPrefix = $xmlout_offset = $xmlout_arrayType = $xmlout_type = $xmlns = '';
00380         $ptype = $array_type_ns = '';
00381 
00382         if (!$name || is_numeric($name))
00383         {
00384             $name = 'item';
00385         }
00386 
00387         if ($this->_wsdl)
00388             list($ptype,$arrayType,$array_type_ns) = $this->_wsdl->getSchemaType($type, $name, $typeNamespace);
00389 
00390         if (!$arrayType) $arrayType = $artype;
00391         if (!$ptype) $ptype = $this->_getType($value);
00392         if (!$type) $type = $ptype;
00393 
00394         if (strcasecmp($ptype,'Struct')==0 || strcasecmp($type,'Struct')==0)
00395         {
00396             // struct
00397             $vars = NULL;
00398             if (is_object($value))
00399             {
00400                 $vars = get_object_vars($value);
00401             }
00402             else
00403             {
00404                 $vars = &$value;
00405             }
00406             if (is_array($vars))
00407             {
00408                 foreach (array_keys($vars) as $k)
00409                 {
00410                     if ($k[0]=='_')
00411                        continue; // hide private vars
00412                     if (is_object($vars[$k]))
00413                     {
00414                         if (is_a($vars[$k],'ilbmfvalue'))
00415                         {
00416                             $xmlout_value .= $vars[$k]->serialize($this);
00417                         }
00418                         else
00419                         {
00420                             // XXX get the members and serialize them instead
00421                             // converting to an array is more overhead than we
00422                             // should realy do, but php-soap is on it's way.
00423                             $objarr = get_object_vars ( $vars[$k] );
00424                             if (!isset ($objarr['OBJTypeNS']) )
00425                             {
00426                                 $xmlout_value .= $this->_serializeValue(get_object_vars($vars[$k]), $k, false, $this->_section5?NULL:$elNamespace, NULL, NULL, NULL, NULL);
00427                             }                   
00428                             else
00429                             {
00430                                 $xmlout_value .= $this->_serializeValue(get_object_vars($vars[$k]), $k, false, $this->_section5?NULL:$elNamespace, NULL, NULL, NULL, NULL, $objarr['OBJTypeNS']);                       
00431                             }
00432                         }
00433                     }
00434                     else
00435                     {
00436                         if ( $k != 'OBJTypeNS' )
00437                         {               
00438                             $xmlout_value .= $this->_serializeValue($vars[$k],$k, false, $this->_section5?NULL:$elNamespace);
00439                         }
00440                     }
00441                 }
00442             }
00443         }
00444         else
00445         {
00446             if (strcasecmp($ptype,'Array')==0 || strcasecmp($type,'Array')==0)
00447             {
00448                 // array
00449                 $typeNamespace = SOAP_SCHEMA_ENCODING;
00450                 $orig_type = $type;
00451                 $type = 'Array';
00452                 $numtypes = 0;
00453                 // XXX this will be slow on larger array's.  Basicly, it flattens array's to allow us
00454                 // to serialize multi-dimensional array's.  We only do this if arrayType is set,
00455                 // which will typicaly only happen if we are using WSDL
00456                 if (isset($options['flatten']) || ($arrayType && (strchr($arrayType,',') || strstr($arrayType,']['))))
00457                 {
00458                     $numtypes = $this->_multiArrayType($value, $arrayType, $ar_size, $xmlout_value);
00459                 }
00460 
00461                 $array_type = $array_type_prefix = '';
00462                 if ($numtypes != 1)
00463                 {
00464                     $arrayTypeQName = new QName($arrayType);
00465                     $arrayType = $arrayTypeQName->name;
00466                     $array_types = array();
00467                     $array_val = NULL;
00468 
00469                     // serialize each array element
00470                     $ar_size = count($value);
00471                     for ($i=0; $i < $ar_size; $i++)
00472                     {
00473                         $array_val =& $value[$i];
00474                         if ($this->_isSoapValue($array_val))
00475                         {
00476                             $array_type = $array_val->type;
00477                             $array_types[$array_type] = 1;
00478                             $array_type_ns = $array_val->type_namespace;
00479                             $xmlout_value .= $array_val->serialize($this);
00480                         }
00481                         else
00482                         {
00483                             $array_type = $this->_getType($array_val);
00484                             $array_types[$array_type] = 1;
00485                             $objarr = get_object_vars ( $array_val );
00486                             if (isset ($objarr['OBJTypeNS']) )
00487                             {
00488                                 $tmp_arr['item'] = $objarr['OBJTypeNS']['item'];
00489                                 $xmlout_value .= $this->_serializeValue($array_val,'item', $array_type, $this->_section5?NULL:$elNamespace, NULL, NULL, NULL, NULL, $tmp_arr );
00490                             }
00491                             else
00492                             {
00493                                 $xmlout_value .= $this->_serializeValue($array_val,'item', $array_type, $this->_section5?NULL:$elNamespace);
00494                             }
00495                         }
00496                     }
00497                     
00498                     $xmlout_offset = " SOAP-ENC:offset=\"[0]\"";
00499                     if (!$arrayType)
00500                     {
00501                         $numtypes = count($array_types);
00502                         if ($numtypes == 1)
00503                            $arrayType = $array_type;
00504                         // using anyType is more interoperable
00505                         if ($array_type == 'Struct')
00506                         {
00507                             $array_type = '';
00508                         }
00509                         else
00510                             if ($array_type == 'Array')
00511                             {
00512                                 $arrayType = 'anyType';
00513                                 $array_type_prefix = 'xsd';
00514                             }
00515                             else
00516                                 if (!$arrayType)
00517                                    $arrayType = $array_type;
00518                     }
00519                 }
00520                 if (!isset($arrayType) || $numtypes > 1)
00521                 {
00522                     $arrayType = 'xsd:anyType'; // should reference what schema we're using
00523                 }
00524                 else
00525                 {
00526                     if ($array_type_ns)
00527                     {
00528                         $array_type_prefix = $this->_getNamespacePrefix($array_type_ns);
00529                     }
00530                     else
00531                         if (array_key_exists($arrayType, $this->_typemap[$this->_XMLSchemaVersion]))
00532                         {
00533                             $array_type_prefix = $this->_namespaces[$this->_XMLSchemaVersion];
00534                         }
00535                     if ($array_type_prefix)
00536                         $arrayType = $array_type_prefix.':'.$arrayType;
00537                 }
00538 
00539                 if ( isset ($value[0]->OBJTypeNS) )
00540                 {
00541                     $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]) . '[' . count($value) . ']"';
00542                     $xmlout_type = $xmlns = $xmlout_offset = $xml_attr = $arrayType = '';
00543                 }
00544                 else
00545                 {
00546                     $xmlout_arrayType = " SOAP-ENC:arrayType=\"".$arrayType."[$ar_size]\"";
00547                 }
00548             }
00549             else
00550             {
00551                 if ($this->_isSoapValue($value))
00552                 {
00553                     $xmlout_value = $value->serialize($this);
00554                 }
00555                 else
00556                 {
00557                     if ($type == 'string')
00558                     {
00559                         $xmlout_value = htmlspecialchars($value);
00560                     }
00561                     else
00562                     {
00563                         if ($type == 'boolean')
00564                         {
00565                             $xmlout_value = $value?'true':'false';
00566                         }
00567                         else
00568                         {
00569                             $xmlout_value = $value;
00570                         }
00571                     }
00572                 }
00573             }
00574         }
00575 
00576         // add namespaces
00577         if ($elNamespace)
00578         {
00579             $elPrefix = $this->_getNamespacePrefix($elNamespace);
00580             $xmlout_name = "$elPrefix:$name";
00581             $xmlns = " xmlns:$elPrefix=\"$elNamespace\"";
00582         }
00583         else
00584         {
00585             $xmlout_name = $name;
00586         }
00587         
00588         if ($typeNamespace)
00589         {
00590             $typePrefix = $this->_getNamespacePrefix($typeNamespace);
00591             $xmlout_type = "$typePrefix:$type";
00592         }
00593         else
00594             if ($type && array_key_exists($type, $this->_typemap[$this->_XMLSchemaVersion]))
00595             {
00596                 $typePrefix = $this->_namespaces[$this->_XMLSchemaVersion];
00597                 $xmlout_type = "$typePrefix:$type";
00598             }
00599 
00600         // handle additional attributes
00601         $xml_attr = '';
00602         if (count($attributes) > 0)
00603         {
00604             foreach ($attributes as $k => $v)
00605             {
00606                 $kqn = new QName($k);
00607                 $vqn = new QName($v);
00608                 $xml_attr .= ' '.$kqn->fqn().'="'.$vqn->fqn().'"';
00609             }
00610         }
00611 
00612         // store the attachement for mime encoding
00613         if (isset($options['attachment']))
00614             $this->__attachments[] = $options['attachment'];
00615             
00616         if ($this->_section5)
00617         {
00618             if ($name == 'item' && isset($OBJTypeNS['item']))
00619             {
00620                 $xmlout_type = $OBJTypeNS['item'];
00621             }
00622             if ($xmlout_type)
00623                $xmlout_type = " xsi:type=\"$xmlout_type\"";
00624 
00625             if (is_null($xmlout_value))
00626             {
00627                 $xml = "\r\n<$xmlout_name$xmlout_type$xmlns$xmlout_arrayType$xml_attr/>";
00628             }
00629             else
00630             {
00631                 if ( isset ($value[0]->OBJTypeNS) )
00632                 {
00633                     $xmlout_type = '';
00634                 }
00635                 $xml = "\r\n<$xmlout_name$xmlout_type$xmlns$xmlout_arrayType$xmlout_offset$xml_attr ";
00636                 if ( isset($OBJTypeNS['namespace']) && isset ($OBJTypeNS['type']) )
00637                 {
00638                     if ( trim($OBJTypeNS['namespace']) != '' || trim($OBJTypeNS['type']) != '' )
00639                     {
00640                         if ( isset($OBJTypeNS['namespace']) && $OBJTypeNS['namespace'] != '')
00641                         {
00642                            $xml .= ' xmlns:';
00643                            if ( isset($OBJTypeNS['nsPrefix']))
00644                               $xml .= $OBJTypeNS['nsPrefix'];
00645                            else
00646                                $xml .= 'intf';
00647                            $xml .= '="' . $OBJTypeNS['namespace'] . '"';
00648                         }
00649                         if (isset ($OBJTypeNS['type'] ) && $OBJTypeNS['type'] != '')
00650                         {
00651                            $xml .= ' xsi:type="';
00652                            if ( strpos($OBJTypeNS['type'], "xsd:") === false )
00653                            {
00654                                if ( isset($OBJTypeNS['nsPrefix']))
00655                                   $xml .= $OBJTypeNS['nsPrefix'] . ':';
00656                                else
00657                                    $xml .= 'intf:';
00658                            }
00659                            $xml .= $OBJTypeNS['type'] . '"';
00660                         }
00661                     }
00662                 }
00663                 $xml .= ">" . $xmlout_value . "</$xmlout_name>";
00664             }
00665         }
00666         else
00667         {
00668             if (is_null($xmlout_value))
00669             {
00670                 $xml = "\r\n<$xmlout_name$xmlns$xml_attr/>";
00671             }
00672             else
00673             {
00674                 $xml = "\r\n<$xmlout_name$xmlns$xml_attr>" . $xmlout_value . "</$xmlout_name>";
00675             }
00676         }
00677 
00678         return $xml;
00679     }
00680     
00681     
00691     function _getType(&$value) {
00692         global $SOAP_OBJECT_STRUCT,$SOAP_RAW_CONVERT;
00693         $type = gettype($value);
00694         switch ($type) {
00695         case 'object':
00696             if (is_a($value,'ilbmfvalue')) {
00697                 $type = $value->type;
00698             } else {
00699                 $type = 'Struct';
00700             }
00701             break;
00702         case 'array':
00703             // XXX hashes always get done as structs by pear::soap
00704             if ($this->_isHash($value)) {
00705                 $type = 'Struct';
00706             } else {
00707                 $ar_size = count($value);
00708                 if ($ar_size > 0 && is_a($value[0],'ilbmfvalue')) {
00709                     // fixme for non-wsdl structs that are all teh same type
00710                     if ($ar_size > 1 &&
00711                         $this->_isSoapValue($value[0]) &&
00712                         $this->_isSoapValue($value[1]) &&
00713                         $value[0]->name != $value[1]->name) {
00714                         // this is a struct, not an array
00715                         $type = 'Struct';
00716                     } else {
00717                         $type = 'Array';
00718                     }
00719                 } else {
00720                     $type = 'Array';
00721                 }
00722             }
00723             break;
00724         case 'integer':
00725         case 'long':
00726             $type = 'int';
00727             break;
00728         case 'boolean':
00729             #$value = $value?'true':'false';
00730             break;
00731         case 'double':
00732             $type = 'decimal'; // double is deprecated in 4.2 and later
00733             break;
00734         case 'NULL':
00735             $type = '';
00736             break;
00737         case 'string':
00738             if (!$SOAP_RAW_CONVERT)
00739             {
00740                 if (is_numeric($value))
00741                 {
00742 /*                     if (strstr($value,'.'))
00743                        $type = 'float';
00744                     else
00745                         $type = 'int'; */
00746                 }
00747                 else
00748                 {
00749 /*                     if (ilBMFType_hexBinary::is_hexbin($value))
00750                     {
00751                         $type = 'hexBinary';
00752                     }
00753                     else */
00754                     {
00755                         if ($this->_isBase64($value))
00756                         {
00757                             $type = 'base64Binary';
00758                         }
00759                         else
00760                         {
00761                             $dt = new ilBMFType_dateTime($value);
00762                             if ($dt->toUnixtime() != -1)
00763                             {
00764                                 $type = 'dateTime';
00765                                 #$value = $dt->toSOAP();
00766                             }
00767                         }
00768                     }
00769                 }
00770             }
00771         default:
00772             break;
00773         }
00774         return $type;
00775     }
00776 
00777     function _multiArrayType(&$value, &$type, &$size, &$xml)
00778     {
00779         $sz = count($value);
00780         if ($sz > 1) {
00781             // seems we have a multi dimensional array, figure it out if we do
00782             $c = count($value);
00783             for ($i=0; $i<$c; $i++) {
00784                 $this->_multiArrayType($value[$i], $type, $size, $xml);
00785             }
00786             
00787             if ($size) {
00788                 $size = $sz.','.$size;
00789             } else {
00790                 $size = $sz;
00791             }
00792             return 1;
00793         } else {
00794             if (is_object($value)) {
00795                 $type = $value->type;
00796                 $xml .= $value->serialize($this); 
00797             } else {
00798                 $type = $this->_getType($value);
00799                 $xml .= $this->_serializeValue($value,'item',$type);
00800             }
00801         }
00802         $size = NULL;
00803         return 1;
00804     }
00805     // support functions
00811     function _isBase64(&$value)
00812     {
00813         $l = strlen($value);
00814         if ($l > 0)
00815             return $value[$l-1] == '=' && preg_match("/[A-Za-z=\/\+]+/",$value);
00816         return FALSE;
00817     }
00818 
00824     function _isHash(&$a) {
00825         # XXX I realy dislike having to loop through this in php code,
00826         # realy large arrays will be slow.  We need a C function to do this.
00827         $names = array();
00828         $it = 0;
00829         foreach ($a as $k => $v) {
00830             # checking the type is faster than regexp.
00831             $t = gettype($k);
00832             if ($t != 'integer') {
00833                 return TRUE;
00834             } else if ($this->_isSoapValue($v)) {
00835                 $names[$v->name] = 1;
00836             }
00837             // if someone has a large hash they should realy be defining the type
00838             if ($it++ > 10) return FALSE;
00839         }
00840         return count($names)>1;
00841     }
00842     
00843     function &_un_htmlentities($string)
00844     {
00845        $trans_tbl = get_html_translation_table (HTML_ENTITIES);
00846        $trans_tbl = array_flip($trans_tbl);
00847        return strtr($string, $trans_tbl);
00848     }
00849     
00854     function &_decode(&$soapval)
00855     {
00856         global $SOAP_OBJECT_STRUCT;
00857         
00858         if (!$this->_isSoapValue($soapval)) {
00859             return $soapval;
00860         } else if (is_array($soapval->value)) {
00861             if ($SOAP_OBJECT_STRUCT && $soapval->type != 'Array') {
00862                 $classname = 'stdClass';
00863                 if (isset($this->_type_translation[$soapval->tqn->fqn()])) {
00864                     // this will force an error in php if the
00865                     // class does not exist
00866                     $classname = $this->_type_translation[$soapval->tqn->fqn()];
00867                 } else if (isset($this->_type_translation[$soapval->type])) {
00868                     // this will force an error in php if the
00869                     // class does not exist
00870                     $classname = $this->_type_translation[$soapval->type];
00871                 } else if ($this->_auto_translation) {
00872                     if (class_exists($soapval->type)) {
00873                         $classname = $soapval->type;
00874                     } else if ($this->_wsdl) {
00875                         $t = $this->_wsdl->getComplexTypeNameForElement($soapval->name, $soapval->namespace);
00876                         if ($t && class_exists($t)) $classname = $t;
00877                     }
00878                 }
00879                 $return = new $classname;
00880             } else {
00881                 $return = array();
00882             }
00883             
00884             $counter = 1;
00885             $isstruct = !$SOAP_OBJECT_STRUCT || !is_array($return);
00886             foreach ($soapval->value as $item) {
00887                 if (is_object($return)) {
00888                     if ($this->_wsdl) {
00889                         // get this childs wsdl information
00890                         // /$soapval->ns/$soapval->type/$item->ns/$item->name
00891                         $child_type = $this->_wsdl->getComplexTypeChildType(
00892                                                 $soapval->namespace,
00893                                                 $soapval->name,
00894                                                 $item->namespace,
00895                                                 $item->name);
00896                         if ($child_type) $item->type = $child_type;
00897                     }
00898                     if (!$isstruct || $item->type == 'Array') {
00899                         if (isset($return->{$item->name}) &&
00900                           is_object($return->{$item->name})) {
00901                             $return->{$item->name} = $this->_decode($item);
00902                         } else if (isset($return->{$item->name}) &&
00903                           is_array($return->{$item->name})) {
00904                             $return->{$item->name}[] = $this->_decode($item);
00905                         } else if (is_array($return)) {
00906                             $return[] = $this->_decode($item);
00907                         } else {
00908                             $return->{$item->name} = $this->_decode($item);
00909                         }
00910                     } else if (isset($return->{$item->name})) {
00911                         $isstruct = FALSE;
00912                         if (count(get_object_vars($return)) == 1) {
00913                             $return = array($return->{$item->name}, $this->_decode($item));
00914                         } else {
00915                             $return->{$item->name} = array($return->{$item->name}, $this->_decode($item));
00916                         }
00917                     } else {
00918                         $return->{$item->name} = $this->_decode($item);
00919                     }
00920                     /* set the attributes as members in the class */
00921                     if (method_exists($return,'__set_attribute')) {
00922                         foreach ($soapval->attributes as $key=>$value) {
00923                             call_user_func_array(array(&$return,'__set_attribute'),array($key,$value));
00924                         }
00925                     }
00926                 } else {
00927                     if ($soapval->arrayType && $this->_isSoapValue($item)) {
00928                         $item->type = $soapval->arrayType;
00929                     }
00930                     if (!$isstruct) {
00931                         $return[] = $this->_decode($item);
00932                     } else if (isset($return[$item->name])) {
00933                         $isstruct = FALSE;
00934                         $return = array($return[$item->name], $this->_decode($item));
00935                     } else {
00936                         $return[$item->name] = $this->_decode($item);
00937                     }
00938                 }
00939             }
00940             return $return;
00941         }
00942         
00943         if ($soapval->type == 'boolean') {
00944             if ($soapval->value != '0' && strcasecmp($soapval->value,'false') !=0) {
00945                 $soapval->value = TRUE;
00946             } else {
00947                 $soapval->value = FALSE;
00948             }
00949         } else if ($soapval->type && array_key_exists($soapval->type, $this->_typemap[SOAP_XML_SCHEMA_VERSION])) {
00950             # if we can, lets set php's variable type
00951             settype($soapval->value, $this->_typemap[SOAP_XML_SCHEMA_VERSION][$soapval->type]);
00952         }
00953         return $soapval->value;
00954     }
00955     
00963     function &_makeEnvelope(&$method, &$headers, $encoding = SOAP_DEFAULT_ENCODING,$options = array())
00964     {
00965         $smsg = $header_xml = $ns_string = '';
00966 
00967         if ($headers) {
00968             $c = count($headers);
00969             for ($i=0; $i < $c; $i++) {
00970                 $header_xml .= $headers[$i]->serialize($this);
00971             }
00972             $header_xml = "<SOAP-ENV:Header>\r\n$header_xml\r\n</SOAP-ENV:Header>\r\n";
00973         }
00974         if (!isset($options['input']) || $options['input'] == 'parse') {
00975             if (is_array($method)) {
00976                 $c = count($method);
00977                 for ($i = 0; $i < $c; $i++) {
00978                     $smsg .= $method[$i]->serialize($this);
00979                 }
00980             }  else {
00981                 $smsg = $method->serialize($this);
00982             }
00983         } else {
00984             $smsg = $method;
00985         }
00986         $body = "<SOAP-ENV:Body>\r\n".$smsg."\r\n</SOAP-ENV:Body>\r\n";
00987         $a = 0;
00988         foreach ($this->_namespaces as $k => $v)
00989         {
00990             if ($a > 3) break;
00991             $ns_string .= " xmlns:$v=\"$k\"\r\n";
00992             $a ++;
00993         }
00994         
00995         /* if use='literal', we do not put in the encodingStyle.  This is denoted by
00996            $this->_section5 being false.
00997            XXX use can be defined at a more granular level than we are dealing with
00998            here, so this does not work for all services.
00999         */
01000         $xml = "<?phpxml version=\"1.0\" encoding=\"$encoding\"?>\r\n\r\n".
01001             "<SOAP-ENV:Envelope $ns_string".
01002             ($this->_section5?" SOAP-ENV:encodingStyle=\"" . SOAP_SCHEMA_ENCODING . "\"":'').
01003             ">\r\n".
01004             "$header_xml$body</SOAP-ENV:Envelope>\r\n";
01005         
01006         return $xml;
01007     }
01008     
01009     function _makeMimeMessage(&$xml, $encoding = SOAP_DEFAULT_ENCODING)
01010     {
01011         global $SOAP_options;
01012         
01013         if (!isset($SOAP_options['Mime'])) {
01014             return $this->_raiseSoapFault('Mime is not installed');
01015         }
01016         
01017         // encode any attachments
01018         // see http://www.w3.org/TR/SOAP-attachments
01019         // now we have to mime encode the message
01020         $params = array('content_type' => 'multipart/related; type=text/xml');
01021         $msg = new Mail_mimePart('', $params);
01022         // add the xml part
01023         $params['content_type'] = 'text/xml';
01024         $params['charset'] = $encoding;
01025         $params['encoding'] = 'base64';
01026         $msg->addSubPart($xml, $params);
01027         
01028         // add the attachements
01029         $c = count($this->__attachments);
01030         for ($i=0; $i < $c; $i++) {
01031             $attachment =& $this->__attachments[$i];
01032             $msg->addSubPart($attachment['body'],$attachment);
01033         }
01034         return $msg->encode();
01035     }
01036     
01037     // XXX this needs to be used from the Transport system
01038     function _makeDIMEMessage(&$xml)
01039     {
01040         global $SOAP_options;
01041         
01042         if (!isset($SOAP_options['DIME'])) {
01043             return $this->_raiseSoapFault('DIME is not installed');
01044         }
01045         
01046         // encode any attachments
01047         // see http://search.ietf.org/internet-drafts/draft-nielsen-dime-soap-00.txt
01048         // now we have to DIME encode the message
01049         $dime = new Net_DIME_Message();
01050         $msg = $dime->encodeData($xml,SOAP_ENVELOP,NULL,NET_DIME_TYPE_URI);
01051         
01052         // add the attachements
01053         $c = count($this->__attachments);
01054         for ($i=0; $i < $c; $i++) {
01055             $attachment =& $this->__attachments[$i];
01056             $msg .= $dime->encodeData($attachment['body'],$attachment['content_type'],$attachment['cid'],NET_DIME_TYPE_MEDIA);
01057         }
01058         $msg .= $dime->endMessage();
01059         return $msg;
01060     }
01061 
01062     function _decodeMimeMessage(&$data, &$headers, &$attachments)
01063     {
01064         global $SOAP_options;
01065         if (!isset($SOAP_options['Mime'])) {
01066             $this->_raiseSoapFault('Mime Unsupported, install PEAR::Mail::Mime','','','Server');
01067             return;
01068         }
01069         
01070         $params['include_bodies'] = TRUE;
01071         $params['decode_bodies']  = TRUE;
01072         $params['decode_headers'] = TRUE;
01073 
01074         // XXX lame thing to have to do for decoding
01075         $decoder = new Mail_mimeDecode($data);
01076         $structure = $decoder->decode($params);
01077         
01078         if (isset($structure->body)) {
01079             $data = $structure->body;
01080             $headers = $structure->headers;
01081             return;
01082         } else if (isset($structure->parts)) {
01083             $data = $structure->parts[0]->body;
01084             $headers = array_merge($structure->headers,$structure->parts[0]->headers);
01085             if (count($structure->parts) > 1) {
01086                 $mime_parts = array_splice($structure->parts,1);
01087                 // prepare the parts for the soap parser
01088                 
01089                 $c = count($mime_parts);
01090                 for ($i = 0; $i < $c; $i++) {
01091                     $p =& $mime_parts[$i];
01092                     if (isset($p->headers['content-location'])) {
01093                         // XXX TODO: modify location per SwA note section 3
01094                         // http://www.w3.org/TR/SOAP-attachments
01095                         $attachments[$p->headers['content-location']] = $p->body;
01096                     } else {
01097                         $cid = 'cid:'.substr($p->headers['content-id'],1,strlen($p->headers['content-id'])-2);
01098                         $attachments[$cid] = $p->body;
01099                     }
01100                 }
01101             }
01102             return;
01103         }
01104         $this->_raiseSoapFault('Mime parsing error','','','Server');
01105     }
01106     
01107     function _decodeDIMEMessage(&$data, &$headers, &$attachments)
01108     {
01109         global $SOAP_options;
01110         if (!isset($SOAP_options['DIME'])) {
01111             $this->_raiseSoapFault('DIME Unsupported, install PEAR::Net::DIME','','','Server');
01112         }
01113         
01114         // XXX this SHOULD be moved to the transport layer, e.g. PHP  itself
01115         // should handle parsing DIME ;)
01116         $dime = new Net_DIME_Message();
01117         $dime->decodeData($data);
01118         if (strcasecmp($dime->parts[0]['type'],SOAP_ENVELOP) !=0 ||
01119             strcasecmp($dime->parts[0]['type'],SOAP_ENVELOP) !=0) {
01120             $this->_raiseSoapFault('Dime record 1 is not a SOAP envelop!','','','Server');
01121         } else {
01122             $data = $dime->parts[0]['data'];
01123             $headers['content-type'] = 'text/xml'; // fake it for now
01124             $c = count($dime->parts);
01125             for ($i = 0; $i < $c; $i++) {
01126                 $part =& $dime->parts[$i];
01127                 // XXX we need to handle URI's better
01128                 $attachments['cid:'.$part['id']] = $part['data'];
01129             }
01130         }
01131     }
01132     
01133     function __set_type_translation($type, $class=NULL)
01134     {
01135         $tq = new QName($type);
01136         if (!$class) {
01137             $class = $tq->name;
01138         }
01139         $this->_type_translation[$type]=$class;
01140     }
01141 }
01142 
01152 class QName
01153 {
01154     var $name = '';
01155     var $ns = '';
01156     var $namespace='';
01157     #var $arrayInfo = '';
01158     
01159     function QName($name, $namespace = '')
01160     {
01161         if ($name && $name[0] == '{' )
01162         {
01163             preg_match('/\{(.*?)\}(.*)/',$name, $m);
01164             $this->name = $m[2];
01165             $this->namespace = $m[1];
01166         }
01167         else
01168         {
01169             if (strpos($name, ':') != FALSE)
01170             {
01171                 $s = split(':',$name);
01172                 $s = array_reverse($s);
01173                 $this->name = $s[0];
01174                 $this->ns = $s[1];
01175                 $this->namespace = $namespace;
01176             }
01177             else
01178             {
01179                 $this->name = $name;
01180                 $this->namespace = $namespace;
01181             }
01182         }
01183         
01184         # a little more magic than should be in a qname
01185         $p = strpos($this->name, '[');
01186         if ($p)
01187         {
01188             # XXX need to re-examine this logic later
01189             # chop off []
01190             $this->arraySize = split(',',substr($this->name,$p+1, strlen($this->name)-$p-2));
01191             $this->arrayInfo = substr($this->name, $p);
01192             $this->name = substr($this->name, 0, $p);
01193         }
01194     }
01195     
01196     function fqn()
01197     {
01198         if ($this->namespace)
01199         {
01200             return '{'.$this->namespace.'}'.$this->name;
01201         }
01202         else
01203         {
01204             if ($this->ns)
01205             {
01206                 return $this->ns.':'.$this->name;
01207             }
01208         }
01209         return $this->name;
01210     }
01211     
01212 }
01213 ?>

Generated on Fri Dec 13 2013 09:06:37 for ILIAS Release_3_4_x_branch .rev 46804 by  doxygen 1.7.1