Completed
Push — master ( e74d7a...0f4fe2 )
by Tobias
04:18
created

HttpApi::handleErrors()   B

Complexity

Conditions 6
Paths 6

Size

Total Lines 18
Code Lines 15

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 42

Importance

Changes 0
Metric Value
dl 0
loc 18
ccs 0
cts 15
cp 0
rs 8.8571
c 0
b 0
f 0
cc 6
eloc 15
nc 6
nop 1
crap 42
1
<?php
2
3
/*
4
 * Copyright (C) 2013-2016 Mailgun
5
 *
6
 * This software may be modified and distributed under the terms
7
 * of the MIT license. See the LICENSE file for details.
8
 */
9
10
namespace Mailgun\Api;
11
12
use Http\Client\Exception as HttplugException;
13
use Http\Client\HttpClient;
14
use Mailgun\Exception\UnknownErrorException;
15
use Mailgun\Hydrator\Hydrator;
16
use Mailgun\Hydrator\NoopHydrator;
17
use Mailgun\Exception\HttpClientException;
18
use Mailgun\Exception\HttpServerException;
19
use Mailgun\RequestBuilder;
20
use Psr\Http\Message\ResponseInterface;
21
22
/**
23
 * @author Tobias Nyholm <[email protected]>
24
 */
25
abstract class HttpApi
26
{
27
    /**
28
     * The HTTP client.
29
     *
30
     * @var HttpClient
31
     */
32
    private $httpClient;
33
34
    /**
35
     * @var Hydrator
36
     */
37
    protected $hydrator;
38
39
    /**
40
     * @var RequestBuilder
41
     */
42
    protected $requestBuilder;
43
44
    /**
45
     * @param HttpClient     $httpClient
46
     * @param RequestBuilder $requestBuilder
47
     * @param Hydrator       $hydrator
48
     */
49 9
    public function __construct(HttpClient $httpClient, RequestBuilder $requestBuilder, Hydrator $hydrator)
50
    {
51 9
        $this->httpClient = $httpClient;
52 9
        $this->requestBuilder = $requestBuilder;
53 9
        if (!$hydrator instanceof NoopHydrator) {
54 9
            $this->hydrator = $hydrator;
55 9
        }
56 9
    }
57
58
    /**
59
     * @param ResponseInterface $response
60
     * @param string            $class
61
     *
62
     * @return mixed|ResponseInterface
63
     *
64
     * @throws \Exception
65
     */
66 7
    protected function hydrateResponse(ResponseInterface $response, $class)
67
    {
68 7
        if (!$this->hydrator) {
69
            return $response;
70
        }
71
72 7
        if ($response->getStatusCode() !== 200 && $response->getStatusCode() !== 201) {
73
            $this->handleErrors($response);
74
        }
75
76 7
        return $this->hydrator->hydrate($response, $class);
77
    }
78
79
    /**
80
     * Throw the correct exception for this error.
81
     *
82
     * @param ResponseInterface $response
83
     *
84
     * @throws \Exception
85
     */
86
    protected function handleErrors(ResponseInterface $response)
87
    {
88
        $statusCode = $response->getStatusCode();
89
        switch ($statusCode) {
90
            case 400:
91
                throw HttpClientException::badRequest($response);
92
            case 401:
93
                throw HttpClientException::unauthorized($response);
94
            case 402:
95
                throw HttpClientException::requestFailed($response);
96
            case 404:
97
                throw HttpClientException::notFound($response);
98
            case 500 <= $statusCode:
99
                throw HttpServerException::serverError($statusCode);
100
            default:
101
                throw new UnknownErrorException();
102
        }
103
    }
104
105
    /**
106
     * Send a GET request with query parameters.
107
     *
108
     * @param string $path           Request path
109
     * @param array  $parameters     GET parameters
110
     * @param array  $requestHeaders Request Headers
111
     *
112
     * @return ResponseInterface
113
     */
114
    protected function httpGet($path, array $parameters = [], array $requestHeaders = [])
115
    {
116
        if (count($parameters) > 0) {
117
            $path .= '?'.http_build_query($parameters);
118
        }
119
120
        try {
121
            $response = $this->httpClient->sendRequest(
122
                $this->requestBuilder->create('GET', $path, $requestHeaders)
123
            );
124
        } catch (HttplugException\NetworkException $e) {
125
            throw HttpServerException::networkError($e);
126
        }
127
128
        return $response;
129
    }
130
131
    /**
132
     * Send a POST request with JSON-encoded parameters.
133
     *
134
     * @param string $path           Request path
135
     * @param array  $parameters     POST parameters to be JSON encoded
136
     * @param array  $requestHeaders Request headers
137
     *
138
     * @return ResponseInterface
139
     */
140
    protected function httpPost($path, array $parameters = [], array $requestHeaders = [])
141
    {
142
        return $this->httpPostRaw($path, $this->createJsonBody($parameters), $requestHeaders);
143
    }
144
145
    /**
146
     * Send a POST request with raw data.
147
     *
148
     * @param string       $path           Request path
149
     * @param array|string $body           Request body
150
     * @param array        $requestHeaders Request headers
151
     *
152
     * @return ResponseInterface
153
     */
154 View Code Duplication
    protected function httpPostRaw($path, $body, array $requestHeaders = [])
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
155
    {
156
        try {
157
            $response = $this->httpClient->sendRequest(
158
                $this->requestBuilder->create('POST', $path, $requestHeaders, $body)
159
            );
160
        } catch (HttplugException\NetworkException $e) {
161
            throw HttpServerException::networkError($e);
162
        }
163
164
        return $response;
165
    }
166
167
    /**
168
     * Send a PUT request with JSON-encoded parameters.
169
     *
170
     * @param string $path           Request path
171
     * @param array  $parameters     POST parameters to be JSON encoded
172
     * @param array  $requestHeaders Request headers
173
     *
174
     * @return ResponseInterface
175
     */
176 View Code Duplication
    protected function httpPut($path, array $parameters = [], array $requestHeaders = [])
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
177
    {
178
        try {
179
            $response = $this->httpClient->sendRequest(
180
                $this->requestBuilder->create('PUT', $path, $requestHeaders, $this->createJsonBody($parameters))
181
            );
182
        } catch (HttplugException\NetworkException $e) {
183
            throw HttpServerException::networkError($e);
184
        }
185
186
        return $response;
187
    }
188
189
    /**
190
     * Send a DELETE request with JSON-encoded parameters.
191
     *
192
     * @param string $path           Request path
193
     * @param array  $parameters     POST parameters to be JSON encoded
194
     * @param array  $requestHeaders Request headers
195
     *
196
     * @return ResponseInterface
197
     */
198 View Code Duplication
    protected function httpDelete($path, array $parameters = [], array $requestHeaders = [])
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
199
    {
200
        try {
201
            $response = $this->httpClient->sendRequest(
202
                $this->requestBuilder->create('DELETE', $path, $requestHeaders, $this->createJsonBody($parameters))
203
            );
204
        } catch (HttplugException\NetworkException $e) {
205
            throw HttpServerException::networkError($e);
206
        }
207
208
        return $response;
209
    }
210
211
    /**
212
     * Create a JSON encoded version of an array of parameters.
213
     *
214
     * @param array $parameters Request parameters
215
     *
216
     * @return null|string
217
     */
218
    protected function createJsonBody(array $parameters)
219
    {
220
        return (count($parameters) === 0) ? null : json_encode($parameters, empty($parameters) ? JSON_FORCE_OBJECT : 0);
221
    }
222
}
223