|
Moodle
2.2.1
http://www.collinsharper.com
|
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 }