155 lines
3.8 KiB
PHP
155 lines
3.8 KiB
PHP
<?php
|
|
|
|
namespace JsonRPC\Response;
|
|
|
|
use BadFunctionCallException;
|
|
use InvalidArgumentException;
|
|
use Exception;
|
|
use JsonRPC\Exception\InvalidJsonFormatException;
|
|
use JsonRPC\Exception\InvalidJsonRpcFormatException;
|
|
use JsonRPC\Exception\ResponseException;
|
|
use JsonRPC\Validator\JsonFormatValidator;
|
|
|
|
/**
|
|
* Class ResponseParser
|
|
*
|
|
* @package JsonRPC\Request
|
|
* @author Frederic Guillot
|
|
*/
|
|
class ResponseParser
|
|
{
|
|
/**
|
|
* Payload
|
|
*
|
|
* @access private
|
|
* @var mixed
|
|
*/
|
|
private $payload;
|
|
|
|
/**
|
|
* Do not immediately throw an exception on error. Return it instead.
|
|
*
|
|
* @var bool
|
|
*/
|
|
private $returnException = false;
|
|
|
|
/**
|
|
* Get new object instance
|
|
*
|
|
* @static
|
|
* @access public
|
|
* @return ResponseParser
|
|
*/
|
|
public static function create()
|
|
{
|
|
return new static();
|
|
}
|
|
|
|
/**
|
|
* Set Return Exception Or Throw It
|
|
*
|
|
* @param $returnException
|
|
* @return ResponseParser
|
|
*/
|
|
public function withReturnException($returnException)
|
|
{
|
|
$this->returnException = $returnException;
|
|
return $this;
|
|
}
|
|
|
|
/**
|
|
* Set payload
|
|
*
|
|
* @access public
|
|
* @param mixed $payload
|
|
* @return $this
|
|
*/
|
|
public function withPayload($payload)
|
|
{
|
|
$this->payload = $payload;
|
|
return $this;
|
|
}
|
|
|
|
/**
|
|
* Parse response
|
|
*
|
|
* @return array|Exception|null
|
|
* @throws InvalidJsonFormatException
|
|
* @throws BadFunctionCallException
|
|
* @throws InvalidJsonRpcFormatException
|
|
* @throws InvalidArgumentException
|
|
* @throws Exception
|
|
* @throws ResponseException
|
|
*/
|
|
public function parse()
|
|
{
|
|
JsonFormatValidator::validate($this->payload);
|
|
|
|
if ($this->isBatchResponse()) {
|
|
$results = array();
|
|
|
|
foreach ($this->payload as $response) {
|
|
$results[] = self::create()
|
|
->withReturnException($this->returnException)
|
|
->withPayload($response)
|
|
->parse();
|
|
}
|
|
|
|
return $results;
|
|
}
|
|
|
|
if (isset($this->payload['error']['code'])) {
|
|
try {
|
|
$this->handleExceptions();
|
|
} catch (Exception $e) {
|
|
if ($this->returnException) {
|
|
return $e;
|
|
}
|
|
throw $e;
|
|
}
|
|
}
|
|
|
|
return isset($this->payload['result']) ? $this->payload['result'] : null;
|
|
}
|
|
|
|
/**
|
|
* Handle exceptions
|
|
*
|
|
* @access private
|
|
* @throws InvalidJsonFormatException
|
|
* @throws InvalidJsonRpcFormatException
|
|
* @throws ResponseException
|
|
*/
|
|
private function handleExceptions()
|
|
{
|
|
switch ($this->payload['error']['code']) {
|
|
case -32700:
|
|
throw new InvalidJsonFormatException('Parse error: '.$this->payload['error']['message']);
|
|
case -32600:
|
|
throw new InvalidJsonRpcFormatException('Invalid Request: '.$this->payload['error']['message']);
|
|
case -32601:
|
|
throw new BadFunctionCallException('Procedure not found: '.$this->payload['error']['message']);
|
|
case -32602:
|
|
throw new InvalidArgumentException('Invalid arguments: '.$this->payload['error']['message']);
|
|
default:
|
|
throw new ResponseException(
|
|
$this->payload['error']['message'],
|
|
$this->payload['error']['code'],
|
|
null,
|
|
isset($this->payload['error']['data']) ? $this->payload['error']['data'] : null
|
|
);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Return true if we have a batch response
|
|
*
|
|
* @access private
|
|
* @return boolean
|
|
*/
|
|
private function isBatchResponse()
|
|
{
|
|
return array_keys($this->payload) === range(0, count($this->payload) - 1);
|
|
}
|
|
}
|