* timed_out (bool) - The socket timed out waiting for data
* blocked (bool) - The socket was blocked
* eof (bool) - Indicates EOF event
* unread_bytes (int) - Number of bytes left in the socket buffer
*
* $server = new XML_RPC_Server(
* array(
* 'isan8' =>
* array(
* 'function' => 'is_8',
* 'signature' =>
* array(
* array('boolean', 'int'),
* array('boolean', 'int', 'boolean'),
* array('boolean', 'string'),
* array('boolean', 'string', 'boolean'),
* ),
* 'docstring' => 'Is the value an 8?'
* ),
* ),
* 1,
* 0
* );
*
*
* @category Web Services
* @package XML_RPC
* @author Edd Dumbill
* require_once 'XML/Util.php';
*
* // replace XML entites:
* $string = XML_Util::replaceEntities('This string contains < & >.');
*
*
* With the optional third parameter, you may pass the character encoding
*
* require_once 'XML/Util.php';
*
* // replace XML entites in UTF-8:
* $string = XML_Util::replaceEntities(
* 'This string contains < & > as well as ä, ö, ß, à and ê',
* XML_UTIL_ENTITIES_HTML,
* 'UTF-8'
* );
*
*
* @param string $string string where XML special chars
* should be replaced
* @param int $replaceEntities setting for entities in attribute values
* (one of XML_UTIL_ENTITIES_XML,
* XML_UTIL_ENTITIES_XML_REQUIRED,
* XML_UTIL_ENTITIES_HTML)
* @param string $encoding encoding value (if any)...
* must be a valid encoding as determined
* by the htmlentities() function
*
* @return string string with replaced chars
* @see reverseEntities()
*/
public static function replaceEntities(
$string, $replaceEntities = XML_UTIL_ENTITIES_XML, $encoding = 'ISO-8859-1'
) {
switch ($replaceEntities) {
case XML_UTIL_ENTITIES_XML:
return strtr(
$string,
array(
'&' => '&',
'>' => '>',
'<' => '<',
'"' => '"',
'\'' => '''
)
);
break;
case XML_UTIL_ENTITIES_XML_REQUIRED:
return strtr(
$string,
array(
'&' => '&',
'<' => '<',
'"' => '"'
)
);
break;
case XML_UTIL_ENTITIES_HTML:
return htmlentities($string, ENT_COMPAT, $encoding);
break;
}
return $string;
}
/**
* Reverse XML entities
*
* With the optional second parameter, you may select, which
* entities should be reversed.
*
*
* require_once 'XML/Util.php';
*
* // reverse XML entites:
* $string = XML_Util::reverseEntities('This string contains < & >.');
*
*
* With the optional third parameter, you may pass the character encoding
*
* require_once 'XML/Util.php';
*
* // reverse XML entites in UTF-8:
* $string = XML_Util::reverseEntities(
* 'This string contains < & > as well as'
* . ' ä, ö, ß, à and ê',
* XML_UTIL_ENTITIES_HTML,
* 'UTF-8'
* );
*
*
* @param string $string string where XML special chars
* should be replaced
* @param int $replaceEntities setting for entities in attribute values
* (one of XML_UTIL_ENTITIES_XML,
* XML_UTIL_ENTITIES_XML_REQUIRED,
* XML_UTIL_ENTITIES_HTML)
* @param string $encoding encoding value (if any)...
* must be a valid encoding as determined
* by the html_entity_decode() function
*
* @return string string with replaced chars
* @see replaceEntities()
*/
public static function reverseEntities(
$string, $replaceEntities = XML_UTIL_ENTITIES_XML, $encoding = 'ISO-8859-1'
) {
switch ($replaceEntities) {
case XML_UTIL_ENTITIES_XML:
return strtr(
$string,
array(
'&' => '&',
'>' => '>',
'<' => '<',
'"' => '"',
''' => '\''
)
);
break;
case XML_UTIL_ENTITIES_XML_REQUIRED:
return strtr(
$string,
array(
'&' => '&',
'<' => '<',
'"' => '"'
)
);
break;
case XML_UTIL_ENTITIES_HTML:
return html_entity_decode($string, ENT_COMPAT, $encoding);
break;
}
return $string;
}
/**
* Build an xml declaration
*
*
* require_once 'XML/Util.php';
*
* // get an XML declaration:
* $xmlDecl = XML_Util::getXMLDeclaration('1.0', 'UTF-8', true);
*
*
* @param string $version xml version
* @param string $encoding character encoding
* @param bool $standalone document is standalone (or not)
*
* @return string xml declaration
* @uses attributesToString() to serialize the attributes of the
* XML declaration
*/
public static function getXMLDeclaration(
$version = '1.0', $encoding = null, $standalone = null
) {
$attributes = array(
'version' => $version,
);
// add encoding
if ($encoding !== null) {
$attributes['encoding'] = $encoding;
}
// add standalone, if specified
if ($standalone !== null) {
$attributes['standalone'] = $standalone ? 'yes' : 'no';
}
return sprintf(
'',
XML_Util::attributesToString($attributes, false)
);
}
/**
* Build a document type declaration
*
*
* require_once 'XML/Util.php';
*
* // get a doctype declaration:
* $xmlDecl = XML_Util::getDocTypeDeclaration('rootTag','myDocType.dtd');
*
*
* @param string $root name of the root tag
* @param string $uri uri of the doctype definition
* (or array with uri and public id)
* @param string $internalDtd internal dtd entries
*
* @return string doctype declaration
* @since 0.2
*/
public static function getDocTypeDeclaration(
$root, $uri = null, $internalDtd = null
) {
if (is_array($uri)) {
$ref = sprintf(' PUBLIC "%s" "%s"', $uri['id'], $uri['uri']);
} elseif (!empty($uri)) {
$ref = sprintf(' SYSTEM "%s"', $uri);
} else {
$ref = '';
}
if (empty($internalDtd)) {
return sprintf('', $root, $ref);
} else {
return sprintf("", $root, $ref, $internalDtd);
}
}
/**
* Create string representation of an attribute list
*
*
* require_once 'XML/Util.php';
*
* // build an attribute string
* $att = array(
* 'foo' => 'bar',
* 'argh' => 'tomato'
* );
*
* $attList = XML_Util::attributesToString($att);
*
*
* @param array $attributes attribute array
* @param bool|array $sort sort attribute list alphabetically,
* may also be an assoc array containing
* the keys 'sort', 'multiline', 'indent',
* 'linebreak' and 'entities'
* @param bool $multiline use linebreaks, if more than
* one attribute is given
* @param string $indent string used for indentation of
* multiline attributes
* @param string $linebreak string used for linebreaks of
* multiline attributes
* @param int $entities setting for entities in attribute values
* (one of XML_UTIL_ENTITIES_NONE,
* XML_UTIL_ENTITIES_XML,
* XML_UTIL_ENTITIES_XML_REQUIRED,
* XML_UTIL_ENTITIES_HTML)
*
* @return string string representation of the attributes
* @uses replaceEntities() to replace XML entities in attribute values
* @todo allow sort also to be an options array
*/
public static function attributesToString(
$attributes, $sort = true, $multiline = false,
$indent = ' ', $linebreak = "\n", $entities = XML_UTIL_ENTITIES_XML
) {
/*
* second parameter may be an array
*/
if (is_array($sort)) {
if (isset($sort['multiline'])) {
$multiline = $sort['multiline'];
}
if (isset($sort['indent'])) {
$indent = $sort['indent'];
}
if (isset($sort['linebreak'])) {
$multiline = $sort['linebreak'];
}
if (isset($sort['entities'])) {
$entities = $sort['entities'];
}
if (isset($sort['sort'])) {
$sort = $sort['sort'];
} else {
$sort = true;
}
}
$string = '';
if (is_array($attributes) && !empty($attributes)) {
if ($sort) {
ksort($attributes);
}
if (!$multiline || count($attributes) == 1) {
foreach ($attributes as $key => $value) {
if ($entities != XML_UTIL_ENTITIES_NONE) {
if ($entities === XML_UTIL_CDATA_SECTION) {
$entities = XML_UTIL_ENTITIES_XML;
}
$value = XML_Util::replaceEntities($value, $entities);
}
$string .= ' ' . $key . '="' . $value . '"';
}
} else {
$first = true;
foreach ($attributes as $key => $value) {
if ($entities != XML_UTIL_ENTITIES_NONE) {
$value = XML_Util::replaceEntities($value, $entities);
}
if ($first) {
$string .= ' ' . $key . '="' . $value . '"';
$first = false;
} else {
$string .= $linebreak . $indent . $key . '="' . $value . '"';
}
}
}
}
return $string;
}
/**
* Collapses empty tags.
*
* @param string $xml XML
* @param int $mode Whether to collapse all empty tags (XML_UTIL_COLLAPSE_ALL)
* or only XHTML (XML_UTIL_COLLAPSE_XHTML_ONLY) ones.
*
* @return string XML
*/
public static function collapseEmptyTags($xml, $mode = XML_UTIL_COLLAPSE_ALL)
{
if (preg_match('~<([^>])+/>~s', $xml, $matches)) {
// it's already an empty tag
return $xml;
}
switch ($mode) {
case XML_UTIL_COLLAPSE_ALL:
$preg1 =
'~<' .
'(?:' .
'(https?://[^:\s]+:\w+)' . //
* require_once 'XML/Util.php';
*
* // create an XML tag:
* $tag = XML_Util::createTag('myNs:myTag',
* array('foo' => 'bar'),
* 'This is inside the tag',
* 'http://www.w3c.org/myNs#');
*
*
* @param string $qname qualified tagname (including namespace)
* @param array $attributes array containg attributes
* @param mixed $content the content
* @param string $namespaceUri URI of the namespace
* @param int $replaceEntities whether to replace XML special chars in
* content, embedd it in a CData section
* or none of both
* @param bool $multiline whether to create a multiline tag where
* each attribute gets written to a single line
* @param string $indent string used to indent attributes
* (_auto indents attributes so they start
* at the same column)
* @param string $linebreak string used for linebreaks
* @param bool $sortAttributes Whether to sort the attributes or not
* @param int $collapseTagMode How to handle a content-less, and thus collapseable, tag
*
* @return string XML tag
* @see createTagFromArray()
* @uses createTagFromArray() to create the tag
*/
public static function createTag(
$qname, $attributes = array(), $content = null,
$namespaceUri = null, $replaceEntities = XML_UTIL_REPLACE_ENTITIES,
$multiline = false, $indent = '_auto', $linebreak = "\n",
$sortAttributes = true, $collapseTagMode = XML_UTIL_COLLAPSE_ALL
) {
$tag = array(
'qname' => $qname,
'attributes' => $attributes
);
// add tag content
if ($content !== null) {
$tag['content'] = $content;
}
// add namespace Uri
if ($namespaceUri !== null) {
$tag['namespaceUri'] = $namespaceUri;
}
return XML_Util::createTagFromArray(
$tag, $replaceEntities, $multiline,
$indent, $linebreak, $sortAttributes,
$collapseTagMode
);
}
/**
* Create a tag from an array.
* This method awaits an array in the following format
*
* array(
* // qualified name of the tag
* 'qname' => $qname
*
* // namespace prefix (optional, if qname is specified or no namespace)
* 'namespace' => $namespace
*
* // local part of the tagname (optional, if qname is specified)
* 'localpart' => $localpart,
*
* // array containing all attributes (optional)
* 'attributes' => array(),
*
* // tag content (optional)
* 'content' => $content,
*
* // namespaceUri for the given namespace (optional)
* 'namespaceUri' => $namespaceUri
* )
*
*
*
* require_once 'XML/Util.php';
*
* $tag = array(
* 'qname' => 'foo:bar',
* 'namespaceUri' => 'http://foo.com',
* 'attributes' => array('key' => 'value', 'argh' => 'fruit&vegetable'),
* 'content' => 'I\'m inside the tag',
* );
* // creating a tag with qualified name and namespaceUri
* $string = XML_Util::createTagFromArray($tag);
*
*
* @param array $tag tag definition
* @param int $replaceEntities whether to replace XML special chars in
* content, embedd it in a CData section
* or none of both
* @param bool $multiline whether to create a multiline tag where each
* attribute gets written to a single line
* @param string $indent string used to indent attributes
* (_auto indents attributes so they start
* at the same column)
* @param string $linebreak string used for linebreaks
* @param bool $sortAttributes Whether to sort the attributes or not
* @param int $collapseTagMode How to handle a content-less, and thus collapseable, tag
*
* @return string XML tag
*
* @see createTag()
* @uses attributesToString() to serialize the attributes of the tag
* @uses splitQualifiedName() to get local part and namespace of a qualified name
* @uses createCDataSection()
* @uses collapseEmptyTags()
* @uses raiseError()
*/
public static function createTagFromArray(
$tag, $replaceEntities = XML_UTIL_REPLACE_ENTITIES,
$multiline = false, $indent = '_auto', $linebreak = "\n",
$sortAttributes = true, $collapseTagMode = XML_UTIL_COLLAPSE_ALL
) {
if (isset($tag['content']) && !is_scalar($tag['content'])) {
return XML_Util::raiseError(
'Supplied non-scalar value as tag content',
XML_UTIL_ERROR_NON_SCALAR_CONTENT
);
}
if (!isset($tag['qname']) && !isset($tag['localPart'])) {
return XML_Util::raiseError(
'You must either supply a qualified name '
. '(qname) or local tag name (localPart).',
XML_UTIL_ERROR_NO_TAG_NAME
);
}
// if no attributes hav been set, use empty attributes
if (!isset($tag['attributes']) || !is_array($tag['attributes'])) {
$tag['attributes'] = array();
}
if (isset($tag['namespaces'])) {
foreach ($tag['namespaces'] as $ns => $uri) {
$tag['attributes']['xmlns:' . $ns] = $uri;
}
}
if (!isset($tag['qname'])) {
// qualified name is not given
// check for namespace
if (isset($tag['namespace']) && !empty($tag['namespace'])) {
$tag['qname'] = $tag['namespace'] . ':' . $tag['localPart'];
} else {
$tag['qname'] = $tag['localPart'];
}
} elseif (isset($tag['namespaceUri']) && !isset($tag['namespace'])) {
// namespace URI is set, but no namespace
$parts = XML_Util::splitQualifiedName($tag['qname']);
$tag['localPart'] = $parts['localPart'];
if (isset($parts['namespace'])) {
$tag['namespace'] = $parts['namespace'];
}
}
if (isset($tag['namespaceUri']) && !empty($tag['namespaceUri'])) {
// is a namespace given
if (isset($tag['namespace']) && !empty($tag['namespace'])) {
$tag['attributes']['xmlns:' . $tag['namespace']]
= $tag['namespaceUri'];
} else {
// define this Uri as the default namespace
$tag['attributes']['xmlns'] = $tag['namespaceUri'];
}
}
if (!array_key_exists('content', $tag)) {
$tag['content'] = '';
}
// check for multiline attributes
if ($multiline === true) {
if ($indent === '_auto') {
$indent = str_repeat(' ', (strlen($tag['qname'])+2));
}
}
// create attribute list
$attList = XML_Util::attributesToString(
$tag['attributes'],
$sortAttributes, $multiline, $indent, $linebreak
);
switch ($replaceEntities) {
case XML_UTIL_ENTITIES_NONE:
break;
case XML_UTIL_CDATA_SECTION:
$tag['content'] = XML_Util::createCDataSection($tag['content']);
break;
default:
$tag['content'] = XML_Util::replaceEntities(
$tag['content'], $replaceEntities
);
break;
}
$tag = sprintf(
'<%s%s>%s%s>', $tag['qname'], $attList, $tag['content'],
$tag['qname']
);
return self::collapseEmptyTags($tag, $collapseTagMode);
}
/**
* Create a start element
*
*
* require_once 'XML/Util.php';
*
* // create an XML start element:
* $tag = XML_Util::createStartElement('myNs:myTag',
* array('foo' => 'bar') ,'http://www.w3c.org/myNs#');
*
*
* @param string $qname qualified tagname (including namespace)
* @param array $attributes array containg attributes
* @param string $namespaceUri URI of the namespace
* @param bool $multiline whether to create a multiline tag where each
* attribute gets written to a single line
* @param string $indent string used to indent attributes (_auto indents
* attributes so they start at the same column)
* @param string $linebreak string used for linebreaks
* @param bool $sortAttributes Whether to sort the attributes or not
*
* @return string XML start element
* @see createEndElement(), createTag()
*/
public static function createStartElement(
$qname, $attributes = array(), $namespaceUri = null,
$multiline = false, $indent = '_auto', $linebreak = "\n",
$sortAttributes = true
) {
// if no attributes hav been set, use empty attributes
if (!isset($attributes) || !is_array($attributes)) {
$attributes = array();
}
if ($namespaceUri != null) {
$parts = XML_Util::splitQualifiedName($qname);
}
// check for multiline attributes
if ($multiline === true) {
if ($indent === '_auto') {
$indent = str_repeat(' ', (strlen($qname)+2));
}
}
if ($namespaceUri != null) {
// is a namespace given
if (isset($parts['namespace']) && !empty($parts['namespace'])) {
$attributes['xmlns:' . $parts['namespace']] = $namespaceUri;
} else {
// define this Uri as the default namespace
$attributes['xmlns'] = $namespaceUri;
}
}
// create attribute list
$attList = XML_Util::attributesToString(
$attributes, $sortAttributes,
$multiline, $indent, $linebreak
);
$element = sprintf('<%s%s>', $qname, $attList);
return $element;
}
/**
* Create an end element
*
*
* require_once 'XML/Util.php';
*
* // create an XML start element:
* $tag = XML_Util::createEndElement('myNs:myTag');
*
*
* @param string $qname qualified tagname (including namespace)
*
* @return string XML end element
* @see createStartElement(), createTag()
*/
public static function createEndElement($qname)
{
$element = sprintf('%s>', $qname);
return $element;
}
/**
* Create an XML comment
*
*
* require_once 'XML/Util.php';
*
* // create an XML start element:
* $tag = XML_Util::createComment('I am a comment');
*
*
* @param string $content content of the comment
*
* @return string XML comment
*/
public static function createComment($content)
{
$comment = sprintf('', $content);
return $comment;
}
/**
* Create a CData section
*
*
* require_once 'XML/Util.php';
*
* // create a CData section
* $tag = XML_Util::createCDataSection('I am content.');
*
*
* @param string $data data of the CData section
*
* @return string CData section with content
*/
public static function createCDataSection($data)
{
return sprintf(
'',
preg_replace('/\]\]>/', ']]]]>', strval($data))
);
}
/**
* Split qualified name and return namespace and local part
*
*
* require_once 'XML/Util.php';
*
* // split qualified tag
* $parts = XML_Util::splitQualifiedName('xslt:stylesheet');
*
* the returned array will contain two elements:
*
* array(
* 'namespace' => 'xslt',
* 'localPart' => 'stylesheet'
* );
*
*
* @param string $qname qualified tag name
* @param string $defaultNs default namespace (optional)
*
* @return array array containing namespace and local part
*/
public static function splitQualifiedName($qname, $defaultNs = null)
{
if (strstr($qname, ':')) {
$tmp = explode(':', $qname);
return array(
'namespace' => $tmp[0],
'localPart' => $tmp[1]
);
}
return array(
'namespace' => $defaultNs,
'localPart' => $qname
);
}
/**
* Check, whether string is valid XML name
*
* XML names are used for tagname, attribute names and various * other, lesser known entities.
*An XML name may only consist of alphanumeric characters, * dashes, undescores and periods, and has to start with a letter * or an underscore.
* *
* require_once 'XML/Util.php';
*
* // verify tag name
* $result = XML_Util::isValidName('invalidTag?');
* if (is_a($result, 'PEAR_Error')) {
* print 'Invalid XML name: ' . $result->getMessage();
* }
*
*
* @param string $string string that should be checked
*
* @return mixed true, if string is a valid XML name, PEAR error otherwise
*
* @todo support for other charsets
* @todo PEAR CS - unable to avoid 85-char limit on second preg_match
*/
public static function isValidName($string)
{
// check for invalid chars
if (!is_string($string) || !strlen($string) || !preg_match('/^[[:alpha:]_]\\z/', $string[0])) {
return XML_Util::raiseError(
'XML names may only start with letter or underscore',
XML_UTIL_ERROR_INVALID_START
);
}
// check for invalid chars
$match = preg_match(
'/^([[:alpha:]_]([[:alnum:]\-\.]*)?:)?'
. '[[:alpha:]_]([[:alnum:]\_\-\.]+)?\\z/',
$string
);
if (!$match) {
return XML_Util::raiseError(
'XML names may only contain alphanumeric '
. 'chars, period, hyphen, colon and underscores',
XML_UTIL_ERROR_INVALID_CHARS
);
}
// XML name is valid
return true;
}
/**
* Replacement for XML_Util::raiseError
*
* Avoids the necessity to always require
* PEAR.php
*
* @param string $msg error message
* @param int $code error code
*
* @return PEAR_Error
* @todo PEAR CS - should this use include_once instead?
*/
public static function raiseError($msg, $code)
{
include_once 'PEAR.php';
return PEAR::raiseError($msg, $code);
}
}
?>
PK u]/= XML/RPC.phpnu [
* @author Stig Bakken ---SENT---\n";
print $op;
print "\n---END---\n";
}
/*
* If we're using a proxy open a socket to the proxy server
* instead to the xml-rpc server
*/
if ($this->proxy) {
if ($this->proxy_protocol == 'http://') {
$protocol = '';
} else {
$protocol = $this->proxy_protocol;
}
if ($timeout > 0) {
$fp = @fsockopen($protocol . $this->proxy, $this->proxy_port,
$this->errno, $this->errstr, $timeout);
} else {
$fp = @fsockopen($protocol . $this->proxy, $this->proxy_port,
$this->errno, $this->errstr);
}
} else {
if ($this->protocol == 'http://') {
$protocol = '';
} else {
$protocol = $this->protocol;
}
if ($timeout > 0) {
$fp = @fsockopen($protocol . $server, $port,
$this->errno, $this->errstr, $timeout);
} else {
$fp = @fsockopen($protocol . $server, $port,
$this->errno, $this->errstr);
}
}
/*
* Just raising the error without returning it is strange,
* but keep it here for backwards compatibility.
*/
if (!$fp && $this->proxy) {
$this->raiseError('Connection to proxy server '
. $this->proxy . ':' . $this->proxy_port
. ' failed. ' . $this->errstr,
XML_RPC_ERROR_CONNECTION_FAILED);
return 0;
} elseif (!$fp) {
$this->raiseError('Connection to RPC server '
. $server . ':' . $port
. ' failed. ' . $this->errstr,
XML_RPC_ERROR_CONNECTION_FAILED);
return 0;
}
if ($timeout) {
/*
* Using socket_set_timeout() because stream_set_timeout()
* was introduced in 4.3.0, but we need to support 4.2.0.
*/
socket_set_timeout($fp, $timeout);
}
if (!fputs($fp, $op, strlen($op))) {
$this->errstr = 'Write error';
return 0;
}
$resp = $msg->parseResponseFile($fp);
$meta = socket_get_status($fp);
if ($meta['timed_out']) {
fclose($fp);
$this->errstr = 'RPC server did not send response before timeout.';
$this->raiseError($this->errstr, XML_RPC_ERROR_CONNECTION_FAILED);
return 0;
}
fclose($fp);
return $resp;
}
/**
* Determines the HTTP headers and puts it in the $headers property
*
* @param object $msg the XML_RPC_Message object
*
* @return boolean TRUE if okay, FALSE if the message payload isn't set.
*
* @access protected
*/
function createHeaders($msg)
{
if (empty($msg->payload)) {
return false;
}
if ($this->proxy) {
$this->headers = 'POST ' . $this->protocol . $this->server;
if ($this->proxy_port) {
$this->headers .= ':' . $this->port;
}
} else {
$this->headers = 'POST ';
}
$this->headers .= $this->path. " HTTP/1.0\r\n";
$this->headers .= "User-Agent: PEAR XML_RPC\r\n";
$this->headers .= 'Host: ' . $this->server . "\r\n";
if ($this->proxy && $this->proxy_user) {
$this->headers .= 'Proxy-Authorization: Basic '
. base64_encode("$this->proxy_user:$this->proxy_pass")
. "\r\n";
}
// thanks to Grant Rauscher ---GOT---\n";
print isset($_SERVER['SERVER_PROTOCOL']) ? htmlspecialchars($data) : $data;
print "\n---END---\n";
}
// See if response is a 200 or a 100 then a 200, else raise error.
// But only do this if we're using the HTTP protocol.
if (preg_match('@^HTTP@', $data) &&
!preg_match('@^HTTP/[0-9\.]+ 200 @', $data) &&
!preg_match('@^HTTP/[0-9\.]+ 10[0-9]([A-Z ]+)?[\r\n]+HTTP/[0-9\.]+ 200@', $data))
{
$errstr = substr($data, 0, strpos($data, "\n") - 1);
error_log('HTTP error, got response: ' . $errstr);
$r = new XML_RPC_Response(0, $XML_RPC_err['http_error'],
$XML_RPC_str['http_error'] . ' (' .
$errstr . ')');
xml_parser_free($parser_resource);
return $r;
}
// gotta get rid of headers here
if (!$hdrfnd && ($brpos = strpos($data,"\r\n\r\n"))) {
$XML_RPC_xh[$parser]['ha'] = substr($data, 0, $brpos);
$data = substr($data, $brpos + 4);
$hdrfnd = 1;
}
/*
* be tolerant of junk after methodResponse
* (e.g. javascript automatically inserted by free hosts)
* thanks to Luca Mariano ---PARSED---\n";
var_dump($XML_RPC_xh[$parser]['value']);
print "---END---\n";
}
if ($XML_RPC_xh[$parser]['isf'] > 1) {
$r = new XML_RPC_Response(0, $XML_RPC_err['invalid_return'],
$XML_RPC_str['invalid_return'].' '.$XML_RPC_xh[$parser]['isf_reason']);
} elseif (!is_object($XML_RPC_xh[$parser]['value'])) {
// then something odd has happened
// and it's time to generate a client side error
// indicating something odd went on
$r = new XML_RPC_Response(0, $XML_RPC_err['invalid_return'],
$XML_RPC_str['invalid_return']);
} else {
$v = $XML_RPC_xh[$parser]['value'];
if ($XML_RPC_xh[$parser]['isf']) {
$f = $v->structmem('faultCode');
$fs = $v->structmem('faultString');
$r = new XML_RPC_Response($v, $f->scalarval(),
$fs->scalarval());
} else {
$r = new XML_RPC_Response($v);
}
}
$r->hdrs = preg_split("@\r?\n@", $XML_RPC_xh[$parser]['ha']);
return $r;
}
}
/**
* The methods and properties that represent data in XML RPC format
*
* @category Web Services
* @package XML_RPC
* @author Edd Dumbill