[ Index ]

PHP Cross Reference of moodle-2.8

title

Body

[close]

/lib/zend/Zend/XmlRpc/ -> Value.php (source)

   1  <?php
   2  /**
   3   * Zend Framework
   4   *
   5   * LICENSE
   6   *
   7   * This source file is subject to the new BSD license that is bundled
   8   * with this package in the file LICENSE.txt.
   9   * It is also available through the world-wide-web at this URL:
  10   * http://framework.zend.com/license/new-bsd
  11   * If you did not receive a copy of the license and are unable to
  12   * obtain it through the world-wide-web, please send an email
  13   * to [email protected] so we can send you a copy immediately.
  14   *
  15   * @category   Zend
  16   * @package    Zend_XmlRpc
  17   * @subpackage Value
  18   * @copyright  Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com)
  19   * @license    http://framework.zend.com/license/new-bsd     New BSD License
  20   * @version    $Id$
  21   */
  22  
  23  /**
  24   * Represent a native XML-RPC value entity, used as parameters for the methods
  25   * called by the Zend_XmlRpc_Client object and as the return value for those calls.
  26   *
  27   * This object as a very important static function Zend_XmlRpc_Value::getXmlRpcValue, this
  28   * function acts likes a factory for the Zend_XmlRpc_Value objects
  29   *
  30   * Using this function, users/Zend_XmlRpc_Client object can create the Zend_XmlRpc_Value objects
  31   * from PHP variables, XML string or by specifing the exact XML-RPC natvie type
  32   *
  33   * @package    Zend_XmlRpc
  34   * @copyright  Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com)
  35   * @license    http://framework.zend.com/license/new-bsd     New BSD License
  36   */
  37  abstract class Zend_XmlRpc_Value
  38  {
  39      /**
  40       * The native XML-RPC representation of this object's value
  41       *
  42       * If the native type of this object is array or struct, this will be an array
  43       * of Zend_XmlRpc_Value objects
  44       */
  45      protected $_value;
  46  
  47      /**
  48       * The native XML-RPC type of this object
  49       * One of the XMLRPC_TYPE_* constants
  50       */
  51      protected $_type;
  52  
  53      /**
  54       * XML code representation of this object (will be calculated only once)
  55       */
  56      protected $_xml;
  57  
  58      /**
  59       * @var Zend_XmlRpc_Generator_GeneratorAbstract
  60       */
  61      protected static $_generator;
  62  
  63      /**
  64       * Specify that the XML-RPC native type will be auto detected from a PHP variable type
  65       */
  66      const AUTO_DETECT_TYPE = 'auto_detect';
  67  
  68      /**
  69       * Specify that the XML-RPC value will be parsed out from a given XML code
  70       */
  71      const XML_STRING = 'xml';
  72  
  73      /**
  74       * All the XML-RPC native types
  75       */
  76      const XMLRPC_TYPE_I4        = 'i4';
  77      const XMLRPC_TYPE_INTEGER   = 'int';
  78      const XMLRPC_TYPE_I8        = 'i8';
  79      const XMLRPC_TYPE_APACHEI8  = 'ex:i8';
  80      const XMLRPC_TYPE_DOUBLE    = 'double';
  81      const XMLRPC_TYPE_BOOLEAN   = 'boolean';
  82      const XMLRPC_TYPE_STRING    = 'string';
  83      const XMLRPC_TYPE_DATETIME  = 'dateTime.iso8601';
  84      const XMLRPC_TYPE_BASE64    = 'base64';
  85      const XMLRPC_TYPE_ARRAY     = 'array';
  86      const XMLRPC_TYPE_STRUCT    = 'struct';
  87      const XMLRPC_TYPE_NIL       = 'nil';
  88      const XMLRPC_TYPE_APACHENIL = 'ex:nil';
  89  
  90      /**
  91       * Get the native XML-RPC type (the type is one of the Zend_XmlRpc_Value::XMLRPC_TYPE_* constants)
  92       *
  93       * @return string
  94       */
  95      public function getType()
  96      {
  97          return $this->_type;
  98      }
  99  
 100      /**
 101       * Get XML generator instance
 102       *
 103       * @return Zend_XmlRpc_Generator_GeneratorAbstract
 104       */
 105      public static function getGenerator()
 106      {
 107          if (!self::$_generator) {
 108              if (extension_loaded('xmlwriter')) {
 109                  require_once 'Zend/XmlRpc/Generator/XmlWriter.php';
 110                  self::$_generator = new Zend_XmlRpc_Generator_XmlWriter();
 111              } else {
 112                  require_once 'Zend/XmlRpc/Generator/DomDocument.php';
 113                  self::$_generator = new Zend_XmlRpc_Generator_DomDocument();
 114              }
 115          }
 116  
 117          return self::$_generator;
 118      }
 119  
 120      /**
 121       * Sets XML generator instance
 122       *
 123       * @param Zend_XmlRpc_Generator_GeneratorAbstract $generator
 124       * @return void
 125       */
 126      public static function setGenerator(Zend_XmlRpc_Generator_GeneratorAbstract $generator)
 127      {
 128          self::$_generator = $generator;
 129      }
 130  
 131      /**
 132       * Changes the encoding of the generator
 133       *
 134       * @param string $encoding
 135       * @return void
 136       */
 137      public static function setEncoding($encoding)
 138      {
 139          $generator = self::getGenerator();
 140          $newGenerator = new $generator($encoding);
 141          self::setGenerator($newGenerator);
 142      }
 143  
 144      /**
 145       * Return the value of this object, convert the XML-RPC native value into a PHP variable
 146       *
 147       * @return mixed
 148       */
 149      abstract public function getValue();
 150  
 151  
 152      /**
 153       * Return the XML code that represent a native MXL-RPC value
 154       *
 155       * @return string
 156       */
 157      public function saveXml()
 158      {
 159          if (!$this->_xml) {
 160              $this->generateXml();
 161              $this->_xml = (string) $this->getGenerator();
 162          }
 163          return $this->_xml;
 164      }
 165  
 166      /**
 167       * Generate XML code that represent a native XML/RPC value
 168       *
 169       * @return void
 170       */
 171      public function generateXml()
 172      {
 173          $this->_generateXml();
 174      }
 175  
 176      /**
 177       * Creates a Zend_XmlRpc_Value* object, representing a native XML-RPC value
 178       * A XmlRpcValue object can be created in 3 ways:
 179       * 1. Autodetecting the native type out of a PHP variable
 180       *    (if $type is not set or equal to Zend_XmlRpc_Value::AUTO_DETECT_TYPE)
 181       * 2. By specifing the native type ($type is one of the Zend_XmlRpc_Value::XMLRPC_TYPE_* constants)
 182       * 3. From a XML string ($type is set to Zend_XmlRpc_Value::XML_STRING)
 183       *
 184       * By default the value type is autodetected according to it's PHP type
 185       *
 186       * @param mixed $value
 187       * @param Zend_XmlRpc_Value::constant $type
 188       *
 189       * @return Zend_XmlRpc_Value
 190       * @static
 191       */
 192      public static function getXmlRpcValue($value, $type = self::AUTO_DETECT_TYPE)
 193      {
 194          switch ($type) {
 195              case self::AUTO_DETECT_TYPE:
 196                  // Auto detect the XML-RPC native type from the PHP type of $value
 197                  return self::_phpVarToNativeXmlRpc($value);
 198  
 199              case self::XML_STRING:
 200                  // Parse the XML string given in $value and get the XML-RPC value in it
 201                  return self::_xmlStringToNativeXmlRpc($value);
 202  
 203              case self::XMLRPC_TYPE_I4:
 204                  // fall through to the next case
 205              case self::XMLRPC_TYPE_INTEGER:
 206                  require_once 'Zend/XmlRpc/Value/Integer.php';
 207                  return new Zend_XmlRpc_Value_Integer($value);
 208  
 209              case self::XMLRPC_TYPE_I8:
 210                  // fall through to the next case
 211              case self::XMLRPC_TYPE_APACHEI8:
 212                  require_once 'Zend/XmlRpc/Value/BigInteger.php';
 213                  return new Zend_XmlRpc_Value_BigInteger($value);
 214  
 215              case self::XMLRPC_TYPE_DOUBLE:
 216                  require_once 'Zend/XmlRpc/Value/Double.php';
 217                  return new Zend_XmlRpc_Value_Double($value);
 218  
 219              case self::XMLRPC_TYPE_BOOLEAN:
 220                  require_once 'Zend/XmlRpc/Value/Boolean.php';
 221                  return new Zend_XmlRpc_Value_Boolean($value);
 222  
 223              case self::XMLRPC_TYPE_STRING:
 224                  require_once 'Zend/XmlRpc/Value/String.php';
 225                  return new Zend_XmlRpc_Value_String($value);
 226  
 227              case self::XMLRPC_TYPE_BASE64:
 228                  require_once 'Zend/XmlRpc/Value/Base64.php';
 229                  return new Zend_XmlRpc_Value_Base64($value);
 230  
 231              case self::XMLRPC_TYPE_NIL:
 232                  // fall through to the next case
 233              case self::XMLRPC_TYPE_APACHENIL:
 234                  require_once 'Zend/XmlRpc/Value/Nil.php';
 235                  return new Zend_XmlRpc_Value_Nil();
 236  
 237              case self::XMLRPC_TYPE_DATETIME:
 238                  require_once 'Zend/XmlRpc/Value/DateTime.php';
 239                  return new Zend_XmlRpc_Value_DateTime($value);
 240  
 241              case self::XMLRPC_TYPE_ARRAY:
 242                  require_once 'Zend/XmlRpc/Value/Array.php';
 243                  return new Zend_XmlRpc_Value_Array($value);
 244  
 245              case self::XMLRPC_TYPE_STRUCT:
 246                  require_once 'Zend/XmlRpc/Value/Struct.php';
 247                  return new Zend_XmlRpc_Value_Struct($value);
 248  
 249              default:
 250                  require_once 'Zend/XmlRpc/Value/Exception.php';
 251                  throw new Zend_XmlRpc_Value_Exception('Given type is not a '. __CLASS__ .' constant');
 252          }
 253      }
 254  
 255  
 256      /**
 257       * Transform a PHP native variable into a XML-RPC native value
 258       *
 259       * @param mixed $value The PHP variable for convertion
 260       *
 261       * @return Zend_XmlRpc_Value
 262       * @static
 263       */
 264      protected static function _phpVarToNativeXmlRpc($value)
 265      {
 266          switch (gettype($value)) {
 267              case 'object':
 268                  // Check to see if it's an XmlRpc value
 269                  if ($value instanceof Zend_XmlRpc_Value) {
 270                      return $value;
 271                  }
 272  
 273                  if ($value instanceof Zend_Crypt_Math_BigInteger) {
 274                      require_once 'Zend/XmlRpc/Value/BigInteger.php';
 275                      return new Zend_XmlRpc_Value_BigInteger($value);
 276                  }
 277  
 278                  if ($value instanceof Zend_Date or $value instanceof DateTime) {
 279                      require_once 'Zend/XmlRpc/Value/DateTime.php';
 280                      return new Zend_XmlRpc_Value_DateTime($value);
 281                  }
 282  
 283                  // Otherwise, we convert the object into a struct
 284                  $value = get_object_vars($value);
 285                  // Break intentionally omitted
 286              case 'array':
 287                  // Default native type for a PHP array (a simple numeric array) is 'array'
 288                  require_once 'Zend/XmlRpc/Value/Array.php';
 289                  $obj = 'Zend_XmlRpc_Value_Array';
 290  
 291                  // Determine if this is an associative array
 292                  if (!empty($value) && is_array($value) && (array_keys($value) !== range(0, count($value) - 1))) {
 293                      require_once 'Zend/XmlRpc/Value/Struct.php';
 294                      $obj = 'Zend_XmlRpc_Value_Struct';
 295                  }
 296                  return new $obj($value);
 297  
 298              case 'integer':
 299                  require_once 'Zend/XmlRpc/Value/Integer.php';
 300                  return new Zend_XmlRpc_Value_Integer($value);
 301  
 302              case 'double':
 303                  require_once 'Zend/XmlRpc/Value/Double.php';
 304                  return new Zend_XmlRpc_Value_Double($value);
 305  
 306              case 'boolean':
 307                  require_once 'Zend/XmlRpc/Value/Boolean.php';
 308                  return new Zend_XmlRpc_Value_Boolean($value);
 309  
 310              case 'NULL':
 311              case 'null':
 312                  require_once 'Zend/XmlRpc/Value/Nil.php';
 313                  return new Zend_XmlRpc_Value_Nil();
 314  
 315              case 'string':
 316                  // Fall through to the next case
 317              default:
 318                  // If type isn't identified (or identified as string), it treated as string
 319                  require_once 'Zend/XmlRpc/Value/String.php';
 320                  return new Zend_XmlRpc_Value_String($value);
 321          }
 322      }
 323  
 324  
 325      /**
 326       * Transform an XML string into a XML-RPC native value
 327       *
 328       * @param string|SimpleXMLElement $xml A SimpleXMLElement object represent the XML string
 329       *                                            It can be also a valid XML string for convertion
 330       *
 331       * @return Zend_XmlRpc_Value
 332       * @static
 333       */
 334      protected static function _xmlStringToNativeXmlRpc($xml)
 335      {
 336          self::_createSimpleXMLElement($xml);
 337  
 338          self::_extractTypeAndValue($xml, $type, $value);
 339  
 340          switch ($type) {
 341              // All valid and known XML-RPC native values
 342              case self::XMLRPC_TYPE_I4:
 343                  // Fall through to the next case
 344              case self::XMLRPC_TYPE_INTEGER:
 345                  require_once 'Zend/XmlRpc/Value/Integer.php';
 346                  $xmlrpcValue = new Zend_XmlRpc_Value_Integer($value);
 347                  break;
 348              case self::XMLRPC_TYPE_APACHEI8:
 349                  // Fall through to the next case
 350              case self::XMLRPC_TYPE_I8:
 351                  require_once 'Zend/XmlRpc/Value/BigInteger.php';
 352                  $xmlrpcValue = new Zend_XmlRpc_Value_BigInteger($value);
 353                  break;
 354              case self::XMLRPC_TYPE_DOUBLE:
 355                  require_once 'Zend/XmlRpc/Value/Double.php';
 356                  $xmlrpcValue = new Zend_XmlRpc_Value_Double($value);
 357                  break;
 358              case self::XMLRPC_TYPE_BOOLEAN:
 359                  require_once 'Zend/XmlRpc/Value/Boolean.php';
 360                  $xmlrpcValue = new Zend_XmlRpc_Value_Boolean($value);
 361                  break;
 362              case self::XMLRPC_TYPE_STRING:
 363                  require_once 'Zend/XmlRpc/Value/String.php';
 364                  $xmlrpcValue = new Zend_XmlRpc_Value_String($value);
 365                  break;
 366              case self::XMLRPC_TYPE_DATETIME:  // The value should already be in a iso8601 format
 367                  require_once 'Zend/XmlRpc/Value/DateTime.php';
 368                  $xmlrpcValue = new Zend_XmlRpc_Value_DateTime($value);
 369                  break;
 370              case self::XMLRPC_TYPE_BASE64:    // The value should already be base64 encoded
 371                  require_once 'Zend/XmlRpc/Value/Base64.php';
 372                  $xmlrpcValue = new Zend_XmlRpc_Value_Base64($value, true);
 373                  break;
 374              case self::XMLRPC_TYPE_NIL:
 375                  // Fall through to the next case
 376              case self::XMLRPC_TYPE_APACHENIL:
 377                  // The value should always be NULL
 378                  require_once 'Zend/XmlRpc/Value/Nil.php';
 379                  $xmlrpcValue = new Zend_XmlRpc_Value_Nil();
 380                  break;
 381              case self::XMLRPC_TYPE_ARRAY:
 382                  // PHP 5.2.4 introduced a regression in how empty($xml->value)
 383                  // returns; need to look for the item specifically
 384                  $data = null;
 385                  foreach ($value->children() as $key => $value) {
 386                      if ('data' == $key) {
 387                          $data = $value;
 388                          break;
 389                      }
 390                  }
 391  
 392                  if (null === $data) {
 393                      require_once 'Zend/XmlRpc/Value/Exception.php';
 394                      throw new Zend_XmlRpc_Value_Exception('Invalid XML for XML-RPC native '. self::XMLRPC_TYPE_ARRAY .' type: ARRAY tag must contain DATA tag');
 395                  }
 396                  $values = array();
 397                  // Parse all the elements of the array from the XML string
 398                  // (simple xml element) to Zend_XmlRpc_Value objects
 399                  foreach ($data->value as $element) {
 400                      $values[] = self::_xmlStringToNativeXmlRpc($element);
 401                  }
 402                  require_once 'Zend/XmlRpc/Value/Array.php';
 403                  $xmlrpcValue = new Zend_XmlRpc_Value_Array($values);
 404                  break;
 405              case self::XMLRPC_TYPE_STRUCT:
 406                  $values = array();
 407                  // Parse all the memebers of the struct from the XML string
 408                  // (simple xml element) to Zend_XmlRpc_Value objects
 409                  foreach ($value->member as $member) {
 410                      // @todo? If a member doesn't have a <value> tag, we don't add it to the struct
 411                      // Maybe we want to throw an exception here ?
 412                      if (!isset($member->value) or !isset($member->name)) {
 413                          continue;
 414                          //throw new Zend_XmlRpc_Value_Exception('Member of the '. self::XMLRPC_TYPE_STRUCT .' XML-RPC native type must contain a VALUE tag');
 415                      }
 416                      $values[(string)$member->name] = self::_xmlStringToNativeXmlRpc($member->value);
 417                  }
 418                  require_once 'Zend/XmlRpc/Value/Struct.php';
 419                  $xmlrpcValue = new Zend_XmlRpc_Value_Struct($values);
 420                  break;
 421              default:
 422                  require_once 'Zend/XmlRpc/Value/Exception.php';
 423                  throw new Zend_XmlRpc_Value_Exception('Value type \''. $type .'\' parsed from the XML string is not a known XML-RPC native type');
 424                  break;
 425          }
 426          $xmlrpcValue->_setXML($xml->asXML());
 427  
 428          return $xmlrpcValue;
 429      }
 430  
 431      protected static function _createSimpleXMLElement(&$xml)
 432      {
 433          if ($xml instanceof SimpleXMLElement) {
 434              return;
 435          }
 436  
 437          try {
 438              $xml = new SimpleXMLElement($xml);
 439          } catch (Exception $e) {
 440              // The given string is not a valid XML
 441              require_once 'Zend/XmlRpc/Value/Exception.php';
 442              throw new Zend_XmlRpc_Value_Exception('Failed to create XML-RPC value from XML string: ' . $e->getMessage(), $e->getCode(), $e);
 443          }
 444      }
 445  
 446      /**
 447       * Extract XML/RPC type and value from SimpleXMLElement object
 448       *
 449       * @param SimpleXMLElement $xml
 450       * @param string &$type Type bind variable
 451       * @param string &$value Value bind variable
 452       * @return void
 453       */
 454      protected static function _extractTypeAndValue(SimpleXMLElement $xml, &$type, &$value)
 455      {
 456          list($type, $value) = each($xml);
 457  
 458          if (!$type and $value === null) {
 459              $namespaces = array('ex' => 'http://ws.apache.org/xmlrpc/namespaces/extensions');
 460              foreach ($namespaces as $namespaceName => $namespaceUri) {
 461                  $namespaceXml = $xml->children($namespaceUri);
 462                  list($type, $value) = each($namespaceXml);
 463                  if ($type !== null) {
 464                      $type = $namespaceName . ':' . $type;
 465                      break;
 466                  }
 467              }
 468          }
 469  
 470          // If no type was specified, the default is string
 471          if (!$type) {
 472              $type = self::XMLRPC_TYPE_STRING;
 473          }
 474      }
 475  
 476      /**
 477       * @param $xml
 478       * @return void
 479       */
 480      protected function _setXML($xml)
 481      {
 482          $this->_xml = $this->getGenerator()->stripDeclaration($xml);
 483      }
 484  }


Generated: Fri Nov 28 20:29:05 2014 Cross-referenced by PHPXref 0.7.1