Example #1
0
 /**
  * Takes an xmlrpc value in object format and translates it into native PHP types.
  *
  * Works with xmlrpc requests objects as input, too.
  *
  * Given proper options parameter, can rebuild generic php object instances
  * (provided those have been encoded to xmlrpc format using a corresponding
  * option in php_xmlrpc_encode())
  * PLEASE NOTE that rebuilding php objects involves calling their constructor function.
  * This means that the remote communication end can decide which php code will
  * get executed on your server, leaving the door possibly open to 'php-injection'
  * style of attacks (provided you have some classes defined on your server that
  * might wreak havoc if instances are built outside an appropriate context).
  * Make sure you trust the remote server/client before eanbling this!
  *
  * @author Dan Libby (dan@libby.com)
  *
  * @param Value|Request $xmlrpcVal
  * @param array $options if 'decode_php_objs' is set in the options array, xmlrpc structs can be decoded into php objects; if 'dates_as_objects' is set xmlrpc datetimes are decoded as php DateTime objects (standard is
  *
  * @return mixed
  */
 public function decode($xmlrpcVal, $options = array())
 {
     switch ($xmlrpcVal->kindOf()) {
         case 'scalar':
             if (in_array('extension_api', $options)) {
                 reset($xmlrpcVal->me);
                 list($typ, $val) = each($xmlrpcVal->me);
                 switch ($typ) {
                     case 'dateTime.iso8601':
                         $xmlrpcVal->scalar = $val;
                         $xmlrpcVal->type = 'datetime';
                         $xmlrpcVal->timestamp = \PhpXmlRpc\Helper\Date::iso8601Decode($val);
                         return $xmlrpcVal;
                     case 'base64':
                         $xmlrpcVal->scalar = $val;
                         $xmlrpcVal->type = $typ;
                         return $xmlrpcVal;
                     default:
                         return $xmlrpcVal->scalarval();
                 }
             }
             if (in_array('dates_as_objects', $options) && $xmlrpcVal->scalartyp() == 'dateTime.iso8601') {
                 // we return a Datetime object instead of a string
                 // since now the constructor of xmlrpc value accepts safely strings, ints and datetimes,
                 // we cater to all 3 cases here
                 $out = $xmlrpcVal->scalarval();
                 if (is_string($out)) {
                     $out = strtotime($out);
                 }
                 if (is_int($out)) {
                     $result = new \Datetime();
                     $result->setTimestamp($out);
                     return $result;
                 } elseif (is_a($out, 'Datetime')) {
                     return $out;
                 }
             }
             return $xmlrpcVal->scalarval();
         case 'array':
             $arr = array();
             foreach ($xmlrpcVal as $value) {
                 $arr[] = $this->decode($value, $options);
             }
             return $arr;
         case 'struct':
             // If user said so, try to rebuild php objects for specific struct vals.
             /// @todo should we raise a warning for class not found?
             // shall we check for proper subclass of xmlrpc value instead of
             // presence of _php_class to detect what we can do?
             if (in_array('decode_php_objs', $options) && $xmlrpcVal->_php_class != '' && class_exists($xmlrpcVal->_php_class)) {
                 $obj = @new $xmlrpcVal->_php_class();
                 foreach ($xmlrpcVal as $key => $value) {
                     $obj->{$key} = $this->decode($value, $options);
                 }
                 return $obj;
             } else {
                 $arr = array();
                 foreach ($xmlrpcVal as $key => $value) {
                     $arr[$key] = $this->decode($value, $options);
                 }
                 return $arr;
             }
         case 'msg':
             $paramCount = $xmlrpcVal->getNumParams();
             $arr = array();
             for ($i = 0; $i < $paramCount; $i++) {
                 $arr[] = $this->decode($xmlrpcVal->getParam($i), $options);
             }
             return $arr;
     }
 }