193 lines
6.2 KiB
PHP
193 lines
6.2 KiB
PHP
|
|
<?php
|
||
|
|
/**
|
||
|
|
* dom_xmlrpc_object_parser handles SAX events to convert a DOM XML-RPC XML string into a PHP array
|
||
|
|
*
|
||
|
|
* Will generate PHP objects instead of structs if directed
|
||
|
|
* @package dom-xmlrpc
|
||
|
|
* @copyright (C) 2004 John Heinstein. All rights reserved
|
||
|
|
* @license http://www.gnu.org/copyleft/lesser.html LGPL License
|
||
|
|
* @author John Heinstein <johnkarl@nbnet.nb.ca>
|
||
|
|
* @link http://www.engageinteractive.com/dom_xmlrpc/ DOM XML-RPC Home Page
|
||
|
|
* DOM XML-RPC is Free Software
|
||
|
|
**/
|
||
|
|
|
||
|
|
if (!defined('DOM_XMLRPC_INCLUDE_PATH')) {
|
||
|
|
define('DOM_XMLRPC_INCLUDE_PATH', (dirname(__FILE__) . "/"));
|
||
|
|
}
|
||
|
|
|
||
|
|
require_once(DOM_XMLRPC_INCLUDE_PATH . 'dom_xmlrpc_parser.php');
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Handles SAX events to convert a DOM XML-RPC XML string into a PHP array
|
||
|
|
*
|
||
|
|
* Will generate PHP objects instead of structs if directed
|
||
|
|
* @package dom-xmlrpc
|
||
|
|
* @author John Heinstein <johnkarl@nbnet.nb.ca>
|
||
|
|
*/
|
||
|
|
class dom_xmlrpc_object_parser extends dom_xmlrpc_parser {
|
||
|
|
/** @var boolean If true, objects will be tested for */
|
||
|
|
var $testingForObject = false; //when a struct is encountered, turn this on
|
||
|
|
/** @var object Handler for PHP objects */
|
||
|
|
var $objectDefinitionHandler = null; //fired when a __phpobject__ definition is required
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Constructor
|
||
|
|
* @param object Reference to a handler for PHP objects
|
||
|
|
*/
|
||
|
|
function dom_xmlrpc_object_parser(&$objectDefinitionHandler) {
|
||
|
|
$this->objectDefinitionHandler =& $objectDefinitionHandler;
|
||
|
|
} //dom_xmlrpc_object_parser
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Handles start element events
|
||
|
|
* @param object A reference to the SAX parser
|
||
|
|
* @param string The name of the start element tag
|
||
|
|
* @param array An array of attributes (never used by XML-RPC spec)
|
||
|
|
*/
|
||
|
|
function startElement($parser, $name, $attrs) {
|
||
|
|
switch($name) {
|
||
|
|
case DOM_XMLRPC_TYPE_METHODCALL:
|
||
|
|
case DOM_XMLRPC_TYPE_METHODRESPONSE:
|
||
|
|
case DOM_XMLRPC_TYPE_FAULT:
|
||
|
|
$this->arrayDocument->methodType = $name; //register methodType
|
||
|
|
break;
|
||
|
|
case DOM_XMLRPC_TYPE_ARRAY:
|
||
|
|
case DOM_XMLRPC_TYPE_STRUCT:
|
||
|
|
$this->lastArrayType[] = $name;
|
||
|
|
$this->lastArray[] = array();
|
||
|
|
$this->testingForObject = true;
|
||
|
|
break;
|
||
|
|
}
|
||
|
|
} //startElement
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Handles end element events
|
||
|
|
* @param object A reference to the SAX parser
|
||
|
|
* @param string The name of the end element tag
|
||
|
|
*/
|
||
|
|
function endElement($parser, $name) {
|
||
|
|
switch($name) {
|
||
|
|
case DOM_XMLRPC_TYPE_STRING:
|
||
|
|
//$this->addValue(html_entity_decode($this->charContainer, ENT_QUOTES));
|
||
|
|
$this->addValue($this->charContainer);
|
||
|
|
break;
|
||
|
|
case DOM_XMLRPC_TYPE_I4:
|
||
|
|
case DOM_XMLRPC_TYPE_INT:
|
||
|
|
$this->addValue((int)($this->charContainer));
|
||
|
|
break;
|
||
|
|
case DOM_XMLRPC_TYPE_DOUBLE:
|
||
|
|
$this->addValue(floatval($this->charContainer));
|
||
|
|
break;
|
||
|
|
case DOM_XMLRPC_TYPE_BOOLEAN:
|
||
|
|
$this->addValue((bool)(trim($this->charContainer)));
|
||
|
|
break;
|
||
|
|
case DOM_XMLRPC_TYPE_BASE64:
|
||
|
|
require_once(DOM_XMLRPC_INCLUDE_PATH . 'dom_xmlrpc_base64.php');
|
||
|
|
$base64 = new dom_xmlrpc_base64();
|
||
|
|
$base64->fromString($this->charContainer);
|
||
|
|
$this->addValue($base64); //should I add object or string?
|
||
|
|
break;
|
||
|
|
case DOM_XMLRPC_TYPE_DATETIME:
|
||
|
|
require_once(DOM_XMLRPC_INCLUDE_PATH . 'dom_xmlrpc_datetime_iso8601.php');
|
||
|
|
$dateTime = new dom_xmlrpc_datetime_iso8601($this->charContainer);
|
||
|
|
$this->addValue($dateTime); //should I add object or string?
|
||
|
|
break;
|
||
|
|
case DOM_XMLRPC_TYPE_VALUE:
|
||
|
|
//if charContainer has anything in it,
|
||
|
|
//then there mustn't be a subnode, therefore a <string>
|
||
|
|
$myValue = trim($this->charContainer);
|
||
|
|
//if ($myValue != '') $this->addValue(html_entity_decode($myValue, ENT_QUOTES));
|
||
|
|
if ($myValue != '') $this->addValue($myValue);
|
||
|
|
break;
|
||
|
|
case DOM_XMLRPC_TYPE_ARRAY:
|
||
|
|
case DOM_XMLRPC_TYPE_STRUCT:
|
||
|
|
$value =& array_pop($this->lastArray);
|
||
|
|
$this->addValue($value);
|
||
|
|
array_pop($this->lastArrayType);
|
||
|
|
break;
|
||
|
|
case DOM_XMLRPC_TYPE_MEMBER:
|
||
|
|
array_pop($this->lastStructName);
|
||
|
|
break;
|
||
|
|
case DOM_XMLRPC_TYPE_NAME:
|
||
|
|
$cn = trim($this->charContainer);
|
||
|
|
$this->lastStructName[] = $cn;
|
||
|
|
$this->charContainer = '';
|
||
|
|
|
||
|
|
if ($this->testingForObject && ($cn == DOM_XMLRPC_PHPOBJECT)) {
|
||
|
|
$this->lastArrayType[(count($this->lastArray) - 1)] = DOM_XMLRPC_PHPOBJECT;
|
||
|
|
}
|
||
|
|
|
||
|
|
$this->testingForObject = false;
|
||
|
|
break;
|
||
|
|
case DOM_XMLRPC_TYPE_METHODNAME:
|
||
|
|
$this->arrayDocument->methodName = trim($this->charContainer);
|
||
|
|
$this->charContainer = '';
|
||
|
|
break;
|
||
|
|
}
|
||
|
|
} //endElement
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Adds an XML-RPC value to the results array
|
||
|
|
* @param mixed The value
|
||
|
|
*/
|
||
|
|
function addValue($value) {
|
||
|
|
$upper = count($this->lastArray) - 1;
|
||
|
|
|
||
|
|
if ($upper > -1) {
|
||
|
|
$lastArrayType = $this->lastArrayType[$upper];
|
||
|
|
|
||
|
|
if ($lastArrayType == DOM_XMLRPC_TYPE_STRUCT) {
|
||
|
|
$currentName = $this->lastStructName[(count($this->lastStructName) - 1)];
|
||
|
|
|
||
|
|
switch ($currentName) {
|
||
|
|
case DOM_XMLRPC_NODEVALUE_FAULTCODE:
|
||
|
|
$this->arrayDocument->faultCode = $value;
|
||
|
|
break;
|
||
|
|
|
||
|
|
case DOM_XMLRPC_NODEVALUE_FAULTSTRING:
|
||
|
|
$this->arrayDocument->faultString = $value;
|
||
|
|
break;
|
||
|
|
|
||
|
|
default:
|
||
|
|
//associative array item
|
||
|
|
$this->lastArray[$upper][$currentName] = $value;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
else if ($lastArrayType == DOM_XMLRPC_PHPOBJECT) {
|
||
|
|
$currentName = $this->lastStructName[(count($this->lastStructName) - 1)];
|
||
|
|
|
||
|
|
if ($currentName == DOM_XMLRPC_PHPOBJECT) {
|
||
|
|
//import class and instantiate new object
|
||
|
|
call_user_func($this->objectDefinitionHandler, $value);
|
||
|
|
$this->lastArray[$upper] = new $value;
|
||
|
|
}
|
||
|
|
else {
|
||
|
|
if ($currentName == DOM_XMLRPC_SERIALIZED) {
|
||
|
|
//could also check for this...
|
||
|
|
//if (is_object($value) && (get_class($value) == 'dom_xmlrpc_base64')) {
|
||
|
|
//unserialize object
|
||
|
|
$serialized =& $value->getBinary();
|
||
|
|
$this->lastArray[$upper] =& unserialize($serialized);
|
||
|
|
}
|
||
|
|
else {
|
||
|
|
//add property to object
|
||
|
|
$myObj =& $this->lastArray[$upper];
|
||
|
|
$myObj->$currentName =& $value;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
else {
|
||
|
|
//indexed array item
|
||
|
|
$this->lastArray[$upper][] =& $value;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
else {
|
||
|
|
//at root level, add value as a new param
|
||
|
|
array_push($this->arrayDocument->params, $value);
|
||
|
|
}
|
||
|
|
|
||
|
|
$this->charContainer = '';
|
||
|
|
} //addValue
|
||
|
|
} //dom_xmlrpc_object_parser
|
||
|
|
|
||
|
|
?>
|