These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more
1 | <?php |
||
2 | |||
3 | declare(strict_types=1); |
||
4 | /* |
||
5 | * This software may be modified and distributed under the terms |
||
6 | * of the MIT license. See the LICENSE file for details. |
||
7 | */ |
||
8 | |||
9 | namespace Billogram\Api; |
||
10 | |||
11 | use Billogram\Exception\Domain as DomainExceptions; |
||
12 | use Billogram\Exception\DomainException; |
||
13 | use Billogram\Hydrator\NoopHydrator; |
||
14 | use Http\Client\HttpClient; |
||
15 | use Billogram\Hydrator\Hydrator; |
||
16 | use Billogram\RequestBuilder; |
||
17 | use Psr\Http\Message\ResponseInterface; |
||
18 | |||
19 | /** |
||
20 | * @author Tobias Nyholm <[email protected]> |
||
21 | */ |
||
22 | abstract class HttpApi |
||
23 | { |
||
24 | /** |
||
25 | * @var HttpClient |
||
26 | */ |
||
27 | protected $httpClient; |
||
28 | /** |
||
29 | * @var Hydrator |
||
30 | */ |
||
31 | protected $hydrator; |
||
32 | /** |
||
33 | * @var RequestBuilder |
||
34 | */ |
||
35 | protected $requestBuilder; |
||
36 | |||
37 | /** |
||
38 | * @param HttpClient $httpClient |
||
39 | * @param RequestBuilder $requestBuilder |
||
40 | * @param Hydrator $hydrator |
||
41 | */ |
||
42 | 13 | public function __construct(HttpClient $httpClient, Hydrator $hydrator, RequestBuilder $requestBuilder) |
|
43 | { |
||
44 | 13 | $this->httpClient = $httpClient; |
|
45 | 13 | $this->requestBuilder = $requestBuilder; |
|
46 | 13 | if (!$hydrator instanceof NoopHydrator) { |
|
47 | 13 | $this->hydrator = $hydrator; |
|
48 | } |
||
49 | 13 | } |
|
50 | |||
51 | /** |
||
52 | * Send a GET request with query parameters. |
||
53 | * |
||
54 | * @param string $path Request path |
||
55 | * @param array $params GET parameters |
||
56 | * @param array $requestHeaders Request Headers |
||
57 | * |
||
58 | * @return ResponseInterface |
||
59 | */ |
||
60 | 9 | protected function httpGet(string $path, array $params = [], array $requestHeaders = []): ResponseInterface |
|
61 | { |
||
62 | 9 | if (count($params) > 0) { |
|
63 | 9 | $path .= '?'.http_build_query($params); |
|
64 | } |
||
65 | |||
66 | 9 | return $this->httpClient->sendRequest( |
|
67 | 9 | $this->requestBuilder->create('GET', $path, $requestHeaders) |
|
68 | ); |
||
69 | } |
||
70 | |||
71 | /** |
||
72 | * Send a POST request with JSON-encoded parameters. |
||
73 | * |
||
74 | * @param string $path Request path |
||
75 | * @param array $params POST parameters to be JSON encoded |
||
76 | * @param array $requestHeaders Request headers |
||
77 | * |
||
78 | * @return ResponseInterface |
||
79 | */ |
||
80 | 3 | protected function httpPost(string $path, array $params = [], array $requestHeaders = []): ResponseInterface |
|
81 | { |
||
82 | 3 | return $this->httpPostRaw($path, $this->createJsonBody($params), $requestHeaders); |
|
83 | } |
||
84 | |||
85 | /** |
||
86 | * Send a POST request with raw data. |
||
87 | * |
||
88 | * @param string $path Request path |
||
89 | * @param array|string $body Request body |
||
90 | * @param array $requestHeaders Request headers |
||
91 | * |
||
92 | * @return ResponseInterface |
||
93 | */ |
||
94 | 3 | protected function httpPostRaw(string $path, $body, array $requestHeaders = []): ResponseInterface |
|
95 | { |
||
96 | 3 | return $response = $this->httpClient->sendRequest( |
|
97 | 3 | $this->requestBuilder->create('POST', $path, $requestHeaders, $body) |
|
98 | ); |
||
99 | } |
||
100 | |||
101 | /** |
||
102 | * Send a PUT request with JSON-encoded parameters. |
||
103 | * |
||
104 | * @param string $path Request path |
||
105 | * @param array $params POST parameters to be JSON encoded |
||
106 | * @param array $requestHeaders Request headers |
||
107 | * |
||
108 | * @return ResponseInterface |
||
109 | */ |
||
110 | 3 | protected function httpPut(string $path, array $params = [], array $requestHeaders = []): ResponseInterface |
|
111 | { |
||
112 | 3 | return $this->httpClient->sendRequest( |
|
113 | 3 | $this->requestBuilder->create('PUT', $path, $requestHeaders, $this->createJsonBody($params)) |
|
114 | ); |
||
115 | } |
||
116 | |||
117 | /** |
||
118 | * Send a DELETE request with JSON-encoded parameters. |
||
119 | * |
||
120 | * @param string $path Request path |
||
121 | * @param array $params POST parameters to be JSON encoded |
||
122 | * @param array $requestHeaders Request headers |
||
123 | * |
||
124 | * @return ResponseInterface |
||
125 | */ |
||
126 | 1 | protected function httpDelete(string $path, array $params = [], array $requestHeaders = []): ResponseInterface |
|
127 | { |
||
128 | 1 | return $this->httpClient->sendRequest( |
|
129 | 1 | $this->requestBuilder->create('DELETE', $path, $requestHeaders, $this->createJsonBody($params)) |
|
130 | ); |
||
131 | } |
||
132 | |||
133 | /** |
||
134 | * Create a JSON encoded version of an array of parameters. |
||
135 | * |
||
136 | * @param array $params Request parameters |
||
137 | * |
||
138 | * @return null|string |
||
139 | */ |
||
140 | 7 | private function createJsonBody(array $params) |
|
141 | { |
||
142 | 7 | return (count($params) === 0) ? null : json_encode($params, empty($params) ? JSON_FORCE_OBJECT : 0); |
|
143 | } |
||
144 | |||
145 | /** |
||
146 | * Handle HTTP errors. |
||
147 | * |
||
148 | * Call is controlled by the specific API methods. |
||
149 | * |
||
150 | * @param ResponseInterface $response |
||
151 | * |
||
152 | * @throws DomainException |
||
153 | */ |
||
154 | protected function handleErrors(ResponseInterface $response) |
||
155 | { |
||
156 | switch ($response->getStatusCode()) { |
||
157 | case 404: |
||
158 | throw new DomainExceptions\NotFoundException($response->getBody()->__toString()); |
||
159 | break; |
||
0 ignored issues
–
show
|
|||
160 | case 400: |
||
161 | throw new DomainExceptions\ValidationException($response->getBody()->__toString()); |
||
162 | break; |
||
0 ignored issues
–
show
break; does not seem to be reachable.
This check looks for unreachable code. It uses sophisticated control flow analysis techniques to find statements which will never be executed. Unreachable code is most often the result of function fx() {
try {
doSomething();
return true;
}
catch (\Exception $e) {
return false;
}
return false;
}
In the above example, the last
Loading history...
|
|||
163 | default: |
||
164 | throw new DomainExceptions\UnknownErrorException($response->getBody()->__toString()); |
||
165 | break; |
||
0 ignored issues
–
show
break; does not seem to be reachable.
This check looks for unreachable code. It uses sophisticated control flow analysis techniques to find statements which will never be executed. Unreachable code is most often the result of function fx() {
try {
doSomething();
return true;
}
catch (\Exception $e) {
return false;
}
return false;
}
In the above example, the last
Loading history...
|
|||
166 | } |
||
167 | } |
||
168 | } |
||
169 |
This check looks for unreachable code. It uses sophisticated control flow analysis techniques to find statements which will never be executed.
Unreachable code is most often the result of
return
,die
orexit
statements that have been added for debug purposes.In the above example, the last
return false
will never be executed, because a return statement has already been met in every possible execution path.