|
<?php |
|
|
|
namespace JsonRPC\Request; |
|
|
|
use Exception; |
|
use JsonRPC\Exception\AccessDeniedException; |
|
use JsonRPC\Exception\AuthenticationFailureException; |
|
use JsonRPC\Exception\InvalidJsonRpcFormatException; |
|
use JsonRPC\MiddlewareHandler; |
|
use JsonRPC\ProcedureHandler; |
|
use JsonRPC\Response\ResponseBuilder; |
|
use JsonRPC\Validator\JsonFormatValidator; |
|
use JsonRPC\Validator\RpcFormatValidator; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class RequestParser |
|
{ |
|
|
|
|
|
|
|
|
|
|
|
|
|
protected $payload; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
protected $localExceptions = array( |
|
'JsonRPC\Exception\AuthenticationFailureException', |
|
'JsonRPC\Exception\AccessDeniedException', |
|
); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
protected $procedureHandler; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
protected $middlewareHandler; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
public static function create() |
|
{ |
|
return new static(); |
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
public function withPayload($payload) |
|
{ |
|
$this->payload = $payload; |
|
return $this; |
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
public function withLocalException($exception) |
|
{ |
|
if (is_array($exception)) { |
|
$this->localExceptions = array_merge($this->localExceptions, $exception); |
|
} else { |
|
$this->localExceptions[] = $exception; |
|
} |
|
|
|
return $this; |
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
public function withProcedureHandler(ProcedureHandler $procedureHandler) |
|
{ |
|
$this->procedureHandler = $procedureHandler; |
|
return $this; |
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
public function withMiddlewareHandler(MiddlewareHandler $middlewareHandler) |
|
{ |
|
$this->middlewareHandler = $middlewareHandler; |
|
return $this; |
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
public function parse() |
|
{ |
|
try { |
|
|
|
JsonFormatValidator::validate($this->payload); |
|
RpcFormatValidator::validate($this->payload); |
|
|
|
$this->middlewareHandler |
|
->withProcedure($this->payload['method']) |
|
->execute(); |
|
|
|
$result = $this->procedureHandler->executeProcedure( |
|
$this->payload['method'], |
|
empty($this->payload['params']) ? array() : $this->payload['params'] |
|
); |
|
|
|
if (! $this->isNotification()) { |
|
return ResponseBuilder::create() |
|
->withId($this->payload['id']) |
|
->withResult($result) |
|
->build(); |
|
} |
|
} catch (Exception $e) { |
|
return $this->handleExceptions($e); |
|
} |
|
|
|
return ''; |
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
protected function handleExceptions(Exception $e) |
|
{ |
|
foreach ($this->localExceptions as $exception) { |
|
if ($e instanceof $exception) { |
|
throw $e; |
|
} |
|
} |
|
|
|
if ($e instanceof InvalidJsonRpcFormatException || ! $this->isNotification()) { |
|
return ResponseBuilder::create() |
|
->withId(isset($this->payload['id']) ? $this->payload['id'] : null) |
|
->withException($e) |
|
->build(); |
|
} |
|
|
|
return ''; |
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
protected function isNotification() |
|
{ |
|
return is_array($this->payload) && !isset($this->payload['id']); |
|
} |
|
} |
|
|