Moodle  2.2.1
http://www.collinsharper.com
C:/xampp/htdocs/moodle/lib/zend/Zend/XmlRpc/Value.php
Go to the documentation of this file.
00001 <?php
00037 abstract class Zend_XmlRpc_Value
00038 {
00045     protected $_value;
00046 
00051     protected $_type;
00052 
00056     protected $_xml;
00057 
00061     protected static $_generator;
00062 
00066     const AUTO_DETECT_TYPE = 'auto_detect';
00067 
00071     const XML_STRING = 'xml';
00072 
00076     const XMLRPC_TYPE_I4        = 'i4';
00077     const XMLRPC_TYPE_INTEGER   = 'int';
00078     const XMLRPC_TYPE_I8        = 'i8';
00079     const XMLRPC_TYPE_APACHEI8  = 'ex:i8';
00080     const XMLRPC_TYPE_DOUBLE    = 'double';
00081     const XMLRPC_TYPE_BOOLEAN   = 'boolean';
00082     const XMLRPC_TYPE_STRING    = 'string';
00083     const XMLRPC_TYPE_DATETIME  = 'dateTime.iso8601';
00084     const XMLRPC_TYPE_BASE64    = 'base64';
00085     const XMLRPC_TYPE_ARRAY     = 'array';
00086     const XMLRPC_TYPE_STRUCT    = 'struct';
00087     const XMLRPC_TYPE_NIL       = 'nil';
00088     const XMLRPC_TYPE_APACHENIL = 'ex:nil';
00089 
00095     public function getType()
00096     {
00097         return $this->_type;
00098     }
00099 
00105     public static function getGenerator()
00106     {
00107         if (!self::$_generator) {
00108             if (extension_loaded('xmlwriter')) {
00109                 require_once 'Zend/XmlRpc/Generator/XmlWriter.php';
00110                 self::$_generator = new Zend_XmlRpc_Generator_XmlWriter();
00111             } else {
00112                 require_once 'Zend/XmlRpc/Generator/DomDocument.php';
00113                 self::$_generator = new Zend_XmlRpc_Generator_DomDocument();
00114             }
00115         }
00116 
00117         return self::$_generator;
00118     }
00119 
00126     public static function setGenerator(Zend_XmlRpc_Generator_GeneratorAbstract $generator)
00127     {
00128         self::$_generator = $generator;
00129     }
00130 
00137     public static function setEncoding($encoding)
00138     {
00139         $generator = self::getGenerator();
00140         $newGenerator = new $generator($encoding);
00141         self::setGenerator($newGenerator);
00142     }
00143 
00149     abstract public function getValue();
00150 
00151 
00157     public function saveXml()
00158     {
00159         if (!$this->_xml) {
00160             $this->generateXml();
00161             $this->_xml = (string) $this->getGenerator();
00162         }
00163         return $this->_xml;
00164     }
00165 
00171     public function generateXml()
00172     {
00173         $this->_generateXml();
00174     }
00175 
00192     public static function getXmlRpcValue($value, $type = self::AUTO_DETECT_TYPE)
00193     {
00194         switch ($type) {
00195             case self::AUTO_DETECT_TYPE:
00196                 // Auto detect the XML-RPC native type from the PHP type of $value
00197                 return self::_phpVarToNativeXmlRpc($value);
00198 
00199             case self::XML_STRING:
00200                 // Parse the XML string given in $value and get the XML-RPC value in it
00201                 return self::_xmlStringToNativeXmlRpc($value);
00202 
00203             case self::XMLRPC_TYPE_I4:
00204                 // fall through to the next case
00205             case self::XMLRPC_TYPE_INTEGER:
00206                 require_once 'Zend/XmlRpc/Value/Integer.php';
00207                 return new Zend_XmlRpc_Value_Integer($value);
00208 
00209             case self::XMLRPC_TYPE_I8:
00210                 // fall through to the next case
00211             case self::XMLRPC_TYPE_APACHEI8:
00212                 require_once 'Zend/XmlRpc/Value/BigInteger.php';
00213                 return new Zend_XmlRpc_Value_BigInteger($value);
00214 
00215             case self::XMLRPC_TYPE_DOUBLE:
00216                 require_once 'Zend/XmlRpc/Value/Double.php';
00217                 return new Zend_XmlRpc_Value_Double($value);
00218 
00219             case self::XMLRPC_TYPE_BOOLEAN:
00220                 require_once 'Zend/XmlRpc/Value/Boolean.php';
00221                 return new Zend_XmlRpc_Value_Boolean($value);
00222 
00223             case self::XMLRPC_TYPE_STRING:
00224                 require_once 'Zend/XmlRpc/Value/String.php';
00225                 return new Zend_XmlRpc_Value_String($value);
00226 
00227             case self::XMLRPC_TYPE_BASE64:
00228                 require_once 'Zend/XmlRpc/Value/Base64.php';
00229                 return new Zend_XmlRpc_Value_Base64($value);
00230 
00231             case self::XMLRPC_TYPE_NIL:
00232                 // fall through to the next case
00233             case self::XMLRPC_TYPE_APACHENIL:
00234                 require_once 'Zend/XmlRpc/Value/Nil.php';
00235                 return new Zend_XmlRpc_Value_Nil();
00236 
00237             case self::XMLRPC_TYPE_DATETIME:
00238                 require_once 'Zend/XmlRpc/Value/DateTime.php';
00239                 return new Zend_XmlRpc_Value_DateTime($value);
00240 
00241             case self::XMLRPC_TYPE_ARRAY:
00242                 require_once 'Zend/XmlRpc/Value/Array.php';
00243                 return new Zend_XmlRpc_Value_Array($value);
00244 
00245             case self::XMLRPC_TYPE_STRUCT:
00246                 require_once 'Zend/XmlRpc/Value/Struct.php';
00247                 return new Zend_XmlRpc_Value_Struct($value);
00248 
00249             default:
00250                 require_once 'Zend/XmlRpc/Value/Exception.php';
00251                 throw new Zend_XmlRpc_Value_Exception('Given type is not a '. __CLASS__ .' constant');
00252         }
00253     }
00254 
00255 
00264     protected static function _phpVarToNativeXmlRpc($value)
00265     {
00266         switch (gettype($value)) {
00267             case 'object':
00268                 // Check to see if it's an XmlRpc value
00269                 if ($value instanceof Zend_XmlRpc_Value) {
00270                     return $value;
00271                 }
00272 
00273                 if ($value instanceof Zend_Crypt_Math_BigInteger) {
00274                     require_once 'Zend/XmlRpc/Value/BigInteger.php';
00275                     return new Zend_XmlRpc_Value_BigInteger($value);
00276                 }
00277 
00278                 if ($value instanceof Zend_Date or $value instanceof DateTime) {
00279                     require_once 'Zend/XmlRpc/Value/DateTime.php';
00280                     return new Zend_XmlRpc_Value_DateTime($value);
00281                 }
00282 
00283                 // Otherwise, we convert the object into a struct
00284                 $value = get_object_vars($value);
00285                 // Break intentionally omitted
00286             case 'array':
00287                 // Default native type for a PHP array (a simple numeric array) is 'array'
00288                 require_once 'Zend/XmlRpc/Value/Array.php';
00289                 $obj = 'Zend_XmlRpc_Value_Array';
00290 
00291                 // Determine if this is an associative array
00292                 if (!empty($value) && is_array($value) && (array_keys($value) !== range(0, count($value) - 1))) {
00293                     require_once 'Zend/XmlRpc/Value/Struct.php';
00294                     $obj = 'Zend_XmlRpc_Value_Struct';
00295                 }
00296                 return new $obj($value);
00297 
00298             case 'integer':
00299                 require_once 'Zend/XmlRpc/Value/Integer.php';
00300                 return new Zend_XmlRpc_Value_Integer($value);
00301 
00302             case 'double':
00303                 require_once 'Zend/XmlRpc/Value/Double.php';
00304                 return new Zend_XmlRpc_Value_Double($value);
00305 
00306             case 'boolean':
00307                 require_once 'Zend/XmlRpc/Value/Boolean.php';
00308                 return new Zend_XmlRpc_Value_Boolean($value);
00309 
00310             case 'NULL':
00311             case 'null':
00312                 require_once 'Zend/XmlRpc/Value/Nil.php';
00313                 return new Zend_XmlRpc_Value_Nil();
00314 
00315             case 'string':
00316                 // Fall through to the next case
00317             default:
00318                 // If type isn't identified (or identified as string), it treated as string
00319                 require_once 'Zend/XmlRpc/Value/String.php';
00320                 return new Zend_XmlRpc_Value_String($value);
00321         }
00322     }
00323 
00324 
00334     protected static function _xmlStringToNativeXmlRpc($xml)
00335     {
00336         self::_createSimpleXMLElement($xml);
00337 
00338         self::_extractTypeAndValue($xml, $type, $value);
00339 
00340         switch ($type) {
00341             // All valid and known XML-RPC native values
00342             case self::XMLRPC_TYPE_I4:
00343                 // Fall through to the next case
00344             case self::XMLRPC_TYPE_INTEGER:
00345                 require_once 'Zend/XmlRpc/Value/Integer.php';
00346                 $xmlrpcValue = new Zend_XmlRpc_Value_Integer($value);
00347                 break;
00348             case self::XMLRPC_TYPE_APACHEI8:
00349                 // Fall through to the next case
00350             case self::XMLRPC_TYPE_I8:
00351                 require_once 'Zend/XmlRpc/Value/BigInteger.php';
00352                 $xmlrpcValue = new Zend_XmlRpc_Value_BigInteger($value);
00353                 break;
00354             case self::XMLRPC_TYPE_DOUBLE:
00355                 require_once 'Zend/XmlRpc/Value/Double.php';
00356                 $xmlrpcValue = new Zend_XmlRpc_Value_Double($value);
00357                 break;
00358             case self::XMLRPC_TYPE_BOOLEAN:
00359                 require_once 'Zend/XmlRpc/Value/Boolean.php';
00360                 $xmlrpcValue = new Zend_XmlRpc_Value_Boolean($value);
00361                 break;
00362             case self::XMLRPC_TYPE_STRING:
00363                 require_once 'Zend/XmlRpc/Value/String.php';
00364                 $xmlrpcValue = new Zend_XmlRpc_Value_String($value);
00365                 break;
00366             case self::XMLRPC_TYPE_DATETIME:  // The value should already be in a iso8601 format
00367                 require_once 'Zend/XmlRpc/Value/DateTime.php';
00368                 $xmlrpcValue = new Zend_XmlRpc_Value_DateTime($value);
00369                 break;
00370             case self::XMLRPC_TYPE_BASE64:    // The value should already be base64 encoded
00371                 require_once 'Zend/XmlRpc/Value/Base64.php';
00372                 $xmlrpcValue = new Zend_XmlRpc_Value_Base64($value, true);
00373                 break;
00374             case self::XMLRPC_TYPE_NIL:
00375                 // Fall through to the next case
00376             case self::XMLRPC_TYPE_APACHENIL:
00377                 // The value should always be NULL
00378                 require_once 'Zend/XmlRpc/Value/Nil.php';
00379                 $xmlrpcValue = new Zend_XmlRpc_Value_Nil();
00380                 break;
00381             case self::XMLRPC_TYPE_ARRAY:
00382                 // PHP 5.2.4 introduced a regression in how empty($xml->value)
00383                 // returns; need to look for the item specifically
00384                 $data = null;
00385                 foreach ($value->children() as $key => $value) {
00386                     if ('data' == $key) {
00387                         $data = $value;
00388                         break;
00389                     }
00390                 }
00391 
00392                 if (null === $data) {
00393                     require_once 'Zend/XmlRpc/Value/Exception.php';
00394                     throw new Zend_XmlRpc_Value_Exception('Invalid XML for XML-RPC native '. self::XMLRPC_TYPE_ARRAY .' type: ARRAY tag must contain DATA tag');
00395                 }
00396                 $values = array();
00397                 // Parse all the elements of the array from the XML string
00398                 // (simple xml element) to Zend_XmlRpc_Value objects
00399                 foreach ($data->value as $element) {
00400                     $values[] = self::_xmlStringToNativeXmlRpc($element);
00401                 }
00402                 require_once 'Zend/XmlRpc/Value/Array.php';
00403                 $xmlrpcValue = new Zend_XmlRpc_Value_Array($values);
00404                 break;
00405             case self::XMLRPC_TYPE_STRUCT:
00406                 $values = array();
00407                 // Parse all the memebers of the struct from the XML string
00408                 // (simple xml element) to Zend_XmlRpc_Value objects
00409                 foreach ($value->member as $member) {
00410                     // @todo? If a member doesn't have a <value> tag, we don't add it to the struct
00411                     // Maybe we want to throw an exception here ?
00412                     if (!isset($member->value) or !isset($member->name)) {
00413                         continue;
00414                         //throw new Zend_XmlRpc_Value_Exception('Member of the '. self::XMLRPC_TYPE_STRUCT .' XML-RPC native type must contain a VALUE tag');
00415                     }
00416                     $values[(string)$member->name] = self::_xmlStringToNativeXmlRpc($member->value);
00417                 }
00418                 require_once 'Zend/XmlRpc/Value/Struct.php';
00419                 $xmlrpcValue = new Zend_XmlRpc_Value_Struct($values);
00420                 break;
00421             default:
00422                 require_once 'Zend/XmlRpc/Value/Exception.php';
00423                 throw new Zend_XmlRpc_Value_Exception('Value type \''. $type .'\' parsed from the XML string is not a known XML-RPC native type');
00424                 break;
00425         }
00426         $xmlrpcValue->_setXML($xml->asXML());
00427 
00428         return $xmlrpcValue;
00429     }
00430 
00431     protected static function _createSimpleXMLElement(&$xml)
00432     {
00433         if ($xml instanceof SimpleXMLElement) {
00434             return;
00435         }
00436 
00437         try {
00438             $xml = new SimpleXMLElement($xml);
00439         } catch (Exception $e) {
00440             // The given string is not a valid XML
00441             require_once 'Zend/XmlRpc/Value/Exception.php';
00442             throw new Zend_XmlRpc_Value_Exception('Failed to create XML-RPC value from XML string: ' . $e->getMessage(), $e->getCode(), $e);
00443         }
00444     }
00445 
00454     protected static function _extractTypeAndValue(SimpleXMLElement $xml, &$type, &$value)
00455     {
00456         list($type, $value) = each($xml);
00457 
00458         if (!$type and $value === null) {
00459             $namespaces = array('ex' => 'http://ws.apache.org/xmlrpc/namespaces/extensions');
00460             foreach ($namespaces as $namespaceName => $namespaceUri) {
00461                 $namespaceXml = $xml->children($namespaceUri);
00462                 list($type, $value) = each($namespaceXml);
00463                 if ($type !== null) {
00464                     $type = $namespaceName . ':' . $type;
00465                     break;
00466                 }
00467             }
00468         }
00469 
00470         // If no type was specified, the default is string
00471         if (!$type) {
00472             $type = self::XMLRPC_TYPE_STRING;
00473         }
00474     }
00475 
00480     protected function _setXML($xml)
00481     {
00482         $this->_xml = $this->getGenerator()->stripDeclaration($xml);
00483     }
00484 }
 All Data Structures Namespaces Files Functions Variables Enumerations