Page Menu
Home
Phabricator
Search
Configure Global Search
Log In
Files
F7170472
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Award Token
Flag For Later
Size
93 KB
Referenced Files
None
Subscribers
None
View Options
diff --git a/library/SOAP/Base.php b/library/SOAP/Base.php
index 984ec45..5762351 100644
--- a/library/SOAP/Base.php
+++ b/library/SOAP/Base.php
@@ -1,1116 +1,1115 @@
<?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('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.11.0');
define('SOAP_LIBRARY_NAME', 'PEAR-SOAP 0.11.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');
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 array
var $_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.
*
* @array
*/
var $_namespaces;
/**
* The default namespace.
*
* @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 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-ENV',
'http://www.w3.org/2001/XMLSchema' => 'xsd',
'http://www.w3.org/2001/XMLSchema-instance' => 'xsi',
'http://schemas.xmlsoap.org/soap/encoding/' => 'SOAP-ENC');
}
/**
* 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 = is_array($this->_namespaces) ? array_flip($this->_namespaces) : array();
$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;
}
function _isSoapValue(&$value)
{
return is_a($value, 'SOAP_Value');
}
function _serializeValue(&$value, $name = '', $type = false,
$elNamespace = null, $typeNamespace = null,
$options = array(), $attributes = array(),
$artype = '')
{
$namespaces = array();
$arrayType = $array_depth = $xmlout_value = null;
$typePrefix = $elPrefix = $xmlout_offset = $xmlout_arrayType = '';
$xmlout_type = $xmlns = $ptype = $array_type_ns = '';
if (!$name || is_numeric($name)) {
$name = 'item';
}
if ($this->_wsdl) {
list($ptype, $arrayType, $array_type_ns, $array_depth)
= $this->_wsdl->getSchemaType($type, $name, $typeNamespace);
}
if (!$arrayType) {
$arrayType = $artype;
}
if (!$ptype) {
$ptype = $this->_getType($value);
}
if (!$type) {
$type = $ptype;
}
if (strcasecmp($ptype, 'Struct') == 0 ||
strcasecmp($type, 'Struct') == 0) {
// Struct
$vars = null;
if (is_object($value)) {
$vars = get_object_vars($value);
} else {
$vars = &$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]), $k, false, $this->_section5 ? null : $elNamespace);
}
} else {
$xmlout_value .= $this->_serializeValue($vars[$k], $k, false, $this->_section5 ? null : $elNamespace);
}
}
}
} elseif (strcasecmp($ptype, 'Array') == 0 ||
strcasecmp($type, 'Array') == 0) {
// Array.
$typeNamespace = SOAP_SCHEMA_ENCODING;
$orig_type = $type;
$type = 'Array';
$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 WSDL
if (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 ($this->_isSoapValue($array_val)) {
$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;
$xmlout_value .= $this->_serializeValue($array_val, 'item', $array_type, $this->_section5 ? null : $elNamespace);
}
}
$xmlout_offset = ' SOAP-ENC:offset="[0]"';
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];
}
if ($array_type_prefix) {
$arrayType = $array_type_prefix . ':' . $arrayType;
}
}
$xmlout_arrayType = ' SOAP-ENC:arrayType="' . $arrayType;
if ($array_depth != null) {
for ($i = 0; $i < $array_depth; $i++) {
$xmlout_arrayType .= '[]';
}
}
$xmlout_arrayType .= "[$ar_size]\"";
} elseif ($this->_isSoapValue($value)) {
$xmlout_value = $value->serialize($this);
} elseif ($type == 'string') {
$xmlout_value = htmlspecialchars($value);
} elseif ($type == 'rawstring') {
$xmlout_value =& $value;
} elseif ($type == 'boolean') {
$xmlout_value = $value ? 'true' : 'false';
} else {
$xmlout_value =& $value;
}
// Add namespaces.
if ($elNamespace) {
$elPrefix = $this->_getNamespacePrefix($elNamespace);
if ($elPrefix) {
$xmlout_name = "$elPrefix:$name";
} else {
$xmlout_name = $name;
}
} else {
$xmlout_name = $name;
}
if ($typeNamespace) {
$typePrefix = $this->_getNamespacePrefix($typeNamespace);
if ($typePrefix) {
$xmlout_type = "$typePrefix:$type";
} else {
$xmlout_type = $type;
}
} elseif ($type &&
isset($this->_typemap[$this->_XMLSchemaVersion][$type])) {
$typePrefix = $this->_namespaces[$this->_XMLSchemaVersion];
if ($typePrefix) {
$xmlout_type = "$typePrefix:$type";
} else {
$xmlout_type = $type;
}
}
// 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" .
"$xmlout_offset$xml_attr>$xmlout_value</$xmlout_name>";
}
} 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.
*
* @access private
*
* @param string $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';
} else {
$ar_size = count($value);
reset($value);
$key1 = key($value);
if ($ar_size > 0 && is_a($key1, 'SOAP_Value')) {
// FIXME: for non-wsdl structs that are all the same type
$key2 = key($value);
if ($ar_size > 1 &&
$this->_isSoapValue($key1) &&
$this->_isSoapValue($key2) &&
$key1->name != $key2->name) {
// This is a struct, not an array.
$type = 'Struct';
} else {
$type = 'Array';
}
} else {
$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, 'item', $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)
{
// I really dislike having to loop through this in PHP code, really
// large arrays will be slow. We need a C function to do this.
$it = 0;
foreach ($a as $k => $v) {
// Checking the type is faster than regexp.
if (!is_int($k)) {
return true;
}
// If someone has a large hash they should really be defining the
// type.
if ($it++ > 10) {
$this->_raiseSoapFault('Large associative array passed where a SOAP_Value was expected');
return false;
}
}
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 StdClass PHP object
*/
function &_decode(&$soapval)
{
if (!$this->_isSoapValue($soapval)) {
return $soapval;
} elseif (is_array($soapval->value)) {
if ($soapval->type != 'Array') {
$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();
}
$counter = 1;
$isstruct = !is_array($return);
foreach ($soapval->value as $item) {
if (is_object($return)) {
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 (!$isstruct || $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})) {
//$isstruct = false;
if (count(get_object_vars($return)) == 1) {
$d =& $this->_decode($item);
$return = array($return->{$item->name}, $d);
} else {
$d =& $this->_decode($item);
$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 && $this->_isSoapValue($item)) {
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;
}
if (!$isstruct) {
$return[] = $this->_decode($item);
} elseif (isset($return[$item->name])) {
$isstruct = false;
$d =& $this->_decode($item);
$return = array($return[$item->name], $d);
} else {
$return[$item->name] = $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]);
}
return $soapval->value;
}
/**
* Creates the SOAP envelope with the SOAP envelop data.
*
* @param mixed $method
* @param array $headers
* @param string $encoding
* @param array $options
*
* @return string
*/
function makeEnvelope(&$method, &$headers,
$encoding = SOAP_DEFAULT_ENCODING,
$options = array())
{
$smsg = $header_xml = $ns_string = '';
if ($headers) {
$c = count($headers);
for ($i = 0; $i < $c; $i++) {
$header_xml .= $headers[$i]->serialize($this);
}
$header_xml = "<SOAP-ENV:Header>\r\n$header_xml\r\n</SOAP-ENV:Header>\r\n";
}
if (!isset($options['input']) || $options['input'] == 'parse') {
if (is_array($method)) {
$c = count($method);
for ($i = 0; $i < $c; $i++) {
$smsg .= $method[$i]->serialize($this);
}
} else {
$smsg = $method->serialize($this);
}
} else {
$smsg = $method;
}
- $body = "<SOAP-ENV:Body>\r\n" . $smsg . "\r\n</SOAP-ENV:Body>\r\n";
+ $body = "<SOAP-ENV:Body>\r\n" . $smsg . "\r\n</SOAP-ENV:Body>\r\n";
- foreach ($this->_namespaces as $k => $v) {
+ foreach ($this->_namespaces as $k => $v) {
$ns_string .= " xmlns:$v=\"$k\"\r\n";
}
if ($this->_namespace) {
$ns_string .= " xmlns=\"{$this->_namespace}\"\r\n";
}
/* If 'use' == 'literal', we 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 = "<?xml version=\"1.0\" encoding=\"$encoding\"?>\r\n\r\n".
"<SOAP-ENV:Envelope $ns_string".
($this->_section5 ? ' SOAP-ENV:encodingStyle="' . SOAP_SCHEMA_ENCODING . '"' : '').
">\r\n".
"$header_xml$body</SOAP-ENV:Envelope>\r\n";
-
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;
$params['encoding'] = 'base64';
$msg->addSubPart($xml, $params);
// Add the attachements
for ($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) {
$mime_parts = array_splice($structure->parts,1);
// Prepare the parts for the SOAP parser.
$c = count($mime_parts);
for ($i = 0; $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'];
}
}
/**
* @deprecated Use setTypeTranslation().
*/
function __set_type_translation($type, $class = null)
{
$this->setTypeTranslation($type, $class);
}
/**
* 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.
*
* @access public
* @package SOAP
* @author Shane Caraveo <shane@php.net> Conversion to PEAR and updates
*/
class QName
{
var $name = '';
var $ns = '';
var $namespace='';
function __construct($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;
}
}
diff --git a/library/SOAP/Client.php b/library/SOAP/Client.php
index 9a4f3e0..3535772 100644
--- a/library/SOAP/Client.php
+++ b/library/SOAP/Client.php
@@ -1,855 +1,855 @@
<?php
/**
* This file contains the code for the SOAP client.
*
* 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-2005 The PHP Group
* @license http://www.php.net/license/2_02.txt PHP License 2.02
* @link http://pear.php.net/package/SOAP
*/
require_once 'SOAP/Value.php';
require_once 'SOAP/Base.php';
require_once 'SOAP/Transport.php';
require_once 'SOAP/WSDL.php';
require_once 'SOAP/Fault.php';
require_once 'SOAP/Parser.php';
// Arnaud: the following code was taken from DataObject and adapted to suit
// this will be horrifically slow!!!!
// NOTE: Overload SEGFAULTS ON PHP4 + Zend Optimizer
// these two are BC/FC handlers for call in PHP4/5
if (!class_exists('SOAP_Client_Overload')) {
if (substr(zend_version(), 0, 1) > 1) {
class SOAP_Client_Overload extends SOAP_Base {
function __call($method, $args)
{
$return = null;
$this->_call($method, $args, $return);
return $return;
}
}
} else {
if (!function_exists('clone')) {
eval('function clone($t) { return $t; }');
}
eval('
class SOAP_Client_Overload extends SOAP_Base {
function __call($method, $args, &$return)
{
return $this->_call($method, $args, $return);
}
}');
}
}
/**
* SOAP Client Class
*
* This class is the main interface for making soap requests.
*
* basic usage:<code>
* $soapclient = new SOAP_Client( string path [ , boolean wsdl] );
* echo $soapclient->call( string methodname [ , array parameters] );
* </code>
* or, if using PHP 5+ or the overload extension:<code>
* $soapclient = new SOAP_Client( string path [ , boolean wsdl] );
* echo $soapclient->methodname( [ array parameters] );
* </code>
*
* Originally based on SOAPx4 by Dietrich Ayala
* http://dietrich.ganx4.com/soapx4
*
* @access public
* @package SOAP
* @author Shane Caraveo <shane@php.net> Conversion to PEAR and updates
* @author Stig Bakken <ssb@fast.no> Conversion to PEAR
* @author Dietrich Ayala <dietrich@ganx4.com> Original Author
*/
class SOAP_Client extends SOAP_Client_Overload
{
/**
* Communication endpoint.
*
* Currently the following transport formats are supported:
* - HTTP
* - SMTP
*
* Example endpoints:
* http://www.example.com/soap/server.php
* https://www.example.com/soap/server.php
* mailto:soap@example.com
*
* @see SOAP_Client()
* @var string
*/
var $_endpoint = '';
/**
* The SOAP PORT name that is used by the client.
*
* @var string
*/
var $_portName = '';
/**
* Endpoint type e.g. 'wdsl'.
*
* @var string
*/
var $_endpointType = '';
/**
* The received xml.
*
* @var string
*/
var $xml;
/**
* The outgoing and incoming data stream for debugging.
*
* @var string
*/
var $wire;
/**
* The outgoing data stream for debugging.
*
* @var string
*/
var $_last_request = null;
/**
* The incoming data stream for debugging.
*
* @var string
*/
var $_last_response = null;
/**
* Options.
*
* @var array
*/
var $_options = array('trace' => false);
/**
* The character encoding used for XML parser, etc.
*
* @var string
*/
var $_encoding = SOAP_DEFAULT_ENCODING;
/**
* The array of SOAP_Headers that we are sending.
*
* @var array
*/
var $headersOut = null;
/**
* The headers we recieved back in the response.
*
* @var array
*/
var $headersIn = null;
/**
* Options for the HTTP_Request class (see HTTP/Request.php).
*
* @var array
*/
var $_proxy_params = array();
/**
* The SOAP_Transport instance.
*
* @var SOAP_Transport
*/
var $_soap_transport = null;
/**
* Constructor.
*
* @access public
*
* @param string $endpoint An URL.
* @param boolean $wsdl Whether the endpoint is a WSDL file.
* @param string $portName The service's port name to use.
* @param array $proxy_params Options for the HTTP_Request class
* @see HTTP_Request
* @param boolean|string $cache Use WSDL caching? The cache directory if
* a string.
*/
function __construct($endpoint, $wsdl = false, $portName = false,
$proxy_params = array(), $cache = false)
{
- parent::SOAP_Base('Client');
+ parent::SOAP_Base('Client');
$this->_endpoint = $endpoint;
$this->_portName = $portName;
$this->_proxy_params = $proxy_params;
// This hack should perhaps be removed as it might cause unexpected
// behaviour.
$wsdl = $wsdl
? $wsdl
: strtolower(substr($endpoint, -4)) == 'wsdl';
// make values
if ($wsdl) {
$this->_endpointType = 'wsdl';
// instantiate wsdl class
$this->_wsdl = new SOAP_WSDL($this->_endpoint,
$this->_proxy_params,
$cache);
if ($this->_wsdl->fault) {
$this->_raiseSoapFault($this->_wsdl->fault);
}
}
}
function _reset()
{
$this->xml = null;
$this->wire = null;
$this->_last_request = null;
$this->_last_response = null;
$this->headersIn = null;
$this->headersOut = null;
}
/**
* Sets the character encoding.
*
* Limited to 'UTF-8', 'US_ASCII' and 'ISO-8859-1'.
*
* @access public
*
* @param string encoding
*
* @return mixed SOAP_Fault on error.
*/
function setEncoding($encoding)
{
if (in_array($encoding, $this->_encodings)) {
$this->_encoding = $encoding;
return;
}
return $this->_raiseSoapFault('Invalid Encoding');
}
/**
* Adds a header to the envelope.
*
* @access public
*
* @param SOAP_Header $soap_value A SOAP_Header or an array with the
* elements 'name', 'namespace',
* 'mustunderstand', and 'actor' to send
* as a header.
*/
function addHeader($soap_value)
{
// Add a new header to the message.
if (is_a($soap_value, 'SOAP_Header')) {
$this->headersOut[] = $soap_value;
} elseif (is_array($soap_value)) {
// name, value, namespace, mustunderstand, actor
$this->headersOut[] = new SOAP_Header($soap_value[0],
null,
$soap_value[1],
$soap_value[2],
$soap_value[3]);
} else {
$this->_raiseSoapFault('Invalid parameter provided to addHeader(). Must be an array or a SOAP_Header.');
}
}
/**
* Calls a method on the SOAP endpoint.
*
* The namespace parameter is overloaded to accept an array of options
* that can contain data necessary for various transports if it is used as
* an array, it MAY contain a namespace value and a soapaction value. If
* it is overloaded, the soapaction parameter is ignored and MUST be
* placed in the options array. This is done to provide backwards
* compatibility with current clients, but may be removed in the future.
* The currently supported values are:<pre>
* namespace
* soapaction
* timeout (HTTP socket timeout)
* transfer-encoding (SMTP, Content-Transfer-Encoding: header)
* from (SMTP, From: header)
* subject (SMTP, Subject: header)
* headers (SMTP, hash of extra SMTP headers)
* </pre>
*
* @access public
*
* @param string $method The method to call.
* @param array $params The method parameters.
* @param string|array $namespace Namespace or hash with options.
* @param string $soapAction
*
* @return mixed The method result or a SOAP_Fault on error.
*/
function &call($method, $params, $namespace = false, $soapAction = false)
- {
+ {
$this->headersIn = null;
$this->_last_request = null;
$this->_last_response = null;
$this->wire = null;
$this->xml = null;
- $soap_data = $this->_generate($method, $params, $namespace, $soapAction);
+ $soap_data = $this->_generate($method, $params, $namespace, $soapAction);
+
if ((new PEAR)->isError($soap_data)) {
$fault = $this->_raiseSoapFault($soap_data);
return $fault;
}
// _generate() may have changed the endpoint if the WSDL has more
// than one service, so we need to see if we need to generate a new
// transport to hook to a different URI. Since the transport protocol
// can also change, we need to get an entirely new object. This could
// probably be optimized.
if (!$this->_soap_transport ||
$this->_endpoint != $this->_soap_transport->url) {
$this->_soap_transport =& SOAP_Transport::getTransport($this->_endpoint);
if ((new PEAR)->isError($this->_soap_transport)) {
$fault =& $this->_soap_transport;
$this->_soap_transport = null;
$fault = $this->_raiseSoapFault($fault);
return $fault;
}
}
$this->_soap_transport->encoding = $this->_encoding;
// Send the message.
$transport_options = array_merge_recursive($this->_proxy_params,
$this->_options);
$this->xml = $this->_soap_transport->send($soap_data, $transport_options);
// Save the wire information for debugging.
if ($this->_options['trace']) {
$this->_last_request = $this->_soap_transport->outgoing_payload;
$this->_last_response = $this->_soap_transport->incoming_payload;
$this->wire = $this->getWire();
}
if ($this->_soap_transport->fault) {
$fault = $this->_raiseSoapFault($this->xml);
return $fault;
}
if (isset($this->_options['result']) &&
$this->_options['result'] != 'parse') {
return $this->xml;
}
- $this->__result_encoding = $this->_soap_transport->result_encoding;
+ $this->__result_encoding = $this->_soap_transport->result_encoding;
$result = &$this->parseResponse($this->xml, $this->__result_encoding,
$this->_soap_transport->attachments);
return $result;
}
/**
* Sets an option to use with the transport layers.
*
* For example:
* <code>
* $soapclient->setOpt('curl', CURLOPT_VERBOSE, 1)
* </code>
* to pass a specific option to curl if using an SSL connection.
*
* @access public
*
* @param string $category Category to which the option applies or option
* name.
* @param string $option An option name if $category is a category name,
* an option value if $category is an option name.
* @param string $value An option value if $category is a category
* name.
*/
function setOpt($category, $option, $value = null)
{
if (!is_null($value)) {
if (!isset($this->_options[$category])) {
$this->_options[$category] = array();
}
$this->_options[$category][$option] = $value;
} else {
$this->_options[$category] = $option;
}
}
/**
* Call method supporting the overload extension.
*
* If the overload extension is loaded, you can call the client class with
* a soap method name:
* <code>
* $soap = new SOAP_Client(....);
* $value = $soap->getStockQuote('MSFT');
* </code>
*
* @access public
*
* @param string $method The method to call.
* @param array $params The method parameters.
* @param mixed $return_value Will get the method's return value
* assigned.
*
* @return boolean Always true.
*/
function _call($method, $params, &$return_value)
{
// Overloading lowercases the method name, we need to look into the
// WSDL and try to find the correct method name to get the correct
// case for the call.
if ($this->_wsdl) {
$this->_wsdl->matchMethod($method);
}
$return_value =& $this->call($method, $params);
return true;
}
/**
* @deprecated Use getLastRequest().
*/
function &__getlastrequest()
{
$request = $this->getLastRequest();
return $request;
}
/**
* Returns the XML content of the last SOAP request.
*
* @return string The last request.
*/
function getLastRequest()
{
return $this->_last_request;
}
/**
* @deprecated Use getLastResponse().
*/
function &__getlastresponse()
{
$response =& $this->getLastResponse;
return $response;
}
/**
* Returns the XML content of the last SOAP response.
*
* @return string The last response.
*/
function getLastResponse()
{
return $this->_last_response;
}
/**
* @deprecated Use setUse().
*/
function __use($use)
{
$this->setUse($use);
}
/**
* Sets the SOAP encoding.
*
* @param string $use Either 'literal' or 'encoded' (section 5).
*/
function setUse($use)
{
$this->_options['use'] = $use;
}
/**
* @deprecated Use setStyle().
*/
function __style($style)
{
$this->setStyle($style);
}
/**
* Sets the SOAP encoding style.
*
* @param string $style Either 'document' or 'rpc'.
*/
function setStyle($style)
{
$this->_options['style'] = $style;
}
/**
* @deprecated Use setTrace().
*/
function __trace($level)
{
$this->setTrace($level);
}
/**
* Sets whether to trace the traffic on the transport level.
*
* @see getWire()
*
* @param boolean $trace
*/
function setTrace($trace)
{
$this->_options['trace'] = $trace;
}
function _generate($method, &$params, $namespace = false,
$soapAction = false)
{
$this->fault = null;
$this->_options['input'] = 'parse';
$this->_options['result'] = 'parse';
$this->_options['parameters'] = false;
if ($params && gettype($params) != 'array') {
$params = array($params);
- }
+ }
if (gettype($namespace) == 'array') {
foreach ($namespace as $optname => $opt) {
$this->_options[strtolower($optname)] = $opt;
}
if (isset($this->_options['namespace'])) {
$namespace = $this->_options['namespace'];
} else {
$namespace = false;
}
} else {
// We'll place $soapAction into our array for usage in the
// transport.
$this->_options['soapaction'] = $soapAction;
$this->_options['namespace'] = $namespace;
}
if ($this->_endpointType == 'wsdl') {
$this->_setSchemaVersion($this->_wsdl->xsd);
// Get port name.
if (!$this->_portName) {
$this->_portName = $this->_wsdl->getPortName($method);
}
if ((new PEAR)->isError($this->_portName)) {
return $this->_raiseSoapFault($this->_portName);
}
// Get endpoint.
$this->_endpoint = $this->_wsdl->getEndpoint($this->_portName);
if ((new PEAR)->isError($this->_endpoint)) {
return $this->_raiseSoapFault($this->_endpoint);
}
// Get operation data.
$opData = $this->_wsdl->getOperationData($this->_portName, $method);
if ((new PEAR)->isError($opData)) {
return $this->_raiseSoapFault($opData);
}
$namespace = $opData['namespace'];
$this->_options['style'] = $opData['style'];
$this->_options['use'] = $opData['input']['use'];
$this->_options['soapaction'] = $opData['soapAction'];
// Set input parameters.
if ($this->_options['input'] == 'parse') {
$this->_options['parameters'] = $opData['parameters'];
$nparams = array();
if (isset($opData['input']['parts']) &&
count($opData['input']['parts'])) {
foreach ($opData['input']['parts'] as $name => $part) {
$xmlns = '';
$attrs = array();
// Is the name a complex type?
if (isset($part['element'])) {
$xmlns = $this->_wsdl->namespaces[$part['namespace']];
$part = $this->_wsdl->elements[$part['namespace']][$part['type']];
$name = $part['name'];
}
if (isset($params[$name]) ||
$this->_wsdl->getDataHandler($name, $part['namespace'])) {
$nparams[$name] =& $params[$name];
} else {
// We now force an associative array for
// parameters if using WSDL.
return $this->_raiseSoapFault("The named parameter $name is not in the call parameters.");
}
if (gettype($nparams[$name]) != 'object' ||
!is_a($nparams[$name], 'SOAP_Value')) {
// Type is likely a qname, split it apart, and get
// the type namespace from WSDL.
$qname = new QName($part['type']);
if ($qname->ns) {
$type_namespace = $this->_wsdl->namespaces[$qname->ns];
} elseif (isset($part['namespace'])) {
$type_namespace = $this->_wsdl->namespaces[$part['namespace']];
} else {
$type_namespace = null;
}
$qname->namespace = $type_namespace;
$pqname = $name;
if ($xmlns) {
$pqname = '{' . $xmlns . '}' . $name;
}
$nparams[$name] = new SOAP_Value($pqname,
$qname->fqn(),
$nparams[$name],
$attrs);
} else {
// WSDL fixups to the SOAP value.
}
}
}
$params =& $nparams;
unset($nparams);
}
} else {
$this->_setSchemaVersion(SOAP_XML_SCHEMA_VERSION);
}
// Serialize the message.
$this->_section5 = (!isset($this->_options['use']) ||
$this->_options['use'] != 'literal');
if (!isset($this->_options['style']) ||
$this->_options['style'] == 'rpc') {
$this->_options['style'] = 'rpc';
$this->docparams = true;
$mqname = new QName($method, $namespace);
$methodValue = new SOAP_Value($mqname->fqn(), 'Struct', $params);
$soap_msg = $this->makeEnvelope($methodValue,
$this->headersOut,
$this->_encoding,
$this->_options);
} else {
if (!$params) {
$mqname = new QName($method, $namespace);
$mynull = null;
$params = new SOAP_Value($mqname->fqn(), 'Struct', $mynull);
} elseif ($this->_options['input'] == 'parse') {
if (is_array($params)) {
$nparams = array();
$keys = array_keys($params);
foreach ($keys as $k) {
if (gettype($params[$k]) != 'object') {
$nparams[] = new SOAP_Value($k,
false,
$params[$k]);
} else {
$nparams[] =& $params[$k];
}
}
$params =& $nparams;
}
if ($this->_options['parameters']) {
$mqname = new QName($method, $namespace);
$params = new SOAP_Value($mqname->fqn(),
'Struct',
$params);
}
}
$soap_msg = $this->makeEnvelope($params,
$this->headersOut,
$this->_encoding,
$this->_options);
}
unset($this->headersOut);
if ((new PEAR)->isError($soap_msg)) {
return $this->_raiseSoapFault($soap_msg);
}
// Handle MIME or DIME encoding.
// TODO: DIME encoding should move to the transport, do it here for
// now and for ease of getting it done.
if (count($this->_attachments)) {
if ((isset($this->_options['attachments']) &&
$this->_options['attachments'] == 'Mime') ||
isset($this->_options['Mime'])) {
$soap_msg = $this->_makeMimeMessage($soap_msg, $this->_encoding);
} else {
// default is dime
$soap_msg = $this->_makeDIMEMessage($soap_msg, $this->_encoding);
$this->_options['headers']['Content-Type'] = 'application/dime';
}
if ((new PEAR)->isError($soap_msg)) {
return $this->_raiseSoapFault($soap_msg);
}
}
// Instantiate client.
if (is_array($soap_msg)) {
$soap_data = $soap_msg['body'];
if (count($soap_msg['headers'])) {
if (isset($this->_options['headers'])) {
$this->_options['headers'] = array_merge($this->_options['headers'], $soap_msg['headers']);
} else {
$this->_options['headers'] = $soap_msg['headers'];
}
}
} else {
$soap_data = $soap_msg;
- }
-
+ }
return $soap_data;
}
/**
* @deprecated Use parseResponse().
*/
function &__parse(&$response, $encoding, &$attachments)
{
return $this->parseResponse($response, $encoding, $attachments);
}
/**
* Parses a SOAP response.
*
* @see SOAP_Parser::
*
* @param string $response XML content of SOAP response.
* @param string $encoding Character set encoding, defaults to 'UTF-8'.
* @param array $attachments List of attachments.
*/
function &parseResponse($response, $encoding, &$attachments)
{
// Parse the response.
$response =new SOAP_Parser($response, $encoding, $attachments);
if ($response->fault) {
$fault = $this->_raiseSoapFault($response->fault);
return $fault;
}
-
// Return array of parameters.
$return = $response->getResponse();
$headers = $response->getHeaders();
if ($headers) {
$this->headersIn = $this->_decodeResponse($headers, false);
}
- $decoded = $this->_decodeResponse($return);
+ $decoded = $this->_decodeResponse($return);
+
return $decoded;
}
/**
* Converts a complex SOAP_Value into a PHP Array
*
* @param SOAP_Value $response value object
* @param boolean $shift FIXME
* @return Array
*/
function &_decodeResponse($response, $shift = true)
{
if (!$response) {
$decoded = null;
return $decoded;
}
// Check for valid response.
if ((new PEAR)->isError($response)) {
$fault =& $this->_raiseSoapFault($response);
return $fault;
} elseif (!is_a($response, 'soap_value')) {
$fault =& $this->_raiseSoapFault("Didn't get SOAP_Value object back from client");
return $fault;
}
// Decode to native php datatype.
$returnArray =& $this->_decode($response);
// Fault?
if ((new PEAR)->isError($returnArray)) {
$fault =& $this->_raiseSoapFault($returnArray);
return $fault;
}
if (is_object($returnArray) &&
strcasecmp(get_class($returnArray), 'stdClass') == 0) {
$returnArray = get_object_vars($returnArray);
}
if (is_array($returnArray)) {
if (isset($returnArray['faultcode']) ||
isset($returnArray['SOAP-ENV:faultcode'])) {
$faultcode = $faultstring = $faultdetail = $faultactor = '';
foreach ($returnArray as $k => $v) {
if (stristr($k, 'faultcode')) $faultcode = $v;
if (stristr($k, 'faultstring')) $faultstring = $v;
if (stristr($k, 'detail')) $faultdetail = $v;
if (stristr($k, 'faultactor')) $faultactor = $v;
}
$fault =& $this->_raiseSoapFault($faultstring, $faultdetail, $faultactor, $faultcode);
return $fault;
}
// Return array of return values.
if ($shift && count($returnArray) == 1) {
$decoded = array_shift($returnArray);
return $decoded;
}
return $returnArray;
}
return $returnArray;
}
/**
* @deprecated Use getWire().
*/
function __get_wire()
{
return $this->getWire();
}
/**
* Returns the outgoing and incoming traffic on the transport level.
*
* Tracing has to be enabled.
*
* @see setTrace()
*
* @return string The complete traffic between the client and the server.
*/
function getWire()
{
if ($this->_options['trace'] &&
($this->_last_request || $this->_last_response)) {
return "OUTGOING:\n\n" .
$this->_last_request .
"\n\nINCOMING\n\n" .
preg_replace("/></",">\r\n<", $this->_last_response);
}
return null;
}
}
diff --git a/library/SOAP/Transport.php b/library/SOAP/Transport.php
index c94d36c..5a79140 100644
--- a/library/SOAP/Transport.php
+++ b/library/SOAP/Transport.php
@@ -1,151 +1,152 @@
<?php
/**
* This file contains the code for an abstract transport layer.
*
* 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>
* @author Shane Caraveo <Shane@Caraveo.com>
* @author Jan Schneider <jan@horde.org>
* @copyright 2003-2006 The PHP Group
* @license http://www.php.net/license/2_02.txt PHP License 2.02
* @link http://pear.php.net/package/SOAP
*/
require_once 'SOAP/Base.php';
/**
* SOAP Transport Layer
*
* This layer can use different protocols dependant on the endpoint url
* provided.
*
* No knowlege of the SOAP protocol is available at this level.
* No knowlege of the transport protocols is available at this level.
*
* @access public
* @package SOAP
* @author Shane Caraveo <shane@php.net>
* @author Jan Schneider <jan@horde.org>
*/
class SOAP_Transport extends SOAP_Base
{
/**
* Connection endpoint URL.
*
* @var string
*/
var $url = '';
/**
* Array containing urlparts.
*
* @see parse_url()
*
* @var mixed
*/
var $urlparts = null;
/**
* Incoming payload.
*
* @var string
*/
var $incoming_payload = '';
/**
* Outgoing payload.
*
* @var string
*/
var $outgoing_payload = '';
/**
* Request encoding.
*
* @var string
*/
var $encoding = SOAP_DEFAULT_ENCODING;
/**
* Response encoding.
*
* We assume UTF-8 if no encoding is set.
*
* @var string
*/
var $result_encoding = 'UTF-8';
/**
* Decoded attachments from the reponse.
*
* @var array
*/
var $attachments;
/**
* Request User-Agent.
*
* @var string
*/
var $_userAgent = SOAP_LIBRARY_NAME;
/**
* Sends and receives SOAP data.
*
* @access public
* @abstract
*
* @param string Outgoing SOAP data.
* @param array Options.
*
* @return string|SOAP_Fault
*/
function send($msg, $options = null)
{
return $this->_raiseSoapFault('SOAP_Transport::send() not implemented.');
}
static function &getTransport($url, $encoding = SOAP_DEFAULT_ENCODING)
{
$urlparts = @parse_url($url);
if (!$urlparts['scheme']) {
- $fault = SOAP_Base_Object::_raiseSoapFault("Invalid transport URI: $url");
+ $soap_base = new SOAP_Base_Object();
+ $fault = $soap_base->_raiseSoapFault("Invalid transport URI: $url");
return $fault;
}
if (strcasecmp($urlparts['scheme'], 'mailto') == 0) {
$transport_type = 'SMTP';
} elseif (strcasecmp($urlparts['scheme'], 'https') == 0) {
$transport_type = 'HTTP';
} else {
/* Handle other transport types */
$transport_type = strtoupper($urlparts['scheme']);
}
$transport_include = 'SOAP/Transport/' . basename($transport_type) . '.php';
$res = @include_once($transport_include);
if (!$res) {
$fault = SOAP_Base_Object::_raiseSoapFault("No Transport for {$urlparts['scheme']}");
return $fault;
}
$transport_class = "SOAP_Transport_$transport_type";
if (!class_exists($transport_class)) {
$fault = SOAP_Base_Object::_raiseSoapFault("No Transport class $transport_class");
return $fault;
}
$t =new $transport_class($url, $encoding);
return $t;
}
}
diff --git a/library/SOAP/Transport/HTTP.php b/library/SOAP/Transport/HTTP.php
index b47ccea..0e1924c 100644
--- a/library/SOAP/Transport/HTTP.php
+++ b/library/SOAP/Transport/HTTP.php
@@ -1,620 +1,621 @@
<?php
/**
* This file contains the code for a HTTP transport layer.
*
* 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 Shane Caraveo <Shane@Caraveo.com>
* @author Jan Schneider <jan@horde.org>
* @copyright 2003-2006 The PHP Group
* @license http://www.php.net/license/2_02.txt PHP License 2.02
* @link http://pear.php.net/package/SOAP
*/
/**
* HTTP Transport class
*
* @package SOAP
* @category Web_Services
*/
/**
* Needed Classes
*/
require_once 'SOAP/Transport.php';
/**
* HTTP Transport for SOAP
*
* @access public
* @package SOAP
* @author Shane Caraveo <shane@php.net>
* @author Jan Schneider <jan@horde.org>
*/
class SOAP_Transport_HTTP extends SOAP_Transport
{
/**
* Basic Auth string.
*
* @var array
*/
var $headers = array();
/**
* Cookies.
*
* @var array
*/
var $cookies;
/**
* Connection timeout in seconds. 0 = none.
*
* @var integer
*/
var $timeout = 4;
/**
* HTTP-Response Content-Type.
*/
var $result_content_type;
var $result_headers = array();
var $result_cookies = array();
/**
* SOAP_Transport_HTTP Constructor
*
* @access public
*
* @param string $url HTTP url to SOAP endpoint.
* @param string $encoding Encoding to use.
*/
function __construct($url, $encoding = SOAP_DEFAULT_ENCODING)
{
parent::SOAP_Base('HTTP');
$this->urlparts = @parse_url($url);
$this->url = $url;
$this->encoding = $encoding;
}
/**
* Sends and receives SOAP data.
*
* @access public
*
* @param string Outgoing SOAP data.
* @param array Options.
*
* @return string|SOAP_Fault
*/
function send($msg, $options = array())
{
$this->fault = null;
if (!$this->_validateUrl()) {
return $this->fault;
}
if (isset($options['timeout'])) {
$this->timeout = (int)$options['timeout'];
}
- if (strcasecmp($this->urlparts['scheme'], 'HTTP') == 0) {
+ if (strcasecmp($this->urlparts['scheme'], 'HTTP') == 0) {
return $this->_sendHTTP($msg, $options);
} elseif (strcasecmp($this->urlparts['scheme'], 'HTTPS') == 0) {
return $this->_sendHTTPS($msg, $options);
}
return $this->_raiseSoapFault('Invalid url scheme ' . $this->url);
}
/**
* Sets data for HTTP authentication, creates authorization header.
*
* @param string $username Username.
* @param string $password Response data, minus HTTP headers.
*
* @access public
*/
function setCredentials($username, $password)
{
$this->headers['Authorization'] = 'Basic ' . base64_encode($username . ':' . $password);
}
/**
* Adds a cookie.
*
* @access public
* @param string $name Cookie name.
* @param mixed $value Cookie value.
*/
function addCookie($name, $value)
{
$this->cookies[$name] = $value;
}
/**
* Generates the correct headers for the cookies.
*
* @access private
*
* @param array $options Cookie options. If 'nocookies' is set and true
* the cookies from the last response are added
* automatically. 'cookies' is name-value-hash with
* a list of cookies to add.
*
* @return string The cookie header value.
*/
function _generateCookieHeader($options)
{
$this->cookies = array();
if (empty($options['nocookies']) &&
isset($this->result_cookies)) {
// Add the cookies we got from the last request.
foreach ($this->result_cookies as $cookie) {
if ($cookie['domain'] == $this->urlparts['host']) {
$this->cookies[$cookie['name']] = $cookie['value'];
}
}
}
// Add cookies the user wants to set.
if (isset($options['cookies'])) {
foreach ($options['cookies'] as $cookie) {
if ($cookie['domain'] == $this->urlparts['host']) {
$this->cookies[$cookie['name']] = $cookie['value'];
}
}
}
$cookies = '';
foreach ($this->cookies as $name => $value) {
if (!empty($cookies)) {
$cookies .= '; ';
}
$cookies .= urlencode($name) . '=' . urlencode($value);
}
return $cookies;
}
/**
* Validate url data passed to constructor.
*
* @access private
* @return boolean
*/
function _validateUrl()
{
if (!is_array($this->urlparts) ) {
$this->_raiseSoapFault('Unable to parse URL ' . $this->url);
return false;
}
if (!isset($this->urlparts['host'])) {
$this->_raiseSoapFault('No host in URL ' . $this->url);
return false;
}
if (!isset($this->urlparts['port'])) {
if (strcasecmp($this->urlparts['scheme'], 'HTTP') == 0) {
$this->urlparts['port'] = 80;
} elseif (strcasecmp($this->urlparts['scheme'], 'HTTPS') == 0) {
$this->urlparts['port'] = 443;
}
}
if (isset($this->urlparts['user'])) {
$this->setCredentials(urldecode($this->urlparts['user']),
urldecode($this->urlparts['pass']));
}
if (!isset($this->urlparts['path']) || !$this->urlparts['path']) {
$this->urlparts['path'] = '/';
}
return true;
}
/**
* Finds out what the encoding is.
* Sets the object property accordingly.
*
* @access private
* @param array $headers Headers.
*/
function _parseEncoding($headers)
{
$h = stristr($headers, 'Content-Type');
preg_match_all('/^Content-Type:\s*(.*)$/im', $h, $ct, PREG_SET_ORDER);
$n = count($ct);
$ct = $ct[$n - 1];
// Strip the string of \r.
$this->result_content_type = str_replace("\r", '', $ct[1]);
if (preg_match('/(.*?)(?:;\s?charset=)(.*)/i',
$this->result_content_type,
$m)) {
$this->result_content_type = $m[1];
if (count($m) > 2) {
$enc = strtoupper(str_replace('"', '', $m[2]));
if (in_array($enc, $this->_encodings)) {
$this->result_encoding = $enc;
}
}
}
// Deal with broken servers that don't set content type on faults.
if (!$this->result_content_type) {
$this->result_content_type = 'text/xml';
}
}
/**
* Parses the headers.
*
* @param array $headers The headers.
*/
function _parseHeaders($headers)
{
/* Largely borrowed from HTTP_Request. */
$this->result_headers = array();
$headers = preg_split("/\r?\n/", $headers);
foreach ($headers as $value) {
if (strpos($value,':') === false) {
$this->result_headers[0] = $value;
continue;
}
list($name, $value) = preg_split('/:/', $value);
$headername = strtolower($name);
$headervalue = trim($value);
$this->result_headers[$headername] = $headervalue;
if ($headername == 'set-cookie') {
// Parse a SetCookie header to fill _cookies array.
$cookie = array('expires' => null,
'domain' => $this->urlparts['host'],
'path' => null,
'secure' => false);
if (!strpos($headervalue, ';')) {
// Only a name=value pair.
list($cookie['name'], $cookie['value']) = array_map('trim', explode('=', $headervalue));
$cookie['name'] = urldecode($cookie['name']);
$cookie['value'] = urldecode($cookie['value']);
} else {
// Some optional parameters are supplied.
$elements = explode(';', $headervalue);
list($cookie['name'], $cookie['value']) = array_map('trim', explode('=', $elements[0]));
$cookie['name'] = urldecode($cookie['name']);
$cookie['value'] = urldecode($cookie['value']);
for ($i = 1; $i < count($elements);$i++) {
list($elName, $elValue) = array_map('trim', explode('=', $elements[$i]));
if ('secure' == $elName) {
$cookie['secure'] = true;
} elseif ('expires' == $elName) {
$cookie['expires'] = str_replace('"', '', $elValue);
} elseif ('path' == $elName OR 'domain' == $elName) {
$cookie[$elName] = urldecode($elValue);
} else {
$cookie[$elName] = $elValue;
}
}
}
$this->result_cookies[] = $cookie;
}
}
}
/**
* Removes HTTP headers from response.
*
* @return boolean
* @access private
*/
function _parseResponse()
{
if (preg_match("/^(.*?)\r?\n\r?\n(.*)/s",
$this->incoming_payload,
$match)) {
- $this->response = $match[2];
+ $this->response = $match[2];
// Find the response error, some servers response with 500 for
// SOAP faults.
- $this->_parseHeaders($match[1]);
+ $this->_parseHeaders($match[1]);
list(, $code, $msg) = sscanf($this->result_headers[0], '%s %s %s');
- unset($this->result_headers[0]);
+ unset($this->result_headers[0]);
switch($code) {
case 100: // Continue
$this->incoming_payload = $match[2];
return $this->_parseResponse();
case 400:
$this->_raiseSoapFault("HTTP Response $code Bad Request");
return false;
break;
case 401:
$this->_raiseSoapFault("HTTP Response $code Authentication Failed");
return false;
break;
case 403:
$this->_raiseSoapFault("HTTP Response $code Forbidden");
return false;
break;
case 404:
$this->_raiseSoapFault("HTTP Response $code Not Found");
return false;
break;
case 407:
$this->_raiseSoapFault("HTTP Response $code Proxy Authentication Required");
return false;
break;
case 408:
$this->_raiseSoapFault("HTTP Response $code Request Timeout");
return false;
break;
case 410:
$this->_raiseSoapFault("HTTP Response $code Gone");
return false;
break;
default:
if ($code >= 400 && $code < 500) {
$this->_raiseSoapFault("HTTP Response $code Not Found, Server message: $msg");
return false;
}
}
$this->_parseEncoding($match[1]);
if ($this->result_content_type == 'application/dime') {
// XXX quick hack insertion of DIME
if (PEAR::isError($this->_decodeDIMEMessage($this->response, $this->headers, $this->attachments))) {
// _decodeDIMEMessage already raised $this->fault
return false;
}
$this->result_content_type = $this->headers['content-type'];
} elseif (stristr($this->result_content_type, 'multipart/related')) {
$this->response = $this->incoming_payload;
if (PEAR::isError($this->_decodeMimeMessage($this->response, $this->headers, $this->attachments))) {
// _decodeMimeMessage already raised $this->fault
return false;
}
} elseif ($this->result_content_type != 'text/xml') {
$this->_raiseSoapFault($this->response);
return false;
}
// if no content, return false
return strlen($this->response) > 0;
}
$this->_raiseSoapFault('Invalid HTTP Response');
return false;
}
/**
* Creates an HTTP request, including headers, for the outgoing request.
*
* @access private
*
* @param string $msg Outgoing SOAP package.
* @param array $options Options.
*
* @return string Outgoing payload.
*/
function _getRequest($msg, $options)
{
$this->headers = array();
$action = isset($options['soapaction']) ? $options['soapaction'] : '';
$fullpath = $this->urlparts['path'];
if (isset($this->urlparts['query'])) {
$fullpath .= '?' . $this->urlparts['query'];
}
if (isset($this->urlparts['fragment'])) {
$fullpath .= '#' . $this->urlparts['fragment'];
}
if (isset($options['proxy_host'])) {
$fullpath = 'http://' . $this->urlparts['host'] . ':' .
$this->urlparts['port'] . $fullpath;
}
if (isset($options['proxy_user'])) {
$this->headers['Proxy-Authorization'] = 'Basic ' .
base64_encode($options['proxy_user'] . ':' .
$options['proxy_pass']);
}
if (isset($options['user'])) {
$this->setCredentials($options['user'], $options['pass']);
}
$this->headers['User-Agent'] = $this->_userAgent;
$this->headers['Host'] = $this->urlparts['host'];
$this->headers['Content-Type'] = "text/xml; charset=$this->encoding";
$this->headers['Content-Length'] = strlen($msg);
$this->headers['SOAPAction'] = '"' . $action . '"';
$this->headers['Connection'] = 'close';
if (isset($options['headers'])) {
$this->headers = array_merge($this->headers, $options['headers']);
}
$cookies = $this->_generateCookieHeader($options);
if ($cookies) {
$this->headers['Cookie'] = $cookies;
}
$headers = '';
foreach ($this->headers as $k => $v) {
$headers .= "$k: $v\r\n";
}
$this->outgoing_payload = "POST $fullpath HTTP/1.0\r\n" . $headers .
"\r\n" . $msg;
return $this->outgoing_payload;
}
/**
* Sends the outgoing HTTP request and reads and parses the response.
*
* @access private
*
* @param string $msg Outgoing SOAP package.
* @param array $options Options.
*
* @return string Response data without HTTP headers.
*/
function _sendHTTP($msg, $options)
{
$this->incoming_payload = '';
$this->_getRequest($msg, $options);
$host = $this->urlparts['host'];
$port = $this->urlparts['port'];
if (isset($options['proxy_host'])) {
$host = $options['proxy_host'];
$port = isset($options['proxy_port']) ? $options['proxy_port'] : 8080;
- }
+ }
+
// Send.
if ($this->timeout > 0) {
$fp = @fsockopen($host, $port, $this->errno, $this->errmsg, $this->timeout);
} else {
$fp = @fsockopen($host, $port, $this->errno, $this->errmsg);
}
if (!$fp) {
return $this->_raiseSoapFault("Connect Error to $host:$port");
}
if ($this->timeout > 0) {
// some builds of PHP do not support this, silence the warning
@socket_set_timeout($fp, $this->timeout);
}
if (!fputs($fp, $this->outgoing_payload, strlen($this->outgoing_payload))) {
return $this->_raiseSoapFault("Error POSTing Data to $host");
- }
+ }
// get reponse
// XXX time consumer
do {
$data = fread($fp, 4096);
$_tmp_status = socket_get_status($fp);
- if ($_tmp_status['timed_out']) {
+ if ($_tmp_status['timed_out']) {
return $this->_raiseSoapFault("Timed out read from $host");
} else {
$this->incoming_payload .= $data;
}
} while (!$_tmp_status['eof']);
fclose($fp);
if (!$this->_parseResponse()) {
return $this->fault;
}
return $this->response;
}
/**
* Sends the outgoing HTTPS request and reads and parses the response.
*
* @access private
*
* @param string $msg Outgoing SOAP package.
* @param array $options Options.
*
* @return string Response data without HTTP headers.
*/
function _sendHTTPS($msg, $options)
{
/* Check if the required curl extension is installed. */
if (!extension_loaded('curl')) {
return $this->_raiseSoapFault('CURL Extension is required for HTTPS');
}
$ch = curl_init();
if (isset($options['proxy_host'])) {
$port = isset($options['proxy_port']) ? $options['proxy_port'] : 8080;
curl_setopt($ch, CURLOPT_PROXY,
$options['proxy_host'] . ':' . $port);
}
if (isset($options['proxy_user'])) {
curl_setopt($ch, CURLOPT_PROXYUSERPWD,
$options['proxy_user'] . ':' . $options['proxy_pass']);
}
if (isset($options['user'])) {
curl_setopt($ch, CURLOPT_USERPWD,
$options['user'] . ':' . $options['pass']);
}
if (!isset($options['soapaction'])) {
$options['soapaction'] = '';
}
if (!isset($options['headers']['Content-Type'])) {
$options['headers']['Content-Type'] = 'text/xml';
}
curl_setopt($ch, CURLOPT_HTTPHEADER,
array('Content-Type: ' . $options['headers']['Content-Type']
. ';charset=' . $this->encoding,
'SOAPAction: "' . $options['soapaction'] . '"'));
curl_setopt($ch, CURLOPT_USERAGENT,
$this->_userAgent);
if ($this->timeout) {
curl_setopt($ch, CURLOPT_TIMEOUT, $this->timeout);
}
curl_setopt($ch, CURLOPT_POSTFIELDS, $msg);
curl_setopt($ch, CURLOPT_URL, $this->url);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_FAILONERROR, 0);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_HEADER, 1);
if (defined('CURLOPT_HTTP_VERSION')) {
curl_setopt($ch, CURLOPT_HTTP_VERSION, 1);
}
if (!ini_get('safe_mode') && !ini_get('open_basedir')) {
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1);
}
$cookies = $this->_generateCookieHeader($options);
if ($cookies) {
curl_setopt($ch, CURLOPT_COOKIE, $cookies);
}
if (isset($options['curl'])) {
foreach ($options['curl'] as $key => $val) {
curl_setopt($ch, $key, $val);
}
}
// Save the outgoing XML. This doesn't quite match _sendHTTP as CURL
// generates the headers, but having the XML is usually the most
// important part for tracing/debugging.
$this->outgoing_payload = $msg;
$this->incoming_payload = curl_exec($ch);
if (!$this->incoming_payload) {
$m = 'curl_exec error ' . curl_errno($ch) . ' ' . curl_error($ch);
curl_close($ch);
return $this->_raiseSoapFault($m);
}
curl_close($ch);
if (!$this->_parseResponse()) {
return $this->fault;
}
return $this->response;
}
}
File Metadata
Details
Attached
Mime Type
text/x-diff
Expires
Tue, Nov 26, 4:45 AM (1 d, 19 h)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
3414143
Default Alt Text
(93 KB)
Attached To
Mode
rCDRT CDRTool
Attached
Detach File
Event Timeline
Log In to Comment