ZF-6445: Zend_XmlRpc_Value should support the 64 bits integer data type
Description
The Zend_XmlRpc_Value class should support the a 64 bits integer data type.
Suggestion:
Add new constant to Zend_XmlRpc_Value class.
const XMLRPC_TYPE_I8 = 'i8';
Add the new constant to the switch in the getXmlRpcValue() method (search for self::XMLRPC_TYPE_I8)
switch ($type) {
case self::AUTO_DETECT_TYPE:
// Auto detect the XML-RPC native type from the PHP type of $value
return self::_phpVarToNativeXmlRpc($value);
case self::XML_STRING:
// Parse the XML string given in $value and get the XML-RPC value in it
return self::_xmlStringToNativeXmlRpc($value);
case self::XMLRPC_TYPE_I4:
// fall through to the next case
case self::XMLRPC_TYPE_INTEGER:
return new Zend_XmlRpc_Value_Integer($value);
case self::XMLRPC_TYPE_DOUBLE:
return new Zend_XmlRpc_Value_Double($value);
case self::XMLRPC_TYPE_BOOLEAN:
return new Zend_XmlRpc_Value_Boolean($value);
case self::XMLRPC_TYPE_I8:
case self::XMLRPC_TYPE_STRING:
return new Zend_XmlRpc_Value_String($value);
case self::XMLRPC_TYPE_BASE64:
return new Zend_XmlRpc_Value_Base64($value);
case self::XMLRPC_TYPE_NIL:
return new Zend_XmlRpc_Value_Nil();
case self::XMLRPC_TYPE_DATETIME:
return new Zend_XmlRpc_Value_DateTime($value);
case self::XMLRPC_TYPE_ARRAY:
return new Zend_XmlRpc_Value_Array($value);
case self::XMLRPC_TYPE_STRUCT:
return new Zend_XmlRpc_Value_Struct($value);
default:
throw new Zend_XmlRpc_Value_Exception('Given type is not a '. __CLASS__ .' constant');
}
Add the new constant to the switch in the _xmlStringToNativeXmlRpc() method (search for self::XMLRPC_TYPE_I8)
switch ($type) {
// All valid and known XML-RPC native values
case self::XMLRPC_TYPE_I4:
// Fall through to the next case
case self::XMLRPC_TYPE_INTEGER:
$xmlrpc_val = new Zend_XmlRpc_Value_Integer($value);
break;
case self::XMLRPC_TYPE_DOUBLE:
$xmlrpc_val = new Zend_XmlRpc_Value_Double($value);
break;
case self::XMLRPC_TYPE_BOOLEAN:
$xmlrpc_val = new Zend_XmlRpc_Value_Boolean($value);
break;
case self::XMLRPC_TYPE_I8:
case self::XMLRPC_TYPE_STRING:
$xmlrpc_val = new Zend_XmlRpc_Value_String($value);
break;
case self::XMLRPC_TYPE_DATETIME: // The value should already be in a iso8601 format
$xmlrpc_val = new Zend_XmlRpc_Value_DateTime($value);
break;
case self::XMLRPC_TYPE_BASE64: // The value should already be base64 encoded
$xmlrpc_val = new Zend_XmlRpc_Value_Base64($value ,true);
break;
case self::XMLRPC_TYPE_NIL: // The value should always be NULL
$xmlrpc_val = new Zend_XmlRpc_Value_Nil();
break;
case self::XMLRPC_TYPE_ARRAY:
// If the XML is valid, $value must be an SimpleXML element and contain the tag
if (!$value instanceof SimpleXMLElement) {
throw new Zend_XmlRpc_Value_Exception('XML string is invalid for XML-RPC native '. self::XMLRPC_TYPE_ARRAY .' type');
}
// PHP 5.2.4 introduced a regression in how empty($xml->value)
// returns; need to look for the item specifically
$data = null;
foreach ($value->children() as $key => $value) {
if ('data' == $key) {
$data = $value;
break;
}
}
if (null === $data) {
throw new Zend_XmlRpc_Value_Exception('Invalid XML for XML-RPC native '. self::XMLRPC_TYPE_ARRAY .' type: ARRAY tag must contain DATA tag');
}
$values = array();
// Parse all the elements of the array from the XML string
// (simple xml element) to Zend_XmlRpc_Value objects
foreach ($data->value as $element) {
$values[] = self::_xmlStringToNativeXmlRpc($element);
}
$xmlrpc_val = new Zend_XmlRpc_Value_Array($values);
break;
case self::XMLRPC_TYPE_STRUCT:
// If the XML is valid, $value must be an SimpleXML
if ((!$value instanceof SimpleXMLElement)) {
throw new Zend_XmlRpc_Value_Exception('XML string is invalid for XML-RPC native '. self::XMLRPC_TYPE_STRUCT .' type');
}
$values = array();
// Parse all the memebers of the struct from the XML string
// (simple xml element) to Zend_XmlRpc_Value objects
foreach ($value->member as $member) {
// @todo? If a member doesn't have a tag, we don't add it to the struct
// Maybe we want to throw an exception here ?
if ((!$member->value instanceof SimpleXMLElement)) {
continue;
//throw new Zend_XmlRpc_Value_Exception('Member of the '. self::XMLRPC_TYPE_STRUCT .' XML-RPC native type must contain a VALUE tag');
}
$values[(string)$member->name] = self::_xmlStringToNativeXmlRpc($member->value);
}
$xmlrpc_val = new Zend_XmlRpc_Value_Struct($values);
break;
default:
throw new Zend_XmlRpc_Value_Exception('Value type \''. $type .'\' parsed from the XML string is not a known XML-RPC native type');
break;
}
Thank you.
Comments
Posted by Michiel Brandenburg (apex) on 2009-06-05T07:06:50.000+0000
Hi,
I ran in to the same "problem" and solved it along the same lines. But instead of casting i8 to string use a (new) Zend_XmlRpc_Value_BigInteger I have attached a diff last svn version.
Posted by Michiel Brandenburg (apex) on 2009-06-05T07:07:39.000+0000
Patch to support BigInts in the xmlrpc client.
Posted by Lars Strojny (lars) on 2009-08-22T09:17:11.000+0000
Michiel, the patch looks good. Could you provide some tests for the marshaling?
Posted by Lars Strojny (lars) on 2009-08-23T07:49:01.000+0000
Please make sure you sign a CLA too so that we can accept your patches: http://framework.zend.com/community/contribute
Posted by Lars Strojny (lars) on 2009-08-31T13:25:24.000+0000
Fixed in r17933. Handles as well as the non-standard Apache XML/RPC extension (http://ws.apache.org/xmlrpc/)
Posted by Jan Pieper (jpieper) on 2010-11-18T11:37:46.000+0000
Zend_XmlRpc_Value_BigInteger has been refactored due to some major bugs. See ZF-8898 for more details.