Passed
Pull Request — master (#11)
by Pavel
07:52
created

JsonRpcController::handle()   A

Complexity

Conditions 3
Paths 4

Size

Total Lines 17
Code Lines 10

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 10
CRAP Score 3

Importance

Changes 0
Metric Value
dl 0
loc 17
ccs 10
cts 10
cp 1
rs 9.4285
c 0
b 0
f 0
cc 3
eloc 10
nc 4
nop 2
crap 3
1
<?php
2
3
namespace Bankiru\Api\JsonRpc\Controller;
4
5
use Bankiru\Api\JsonRpc\Exception\InvalidRequestException;
6
use Bankiru\Api\JsonRpc\Exception\RpcMethodNotFoundException;
7
use Bankiru\Api\JsonRpc\Http\JsonRpcHttpResponse;
8
use Bankiru\Api\JsonRpc\Specification\JsonRpcRequest;
9
use Bankiru\Api\JsonRpc\Specification\RichJsonRpcRequest;
10
use Bankiru\Api\Rpc\Controller\RpcController;
11
use Bankiru\Api\Rpc\Routing\ControllerResolver\ControllerResolverInterface;
12
use ScayTrase\Api\Rpc\RpcResponseInterface;
13
use Symfony\Component\HttpFoundation\Request;
14
use Symfony\Component\HttpKernel\Exception\BadRequestHttpException;
15
16
final class JsonRpcController extends RpcController
17
{
18
    /**
19
     * JSON-RPC Controller
20
     *
21
     * @param Request $request
22
     *
23
     * @return JsonRpcHttpResponse
24
     *
25
     * @throws BadRequestHttpException
26
     * @throws RpcMethodNotFoundException
27
     * @throws InvalidRequestException
28
     */
29 24
    public function jsonRpcAction(Request $request)
30
    {
31 24
        $request->attributes->set('_format', 'json');
32
33 24
        $jsonrpc = json_decode($request->getContent());
34 24
        if ((!is_array($jsonrpc) && !is_object($jsonrpc)) || json_last_error() !== JSON_ERROR_NONE) {
35 4
            throw new BadRequestHttpException('Not a valid JSON-RPC request');
36
        }
37
38 20
        $singleRequest = false;
39 20
        if (!is_array($jsonrpc)) {
40 15
            $jsonrpc       = [$jsonrpc];
41 15
            $singleRequest = true;
42 15
        }
43
44 20
        $responses = [];
45 20
        foreach ($jsonrpc as $call) {
46 19
            if (!$call instanceof \stdClass) {
47
                throw InvalidRequestException::notAJsonRpc();
48
            }
49 19
            $response = $this->handle($call, $request->get('_route'));
50 13
            if (null !== $response) {
51 13
                $responses[] = $response;
52 13
            }
53 14
        }
54
55 14
        if ($singleRequest) {
56 9
            $responses = array_shift($responses);
57 9
        }
58
59 14
        return new JsonRpcHttpResponse($responses);
60
    }
61
62
    /**
63
     * @return ControllerResolverInterface
64
     */
65 13
    protected function getResolver()
66
    {
67 13
        return $this->get('jsonrpc_server.controller_resolver');
68
    }
69
70
    /**
71
     * @param \stdClass $call
72
     * @param string    $endpoint
73
     *
74
     * @return null|RpcResponseInterface Null on notification response
75
     * @throws \Exception
76
     */
77 19
    private function handle(\stdClass $call, $endpoint)
78
    {
79 19
        $jsonRequest = new RichJsonRpcRequest(JsonRpcRequest::fromStdClass($call));
80 13
        $jsonRequest->getAttributes()->set('_endpoint', $endpoint);
81
82
        try {
83 13
            $jsonResponse = $this->handleSingleRequest($jsonRequest);
84 13
        } catch (\Exception $e) {
85 4
            $jsonResponse = $this->handleException($e, $jsonRequest);
86
        }
87
88 13
        if ($jsonRequest->isNotification()) {
89 2
            return null;
90
        }
91
92 13
        return $jsonResponse;
93 1
    }
94
}
95