X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=src%2FHelper%2FXMLParser.php;h=2d3296d4ee6eae2dad2f8617cda1d743ba0dd749;hb=25b0d7c6c540615e854f941dc457f556bfca2408;hp=2b619a121076445050167c37ec0be9b393bacecd;hpb=f3071840b51abc78eff0d5e0d84bcef221737c56;p=plcapi.git diff --git a/src/Helper/XMLParser.php b/src/Helper/XMLParser.php index 2b619a1..2d3296d 100644 --- a/src/Helper/XMLParser.php +++ b/src/Helper/XMLParser.php @@ -7,15 +7,18 @@ use PhpXmlRpc\Value; /** * Deals with parsing the XML. + * @see http://xmlrpc.com/spec.md */ class XMLParser { const RETURN_XMLRPCVALS = 'xmlrpcvals'; + const RETURN_EPIVALS = 'epivals'; const RETURN_PHP = 'phpvals'; const ACCEPT_REQUEST = 1; const ACCEPT_RESPONSE = 2; const ACCEPT_VALUE = 4; + const ACCEPT_FAULT = 8; // Used to store state during parsing. // Quick explanation of components: @@ -30,7 +33,7 @@ class XMLParser // method - used to store method name // params - used to store parameters in method calls // pt - used to store the type of each received parameter. Useful if parameters are automatically decoded to php values - // rt - 'methodcall', 'methodresponse' or 'value' + // rt - 'methodcall', 'methodresponse', 'value' or 'fault' (the last one used only in EPI emulation mode) public $_xh = array( 'ac' => '', 'stack' => array(), @@ -121,10 +124,15 @@ class XMLParser xml_set_object($parser, $this); - if ($returnType == self::RETURN_PHP) { - xml_set_element_handler($parser, 'xmlrpc_se', 'xmlrpc_ee_fast'); - } else { - xml_set_element_handler($parser, 'xmlrpc_se', 'xmlrpc_ee'); + switch($returnType) { + case self::RETURN_PHP: + xml_set_element_handler($parser, 'xmlrpc_se', 'xmlrpc_ee_fast'); + break; + case self::RETURN_EPIVALS: + xml_set_element_handler($parser, 'xmlrpc_se', 'xmlrpc_ee_epi'); + break; + default: + xml_set_element_handler($parser, 'xmlrpc_se', 'xmlrpc_ee'); } xml_set_character_data_handler($parser, 'xmlrpc_cd'); @@ -152,6 +160,7 @@ class XMLParser /** * xml parser handler function for opening element tags. + * @internal * @param resource $parser * @param string $name * @param $attrs @@ -175,7 +184,8 @@ class XMLParser } if (($name == 'METHODCALL' && ($accept & self::ACCEPT_REQUEST)) || ($name == 'METHODRESPONSE' && ($accept & self::ACCEPT_RESPONSE)) || - ($name == 'VALUE' && ($accept & self::ACCEPT_VALUE))) { + ($name == 'VALUE' && ($accept & self::ACCEPT_VALUE)) || + ($name == 'FAULT' && ($accept & self::ACCEPT_FAULT))) { $this->_xh['rt'] = strtolower($name); } else { $this->_xh['isf'] = 2; @@ -327,11 +337,12 @@ class XMLParser /** * xml parser handler function for close element tags. + * @internal * @param resource $parser * @param string $name - * @param bool $rebuildXmlrpcvals + * @param int $rebuildXmlrpcvals >1 for rebuilding xmlrpcvals, 0 for rebuilding php values, -1 for xmlrpc-extension compatibility */ - public function xmlrpc_ee($parser, $name, $rebuildXmlrpcvals = true) + public function xmlrpc_ee($parser, $name, $rebuildXmlrpcvals = 1) { if ($this->_xh['isf'] < 2) { // push this element name from stack @@ -348,7 +359,7 @@ class XMLParser $this->_xh['vt'] = Value::$xmlrpcString; } - if ($rebuildXmlrpcvals) { + if ($rebuildXmlrpcvals > 0) { // build the xmlrpc val out of the data received, and substitute it $temp = new Value($this->_xh['value'], $this->_xh['vt']); // in case we got info about underlying php class, save it @@ -356,27 +367,33 @@ class XMLParser if (isset($this->_xh['php_class'])) { $temp->_php_class = $this->_xh['php_class']; } - // check if we are inside an array or struct: - // if value just built is inside an array, let's move it into array on the stack - $vscount = count($this->_xh['valuestack']); - if ($vscount && $this->_xh['valuestack'][$vscount - 1]['type'] == 'ARRAY') { - $this->_xh['valuestack'][$vscount - 1]['values'][] = $temp; - } else { - $this->_xh['value'] = $temp; + $this->_xh['value'] = $temp; + } elseif ($rebuildXmlrpcvals < 0) { + if ($this->_xh['vt'] == Value::$xmlrpcDateTime) { + $this->_xh['value'] = (object)array( + 'xmlrpc_type' => 'datetime', + 'scalar' => $this->_xh['value'], + 'timestamp' => \PhpXmlRpc\Helper\Date::iso8601Decode($this->_xh['value']) + ); + } elseif ($this->_xh['vt'] == Value::$xmlrpcBase64) { + $this->_xh['value'] = (object)array( + 'xmlrpc_type' => 'base64', + 'scalar' => $this->_xh['value'] + ); } } else { - /// @todo this needs to treat correctly php-serialized objects, + /// @todo this should handle php-serialized objects, /// since std deserializing is done by php_xmlrpc_decode, /// which we will not be calling... - if (isset($this->_xh['php_class'])) { - } + //if (isset($this->_xh['php_class'])) { + //} + } - // check if we are inside an array or struct: - // if value just built is inside an array, let's move it into array on the stack - $vscount = count($this->_xh['valuestack']); - if ($vscount && $this->_xh['valuestack'][$vscount - 1]['type'] == 'ARRAY') { - $this->_xh['valuestack'][$vscount - 1]['values'][] = $this->_xh['value']; - } + // check if we are inside an array or struct: + // if value just built is inside an array, let's move it into array on the stack + $vscount = count($this->_xh['valuestack']); + if ($vscount && $this->_xh['valuestack'][$vscount - 1]['type'] == 'ARRAY') { + $this->_xh['valuestack'][$vscount - 1]['values'][] = $this->_xh['value']; } break; case 'BOOLEAN': @@ -507,16 +524,29 @@ class XMLParser /** * Used in decoding xmlrpc requests/responses without rebuilding xmlrpc Values. + * @internal * @param resource $parser * @param string $name */ public function xmlrpc_ee_fast($parser, $name) { - $this->xmlrpc_ee($parser, $name, false); + $this->xmlrpc_ee($parser, $name, 0); + } + + /** + * Used in decoding xmlrpc requests/responses while building xmlrpc-extension Values (plain php for all but base64 and datetime). + * @internal + * @param resource $parser + * @param string $name + */ + public function xmlrpc_ee_epi($parser, $name) + { + $this->xmlrpc_ee($parser, $name, -1); } /** * xml parser handler function for character data. + * @internal * @param resource $parser * @param string $data */ @@ -535,6 +565,7 @@ class XMLParser /** * xml parser handler function for 'other stuff', ie. not char data or * element start/end tag. In fact it only gets called on unknown entities... + * @internal * @param $parser * @param string data */