SOAP--Client
[ class tree: SOAP--Client ] [ index: SOAP--Client ] [ all elements ]

Source for file Base.php

Documentation is available at Base.php

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

Documentation generated on Mon, 11 Mar 2019 13:59:44 -0400 by phpDocumentor 1.4.4. PEAR Logo Copyright © PHP Group 2004.