Blame | Letzte Änderung | Log anzeigen | RSS feed
<?php/*** This file loads all required libraries, defines constants used across the* SOAP package, and defines the base classes that most other classes of this* package extend.** PHP versions 4 and 5** LICENSE: This source file is subject to version 2.02 of the PHP license,* that is bundled with this package in the file LICENSE, and is available at* through the world-wide-web at http://www.php.net/license/2_02.txt. If you* did not receive a copy of the PHP license and are unable to obtain it* through the world-wide-web, please send a note to license@php.net so we can* mail you a copy immediately.** @category Web Services* @package SOAP* @author Dietrich Ayala <dietrich@ganx4.com> Original Author* @author Shane Caraveo <Shane@Caraveo.com> Port to PEAR and more* @author Chuck Hagenbuch <chuck@horde.org> Maintenance* @author Jan Schneider <jan@horde.org> Maintenance* @copyright 2003-2007 The PHP Group* @license http://www.php.net/license/2_02.txt PHP License 2.02* @link http://pear.php.net/package/SOAP*//** Define linebreak sequence for the Mail_Mime package. */define('MAIL_MIMEPART_CRLF', "\r\n");require_once 'PEAR.php';if (!defined('INF')) {define('INF', 1.8e307);}if (!defined('NAN')) {define('NAN', 0.0);}define('SOAP_LIBRARY_VERSION', '0.12.0');define('SOAP_LIBRARY_NAME', 'PEAR-SOAP 0.12.0-beta');// Set schema version.define('SOAP_XML_SCHEMA_VERSION', 'http://www.w3.org/2001/XMLSchema');define('SOAP_XML_SCHEMA_INSTANCE', 'http://www.w3.org/2001/XMLSchema-instance');define('SOAP_XML_SCHEMA_1999', 'http://www.w3.org/1999/XMLSchema');define('SOAP_SCHEMA', 'http://schemas.xmlsoap.org/wsdl/soap/');define('SOAP_SCHEMA_ENCODING', 'http://schemas.xmlsoap.org/soap/encoding/');define('SOAP_ENVELOP', 'http://schemas.xmlsoap.org/soap/envelope/');define('SCHEMA_DISCO', 'http://schemas.xmlsoap.org/disco/');define('SCHEMA_DISCO_SCL', 'http://schemas.xmlsoap.org/disco/scl/');define('SCHEMA_SOAP', 'http://schemas.xmlsoap.org/wsdl/soap/');define('SCHEMA_SOAP12', 'http://schemas.xmlsoap.org/wsdl/soap12/');define('SCHEMA_SOAP_HTTP', 'http://schemas.xmlsoap.org/soap/http');define('SCHEMA_WSDL_HTTP', 'http://schemas.xmlsoap.org/wsdl/http/');define('SCHEMA_MIME', 'http://schemas.xmlsoap.org/wsdl/mime/');define('SCHEMA_WSDL', 'http://schemas.xmlsoap.org/wsdl/');define('SCHEMA_DIME', 'http://schemas.xmlsoap.org/ws/2002/04/dime/wsdl/');define('SCHEMA_CONTENT', 'http://schemas.xmlsoap.org/ws/2002/04/content-type/');define('SCHEMA_REF', 'http://schemas.xmlsoap.org/ws/2002/04/reference/');define('SOAP_DEFAULT_ENCODING', 'UTF-8');/*** @package SOAP*/class SOAP_Base_Object extends PEAR{/*** Supported encodings, limited by XML extension.** @var array $_encodings*/var $_encodings = array('ISO-8859-1', 'US-ASCII', 'UTF-8');/*** Fault code.** @var string $_myfaultcode*/var $_myfaultcode = '';/*** Recent PEAR_Error object.** @var PEAR_Error $fault*/var $fault = null;/*** Constructor.** @param string $faultcode Error code.*/function SOAP_Base_Object($faultcode = 'Client'){$this->_myfaultcode = $faultcode;parent::PEAR('SOAP_Fault');}/*** Raises a SOAP error.** Please refer to the SOAP definition for an impression of what a certain* parameter stands for.** @param string|object $str Error message or object.* @param string $detail Detailed error message.* @param string $actorURI* @param mixed $code* @param mixed $mode* @param mixed $options* @param boolean $skipmsg*/function &_raiseSoapFault($str, $detail = '', $actorURI = '', $code = null,$mode = null, $options = null, $skipmsg = false){// Pass through previous faults.$is_instance = isset($this) && is_a($this, 'SOAP_Base_Object');if (is_object($str)) {$fault = $str;} else {if (!$code) {$code = $is_instance ? $this->_myfaultcode : 'Client';}require_once 'SOAP/Fault.php';$fault = new SOAP_Fault($str, $code, $actorURI, $detail, $mode,$options);}if ($is_instance) {$this->fault = $fault;}return $fault;}function _isfault(){return $this->fault != null;}function &_getfault(){return $this->fault;}}/*** Common base class of all SOAP classes.** @access public* @package SOAP* @author Shane Caraveo <shane@php.net> Conversion to PEAR and updates*/class SOAP_Base extends SOAP_Base_Object{var $_XMLSchema = array('http://www.w3.org/2001/XMLSchema','http://www.w3.org/1999/XMLSchema');var $_XMLSchemaVersion = 'http://www.w3.org/2001/XMLSchema';// load types into typemap arrayvar $_typemap = array('http://www.w3.org/2001/XMLSchema' => array('string' => 'string','boolean' => 'boolean','float' => 'float','double' => 'float','decimal' => 'float','duration' => 'integer','dateTime' => 'string','time' => 'string','date' => 'string','gYearMonth' => 'integer','gYear' => 'integer','gMonthDay' => 'integer','gDay' => 'integer','gMonth' => 'integer','hexBinary' => 'string','base64Binary' => 'string',// derived datatypes'normalizedString' => 'string','token' => 'string','language' => 'string','NMTOKEN' => 'string','NMTOKENS' => 'string','Name' => 'string','NCName' => 'string','ID' => 'string','IDREF' => 'string','IDREFS' => 'string','ENTITY' => 'string','ENTITIES' => 'string','integer' => 'integer','nonPositiveInteger' => 'integer','negativeInteger' => 'integer',// longs (64bit ints) are not supported cross-platform.'long' => 'string','int' => 'integer','short' => 'integer','byte' => 'string','nonNegativeInteger' => 'integer','unsignedLong' => 'integer','unsignedInt' => 'integer','unsignedShort' => 'integer','unsignedByte' => 'integer','positiveInteger' => 'integer','anyType' => 'string','anyURI' => 'string','QName' => 'string'),'http://www.w3.org/1999/XMLSchema' => array('i4' => 'integer','int' => 'integer','boolean' => 'boolean','string' => 'string','double' => 'float','float' => 'float','dateTime' => 'string','timeInstant' => 'string','base64Binary' => 'string','base64' => 'string','ur-type' => 'string'),'http://schemas.xmlsoap.org/soap/encoding/' => array('base64' => 'string','array' => 'array','Array' => 'array','Struct' => 'array'));/*** Default class name to use for decoded response objects.** @var string $_defaultObjectClassname*/var $_defaultObjectClassname = 'stdClass';/*** Hash with used namespaces.** @var array*/var $_namespaces;/*** The default namespace.** @var string*/var $_namespace;var $_xmlEntities = array('&' => '&','<' => '<','>' => '>',"'" => ''','"' => '"');var $_doconversion = false;var $_attachments = array();var $_wsdl = null;/*** True if we use section 5 encoding, or false if this is literal.** @var boolean $_section5*/var $_section5 = true;// Handle type to class mapping.var $_auto_translation = false;var $_type_translation = array();/*** Constructor.** @param string $faultcode Error code.*/function SOAP_Base($faultcode = 'Client'){parent::SOAP_Base_Object($faultcode);$this->_resetNamespaces();}/*** Sets the SOAP-ENV prefix and returns the current value.** @access public** @param string SOAP-ENV prefix** @return string current SOAP-ENV prefix.*/function SOAPENVPrefix($prefix = null){static $_soapenv_prefix = 'SOAP-ENV';if (!is_null($prefix)) {$_soapenv_prefix = $prefix;}return $_soapenv_prefix;}/*** Sets the SOAP-ENC prefix and returns the current value.** @access public** @param string SOAP-ENC prefix** @return string current SOAP-ENC prefix.*/function SOAPENCPrefix($prefix = null){static $_soapenv_prefix = 'SOAP-ENC';if (!is_null($prefix)) {$_soapenv_prefix = $prefix;}return $_soapenv_prefix;}/*** Sets the default namespace.** @param string $namespace The default namespace.*/function setDefaultNamespace($namespace){$this->_namespace = $namespace;}function _resetNamespaces(){$this->_namespaces = array('http://schemas.xmlsoap.org/soap/envelope/' => SOAP_BASE::SOAPENVPrefix(),'http://www.w3.org/2001/XMLSchema' => 'xsd','http://www.w3.org/2001/XMLSchema-instance' => 'xsi','http://schemas.xmlsoap.org/soap/encoding/' => SOAP_BASE::SOAPENCPrefix());}/*** Sets the schema version used in the SOAP message.** @access private* @see $_XMLSchema** @param string $schemaVersion The schema version.*/function _setSchemaVersion($schemaVersion){if (!in_array($schemaVersion, $this->_XMLSchema)) {return $this->_raiseSoapFault("unsuported XMLSchema $schemaVersion");}$this->_XMLSchemaVersion = $schemaVersion;$tmpNS = array_flip($this->_namespaces);$tmpNS['xsd'] = $this->_XMLSchemaVersion;$tmpNS['xsi'] = $this->_XMLSchemaVersion . '-instance';$this->_namespaces = array_flip($tmpNS);}function _getNamespacePrefix($ns){if ($this->_namespace && $ns == $this->_namespace) {return '';}if (isset($this->_namespaces[$ns])) {return $this->_namespaces[$ns];}$prefix = 'ns' . count($this->_namespaces);$this->_namespaces[$ns] = $prefix;return $prefix;}function _getNamespaceForPrefix($prefix){$flipped = array_flip($this->_namespaces);if (isset($flipped[$prefix])) {return $flipped[$prefix];}return null;}/*** Serializes a value, array or object according to the rules set by this* object.** @see SOAP_Value** @param mixed $value The actual value.* @param QName $name The value name.* @param QName $type The value type.* @param array $options A list of encoding and serialization options.* @param array $attributes A hash of additional attributes.* @param string $artype The type of any array elements.*/function _serializeValue($value, $name = null, $type = null,$options = array(), $attributes = array(),$artype = ''){$namespaces = array();$arrayType = $array_depth = $xmlout_value = null;$typePrefix = $elPrefix = $xmlout_arrayType = '';$xmlout_type = $xmlns = $ptype = $array_type_ns = '';if (!$name->name || is_numeric($name->name)) {$name->name = 'item';}if ($this->_wsdl) {list($ptype, $arrayType, $array_type_ns, $array_depth)= $this->_wsdl->getSchemaType($type, $name);}if (!$arrayType) {$arrayType = $artype;}if (!$ptype) {$ptype = $this->_getType($value);}if (!$type) {$type = new QName($ptype);}if (strcasecmp($ptype, 'Struct') == 0 ||strcasecmp($type->name, 'Struct') == 0) {// Struct$vars = is_object($value) ? get_object_vars($value) : $value;if (is_array($vars)) {foreach (array_keys($vars) as $k) {// Hide private vars.if ($k[0] == '_') {continue;}if (is_object($vars[$k])) {if (is_a($vars[$k], 'SOAP_Value')) {$xmlout_value .= $vars[$k]->serialize($this);} else {// XXX get the members and serialize them instead// converting to an array is more overhead than we// should really do.$xmlout_value .= $this->_serializeValue(get_object_vars($vars[$k]), new QName($k, $this->_section5 ? null : $name->namepace), null, $options);}} else {$xmlout_value .= $this->_serializeValue($vars[$k], new QName($k, $this->_section5 ? null : $name->namespace), false, $options);}}}} elseif (strcasecmp($ptype, 'Array') == 0 ||strcasecmp($type->name, 'Array') == 0) {// Array.$type = new QName('Array', SOAP_SCHEMA_ENCODING);$numtypes = 0;$value = (array)$value;// XXX this will be slow on larger arrays. Basically, it flattens// arrays to allow us to serialize multi-dimensional arrays. We// only do this if arrayType is set, which will typically only// happen if we are using WSDLif (isset($options['flatten']) ||($arrayType &&(strchr($arrayType, ',') || strstr($arrayType, '][')))) {$numtypes = $this->_multiArrayType($value, $arrayType,$ar_size, $xmlout_value);}$array_type = $array_type_prefix = '';if ($numtypes != 1) {$arrayTypeQName = new QName($arrayType);$arrayType = $arrayTypeQName->name;$array_types = array();$array_val = null;// Serialize each array element.$ar_size = count($value);foreach ($value as $array_val) {if (is_a($array_val, 'SOAP_Value')) {$array_type = $array_val->type;$array_types[$array_type] = 1;$array_type_ns = $array_val->type_namespace;$xmlout_value .= $array_val->serialize($this);} else {$array_type = $this->_getType($array_val);$array_types[$array_type] = 1;if (empty($options['keep_arrays_flat'])) {$xmlout_value .= $this->_serializeValue($array_val, new QName('item', $this->_section5 ? null : $name->namespace), new QName($array_type), $options);} else {$xmlout_value .= $this->_serializeValue($array_val, $name, new QName($array_type), $options, $attributes);}}}if (!$arrayType) {$numtypes = count($array_types);if ($numtypes == 1) {$arrayType = $array_type;}// Using anyType is more interoperable.if ($array_type == 'Struct') {$array_type = '';} elseif ($array_type == 'Array') {$arrayType = 'anyType';$array_type_prefix = 'xsd';} else {if (!$arrayType) {$arrayType = $array_type;}}}}if (!$arrayType || $numtypes > 1) {// Should reference what schema we're using.$arrayType = 'xsd:anyType';} else {if ($array_type_ns) {$array_type_prefix = $this->_getNamespacePrefix($array_type_ns);} elseif (isset($this->_typemap[$this->_XMLSchemaVersion][$arrayType])) {$array_type_prefix = $this->_namespaces[$this->_XMLSchemaVersion];} elseif (isset($this->_typemap[SOAP_SCHEMA_ENCODING][$arrayType])) {$array_type_prefix = SOAP_BASE::SOAPENCPrefix();}if ($array_type_prefix) {$arrayType = $array_type_prefix . ':' . $arrayType;}}$xmlout_arrayType = ' ' . SOAP_BASE::SOAPENCPrefix(). ':arrayType="' . $arrayType;if ($array_depth != null) {for ($i = 0; $i < $array_depth; $i++) {$xmlout_arrayType .= '[]';}}$xmlout_arrayType .= "[$ar_size]\"";} elseif (is_a($value, 'SOAP_Value')) {$xmlout_value = $value->serialize($this);} elseif ($type->name == 'string') {$xmlout_value = htmlspecialchars($value);} elseif ($type->name == 'rawstring') {$xmlout_value = $value;} elseif ($type->name == 'boolean') {$xmlout_value = $value ? 'true' : 'false';} else {$xmlout_value = $value;}// Add namespaces.if ($name->namespace) {$elPrefix = $this->_getNamespacePrefix($name->namespace);if ($elPrefix) {$xmlout_name = $elPrefix . ':' . $name->name;} else {$xmlout_name = $name->name;}} else {$xmlout_name = $name->name;}if ($type->namespace) {$typePrefix = false;if (empty($options['no_type_prefix'])) {$typePrefix = $this->_getNamespacePrefix($type->namespace);}if ($typePrefix) {$xmlout_type = $typePrefix . ':' . $type->name;} else {$xmlout_type = $type->name;}} elseif ($type->name &&isset($this->_typemap[$this->_XMLSchemaVersion][$type->name])) {$typePrefix = $this->_namespaces[$this->_XMLSchemaVersion];if ($typePrefix) {$xmlout_type = $typePrefix . ':' . $type->name;} else {$xmlout_type = $type->name;}}// Handle additional attributes.$xml_attr = '';if (count($attributes)) {foreach ($attributes as $k => $v) {$kqn = new QName($k);$vqn = new QName($v);$xml_attr .= ' ' . $kqn->fqn() . '="' . $vqn->fqn() . '"';}}// Store the attachment for mime encoding.if (isset($options['attachment']) &&!PEAR::isError($options['attachment'])) {$this->_attachments[] = $options['attachment'];}if ($this->_section5) {if ($xmlout_type) {$xmlout_type = " xsi:type=\"$xmlout_type\"";}if (is_null($xmlout_value)) {$xml = "\r\n<$xmlout_name$xmlout_type$xmlns$xmlout_arrayType" ."$xml_attr xsi:nil=\"true\"/>";} else {$xml = "\r\n<$xmlout_name$xmlout_type$xmlns$xmlout_arrayType" ."$xml_attr>$xmlout_value</$xmlout_name>";}} elseif ($type->name == 'Array' && !empty($options['keep_arrays_flat'])) {$xml = $xmlout_value;} else {if (is_null($xmlout_value)) {$xml = "\r\n<$xmlout_name$xmlns$xml_attr/>";} else {$xml = "\r\n<$xmlout_name$xmlns$xml_attr>" .$xmlout_value . "</$xmlout_name>";}}return $xml;}/*** Converts a PHP type to a SOAP type.** @param mixed $value The value to inspect.** @return string The value's SOAP type.*/function _getType($value){$type = gettype($value);switch ($type) {case 'object':if (is_a($value, 'soap_value')) {$type = $value->type;} else {$type = 'Struct';}break;case 'array':// Hashes are always handled as structs.if ($this->_isHash($value)) {$type = 'Struct';break;}if (count($value) > 1) {// For non-wsdl structs that are all the same typereset($value);$value1 = next($value);$value2 = next($value);if (is_a($value1, 'SOAP_Value') &&is_a($value2, 'SOAP_Value') &&$value1->name != $value2->name) {// This is a struct, not an array.$type = 'Struct';break;}}$type = 'Array';break;case 'integer':case 'long':$type = 'int';break;case 'boolean':break;case 'double':// double is deprecated in PHP 4.2 and later.$type = 'float';break;case 'null':$type = '';break;case 'string':default:break;}return $type;}function _multiArrayType($value, &$type, &$size, &$xml){if (is_array($value)) {// Seems we have a multi dimensional array, figure it out if we// do.for ($i = 0, $c = count($value); $i < $c; ++$i) {$this->_multiArrayType($value[$i], $type, $size, $xml);}$sz = count($value);if ($size) {$size = $sz . ',' . $size;} else {$size = $sz;}return 1;} elseif (is_object($value)) {$type = $value->type;$xml .= $value->serialize($this);} else {$type = $this->_getType($value);$xml .= $this->_serializeValue($value, new QName('item'), new QName($type));}$size = null;return 1;}/*** Returns whether a type is a base64 type.** @param string $type A type name.** @return boolean True if the type name is a base64 type.*/function _isBase64Type($type){return $type == 'base64' || $type == 'base64Binary';}/*** Returns whether an array is a hash.** @param array $a An array to check.** @return boolean True if the specified array is a hash.*/function _isHash($a){foreach (array_keys($a) as $k) {// Checking the type is faster than regexp.if (!is_int($k)) {return true;}}return false;}function _un_htmlentities($string){$trans_tbl = get_html_translation_table(HTML_ENTITIES);$trans_tbl = array_flip($trans_tbl);return strtr($string, $trans_tbl);}/*** Converts a SOAP_Value object into a PHP value.*/function _decode($soapval){if (!is_a($soapval, 'SOAP_Value')) {return $soapval;}if (is_array($soapval->value)) {$isstruct = $soapval->type != 'Array';if ($isstruct) {$classname = $this->_defaultObjectClassname;if (isset($this->_type_translation[$soapval->tqn->fqn()])) {// This will force an error in PHP if the class does not// exist.$classname = $this->_type_translation[$soapval->tqn->fqn()];} elseif (isset($this->_type_translation[$soapval->type])) {// This will force an error in PHP if the class does not// exist.$classname = $this->_type_translation[$soapval->type];} elseif ($this->_auto_translation) {if (class_exists($soapval->type)) {$classname = $soapval->type;} elseif ($this->_wsdl) {$t = $this->_wsdl->getComplexTypeNameForElement($soapval->name, $soapval->namespace);if ($t && class_exists($t)) {$classname = $t;}}}$return = new $classname;} else {$return = array();}foreach ($soapval->value as $item) {if ($isstruct) {if ($this->_wsdl) {// Get this child's WSDL information.// /$soapval->ns/$soapval->type/$item->ns/$item->name$child_type = $this->_wsdl->getComplexTypeChildType($soapval->namespace,$soapval->name,$item->namespace,$item->name);if ($child_type) {$item->type = $child_type;}}if ($item->type == 'Array') {if (isset($return->{$item->name}) &&is_object($return->{$item->name})) {$return->{$item->name} = $this->_decode($item);} elseif (isset($return->{$item->name}) &&is_array($return->{$item->name})) {$return->{$item->name}[] = $this->_decode($item);} elseif (isset($return->{$item->name})) {$return->{$item->name} = array($return->{$item->name},$this->_decode($item));} elseif (is_array($return)) {$return[] = $this->_decode($item);} else {$return->{$item->name} = $this->_decode($item);}} elseif (isset($return->{$item->name})) {$d = $this->_decode($item);if (count(get_object_vars($return)) == 1) {$isstruct = false;$return = array($return->{$item->name}, $d);} else {$return->{$item->name} = array($return->{$item->name}, $d);}} else {$return->{$item->name} = $this->_decode($item);}// Set the attributes as members in the class.if (method_exists($return, '__set_attribute')) {foreach ($soapval->attributes as $key => $value) {call_user_func_array(array(&$return,'__set_attribute'),array($key, $value));}}} else {if ($soapval->arrayType && is_a($item, 'SOAP_Value')) {if ($this->_isBase64Type($item->type) &&!$this->_isBase64Type($soapval->arrayType)) {// Decode the value if we're losing the base64// type information.$item->value = base64_decode($item->value);}$item->type = $soapval->arrayType;}$return[] = $this->_decode($item);}}return $return;}if ($soapval->type == 'boolean') {if ($soapval->value != '0' &&strcasecmp($soapval->value, 'false') != 0) {$soapval->value = true;} else {$soapval->value = false;}} elseif ($soapval->type &&isset($this->_typemap[SOAP_XML_SCHEMA_VERSION][$soapval->type])) {// If we can, set variable type.settype($soapval->value,$this->_typemap[SOAP_XML_SCHEMA_VERSION][$soapval->type]);} elseif ($soapval->type == 'Struct') {$soapval->value = null;}return $soapval->value;}/*** Creates the SOAP envelope with the SOAP envelop data.** @param SOAP_Value $method SOAP_Value instance with the method name as* the name, and the method arguments as the* value.* @param array $headers A list of additional SOAP_Header objects.* @param string $encoding The charset of the SOAP message.* @param array $options A list of encoding/serialization options.** @return string The complete SOAP message.*/function makeEnvelope($method, $headers, $encoding = SOAP_DEFAULT_ENCODING,$options = array()){$smsg = $header_xml = $ns_string = '';if ($headers) {for ($i = 0, $c = count($headers); $i < $c; $i++) {$header_xml .= $headers[$i]->serialize($this);}$header_xml = sprintf("<%s:Header>\r\n%s\r\n</%s:Header>\r\n",SOAP_BASE::SOAPENVPrefix(), $header_xml,SOAP_BASE::SOAPENVPrefix());}if (!isset($options['input']) || $options['input'] == 'parse') {if (is_array($method)) {for ($i = 0, $c = count($method); $i < $c; $i++) {$smsg .= $method[$i]->serialize($this);}} else {$smsg = $method->serialize($this);}} else {$smsg = $method;}$body = sprintf("<%s:Body>%s\r\n</%s:Body>\r\n",SOAP_BASE::SOAPENVPrefix(), $smsg,SOAP_BASE::SOAPENVPrefix());foreach ($this->_namespaces as $k => $v) {$ns_string .= "\r\n " . sprintf('xmlns:%s="%s"', $v, $k);}if ($this->_namespace) {$ns_string .= "\r\n " . sprintf('xmlns="%s"', $this->_namespace);}/* If 'use' == 'literal', do not put in the encodingStyle. This is* denoted by $this->_section5 being false. 'use' can be defined at a* more granular level than we are dealing with here, so this does not* work for all services. */$xml = sprintf('<?xml version="1.0" encoding="%s"?>%s<%s:Envelope%s',$encoding, "\r\n", SOAP_BASE::SOAPENVPrefix(),$ns_string);if ($this->_section5) {$xml .= "\r\n " . sprintf('%s:encodingStyle="%s"',SOAP_BASE::SOAPENVPrefix(),SOAP_SCHEMA_ENCODING);}$xml .= sprintf('>%s%s%s</%s:Envelope>' . "\r\n","\r\n", $header_xml, $body, SOAP_BASE::SOAPENVPrefix());return $xml;}function _makeMimeMessage($xml, $encoding = SOAP_DEFAULT_ENCODING){if (!@include_once 'Mail/mimePart.php') {return $this->_raiseSoapFault('MIME messages are unsupported, the Mail_Mime package is not installed');}// Encode any attachments. See http://www.w3.org/TR/SOAP-attachments// Now we have to mime encode the message.$params = array('content_type' => 'multipart/related; type="text/xml"');$msg = new Mail_mimePart('', $params);// Add the xml part.$params['content_type'] = 'text/xml';$params['charset'] = $encoding;$msg->addSubPart($xml, $params);// Add the attachementsfor ($i = 0, $c = count($this->_attachments); $i < $c; ++$i) {$msg->addSubPart($this->_attachments[$i]['body'],$this->_attachments[$i]);}return $msg->encode();}// TODO: this needs to be used from the Transport system.function _makeDIMEMessage($xml){if (!@include_once 'Net/DIME.php') {return $this->_raiseSoapFault('DIME messages are unsupported, the Net_DIME package is not installed');}// Encode any attachments. See// http://search.ietf.org/internet-drafts/draft-nielsen-dime-soap-00.txt// Now we have to DIME encode the message$dime = new Net_DIME_Message();$msg = $dime->encodeData($xml, SOAP_ENVELOP, null, NET_DIME_TYPE_URI);// Add the attachments.$c = count($this->_attachments);for ($i = 0; $i < $c; $i++) {$msg .= $dime->encodeData($this->_attachments[$i]['body'],$this->_attachments[$i]['content_type'],$this->_attachments[$i]['cid'],NET_DIME_TYPE_MEDIA);}$msg .= $dime->endMessage();return $msg;}function _decodeMimeMessage(&$data, &$headers, &$attachments){if (!@include_once 'Mail/mimeDecode.php') {return $this->_raiseSoapFault('MIME messages are unsupported, the Mail_Mime package is not installed');}$params['include_bodies'] = true;$params['decode_bodies'] = true;$params['decode_headers'] = true;// Lame thing to have to do for decoding.$decoder = new Mail_mimeDecode($data);$structure = $decoder->decode($params);if (isset($structure->body)) {$data = $structure->body;$headers = $structure->headers;return;} elseif (isset($structure->parts)) {$data = $structure->parts[0]->body;$headers = array_merge($structure->headers,$structure->parts[0]->headers);if (count($structure->parts) <= 1) {return;}$mime_parts = array_splice($structure->parts, 1);// Prepare the parts for the SOAP parser.for ($i = 0, $c = count($mime_parts); $i < $c; $i++) {$p = $mime_parts[$i];if (isset($p->headers['content-location'])) {// TODO: modify location per SwA note section 3// http://www.w3.org/TR/SOAP-attachments$attachments[$p->headers['content-location']] = $p->body;} else {$cid = 'cid:' . substr($p->headers['content-id'], 1, -1);$attachments[$cid] = $p->body;}}return;}$this->_raiseSoapFault('Mime parsing error', '', '', 'Server');}function _decodeDIMEMessage(&$data, &$headers, &$attachments){if (!@include_once 'Net/DIME.php') {return $this->_raiseSoapFault('DIME messages are unsupported, the Net_DIME package is not installed');}// This SHOULD be moved to the transport layer, e.g. PHP itself should// handle parsing DIME ;)$dime = new Net_DIME_Message();$err = $dime->decodeData($data);if (PEAR::isError($err)) {$this->_raiseSoapFault('Failed to decode the DIME message!', '', '', 'Server');return;}if (strcasecmp($dime->parts[0]['type'], SOAP_ENVELOP) != 0) {$this->_raiseSoapFault('DIME record 1 is not a SOAP envelop!', '', '', 'Server');return;}$data = $dime->parts[0]['data'];// Fake it for now.$headers['content-type'] = 'text/xml';$c = count($dime->parts);for ($i = 0; $i < $c; $i++) {$part =& $dime->parts[$i];// We need to handle URI's better.$id = strncmp($part['id'], 'cid:', 4)? 'cid:' . $part['id']: $part['id'];$attachments[$id] = $part['data'];}}/*** Explicitly sets the translation for a specific class.** Auto translation works for all cases, but opens ANY class in the script* to be used as a data type, and may not be desireable.** @param string $type A SOAP type.* @param string $class A PHP class name.*/function setTypeTranslation($type, $class = null){$tq = new QName($type);if (!$class) {$class = $tq->name;}$this->_type_translation[$type]=$class;}}/*** Class used to handle QNAME values in XML.** @package SOAP* @author Shane Caraveo <shane@php.net> Conversion to PEAR and updates*/class QName{var $name = '';var $ns = '';var $namespace = '';function QName($name, $namespace = ''){if ($name && $name[0] == '{') {preg_match('/\{(.*?)\}(.*)/', $name, $m);$this->name = $m[2];$this->namespace = $m[1];} elseif (substr_count($name, ':') == 1) {$s = explode(':', $name);$s = array_reverse($s);$this->name = $s[0];$this->ns = $s[1];$this->namespace = $namespace;} else {$this->name = $name;$this->namespace = $namespace;}// A little more magic than should be in a qname.$p = strpos($this->name, '[');if ($p) {// TODO: Need to re-examine this logic later.// Chop off [].$this->arraySize = explode(',', substr($this->name, $p + 1, -$p - 2));$this->arrayInfo = substr($this->name, $p);$this->name = substr($this->name, 0, $p);}}function fqn(){if ($this->namespace) {return '{' . $this->namespace . '}' . $this->name;} elseif ($this->ns) {return $this->ns . ':' . $this->name;}return $this->name;}}