Completed
Push — master ( fab86b...27b5c8 )
by Tobias
10:27 queued 07:31
created

HttpApi::handleErrors()   B

Complexity

Conditions 6
Paths 6

Size

Total Lines 18
Code Lines 15

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 8
CRAP Score 9.6594

Importance

Changes 0
Metric Value
dl 0
loc 18
ccs 8
cts 15
cp 0.5333
rs 8.8571
c 0
b 0
f 0
cc 6
eloc 15
nc 6
nop 1
crap 9.6594
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 34
    public function __construct(HttpClient $httpClient, RequestBuilder $requestBuilder, Hydrator $hydrator)
50
    {
51 34
        $this->httpClient = $httpClient;
52 34
        $this->requestBuilder = $requestBuilder;
53 34
        if (!$hydrator instanceof NoopHydrator) {
54 34
            $this->hydrator = $hydrator;
55 34
        }
56 34
    }
57
58
    /**
59
     * @param ResponseInterface $response
60
     * @param string            $class
61
     *
62
     * @return mixed|ResponseInterface
63
     *
64
     * @throws \Exception
65
     */
66 28
    protected function hydrateResponse(ResponseInterface $response, $class)
67
    {
68 28
        if (!$this->hydrator) {
69
            return $response;
70
        }
71
72 28
        if ($response->getStatusCode() !== 200 && $response->getStatusCode() !== 201) {
73 6
            $this->handleErrors($response);
74
        }
75
76 22
        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 6
    protected function handleErrors(ResponseInterface $response)
87
    {
88 6
        $statusCode = $response->getStatusCode();
89
        switch ($statusCode) {
90 6
            case 400:
91 2
                throw HttpClientException::badRequest($response);
92 4
            case 401:
93
                throw HttpClientException::unauthorized($response);
94 4
            case 402:
95
                throw HttpClientException::requestFailed($response);
96 4
            case 404:
97 4
                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 7
    protected function httpGet($path, array $parameters = [], array $requestHeaders = [])
115
    {
116 7
        if (count($parameters) > 0) {
117 4
            $path .= '?'.http_build_query($parameters);
118 4
        }
119
120
        try {
121 7
            $response = $this->httpClient->sendRequest(
122 7
                $this->requestBuilder->create('GET', $path, $requestHeaders)
123 7
            );
124 7
        } catch (HttplugException\NetworkException $e) {
125
            throw HttpServerException::networkError($e);
126
        }
127
128 7
        return $response;
129
    }
130
131
    /**
132
     * Send a POST request with parameters.
133
     *
134
     * @param string $path           Request path
135
     * @param array  $parameters     POST parameters
136
     * @param array  $requestHeaders Request headers
137
     *
138
     * @return ResponseInterface
139
     */
140 5
    protected function httpPost($path, array $parameters = [], array $requestHeaders = [])
141
    {
142 5
        return $this->httpPostRaw($path, $this->createRequestBody($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 5 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 5
            $response = $this->httpClient->sendRequest(
158 5
                $this->requestBuilder->create('POST', $path, $requestHeaders, $body)
159 5
            );
160 5
        } catch (HttplugException\NetworkException $e) {
161
            throw HttpServerException::networkError($e);
162
        }
163
164 5
        return $response;
165
    }
166
167
    /**
168
     * Send a PUT request.
169
     *
170
     * @param string $path           Request path
171
     * @param array  $parameters     PUT parameters
172
     * @param array  $requestHeaders Request headers
173
     *
174
     * @return ResponseInterface
175
     */
176 3 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 3
            $response = $this->httpClient->sendRequest(
180 3
                $this->requestBuilder->create('PUT', $path, $requestHeaders, $this->createRequestBody($parameters))
181 3
            );
182 3
        } catch (HttplugException\NetworkException $e) {
183
            throw HttpServerException::networkError($e);
184
        }
185
186 3
        return $response;
187
    }
188
189
    /**
190
     * Send a DELETE request.
191
     *
192
     * @param string $path           Request path
193
     * @param array  $parameters     DELETE parameters
194
     * @param array  $requestHeaders Request headers
195
     *
196
     * @return ResponseInterface
197
     */
198 6 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 6
            $response = $this->httpClient->sendRequest(
202 6
                $this->requestBuilder->create('DELETE', $path, $requestHeaders, $this->createRequestBody($parameters))
203 6
            );
204 6
        } catch (HttplugException\NetworkException $e) {
205
            throw HttpServerException::networkError($e);
206
        }
207
208 6
        return $response;
209
    }
210
211
    /**
212
     * Prepare a set of key-value-pairs to be encoded as multipart/form-data.
213
     *
214
     * @param array $parameters Request parameters
215
     *
216
     * @return array
217
     */
218 14
    protected function createRequestBody(array $parameters)
219
    {
220 14
        $resources = [];
221 14
        foreach ($parameters as $key => $values) {
222 8
            if (!is_array($values)) {
223 8
                $values = [$values];
224 8
            }
225 8
            foreach ($values as $value) {
226 8
                $resources[] = [
227 8
                    'name' => $key,
228 8
                    'content' => $value,
229
                ];
230 8
            }
231 14
        }
232
233 14
        return $resources;
234
    }
235
}
236