+++ /dev/null
-<?php
-
-abstract class IPF_Server_Abstract implements IPF_Server_Interface
-{
- protected static $magic_methods = array(
- '__construct',
- '__destruct',
- '__get',
- '__set',
- '__call',
- '__sleep',
- '__wakeup',
- '__isset',
- '__unset',
- '__tostring',
- '__clone',
- '__set_state',
- );
-
- public static function lowerCase(&$value, &$key)
- {
- return $value = strtolower($value);
- }
-}
+++ /dev/null
-<?php
-
-interface IPF_Server_Interface
-{
- public function addFunction($function, $namespace = '');
- public function setClass($class, $namespace = '', $argv = null);
- public function fault($fault = null, $code = 404);
- public function handle($request = false);
- public function getFunctions();
- public function loadFunctions($definition);
- public function setPersistence($mode);
-}
+++ /dev/null
-<?php
-
-class IPF_Server_Reflection
-{
- public static function reflectClass($class, $argv = false, $namespace = '')
- {
- if (is_object($class)) {
- $reflection = new ReflectionObject($class);
- } elseif (class_exists($class)) {
- $reflection = new ReflectionClass($class);
- } else {
- throw new IPF_Exception('Invalid class or object passed to attachClass()');
- }
-
- if ($argv && !is_array($argv)) {
- throw new IPF_Exception('Invalid argv argument passed to reflectClass');
- }
- return new IPF_Server_Reflection_Class($reflection, $namespace, $argv);
- }
-
- public static function reflectFunction($function, $argv = false, $namespace = '')
- {
- if (!is_string($function) || !function_exists($function)) {
- throw new IPF_Exception('Invalid function "' . $function . '" passed to reflectFunction');
- }
- if ($argv && !is_array($argv)) {
- throw new IPF_Exception('Invalid argv argument passed to reflectClass');
- }
- return new IPF_Server_Reflection_Function(new ReflectionFunction($function), $namespace, $argv);
- }
-}
+++ /dev/null
-<?php
-
-class IPF_Server_Reflection_Class
-{
- protected $_config = array();
- protected $_methods = array();
- protected $_namespace = null;
- protected $_reflection;
- public function __construct(ReflectionClass $reflection, $namespace = null, $argv = false)
- {
- $this->_reflection = $reflection;
- $this->setNamespace($namespace);
-
- foreach ($reflection->getMethods() as $method) {
- // Don't aggregate magic methods
- if ('__' == substr($method->getName(), 0, 2)) {
- continue;
- }
-
- if ($method->isPublic()) {
- // Get signatures and description
- $this->_methods[] = new IPF_Server_Reflection_Method($this, $method, $this->getNamespace(), $argv);
- }
- }
- }
-
- public function __call($method, $args)
- {
- if (method_exists($this->_reflection, $method)) {
- return call_user_func_array(array($this->_reflection, $method), $args);
- }
- throw new IPF_Exception('Invalid reflection method');
- }
-
- public function __get($key)
- {
- if (isset($this->_config[$key])) {
- return $this->_config[$key];
- }
-
- return null;
- }
-
- public function __set($key, $value)
- {
- $this->_config[$key] = $value;
- }
-
- public function getMethods()
- {
- return $this->_methods;
- }
-
- public function getNamespace()
- {
- return $this->_namespace;
- }
-
- public function setNamespace($namespace)
- {
- if (empty($namespace)) {
- $this->_namespace = '';
- return;
- }
-
- if (!is_string($namespace) || !preg_match('/[a-z0-9_\.]+/i', $namespace)) {
- throw new IPF_Exception('Invalid namespace');
- }
-
- $this->_namespace = $namespace;
- }
-
- public function __wakeup()
- {
- $this->_reflection = new ReflectionClass($this->getName());
- }
-}
+++ /dev/null
-<?php
-
-class IPF_Server_Reflection_Function extends IPF_Server_Reflection_Function_Abstract{
-}
+++ /dev/null
-<?php
-
-class IPF_Server_Reflection_Function_Abstract
-{
- protected $_reflection;
- protected $_argv = array();
- protected $_config = array();
- protected $_class;
- protected $_description = '';
- protected $_namespace;
-
- protected $_prototypes = array();
-
- private $_return;
- private $_returnDesc;
- private $_paramDesc;
- private $_sigParams;
- private $_sigParamsDepth;
-
- public function __construct(Reflector $r, $namespace = null, $argv = array())
- {
- // In PHP 5.1.x, ReflectionMethod extends ReflectionFunction. In 5.2.x,
- // both extend ReflectionFunctionAbstract. So, we can't do normal type
- // hinting in the prototype, but instead need to do some explicit
- // testing here.
- if ((!$r instanceof ReflectionFunction)
- && (!$r instanceof ReflectionMethod)) {
- throw new IPF_Exception('Invalid reflection class');
- }
- $this->_reflection = $r;
-
- // Determine namespace
- if (null !== $namespace){
- $this->setNamespace($namespace);
- }
-
- // Determine arguments
- if (is_array($argv)) {
- $this->_argv = $argv;
- }
-
- // If method call, need to store some info on the class
- if ($r instanceof ReflectionMethod) {
- $this->_class = $r->getDeclaringClass()->getName();
- }
-
- // Perform some introspection
- $this->_reflect();
- }
-
- protected function _addTree(IPF_Server_Reflection_Node $parent, $level = 0)
- {
- if ($level >= $this->_sigParamsDepth) {
- return;
- }
-
- foreach ($this->_sigParams[$level] as $value) {
- $node = new IPF_Server_Reflection_Node($value, $parent);
- if ((null !== $value) && ($this->_sigParamsDepth > $level + 1)) {
- $this->_addTree($node, $level + 1);
- }
- }
- }
-
- protected function _buildTree()
- {
- $returnTree = array();
- foreach ((array) $this->_return as $value) {
- $node = new IPF_Server_Reflection_Node($value);
- $this->_addTree($node);
- $returnTree[] = $node;
- }
-
- return $returnTree;
- }
-
- protected function _buildSignatures($return, $returnDesc, $paramTypes, $paramDesc)
- {
- $this->_return = $return;
- $this->_returnDesc = $returnDesc;
- $this->_paramDesc = $paramDesc;
- $this->_sigParams = $paramTypes;
- $this->_sigParamsDepth = count($paramTypes);
- $signatureTrees = $this->_buildTree();
- $signatures = array();
-
- $endPoints = array();
- foreach ($signatureTrees as $root) {
- $tmp = $root->getEndPoints();
- if (empty($tmp)) {
- $endPoints = array_merge($endPoints, array($root));
- } else {
- $endPoints = array_merge($endPoints, $tmp);
- }
- }
-
- foreach ($endPoints as $node) {
- if (!$node instanceof IPF_Server_Reflection_Node) {
- continue;
- }
-
- $signature = array();
- do {
- array_unshift($signature, $node->getValue());
- $node = $node->getParent();
- } while ($node instanceof IPF_Server_Reflection_Node);
-
- $signatures[] = $signature;
- }
-
- // Build prototypes
- $params = $this->_reflection->getParameters();
- foreach ($signatures as $signature) {
- $return = new IPF_Server_Reflection_ReturnValue(array_shift($signature), $this->_returnDesc);
- $tmp = array();
- foreach ($signature as $key => $type) {
- $param = new IPF_Server_Reflection_Parameter($params[$key], $type, $this->_paramDesc[$key]);
- $param->setPosition($key);
- $tmp[] = $param;
- }
-
- $this->_prototypes[] = new IPF_Server_Reflection_Prototype($return, $tmp);
- }
- }
-
- protected function _reflect()
- {
- $function = $this->_reflection;
- $helpText = '';
- $signatures = array();
- $returnDesc = '';
- $paramCount = $function->getNumberOfParameters();
- $paramCountRequired = $function->getNumberOfRequiredParameters();
- $parameters = $function->getParameters();
- $docBlock = $function->getDocComment();
-
- if (!empty($docBlock)) {
- // Get help text
- if (preg_match(':/\*\*\s*\r?\n\s*\*\s(.*?)\r?\n\s*\*(\s@|/):s', $docBlock, $matches))
- {
- $helpText = $matches[1];
- $helpText = preg_replace('/(^\s*\*\s)/m', '', $helpText);
- $helpText = preg_replace('/\r?\n\s*\*\s*(\r?\n)*/s', "\n", $helpText);
- $helpText = trim($helpText);
- }
-
- // Get return type(s) and description
- $return = 'void';
- if (preg_match('/@return\s+(\S+)/', $docBlock, $matches)) {
- $return = explode('|', $matches[1]);
- if (preg_match('/@return\s+\S+\s+(.*?)(@|\*\/)/s', $docBlock, $matches))
- {
- $value = $matches[1];
- $value = preg_replace('/\s?\*\s/m', '', $value);
- $value = preg_replace('/\s{2,}/', ' ', $value);
- $returnDesc = trim($value);
- }
- }
-
- // Get param types and description
- if (preg_match_all('/@param\s+([^\s]+)/m', $docBlock, $matches)) {
- $paramTypesTmp = $matches[1];
- if (preg_match_all('/@param\s+\S+\s+(\$^\S+)\s+(.*?)(@|\*\/)/s', $docBlock, $matches))
- {
- $paramDesc = $matches[2];
- foreach ($paramDesc as $key => $value) {
- $value = preg_replace('/\s?\*\s/m', '', $value);
- $value = preg_replace('/\s{2,}/', ' ', $value);
- $paramDesc[$key] = trim($value);
- }
- }
- }
- } else {
- $helpText = $function->getName();
- $return = 'void';
- }
-
- // Set method description
- $this->setDescription($helpText);
-
- // Get all param types as arrays
- if (!isset($paramTypesTmp) && (0 < $paramCount)) {
- $paramTypesTmp = array_fill(0, $paramCount, 'mixed');
- } elseif (!isset($paramTypesTmp)) {
- $paramTypesTmp = array();
- } elseif (count($paramTypesTmp) < $paramCount) {
- $start = $paramCount - count($paramTypesTmp);
- for ($i = $start; $i < $paramCount; ++$i) {
- $paramTypesTmp[$i] = 'mixed';
- }
- }
-
- // Get all param descriptions as arrays
- if (!isset($paramDesc) && (0 < $paramCount)) {
- $paramDesc = array_fill(0, $paramCount, '');
- } elseif (!isset($paramDesc)) {
- $paramDesc = array();
- } elseif (count($paramDesc) < $paramCount) {
- $start = $paramCount - count($paramDesc);
- for ($i = $start; $i < $paramCount; ++$i) {
- $paramDesc[$i] = '';
- }
- }
-
-
- $paramTypes = array();
- foreach ($paramTypesTmp as $i => $param) {
- $tmp = explode('|', $param);
- if ($parameters[$i]->isOptional()) {
- array_unshift($tmp, null);
- }
- $paramTypes[] = $tmp;
- }
-
- $this->_buildSignatures($return, $returnDesc, $paramTypes, $paramDesc);
- }
-
- public function __call($method, $args)
- {
- if (method_exists($this->_reflection, $method)) {
- return call_user_func_array(array($this->_reflection, $method), $args);
- }
-
- throw new IPF_Exception('Invalid reflection method ("' .$method. '")');
- }
-
- public function __get($key)
- {
- if (isset($this->_config[$key])) {
- return $this->_config[$key];
- }
-
- return null;
- }
-
- public function __set($key, $value)
- {
- $this->_config[$key] = $value;
- }
-
- public function setNamespace($namespace)
- {
- if (empty($namespace)) {
- $this->_namespace = '';
- return;
- }
-
- if (!is_string($namespace) || !preg_match('/[a-z0-9_\.]+/i', $namespace)) {
- throw new IPF_Exception('Invalid namespace');
- }
-
- $this->_namespace = $namespace;
- }
-
- public function getNamespace()
- {
- return $this->_namespace;
- }
-
- public function setDescription($string)
- {
- if (!is_string($string)) {
- throw new IPF_Exception('Invalid description');
- }
-
- $this->_description = $string;
- }
-
- public function getDescription()
- {
- return $this->_description;
- }
-
- public function getPrototypes()
- {
- return $this->_prototypes;
- }
-
- public function getInvokeArguments()
- {
- return $this->_argv;
- }
-
- public function __wakeup()
- {
- if ($this->_reflection instanceof ReflectionMethod) {
- $class = new ReflectionClass($this->_class);
- $this->_reflection = new ReflectionMethod($class->newInstance(), $this->getName());
- } else {
- $this->_reflection = new ReflectionFunction($this->getName());
- }
- }
-}
+++ /dev/null
-<?php
-
-class IPF_Server_Reflection_Method extends IPF_Server_Reflection_Function_Abstract
-{
- protected $_class;
- protected $_classReflection;
-
- public function __construct(IPF_Server_Reflection_Class $class, ReflectionMethod $r, $namespace = null, $argv = array())
- {
- $this->_classReflection = $class;
- $this->_reflection = $r;
-
- $classNamespace = $class->getNamespace();
-
- // Determine namespace
- if (!empty($namespace)) {
- $this->setNamespace($namespace);
- } elseif (!empty($classNamespace)) {
- $this->setNamespace($classNamespace);
- }
-
- // Determine arguments
- if (is_array($argv)) {
- $this->_argv = $argv;
- }
-
- // If method call, need to store some info on the class
- $this->_class = $class->getName();
-
- // Perform some introspection
- $this->_reflect();
- }
-
- public function getDeclaringClass()
- {
- return $this->_classReflection;
- }
-
- public function __wakeup()
- {
- $this->_classReflection = new IPF_Server_Reflection_Class(new ReflectionClass($this->_class), $this->getNamespace(), $this->getInvokeArguments());
- $this->_reflection = new ReflectionMethod($this->_classReflection->getName(), $this->getName());
- }
-
-}
+++ /dev/null
-<?php
-
-class IPF_Server_Reflection_Node
-{
- protected $_value = null;
- protected $_children = array();
- protected $_parent = null;
-
- public function __construct($value, IPF_Server_Reflection_Node $parent = null)
- {
- $this->_value = $value;
- if (null !== $parent) {
- $this->setParent($parent, true);
- }
-
- return $this;
- }
-
- public function setParent(IPF_Server_Reflection_Node $node, $new = false)
- {
- $this->_parent = $node;
-
- if ($new) {
- $node->attachChild($this);
- return;
- }
- }
-
- public function createChild($value)
- {
- $child = new self($value, $this);
-
- return $child;
- }
-
- public function attachChild(IPF_Server_Reflection_Node $node)
- {
- $this->_children[] = $node;
-
- if ($node->getParent() !== $this) {
- $node->setParent($this);
- }
- }
-
- public function getChildren()
- {
- return $this->_children;
- }
-
- public function hasChildren()
- {
- return count($this->_children) > 0;
- }
-
- public function getParent()
- {
- return $this->_parent;
- }
-
- public function getValue()
- {
- return $this->_value;
- }
-
- public function setValue($value)
- {
- $this->_value = $value;
- }
-
- public function getEndPoints()
- {
- $endPoints = array();
- if (!$this->hasChildren()) {
- return $endPoints;
- }
-
- foreach ($this->_children as $child) {
- $value = $child->getValue();
-
- if (null === $value) {
- $endPoints[] = $this;
- } elseif ((null !== $value)
- && $child->hasChildren())
- {
- $childEndPoints = $child->getEndPoints();
- if (!empty($childEndPoints)) {
- $endPoints = array_merge($endPoints, $childEndPoints);
- }
- } elseif ((null !== $value) && !$child->hasChildren()) {
- $endPoints[] = $child;
- }
- }
-
- return $endPoints;
- }
-}
+++ /dev/null
-<?php
-
-class IPF_Server_Reflection_Parameter
-{
- protected $_reflection;
- protected $_position;
- protected $_type;
- protected $_description;
-
- public function __construct(ReflectionParameter $r, $type = 'mixed', $description = '')
- {
- $this->_reflection = $r;
- $this->setType($type);
- $this->setDescription($description);
- }
-
- public function __call($method, $args)
- {
- if (method_exists($this->_reflection, $method)) {
- return call_user_func_array(array($this->_reflection, $method), $args);
- }
- throw new IPF_Exception('Invalid reflection method');
- }
-
- public function getType()
- {
- return $this->_type;
- }
-
- public function setType($type)
- {
- if (!is_string($type) && (null !== $type)) {
- throw new IPF_Exception('Invalid parameter type');
- }
- $this->_type = $type;
- }
-
- public function getDescription()
- {
- return $this->_description;
- }
-
- public function setDescription($description)
- {
- if (!is_string($description) && (null !== $description)) {
- throw new IPF_Exception('Invalid parameter description');
- }
- $this->_description = $description;
- }
-
- public function setPosition($index)
- {
- $this->_position = (int) $index;
- }
-
- public function getPosition()
- {
- return $this->_position;
- }
-}
+++ /dev/null
-<?php
-
-class IPF_Server_Reflection_Prototype
-{
- public function __construct(IPF_Server_Reflection_ReturnValue $return, $params = null)
- {
- $this->_return = $return;
-
- if (!is_array($params) && (null !== $params)) {
- throw new IPF_Exception('Invalid parameters');
- }
-
- if (is_array($params)) {
- foreach ($params as $param) {
- if (!$param instanceof IPF_Server_Reflection_Parameter) {
- throw new IPF_Exception('One or more params are invalid');
- }
- }
- }
-
- $this->_params = $params;
- }
-
- public function getReturnType()
- {
- return $this->_return->getType();
- }
-
- public function getReturnValue()
- {
- return $this->_return;
- }
-
- public function getParameters()
- {
- return $this->_params;
- }
-}
+++ /dev/null
-<?php
-
-class IPF_Server_Reflection_ReturnValue
-{
- protected $_type;
- protected $_description;
-
- public function __construct($type = 'mixed', $description = '')
- {
- $this->setType($type);
- $this->setDescription($description);
- }
-
- public function getType()
- {
- return $this->_type;
- }
-
- public function setType($type)
- {
- if (!is_string($type) && (null !== $type)) {
- throw new IPF_Exception('Invalid parameter type');
- }
- $this->_type = $type;
- }
-
- public function getDescription()
- {
- return $this->_description;
- }
-
- public function setDescription($description)
- {
- if (!is_string($description) && (null !== $description)) {
- throw new IPF_Exception('Invalid parameter description');
- }
- $this->_description = $description;
- }
-}
+++ /dev/null
-<?php
-
-class IPF_XmlRpc_Fault
-{
- protected $_code;
- protected $_encoding = 'UTF-8';
- protected $_message;
-
- protected $_internal = array(
- 404 => 'Unknown Error',
-
- // 610 - 619 reflection errors
- 610 => 'Invalid method class',
- 611 => 'Unable to attach function or callback; not callable',
- 612 => 'Unable to load array; not an array',
- 613 => 'One or more method records are corrupt or otherwise unusable',
-
- // 620 - 629 dispatch errors
- 620 => 'Method does not exist',
- 621 => 'Error instantiating class to invoke method',
- 622 => 'Method missing implementation',
- 623 => 'Calling parameters do not match signature',
-
- // 630 - 639 request errors
- 630 => 'Unable to read request',
- 631 => 'Failed to parse request',
- 632 => 'Invalid request, no method passed; request must contain a \'methodName\' tag',
- 633 => 'Param must contain a value',
- 634 => 'Invalid method name',
- 635 => 'Invalid XML provided to request',
- 636 => 'Error creating xmlrpc value',
-
- // 640 - 649 system.* errors
- 640 => 'Method does not exist',
-
- // 650 - 659 response errors
- 650 => 'Invalid XML provided for response',
- 651 => 'Failed to parse response',
- 652 => 'Invalid response',
- 653 => 'Invalid XMLRPC value in response',
- );
-
- public function __construct($code = 404, $message = '')
- {
- $this->setCode($code);
- $code = $this->getCode();
-
- if (empty($message) && isset($this->_internal[$code])) {
- $message = $this->_internal[$code];
- } elseif (empty($message)) {
- $message = 'Unknown error';
- }
- $this->setMessage($message);
- }
-
- public function setCode($code)
- {
- $this->_code = (int) $code;
- return $this;
- }
-
- public function getCode()
- {
- return $this->_code;
- }
-
- public function setMessage($message)
- {
- $this->_message = (string) $message;
- return $this;
- }
-
- public function getMessage()
- {
- return $this->_message;
- }
-
- public function setEncoding($encoding)
- {
- $this->_encoding = $encoding;
- return $this;
- }
-
- public function getEncoding()
- {
- return $this->_encoding;
- }
-
- public function loadXml($fault)
- {
- if (!is_string($fault)) {
- throw new IPF_Exception('Invalid XML provided to fault');
- }
-
- try {
- $xml = @new SimpleXMLElement($fault);
- } catch (Exception $e) {
- // Not valid XML
- throw new IPF_Exception('Failed to parse XML fault: ' . $e->getMessage(), 500);
- }
-
- // Check for fault
- if (!$xml->fault) {
- // Not a fault
- return false;
- }
-
- if (!$xml->fault->value->struct) {
- // not a proper fault
- throw new IPF_Exception('Invalid fault structure', 500);
- }
-
- $structXml = $xml->fault->value->asXML();
- $structXml = preg_replace('/<\?xml version=.*?\?>/i', '', $structXml);
- $struct = IPF_XmlRpc_Value::getXmlRpcValue(trim($structXml), IPF_XmlRpc_Value::XML_STRING);
- $struct = $struct->getValue();
-
- if (isset($struct['faultCode'])) {
- $code = $struct['faultCode'];
- }
- if (isset($struct['faultString'])) {
- $message = $struct['faultString'];
- }
-
- if (empty($code) && empty($message)) {
- throw new IPF_Exception('Fault code and string required');
- }
-
- if (empty($code)) {
- $code = '404';
- }
-
- if (empty($message)) {
- if (isset($this->_internal[$code])) {
- $message = $this->_internal[$code];
- } else {
- $message = 'Unknown Error';
- }
- }
-
- $this->setCode($code);
- $this->setMessage($message);
-
- return true;
- }
-
- public static function isFault($xml)
- {
- $fault = new self();
- try {
- $isFault = $fault->loadXml($xml);
- } catch (IPF_Exception $e) {
- $isFault = false;
- }
-
- return $isFault;
- }
-
- public function saveXML()
- {
- // Create fault value
- $faultStruct = array(
- 'faultCode' => $this->getCode(),
- 'faultString' => $this->getMessage()
- );
- $value = IPF_XmlRpc_Value::getXmlRpcValue($faultStruct);
- $valueDOM = new DOMDocument('1.0', $this->getEncoding());
- $valueDOM->loadXML($value->saveXML());
-
- // Build response XML
- $dom = new DOMDocument('1.0', 'ISO-8859-1');
- $r = $dom->appendChild($dom->createElement('methodResponse'));
- $f = $r->appendChild($dom->createElement('fault'));
- $f->appendChild($dom->importNode($valueDOM->documentElement, 1));
-
- return $dom->saveXML();
- }
-
- public function __toString()
- {
- return $this->saveXML();
- }
-}
+++ /dev/null
-<?php
-
-class IPF_XmlRpc_Request
-{
- protected $_encoding = 'UTF-8';
- protected $_method;
- protected $_xml;
- protected $_params = array();
- protected $_fault = null;
- protected $_types = array();
- protected $_xmlRpcParams = array();
-
- public function __construct($method = null, $params = null)
- {
- if ($method !== null) {
- $this->setMethod($method);
- }
-
- if ($params !== null) {
- $this->setParams($params);
- }
- }
-
- public function setEncoding($encoding)
- {
- $this->_encoding = $encoding;
- return $this;
- }
-
- public function getEncoding()
- {
- return $this->_encoding;
- }
-
- public function setMethod($method)
- {
- if (!is_string($method) || !preg_match('/^[a-z0-9_.:\/]+$/i', $method)) {
- $this->_fault = new IPF_XmlRpc_Fault(634, 'Invalid method name ("' . $method . '")');
- $this->_fault->setEncoding($this->getEncoding());
- return false;
- }
-
- $this->_method = $method;
- return true;
- }
-
- public function getMethod()
- {
- return $this->_method;
- }
-
- public function addParam($value, $type = null)
- {
- $this->_params[] = $value;
- if (null === $type) {
- // Detect type if not provided explicitly
- if ($value instanceof IPF_XmlRpc_Value) {
- $type = $value->getType();
- } else {
- $xmlRpcValue = IPF_XmlRpc_Value::getXmlRpcValue($value);
- $type = $xmlRpcValue->getType();
- }
- }
- $this->_types[] = $type;
- $this->_xmlRpcParams[] = array('value' => $value, 'type' => $type);
- }
-
- public function setParams()
- {
- $argc = func_num_args();
- $argv = func_get_args();
- if (0 == $argc) {
- return;
- }
-
- if ((1 == $argc) && is_array($argv[0])) {
- $params = array();
- $types = array();
- $wellFormed = true;
- foreach ($argv[0] as $arg) {
- if (!is_array($arg) || !isset($arg['value'])) {
- $wellFormed = false;
- break;
- }
- $params[] = $arg['value'];
-
- if (!isset($arg['type'])) {
- $xmlRpcValue = IPF_XmlRpc_Value::getXmlRpcValue($arg['value']);
- $arg['type'] = $xmlRpcValue->getType();
- }
- $types[] = $arg['type'];
- }
- if ($wellFormed) {
- $this->_xmlRpcParams = $argv[0];
- $this->_params = $params;
- $this->_types = $types;
- } else {
- $this->_params = $argv[0];
- $this->_types = array();
- $xmlRpcParams = array();
- foreach ($argv[0] as $arg) {
- if ($arg instanceof IPF_XmlRpc_Value) {
- $type = $arg->getType();
- } else {
- $xmlRpcValue = IPF_XmlRpc_Value::getXmlRpcValue($arg);
- $type = $xmlRpcValue->getType();
- }
- $xmlRpcParams[] = array('value' => $arg, 'type' => $type);
- $this->_types[] = $type;
- }
- $this->_xmlRpcParams = $xmlRpcParams;
- }
- return;
- }
-
- $this->_params = $argv;
- $this->_types = array();
- $xmlRpcParams = array();
- foreach ($argv as $arg) {
- if ($arg instanceof IPF_XmlRpc_Value) {
- $type = $arg->getType();
- } else {
- $xmlRpcValue = IPF_XmlRpc_Value::getXmlRpcValue($arg);
- $type = $xmlRpcValue->getType();
- }
- $xmlRpcParams[] = array('value' => $arg, 'type' => $type);
- $this->_types[] = $type;
- }
- $this->_xmlRpcParams = $xmlRpcParams;
- }
-
- public function getParams()
- {
- return $this->_params;
- }
-
- public function getTypes()
- {
- return $this->_types;
- }
-
- public function loadXml($request)
- {
- if (!is_string($request)) {
- $this->_fault = new IPF_XmlRpc_Fault(635);
- $this->_fault->setEncoding($this->getEncoding());
- return false;
- }
-
- try {
- $xml = @new SimpleXMLElement($request);
- } catch (Exception $e) {
- // Not valid XML
- $this->_fault = new IPF_XmlRpc_Fault(631);
- $this->_fault->setEncoding($this->getEncoding());
- return false;
- }
-
- // Check for method name
- if (empty($xml->methodName)) {
- // Missing method name
- $this->_fault = new IPF_XmlRpc_Fault(632);
- $this->_fault->setEncoding($this->getEncoding());
- return false;
- }
-
- $this->_method = (string) $xml->methodName;
-
- // Check for parameters
- if (!empty($xml->params)) {
- $types = array();
- $argv = array();
- foreach ($xml->params->children() as $param) {
- if (! $param->value instanceof SimpleXMLElement) {
- $this->_fault = new IPF_XmlRpc_Fault(633);
- $this->_fault->setEncoding($this->getEncoding());
- return false;
- }
-
- try {
- $param = IPF_XmlRpc_Value::getXmlRpcValue($param->value, IPF_XmlRpc_Value::XML_STRING);
- $types[] = $param->getType();
- $argv[] = $param->getValue();
- } catch (Exception $e) {
- $this->_fault = new IPF_XmlRpc_Fault(636);
- $this->_fault->setEncoding($this->getEncoding());
- return false;
- }
- }
-
- $this->_types = $types;
- $this->_params = $argv;
- }
-
- $this->_xml = $request;
-
- return true;
- }
-
- public function isFault()
- {
- return $this->_fault instanceof IPF_XmlRpc_Fault;
- }
-
- public function getFault()
- {
- return $this->_fault;
- }
-
- protected function _getXmlRpcParams()
- {
- $params = array();
- if (is_array($this->_xmlRpcParams)) {
- foreach ($this->_xmlRpcParams as $param) {
- $value = $param['value'];
- $type = isset($param['type']) ? $param['type'] : IPF_XmlRpc_Value::AUTO_DETECT_TYPE;
-
- if (!$value instanceof IPF_XmlRpc_Value) {
- $value = IPF_XmlRpc_Value::getXmlRpcValue($value, $type);
- }
- $params[] = $value;
- }
- }
-
- return $params;
- }
-
- public function saveXML()
- {
- $args = $this->_getXmlRpcParams();
- $method = $this->getMethod();
-
- $dom = new DOMDocument('1.0', $this->getEncoding());
- $mCall = $dom->appendChild($dom->createElement('methodCall'));
- $mName = $mCall->appendChild($dom->createElement('methodName', $method));
-
- if (is_array($args) && count($args)) {
- $params = $mCall->appendChild($dom->createElement('params'));
-
- foreach ($args as $arg) {
- /* @var $arg IPF_XmlRpc_Value */
- $argDOM = new DOMDocument('1.0', $this->getEncoding());
- $argDOM->loadXML($arg->saveXML());
-
- $param = $params->appendChild($dom->createElement('param'));
- $param->appendChild($dom->importNode($argDOM->documentElement, 1));
- }
- }
-
- return $dom->saveXML();
- }
-
- public function __toString()
- {
- return $this->saveXML();
- }
-}
+++ /dev/null
-<?php
-
-class IPF_XmlRpc_Request_Http extends IPF_XmlRpc_Request
-{
- protected $_headers;
- protected $_xml;
- public function __construct()
- {
- $fh = fopen('php://input', 'r');
- if (!$fh) {
- $this->_fault = new IPF_Exception(630);
- return;
- }
-
- $xml = '';
- while (!feof($fh)) {
- $xml .= fgets($fh);
- }
- fclose($fh);
-
- $this->_xml = $xml;
-
- $this->loadXml($xml);
- }
-
- public function getRawRequest()
- {
- return $this->_xml;
- }
-
- public function getHeaders()
- {
- if (null === $this->_headers) {
- $this->_headers = array();
- foreach ($_SERVER as $key => $value) {
- if ('HTTP_' == substr($key, 0, 5)) {
- $header = str_replace(' ', '-', ucwords(strtolower(str_replace('_', ' ', substr($key, 5)))));
- $this->_headers[$header] = $value;
- }
- }
- }
-
- return $this->_headers;
- }
-
- public function getFullRequest()
- {
- $request = '';
- foreach ($this->getHeaders() as $key => $value) {
- $request .= $key . ': ' . $value . "\n";
- }
-
- $request .= $this->_xml;
-
- return $request;
- }
-}
+++ /dev/null
-<?php
-
-class IPF_XmlRpc_Request_Stdin extends IPF_XmlRpc_Request
-{
- protected $_xml;
-
- public function __construct()
- {
- $fh = fopen('php://stdin', 'r');
- if (!$fh) {
- $this->_fault = new IPF_XmlRpc_Fault(630);
- return;
- }
-
- $xml = '';
- while (!feof($fh)) {
- $xml .= fgets($fh);
- }
- fclose($fh);
-
- $this->_xml = $xml;
-
- $this->loadXml($xml);
- }
-
- public function getRawRequest()
- {
- return $this->_xml;
- }
-}
+++ /dev/null
-<?php
-
-class IPF_XmlRpc_Response
-{
- protected $_return;
- protected $_type;
- protected $_encoding = 'UTF-8';
- protected $_fault = null;
-
- public function __construct($return = null, $type = null)
- {
- $this->setReturnValue($return, $type);
- }
-
- public function setEncoding($encoding)
- {
- $this->_encoding = $encoding;
- return $this;
- }
-
- public function getEncoding()
- {
- return $this->_encoding;
- }
-
- public function setReturnValue($value, $type = null)
- {
- $this->_return = $value;
- $this->_type = (string) $type;
- }
-
- public function getReturnValue()
- {
- return $this->_return;
- }
-
- protected function _getXmlRpcReturn()
- {
- return IPF_XmlRpc_Value::getXmlRpcValue($this->_return);
- }
-
- public function isFault()
- {
- return $this->_fault instanceof IPF_XmlRpc_Fault;
- }
-
- public function getFault()
- {
- return $this->_fault;
- }
-
- public function loadXml($response)
- {
- if (!is_string($response)) {
- $this->_fault = new IPF_XmlRpc_Fault(650);
- $this->_fault->setEncoding($this->getEncoding());
- return false;
- }
-
- try {
- $xml = @new SimpleXMLElement($response);
- } catch (Exception $e) {
- // Not valid XML
- $this->_fault = new IPF_XmlRpc_Fault(651);
- $this->_fault->setEncoding($this->getEncoding());
- return false;
- }
-
- if (!empty($xml->fault)) {
- // fault response
- $this->_fault = new IPF_XmlRpc_Fault();
- $this->_fault->setEncoding($this->getEncoding());
- $this->_fault->loadXml($response);
- return false;
- }
-
- if (empty($xml->params)) {
- // Invalid response
- $this->_fault = new IPF_XmlRpc_Fault(652);
- $this->_fault->setEncoding($this->getEncoding());
- return false;
- }
-
- try {
- if (!isset($xml->params) || !isset($xml->params->param) || !isset($xml->params->param->value)) {
- throw new IPF_Exception('Missing XML-RPC value in XML');
- }
- $valueXml = $xml->params->param->value->asXML();
- $valueXml = preg_replace('/<\?xml version=.*?\?>/i', '', $valueXml);
- $value = IPF_XmlRpc_Value::getXmlRpcValue(trim($valueXml), IPF_XmlRpc_Value::XML_STRING);
- } catch (IPF_Exception $e) {
- $this->_fault = new IPF_XmlRpc_Fault(653);
- $this->_fault->setEncoding($this->getEncoding());
- return false;
- }
-
- $this->setReturnValue($value->getValue());
- return true;
- }
-
- public function saveXML()
- {
- $value = $this->_getXmlRpcReturn();
- $valueDOM = new DOMDocument('1.0', $this->getEncoding());
- $valueDOM->loadXML($value->saveXML());
-
- $dom = new DOMDocument('1.0', $this->getEncoding());
- $response = $dom->appendChild($dom->createElement('methodResponse'));
- $params = $response->appendChild($dom->createElement('params'));
- $param = $params->appendChild($dom->createElement('param'));
-
- $param->appendChild($dom->importNode($valueDOM->documentElement, true));
-
- return $dom->saveXML();
- }
-
- public function __toString()
- {
- return $this->saveXML();
- }
-}
+++ /dev/null
-<?php
-
-class IPF_XmlRpc_Response_Http extends IPF_XmlRpc_Response
-{
- public function __toString()
- {
- if (!headers_sent()) {
- header('Content-Type: text/xml; charset=' . strtolower($this->getEncoding()));
- }
- return parent::__toString();
- }
-}
+++ /dev/null
-<?php
-
-class IPF_XmlRpc_Server
-{
- protected $_encoding = 'UTF-8';
- protected $_methods = array();
- protected $_request = null;
- protected $_responseClass = 'IPF_XmlRpc_Response_Http';
-
- protected $_table = array();
-
- protected $_typeMap = array(
- 'i4' => 'i4',
- 'int' => 'int',
- 'integer' => 'int',
- 'double' => 'double',
- 'float' => 'double',
- 'real' => 'double',
- 'boolean' => 'boolean',
- 'bool' => 'boolean',
- 'true' => 'boolean',
- 'false' => 'boolean',
- 'string' => 'string',
- 'str' => 'string',
- 'base64' => 'base64',
- 'dateTime.iso8601' => 'dateTime.iso8601',
- 'date' => 'dateTime.iso8601',
- 'time' => 'dateTime.iso8601',
- 'time' => 'dateTime.iso8601',
- 'array' => 'array',
- 'struct' => 'struct',
- 'null' => 'nil',
- 'nil' => 'nil',
- 'void' => 'void',
- 'mixed' => 'struct'
- );
-
- public function __construct()
- {
- // Setup system.* methods
- $system = array(
- 'listMethods',
- 'methodHelp',
- 'methodSignature',
- 'multicall'
- );
-
- $class = IPF_Server_Reflection::reflectClass($this);
- foreach ($system as $method) {
- $reflection = new IPF_Server_Reflection_Method($class, new ReflectionMethod($this, $method), 'system');
- $reflection->system = true;
- $this->_methods[] = $reflection;
- }
-
- $this->_buildDispatchTable();
- }
-
- protected function _fixTypes(IPF_Server_Reflection_Function_Abstract $method)
- {
- foreach ($method->getPrototypes() as $prototype) {
- foreach ($prototype->getParameters() as $param) {
- $pType = $param->getType();
- if (isset($this->_typeMap[$pType])) {
- $param->setType($this->_typeMap[$pType]);
- } else {
- $param->setType('void');
- }
- }
- }
- }
-
- protected function _buildDispatchTable()
- {
- $table = array();
- foreach ($this->_methods as $dispatchable) {
- if ($dispatchable instanceof IPF_Server_Reflection_Function_Abstract) {
- // function/method call
- $ns = $dispatchable->getNamespace();
- $name = $dispatchable->getName();
- $name = empty($ns) ? $name : $ns . '.' . $name;
-
- if (isset($table[$name])) {
- throw new IPF_Exception('Duplicate method registered: ' . $name);
- }
- $table[$name] = $dispatchable;
- $this->_fixTypes($dispatchable);
-
- continue;
- }
-
- if ($dispatchable instanceof IPF_Server_Reflection_Class) {
- foreach ($dispatchable->getMethods() as $method) {
- $ns = $method->getNamespace();
- $name = $method->getName();
- $name = empty($ns) ? $name : $ns . '.' . $name;
-
- if (isset($table[$name])) {
- throw new IPF_Exception('Duplicate method registered: ' . $name);
- }
- $table[$name] = $method;
- $this->_fixTypes($method);
- continue;
- }
- }
- }
-
- $this->_table = $table;
- }
-
- public function setEncoding($encoding)
- {
- $this->_encoding = $encoding;
- return $this;
- }
-
- public function getEncoding()
- {
- return $this->_encoding;
- }
-
- public function addFunction($function, $namespace = '')
- {
- if (!is_string($function) && !is_array($function)) {
- throw new IPF_Exception('Unable to attach function; invalid', 611);
- }
-
- $argv = null;
- if (2 < func_num_args()) {
- $argv = func_get_args();
- $argv = array_slice($argv, 2);
- }
-
- $function = (array) $function;
- foreach ($function as $func) {
- if (!is_string($func) || !function_exists($func)) {
- throw new IPF_Exception('Unable to attach function; invalid', 611);
- }
- $this->_methods[] = IPF_Server_Reflection::reflectFunction($func, $argv, $namespace);
- }
-
- $this->_buildDispatchTable();
- }
-
- public function loadFunctions($array)
- {
- if (!is_array($array)) {
- throw new IPF_Exception('Unable to load array; not an array', 612);
- }
-
- foreach ($array as $key => $value) {
- if (!$value instanceof IPF_Server_Reflection_Function_Abstract
- && !$value instanceof IPF_Server_Reflection_Class)
- {
- throw new IPF_Exception('One or more method records are corrupt or otherwise unusable', 613);
- }
-
- if ($value->system) {
- unset($array[$key]);
- }
- }
-
- foreach ($array as $dispatchable) {
- $this->_methods[] = $dispatchable;
- }
-
- $this->_buildDispatchTable();
- }
-
- public function setPersistence($class = null)
- {
- }
-
- public function setClass($class, $namespace = '', $argv = null)
- {
- if (is_string($class) && !class_exists($class)) {
- if (!class_exists($class)) {
- throw new IPF_Exception('Invalid method class', 610);
- }
- }
-
- $argv = null;
- if (3 < func_num_args()) {
- $argv = func_get_args();
- $argv = array_slice($argv, 3);
- }
-
- $this->_methods[] = IPF_Reflection::reflectClass($class, $argv, $namespace);
- $this->_buildDispatchTable();
- }
-
- public function setRequest($request)
- {
- if (is_string($request) && class_exists($request)) {
- $request = new $request();
- if (!$request instanceof IPF_XmlRpc_Request) {
- throw new IPF_Exception('Invalid request class');
- }
- $request->setEncoding($this->getEncoding());
- } elseif (!$request instanceof IPF_XmlRpc_Request) {
- throw new IPF_Exception('Invalid request object');
- }
-
- $this->_request = $request;
- return $this;
- }
-
- public function getRequest()
- {
- return $this->_request;
- }
-
- public function fault($fault, $code = 404)
- {
- if (!$fault instanceof Exception) {
- $fault = (string) $fault;
- $fault = new IPF_Exception($fault, $code);
- }
- return IPF_XmlRpc_Server_Fault::getInstance($fault);
- }
-
- protected function _handle(IPF_XmlRpc_Request $request)
- {
- $method = $request->getMethod();
-
- // Check for valid method
- if (!isset($this->_table[$method])) {
- throw new IPF_Exception('Method "' . $method . '" does not exist', 620);
- }
-
- $info = $this->_table[$method];
- $params = $request->getParams();
- $argv = $info->getInvokeArguments();
- if (0 < count($argv)) {
- $params = array_merge($params, $argv);
- }
-
- // Check calling parameters against signatures
- $matched = false;
- $sigCalled = $request->getTypes();
-
- $sigLength = count($sigCalled);
- $paramsLen = count($params);
- if ($sigLength < $paramsLen) {
- for ($i = $sigLength; $i < $paramsLen; ++$i) {
- $xmlRpcValue = IPF_XmlRpc_Value::getXmlRpcValue($params[$i]);
- $sigCalled[] = $xmlRpcValue->getType();
- }
- }
-
- $signatures = $info->getPrototypes();
- foreach ($signatures as $signature) {
- $sigParams = $signature->getParameters();
- $tmpParams = array();
- foreach ($sigParams as $param) {
- $tmpParams[] = $param->getType();
- }
- if ($sigCalled === $tmpParams) {
- $matched = true;
- break;
- }
- }
- if (!$matched) {
- throw new IPF_Exception('Calling parameters do not match signature', 623);
- }
-
- if ($info instanceof IPF_Server_Reflection_Function) {
- $func = $info->getName();
- $return = call_user_func_array($func, $params);
- } elseif (($info instanceof IPF_Server_Reflection_Method) && $info->system) {
- // System methods
- $return = $info->invokeArgs($this, $params);
- } elseif ($info instanceof IPF_Server_Reflection_Method) {
- // Get class
- $class = $info->getDeclaringClass()->getName();
-
- if ('static' == $info->isStatic()) {
- // for some reason, invokeArgs() does not work the same as
- // invoke(), and expects the first argument to be an object.
- // So, using a callback if the method is static.
- $return = call_user_func_array(array($class, $info->getName()), $params);
- } else {
- // Object methods
- try {
- $object = $info->getDeclaringClass()->newInstance();
- } catch (Exception $e) {
- throw new IPF_Exception('Error instantiating class ' . $class . ' to invoke method ' . $info->getName(), 621);
- }
-
- $return = $info->invokeArgs($object, $params);
- }
- } else {
- throw new IPF_Exception('Method missing implementation ' . get_class($info), 622);
- }
-
- $response = new ReflectionClass($this->_responseClass);
- return $response->newInstance($return);
- }
-
- public function handle(IPF_XmlRpc_Request $request = null)
- {
- // Get request
- if ((null === $request) && (null === ($request = $this->getRequest()))) {
- $request = new IPF_XmlRpc_Request_Http();
- $request->setEncoding($this->getEncoding());
- }
-
- $this->setRequest($request);
-
- if ($request->isFault()) {
- $response = $request->getFault();
- } else {
- try {
- $response = $this->_handle($request);
- } catch (Exception $e) {
- $response = $this->fault($e);
- }
- }
-
- // Set output encoding
- $response->setEncoding($this->getEncoding());
-
- return $response;
- }
-
- public function setResponseClass($class)
- {
- if (class_exists($class)) {
- $reflection = new ReflectionClass($class);
- if ($reflection->isSubclassOf(new ReflectionClass('IPF_XmlRpc_Response'))) {
- $this->_responseClass = $class;
- return true;
- }
- }
-
- return false;
- }
-
- public function getFunctions()
- {
- $return = array();
- foreach ($this->_methods as $method) {
- if ($method instanceof IPF_Server_Reflection_Class
- && ($method->system))
- {
- continue;
- }
-
- $return[] = $method;
- }
-
- return $return;
- }
-
- public function listMethods()
- {
- return array_keys($this->_table);
- }
-
- public function methodHelp($method)
- {
- if (!isset($this->_table[$method])) {
- throw new IPF_Exception('Method "' . $method . '"does not exist', 640);
- }
-
- return $this->_table[$method]->getDescription();
- }
-
- public function methodSignature($method)
- {
- if (!isset($this->_table[$method])) {
- throw new IPF_Exception('Method "' . $method . '"does not exist', 640);
- }
- $prototypes = $this->_table[$method]->getPrototypes();
-
- $signatures = array();
- foreach ($prototypes as $prototype) {
- $signature = array($prototype->getReturnType());
- foreach ($prototype->getParameters() as $parameter) {
- $signature[] = $parameter->getType();
- }
- $signatures[] = $signature;
- }
-
- return $signatures;
- }
-
- public function multicall($methods)
- {
- $responses = array();
- foreach ($methods as $method) {
- $fault = false;
- if (!is_array($method)) {
- $fault = $this->fault('system.multicall expects each method to be a struct', 601);
- } elseif (!isset($method['methodName'])) {
- $fault = $this->fault('Missing methodName', 602);
- } elseif (!isset($method['params'])) {
- $fault = $this->fault('Missing params', 603);
- } elseif (!is_array($method['params'])) {
- $fault = $this->fault('Params must be an array', 604);
- } else {
- if ('system.multicall' == $method['methodName']) {
- // don't allow recursive calls to multicall
- $fault = $this->fault('Recursive system.multicall forbidden', 605);
- }
- }
-
- if (!$fault) {
- try {
- $request = new IPF_XmlRpc_Request();
- $request->setMethod($method['methodName']);
- $request->setParams($method['params']);
- $response = $this->_handle($request);
- $responses[] = $response->getReturnValue();
- } catch (Exception $e) {
- $fault = $this->fault($e);
- }
- }
-
- if ($fault) {
- $responses[] = array(
- 'faultCode' => $fault->getCode(),
- 'faultString' => $fault->getMessage()
- );
- }
- }
- return $responses;
- }
-}
+++ /dev/null
-<?php
-
-class IPF_XmlRpc_Server_Cache
-{
- public static function save($filename, IPF_XmlRpc_Server $server)
- {
- if (!is_string($filename)
- || (!file_exists($filename) && !is_writable(dirname($filename))))
- {
- return false;
- }
-
- // Remove system.* methods
- $methods = $server->getFunctions();
- foreach ($methods as $name => $method) {
- if ($method->system) {
- unset($methods[$name]);
- }
- }
-
- // Store
- if (0 === @file_put_contents($filename, serialize($methods))) {
- return false;
- }
-
- return true;
- }
-
- public static function get($filename, IPF_XmlRpc_Server $server)
- {
- if (!is_string($filename)
- || !file_exists($filename)
- || !is_readable($filename))
- {
- return false;
- }
-
- if (false === ($dispatch = @file_get_contents($filename))) {
- return false;
- }
-
- if (false === ($dispatchArray = @unserialize($dispatch))) {
- return false;
- }
-
- $server->loadFunctions($dispatchArray);
-
- return true;
- }
-
- public static function delete($filename)
- {
- if (is_string($filename) && file_exists($filename)) {
- unlink($filename);
- return true;
- }
-
- return false;
- }
-}
+++ /dev/null
-<?php
-
-class IPF_XmlRpc_Server_Fault extends IPF_XmlRpc_Fault
-{
- protected $_exception;
- protected static $_faultExceptionClasses = array('IPF_Exception' => true);
- protected static $_observers = array();
-
- public function __construct(Exception $e)
- {
- $this->_exception = $e;
- $code = 404;
- $message = 'Unknown error';
- $exceptionClass = get_class($e);
-
- foreach (array_keys(self::$_faultExceptionClasses) as $class) {
- if ($e instanceof $class) {
- $code = $e->getCode();
- $message = $e->getMessage();
- break;
- }
- }
-
- parent::__construct($code, $message);
-
- // Notify exception observers, if present
- if (!empty(self::$_observers)) {
- foreach (array_keys(self::$_observers) as $observer) {
- call_user_func(array($observer, 'observe'), $this);
- }
- }
- }
-
- public static function getInstance(Exception $e)
- {
- return new self($e);
- }
-
- public static function attachFaultException($classes)
- {
- if (!is_array($classes)) {
- $classes = (array) $classes;
- }
-
- foreach ($classes as $class) {
- if (is_string($class) && class_exists($class)) {
- self::$_faultExceptionClasses[$class] = true;
- }
- }
- }
-
- public static function detachFaultException($classes)
- {
- if (!is_array($classes)) {
- $classes = (array) $classes;
- }
-
- foreach ($classes as $class) {
- if (is_string($class) && isset(self::$_faultExceptionClasses[$class])) {
- unset(self::$_faultExceptionClasses[$class]);
- }
- }
- }
-
- public static function attachObserver($class)
- {
- if (!is_string($class)
- || !class_exists($class)
- || !is_callable(array($class, 'observe')))
- {
- return false;
- }
-
- if (!isset(self::$_observers[$class])) {
- self::$_observers[$class] = true;
- }
-
- return true;
- }
-
- public static function detachObserver($class)
- {
- if (!isset(self::$_observers[$class])) {
- return false;
- }
-
- unset(self::$_observers[$class]);
- return true;
- }
-
- public function getException()
- {
- return $this->_exception;
- }
-}
+++ /dev/null
-<?php
-
-abstract class IPF_XmlRpc_Value
-{
- protected $_value;
- protected $_type;
- protected $_as_xml;
- protected $_as_dom;
-
- const AUTO_DETECT_TYPE = 'auto_detect';
- const XML_STRING = 'xml';
-
- const XMLRPC_TYPE_I4 = 'i4';
- const XMLRPC_TYPE_INTEGER = 'int';
- const XMLRPC_TYPE_DOUBLE = 'double';
- const XMLRPC_TYPE_BOOLEAN = 'boolean';
- const XMLRPC_TYPE_STRING = 'string';
- const XMLRPC_TYPE_DATETIME = 'dateTime.iso8601';
- const XMLRPC_TYPE_BASE64 = 'base64';
- const XMLRPC_TYPE_ARRAY = 'array';
- const XMLRPC_TYPE_STRUCT = 'struct';
- const XMLRPC_TYPE_NIL = 'nil';
-
- public function getType()
- {
- return $this->_type;
- }
-
- abstract public function getValue();
- abstract public function saveXML();
-
- public function getAsDOM()
- {
- if (!$this->_as_dom) {
- $doc = new DOMDocument('1.0');
- $doc->loadXML($this->saveXML());
- $this->_as_dom = $doc->documentElement;
- }
-
- return $this->_as_dom;
- }
-
- protected function _stripXmlDeclaration(DOMDocument $dom)
- {
- return preg_replace('/<\?xml version="1.0"( encoding="[^\"]*")?\?>\n/u', '', $dom->saveXML());
- }
-
- public static function getXmlRpcValue($value, $type = self::AUTO_DETECT_TYPE)
- {
- 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 IPF_XmlRpc_Value_Integer($value);
-
- case self::XMLRPC_TYPE_DOUBLE:
- return new IPF_XmlRpc_Value_Double($value);
-
- case self::XMLRPC_TYPE_BOOLEAN:
- return new IPF_XmlRpc_Value_Boolean($value);
-
- case self::XMLRPC_TYPE_STRING:
- return new IPF_XmlRpc_Value_String($value);
-
- case self::XMLRPC_TYPE_BASE64:
- return new IPF_XmlRpc_Value_Base64($value);
-
- case self::XMLRPC_TYPE_NIL:
- return new IPF_XmlRpc_Value_Nil();
-
- case self::XMLRPC_TYPE_DATETIME:
- return new IPF_XmlRpc_Value_DateTime($value);
-
- case self::XMLRPC_TYPE_ARRAY:
- return new IPF_XmlRpc_Value_Array($value);
-
- case self::XMLRPC_TYPE_STRUCT:
- return new IPF_XmlRpc_Value_Struct($value);
-
- default:
- throw new IPF_Exception('Given type is not a '. __CLASS__ .' constant');
- }
- }
-
- private static function _phpVarToNativeXmlRpc($value)
- {
- switch (gettype($value)) {
- case 'object':
- // Check to see if it's an XmlRpc value
- if ($value instanceof IPF_XmlRpc_Value) {
- return $value;
- }
-
- // Otherwise, we convert the object into a struct
- $value = get_object_vars($value);
- // Break intentionally omitted
- case 'array':
- // Default native type for a PHP array (a simple numeric array) is 'array'
- $obj = 'IPF_XmlRpc_Value_Array';
-
- // Determine if this is an associative array
- if (!empty($value) && is_array($value) && (array_keys($value) !== range(0, count($value) - 1))) {
- $obj = 'IPF_XmlRpc_Value_Struct';
- }
- return new $obj($value);
-
- case 'integer':
- return new IPF_XmlRpc_Value_Integer($value);
-
- case 'double':
- return new IPF_XmlRpc_Value_Double($value);
-
- case 'boolean':
- return new IPF_XmlRpc_Value_Boolean($value);
-
- case 'NULL':
- case 'null':
- return new IPF_XmlRpc_Value_Nil();
-
- case 'string':
- // Fall through to the next case
- default:
- // If type isn't identified (or identified as string), it treated as string
- return new IPF_XmlRpc_Value_String($value);
- }
- }
-
- private static function _xmlStringToNativeXmlRpc($simple_xml)
- {
- if (!$simple_xml instanceof SimpleXMLElement) {
- try {
- $simple_xml = @new SimpleXMLElement($simple_xml);
- } catch (Exception $e) {
- // The given string is not a valid XML
- throw new IPF_Exception('Failed to create XML-RPC value from XML string: '.$e->getMessage(),$e->getCode());
- }
- }
-
- // Get the key (tag name) and value from the simple xml object and convert the value to an XML-RPC native value
- list($type, $value) = each($simple_xml);
- if (!$type) { // If no type was specified, the default is string
- $type = self::XMLRPC_TYPE_STRING;
- }
-
- 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 IPF_XmlRpc_Value_Integer($value);
- break;
- case self::XMLRPC_TYPE_DOUBLE:
- $xmlrpc_val = new IPF_XmlRpc_Value_Double($value);
- break;
- case self::XMLRPC_TYPE_BOOLEAN:
- $xmlrpc_val = new IPF_XmlRpc_Value_Boolean($value);
- break;
- case self::XMLRPC_TYPE_STRING:
- $xmlrpc_val = new IPF_XmlRpc_Value_String($value);
- break;
- case self::XMLRPC_TYPE_DATETIME: // The value should already be in a iso8601 format
- $xmlrpc_val = new IPF_XmlRpc_Value_DateTime($value);
- break;
- case self::XMLRPC_TYPE_BASE64: // The value should already be base64 encoded
- $xmlrpc_val = new IPF_XmlRpc_Value_Base64($value ,true);
- break;
- case self::XMLRPC_TYPE_NIL: // The value should always be NULL
- $xmlrpc_val = new IPF_XmlRpc_Value_Nil();
- break;
- case self::XMLRPC_TYPE_ARRAY:
- // If the XML is valid, $value must be an SimpleXML element and contain the <data> tag
- if (!$value instanceof SimpleXMLElement) {
- throw new IPF_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 IPF_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 IPF_XmlRpc_Value objects
- foreach ($data->value as $element) {
- $values[] = self::_xmlStringToNativeXmlRpc($element);
- }
- $xmlrpc_val = new IPF_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 IPF_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 IPF_XmlRpc_Value objects
- foreach ($value->member as $member) {
- // @todo? If a member doesn't have a <value> tag, we don't add it to the struct
- // Maybe we want to throw an exception here ?
- if ((!$member->value instanceof SimpleXMLElement) || empty($member->value)) {
- continue;
- //throw new IPF_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 IPF_XmlRpc_Value_Struct($values);
- break;
- default:
- throw new IPF_Exception('Value type \''. $type .'\' parsed from the XML string is not a known XML-RPC native type');
- break;
- }
- $xmlrpc_val->_setXML($simple_xml->asXML());
-
- return $xmlrpc_val;
- }
-
- private function _setXML($xml)
- {
- $this->_as_xml = $xml;
- }
-
-}
-
-
+++ /dev/null
-<?php
-
-class IPF_XmlRpc_Value_Array extends IPF_XmlRpc_Value_Collection
-{
- public function __construct($value)
- {
- $this->_type = self::XMLRPC_TYPE_ARRAY;
- parent::__construct($value);
- }
-
- public function saveXML()
- {
- if (!$this->_as_xml) { // The XML code was not calculated yet
- $dom = new DOMDocument('1.0');
- $value = $dom->appendChild($dom->createElement('value'));
- $array = $value->appendChild($dom->createElement('array'));
- $data = $array->appendChild($dom->createElement('data'));
-
- if (is_array($this->_value)) {
- foreach ($this->_value as $val) {
- /* @var $val IPF_XmlRpc_Value */
- $data->appendChild($dom->importNode($val->getAsDOM(), true));
- }
- }
-
- $this->_as_dom = $value;
- $this->_as_xml = $this->_stripXmlDeclaration($dom);
- }
-
- return $this->_as_xml;
- }
-}
-
+++ /dev/null
-<?php
-
-class IPF_XmlRpc_Value_Base64 extends IPF_XmlRpc_Value_Scalar
-{
- public function __construct($value, $already_encoded=false)
- {
- $this->_type = self::XMLRPC_TYPE_BASE64;
-
- $value = (string)$value; // Make sure this value is string
- if (!$already_encoded) {
- $value = base64_encode($value); // We encode it in base64
- }
- $this->_value = $value;
- }
-
- public function getValue()
- {
- return base64_decode($this->_value);
- }
-
- public function saveXML()
- {
- if (! $this->_as_xml) { // The XML was not generated yet
- $dom = new DOMDocument('1.0', 'UTF-8');
- $value = $dom->appendChild($dom->createElement('value'));
- $type = $value->appendChild($dom->createElement($this->_type));
- $type->appendChild($dom->createTextNode($this->_value));
-
- $this->_as_dom = $value;
- $this->_as_xml = $this->_stripXmlDeclaration($dom);
- }
-
- return $this->_as_xml;
- }
-}
-
+++ /dev/null
-<?php
-
-class IPF_XmlRpc_Value_Boolean extends IPF_XmlRpc_Value_Scalar
-{
- public function __construct($value)
- {
- $this->_type = self::XMLRPC_TYPE_BOOLEAN;
- $this->_value = (int)(bool)$value;
- }
-
- public function getValue()
- {
- return (bool)$this->_value;
- }
-
- public function saveXML()
- {
- if (! $this->_as_xml) { // The XML was not generated yet
- $dom = new DOMDocument('1.0', 'UTF-8');
- $value = $dom->appendChild($dom->createElement('value'));
- $type = $value->appendChild($dom->createElement($this->_type));
- $type->appendChild($dom->createTextNode($this->_value));
-
- $this->_as_dom = $value;
- $this->_as_xml = $this->_stripXmlDeclaration($dom);
- }
-
- return $this->_as_xml;
- }
-}
-
+++ /dev/null
-<?php
-
-abstract class IPF_XmlRpc_Value_Collection extends IPF_XmlRpc_Value
-{
- public function __construct($value)
- {
- $values = (array)$value; // Make sure that the value is an array
- foreach ($values as $key => $value) {
- // If the elements of the given array are not IPF_XmlRpc_Value objects,
- // we need to convert them as such (using auto-detection from PHP value)
- if (!$value instanceof parent) {
- $value = self::getXmlRpcValue($value, self::AUTO_DETECT_TYPE);
- }
- $this->_value[$key] = $value;
- }
- }
-
- public function getValue()
- {
- $values = (array)$this->_value;
- foreach ($values as $key => $value) {
- /* @var $value IPF_XmlRpc_Value */
- if (!$value instanceof parent) {
- throw new IPF_Exception('Values of '. get_class($this) .' type must be IPF_XmlRpc_Value objects');
- }
- $values[$key] = $value->getValue();
- }
- return $values;
- }
-
-}
-
+++ /dev/null
-<?php
-
-class IPF_XmlRpc_Value_DateTime extends IPF_XmlRpc_Value_Scalar
-{
- public function __construct($value)
- {
- $this->_type = self::XMLRPC_TYPE_DATETIME;
-
- // If the value is not numeric, we try to convert it to a timestamp (using the strtotime function)
- if (is_numeric($value)) { // The value is numeric, we make sure it is an integer
- $value = (int)$value;
- } else {
- $value = strtotime($value);
- if ($value === false || $value == -1) { // cannot convert the value to a timestamp
- throw new IPF_Exception('Cannot convert given value \''. $value .'\' to a timestamp');
- }
- }
- $value = date('c', $value); // Convert the timestamp to iso8601 format
-
- // Strip out TZ information and dashes
- $value = preg_replace('/(\+|-)\d{2}:\d{2}$/', '', $value);
- $value = str_replace('-', '', $value);
-
- $this->_value = $value;
- }
-
- public function getValue()
- {
- return $this->_value;
- }
-
-}
-
+++ /dev/null
-<?php
-
-class IPF_XmlRpc_Value_Double extends IPF_XmlRpc_Value_Scalar
-{
- public function __construct($value)
- {
- $this->_type = self::XMLRPC_TYPE_DOUBLE;
- $this->_value = sprintf('%f',(float)$value); // Make sure this value is float (double) and without the scientific notation
- }
-
- public function getValue()
- {
- return (float)$this->_value;
- }
-
-}
-
+++ /dev/null
-<?php
-
-class IPF_XmlRpc_Value_Integer extends IPF_XmlRpc_Value_Scalar
-{
- public function __construct($value)
- {
- $this->_type = self::XMLRPC_TYPE_INTEGER;
- $this->_value = (int)$value; // Make sure this value is integer
- }
-
- public function getValue()
- {
- return $this->_value;
- }
-
-}
-
+++ /dev/null
-<?php
-
-class IPF_XmlRpc_Value_Nil extends IPF_XmlRpc_Value_Scalar
-{
- public function __construct()
- {
- $this->_type = self::XMLRPC_TYPE_NIL;
- $this->_value = null;
- }
-
- public function getValue()
- {
- return null;
- }
-
- public function saveXML()
- {
- if (! $this->_as_xml) { // The XML was not generated yet
- $dom = new DOMDocument('1.0', 'UTF-8');
- $value = $dom->appendChild($dom->createElement('value'));
- $type = $value->appendChild($dom->createElement($this->_type));
-
- $this->_as_dom = $value;
- $this->_as_xml = $this->_stripXmlDeclaration($dom);
- }
-
- return $this->_as_xml;
- }
-}
-
+++ /dev/null
-<?php
-
-abstract class IPF_XmlRpc_Value_Scalar extends IPF_XmlRpc_Value
-{
- public function saveXML()
- {
- if (!$this->_as_xml) { // The XML code was not calculated yet
- $dom = new DOMDocument('1.0');
- $value = $dom->appendChild($dom->createElement('value'));
- $type = $value->appendChild($dom->createElement($this->_type));
- $type->appendChild($dom->createTextNode($this->getValue()));
-
- $this->_as_dom = $value;
- $this->_as_xml = $this->_stripXmlDeclaration($dom);
- }
-
- return $this->_as_xml;
- }
-}
-
+++ /dev/null
-<?php
-
-class IPF_XmlRpc_Value_String extends IPF_XmlRpc_Value_Scalar
-{
- public function __construct($value)
- {
- $this->_type = self::XMLRPC_TYPE_STRING;
-
- // Make sure this value is string and all XML characters are encoded
- $this->_value = $this->_xml_entities($value);
- }
-
- public function getValue()
- {
- return html_entity_decode($this->_value, ENT_QUOTES, 'UTF-8');
- }
-
- private function _xml_entities($str)
- {
- return htmlentities($str, ENT_QUOTES, 'UTF-8');
- }
-
-}
-
+++ /dev/null
-<?php
-
-class IPF_XmlRpc_Value_Struct extends IPF_XmlRpc_Value_Collection
-{
- public function __construct($value)
- {
- $this->_type = self::XMLRPC_TYPE_STRUCT;
- parent::__construct($value);
- }
-
- public function saveXML()
- {
- if (!$this->_as_xml) { // The XML code was not calculated yet
- $dom = new DOMDocument('1.0');
- $value = $dom->appendChild($dom->createElement('value'));
- $struct = $value->appendChild($dom->createElement('struct'));
-
- if (is_array($this->_value)) {
- foreach ($this->_value as $name => $val) {
- /* @var $val IPF_XmlRpc_Value */
- $member = $struct->appendChild($dom->createElement('member'));
- $member->appendChild($dom->createElement('name', $name));
- $member->appendChild($dom->importNode($val->getAsDOM(), 1));
- }
- }
-
- $this->_as_dom = $value;
- $this->_as_xml = $this->_stripXmlDeclaration($dom);
- }
-
- return $this->_as_xml;
- }
-}
-