| <?php |
|
|
| namespace JsonRPC; |
|
|
| use BadFunctionCallException; |
| use Closure; |
| use InvalidArgumentException; |
| use ReflectionFunction; |
| use ReflectionMethod; |
|
|
| |
| |
| |
| |
| |
| |
| class ProcedureHandler |
| { |
| |
| |
| |
| |
| |
| |
| protected $callbacks = array(); |
|
|
| |
| |
| |
| |
| |
| |
| protected $classes = array(); |
|
|
| |
| |
| |
| |
| |
| |
| protected $instances = array(); |
|
|
| |
| |
| |
| |
| |
| |
| protected $beforeMethodName = ''; |
|
|
| |
| |
| |
| |
| |
| |
| |
| |
| public function withCallback($procedure, Closure $callback) |
| { |
| $this->callbacks[$procedure] = $callback; |
| return $this; |
| } |
|
|
| |
| |
| |
| |
| |
| |
| |
| |
| |
| public function withClassAndMethod($procedure, $class, $method = '') |
| { |
| if ($method === '') { |
| $method = $procedure; |
| } |
|
|
| $this->classes[$procedure] = array($class, $method); |
| return $this; |
| } |
|
|
| |
| |
| |
| |
| |
| |
| |
| public function withObject($instance) |
| { |
| $this->instances[] = $instance; |
| return $this; |
| } |
|
|
| |
| |
| |
| |
| |
| |
| |
| public function withBeforeMethod($methodName) |
| { |
| $this->beforeMethodName = $methodName; |
| return $this; |
| } |
|
|
| |
| |
| |
| |
| |
| |
| |
| public function withCallbackArray($callbacks) |
| { |
| foreach ($callbacks as $procedure => $callback) { |
| $this->withCallback($procedure, $callback); |
| } |
|
|
| return $this; |
| } |
|
|
| |
| |
| |
| |
| |
| |
| |
| public function withClassAndMethodArray($callbacks) |
| { |
| foreach ($callbacks as $procedure => $callback) { |
| $this->withClassAndMethod($procedure, $callback[0], $callback[1]); |
| } |
|
|
| return $this; |
| } |
|
|
| |
| |
| |
| |
| |
| |
| |
| |
| public function executeProcedure($procedure, array $params = array()) |
| { |
| if (isset($this->callbacks[$procedure])) { |
| return $this->executeCallback($this->callbacks[$procedure], $params); |
| } elseif (isset($this->classes[$procedure]) && method_exists($this->classes[$procedure][0], $this->classes[$procedure][1])) { |
| return $this->executeMethod($this->classes[$procedure][0], $this->classes[$procedure][1], $params); |
| } |
|
|
| foreach ($this->instances as $instance) { |
| if (method_exists($instance, $procedure)) { |
| return $this->executeMethod($instance, $procedure, $params); |
| } |
| } |
|
|
| throw new BadFunctionCallException('Unable to find the procedure'); |
| } |
|
|
| |
| |
| |
| |
| |
| |
| |
| |
| public function executeCallback(Closure $callback, $params) |
| { |
| $reflection = new ReflectionFunction($callback); |
|
|
| $arguments = $this->getArguments( |
| $params, |
| $reflection->getParameters(), |
| $reflection->getNumberOfRequiredParameters(), |
| $reflection->getNumberOfParameters() |
| ); |
|
|
| return $reflection->invokeArgs($arguments); |
| } |
|
|
| |
| |
| |
| |
| |
| |
| |
| |
| |
| public function executeMethod($class, $method, $params) |
| { |
| $instance = is_string($class) ? new $class : $class; |
| $reflection = new ReflectionMethod($class, $method); |
|
|
| $this->executeBeforeMethod($instance, $method); |
|
|
| $arguments = $this->getArguments( |
| $params, |
| $reflection->getParameters(), |
| $reflection->getNumberOfRequiredParameters(), |
| $reflection->getNumberOfParameters() |
| ); |
|
|
| return $reflection->invokeArgs($instance, $arguments); |
| } |
|
|
| |
| |
| |
| |
| |
| |
| |
| public function executeBeforeMethod($object, $method) |
| { |
| if ($this->beforeMethodName !== '' && method_exists($object, $this->beforeMethodName)) { |
| call_user_func_array(array($object, $this->beforeMethodName), array($method)); |
| } |
| } |
|
|
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| public function getArguments(array $requestParams, array $methodParams, $nbRequiredParams, $nbMaxParams) |
| { |
| $nbParams = count($requestParams); |
|
|
| if ($nbParams < $nbRequiredParams) { |
| throw new InvalidArgumentException('Wrong number of arguments'); |
| } |
|
|
| if ($nbParams > $nbMaxParams) { |
| throw new InvalidArgumentException('Too many arguments'); |
| } |
|
|
| if ($this->isPositionalArguments($requestParams)) { |
| return $requestParams; |
| } |
|
|
| return $this->getNamedArguments($requestParams, $methodParams); |
| } |
|
|
| |
| |
| |
| |
| |
| |
| |
| public function isPositionalArguments(array $request_params) |
| { |
| return array_keys($request_params) === range(0, count($request_params) - 1); |
| } |
|
|
| |
| |
| |
| |
| |
| |
| |
| |
| public function getNamedArguments(array $requestParams, array $methodParams) |
| { |
| $params = array(); |
|
|
| foreach ($methodParams as $p) { |
| $name = $p->getName(); |
|
|
| if (array_key_exists($name, $requestParams)) { |
| $params[$name] = $requestParams[$name]; |
| } elseif ($p->isDefaultValueAvailable()) { |
| $params[$name] = $p->getDefaultValue(); |
| } else { |
| throw new InvalidArgumentException('Missing argument: '.$name); |
| } |
| } |
|
|
| return $params; |
| } |
| } |
|
|