Completed
Push — master ( 645e2d...f9b1bd )
by Adam
02:34
created

Service::buildResponses()   B

Complexity

Conditions 6
Paths 10

Size

Total Lines 23
Code Lines 14

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 14
CRAP Score 6

Importance

Changes 0
Metric Value
dl 0
loc 23
ccs 14
cts 14
cp 1
rs 8.5906
c 0
b 0
f 0
cc 6
eloc 14
nc 10
nop 1
crap 6
1
<?php
2
3
namespace PhpJsonRpc\Server\Service;
4
5
use PhpJsonRpc\Server\Response\Error;
6
use PhpJsonRpc\Server\Request\Request;
7
use PhpJsonRpc\Server\Error\MethodNotFound;
8
use PhpJsonRpc\Server\Request\RequestBuilder;
9
use PhpJsonRpc\Server\Request\AbstractRequest;
10
use PhpJsonRpc\Server\Response\AbstractResponse;
11
use PhpJsonRpc\Server\Request\NotificationRequest;
12
use PhpJsonRpc\Server\Response\SuccessfulResponse;
13
use PhpJsonRpc\Server\Response\UnsuccessfulResponse;
14
use PhpJsonRpc\Server\Service\Method\Contract\Method;
15
use PhpJsonRpc\Server\Response\Contract\ErrorFormatter;
16
use PhpJsonRpc\Server\Response\ErrorFormatter\DefaultErrorFormatter;
17
18
class Service
19
{
20
    /**
21
     * @var string
22
     */
23
    protected $endpoint;
24
25
    /**
26
     * @var ErrorFormatter
27
     */
28
    protected $errorFormatter;
29
30
    /**
31
     * @var Method[]
32
     */
33
    protected $methods = [];
34
35
    /**
36
     * @param string $endpoint
37
     * @param ErrorFormatter|null $errorFormatter
38
     */
39 39
    public function __construct($endpoint, ErrorFormatter $errorFormatter = null)
40
    {
41 39
        $this->endpoint         = $endpoint;
42 39
        $this->errorFormatter   = $errorFormatter ? $errorFormatter : new DefaultErrorFormatter;
43 39
    }
44
45
    /**
46
     * @param string $message
47
     *
48
     * @return AbstractResponse[]|AbstractResponse|null
49
     *
50
     * @throws \Exception
51
     */
52 33
    public function dispatch($message)
53
    {
54
        try {
55 33
            $requestBuilder = new RequestBuilder($message);
56 33
        } catch (\Exception $e) {
57 6
            return new UnsuccessfulResponse(null, new Error($e, $this->errorFormatter));
58
        }
59
60 27
        if ($requestBuilder->isBatchRequest()) {
61 12
            return $this->buildResponses($requestBuilder);
62
        }
63
64
        try {
65 15
            $request = $requestBuilder->buildRequest($requestBuilder->decodedJson());
66 15
        } catch (\Exception $e) {
67 3
            return new UnsuccessfulResponse(null, new Error($e, $this->errorFormatter));
68
        }
69
70 12
        if ($request instanceof Request) {
71
            try {
72 9
                return $this->buildResponse($request);
73 6
            } catch (\Exception $e) {
74 3
                return new UnsuccessfulResponse($request->id(), new Error($e, $this->errorFormatter));
75
            }
76
        }
77 3
    }
78
79
    /**
80
     * @param Method $method
81
     */
82 21
    public function add(Method $method)
83
    {
84 21
        $this->methods[$method->rpcMethodName()] = $method;
85 21
    }
86
87
    /**
88
     * @return string
89
     */
90 6
    public function endpoint()
91
    {
92 6
        return $this->endpoint;
93
    }
94
95
    /**
96
     * @return Method[]
97
     */
98 18
    public function methods()
99
    {
100 18
        return $this->methods;
101
    }
102
103
    /**
104
     * @param string $methodName
105
     *
106
     * @return Method
107
     *
108
     * @throws MethodNotFound
109
     */
110 18
    public function findMethodBy($methodName)
111
    {
112 18
        if (!array_key_exists($methodName, $this->methods())) {
113 6
            throw new MethodNotFound;
114
        }
115
116 15
        return $this->methods()[$methodName];
117
    }
118
119
    /**
120
     * @param RequestBuilder $requestBuilder
121
     *
122
     * @return AbstractResponse[]|null
123
     */
124 12
    protected function buildResponses(RequestBuilder $requestBuilder)
125
    {
126 12
        $responses = [];
127
128 12
        foreach ($requestBuilder->decodedJson() as $messageObject) {
129
            try {
130 12
                $request = $requestBuilder->buildRequest($messageObject);
131 12
            } catch (\Exception $e) {
132 6
                $responses[] = new UnsuccessfulResponse(null, new Error($e, $this->errorFormatter));
133 6
                continue;
134
            }
135
136 9
            if ($request instanceof Request) {
137
                try {
138 6
                    $responses[] = $this->buildResponse($request);
139 6
                } catch (\Exception $e) {
140 3
                    $responses[] = new UnsuccessfulResponse($request->id(), new Error($e, $this->errorFormatter));
141
                }
142 6
            }
143 12
        }
144
145 12
        return $responses ? : null;
146
    }
147
148
    /**
149
     * @param AbstractRequest $request
150
     *
151
     * @return null|SuccessfulResponse
152
     *
153
     * @throws \Exception
154
     */
155 15
    protected function buildResponse(AbstractRequest $request)
156
    {
157
        try {
158 15
            $method         = $this->findMethodBy($request->method());
159 12
            $methodResult   = $method->run($request->params());
160 15
        } catch (\Exception $e) {
161 6
            if ($request instanceof NotificationRequest) {
162
                return null;
163
            }
164
165 6
            throw $e;
166
        }
167
168 12
        if ($request instanceof Request) {
169 12
            return new SuccessfulResponse($request->id(), $methodResult);
170
        }
171
172
        return null;
173
    }
174
}
175