Completed
Push — master ( b3f24e...84a5c5 )
by Tobias
03:15
created

HttpApi::safeDeserialize()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 10
Code Lines 7

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 3
CRAP Score 4.125

Importance

Changes 0
Metric Value
dl 0
loc 10
ccs 3
cts 6
cp 0.5
rs 9.4285
c 0
b 0
f 0
cc 3
eloc 7
nc 3
nop 2
crap 4.125
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\Hydrator\Hydrator;
15
use Mailgun\Hydrator\NoopHydrator;
16
use Mailgun\Exception\HttpClientException;
17
use Mailgun\Exception\HttpServerException;
18
use Mailgun\RequestBuilder;
19
use Mailgun\Model\ErrorResponse;
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
     * Attempts to safely deserialize the response into the given class.
60
     * If the HTTP return code != 200, deserializes into SimpleResponse::class
61
     * to contain the error message and any other information provided.
62
     *
63
     * @param ResponseInterface $response
64
     * @param string            $className
65
     *
66
     * @throws HttpClientException
67
     *
68
     * @return object $class
69
     */
70 7
    protected function safeHydrate(ResponseInterface $response, $className)
71
    {
72 7
        if (!$this->hydrator) {
73
            return $response;
74
        }
75
76 7
        if ($response->getStatusCode() === 200) {
77 7
            return $this->hydrator->deserialize($response, $className);
78
        } elseif ($response->getStatusCode() === 401) {
79
            throw HttpClientException::unauthorized();
80
        } else {
81
            return $this->hydrator->deserialize($response, ErrorResponse::class);
82
        }
83
    }
84
85
    /**
86
     * Send a GET request with query parameters.
87
     *
88
     * @param string $path           Request path.
89
     * @param array  $parameters     GET parameters.
90
     * @param array  $requestHeaders Request Headers.
91
     *
92
     * @return ResponseInterface
93
     */
94
    protected function httpGet($path, array $parameters = [], array $requestHeaders = [])
95
    {
96
        if (count($parameters) > 0) {
97
            $path .= '?'.http_build_query($parameters);
98
        }
99
100
        try {
101
            $response = $this->httpClient->sendRequest(
102
                $this->requestBuilder->create('GET', $path, $requestHeaders)
103
            );
104
        } catch (HttplugException\NetworkException $e) {
105
            throw HttpServerException::networkError($e);
106
        }
107
108
        return $response;
109
    }
110
111
    /**
112
     * Send a POST request with JSON-encoded parameters.
113
     *
114
     * @param string $path           Request path.
115
     * @param array  $parameters     POST parameters to be JSON encoded.
116
     * @param array  $requestHeaders Request headers.
117
     *
118
     * @return ResponseInterface
119
     */
120
    protected function httpPost($path, array $parameters = [], array $requestHeaders = [])
121
    {
122
        return $this->httpPostRaw($path, $this->createJsonBody($parameters), $requestHeaders);
123
    }
124
125
    /**
126
     * Send a POST request with raw data.
127
     *
128
     * @param string       $path           Request path.
129
     * @param array|string $body           Request body.
130
     * @param array        $requestHeaders Request headers.
131
     *
132
     * @return ResponseInterface
133
     */
134 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...
135
    {
136
        try {
137
            $response = $this->httpClient->sendRequest(
138
                $this->requestBuilder->create('POST', $path, $requestHeaders, $body)
139
            );
140
        } catch (HttplugException\NetworkException $e) {
141
            throw HttpServerException::networkError($e);
142
        }
143
144
        return $response;
145
    }
146
147
    /**
148
     * Send a PUT request with JSON-encoded parameters.
149
     *
150
     * @param string $path           Request path.
151
     * @param array  $parameters     POST parameters to be JSON encoded.
152
     * @param array  $requestHeaders Request headers.
153
     *
154
     * @return ResponseInterface
155
     */
156 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...
157
    {
158
        try {
159
            $response = $this->httpClient->sendRequest(
160
                $this->requestBuilder->create('PUT', $path, $requestHeaders, $this->createJsonBody($parameters))
161
            );
162
        } catch (HttplugException\NetworkException $e) {
163
            throw HttpServerException::networkError($e);
164
        }
165
166
        return $response;
167
    }
168
169
    /**
170
     * Send a DELETE request with JSON-encoded parameters.
171
     *
172
     * @param string $path           Request path.
173
     * @param array  $parameters     POST parameters to be JSON encoded.
174
     * @param array  $requestHeaders Request headers.
175
     *
176
     * @return ResponseInterface
177
     */
178 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...
179
    {
180
        try {
181
            $response = $this->httpClient->sendRequest(
182
                $this->requestBuilder->create('DELETE', $path, $requestHeaders, $this->createJsonBody($parameters))
183
            );
184
        } catch (HttplugException\NetworkException $e) {
185
            throw HttpServerException::networkError($e);
186
        }
187
188
        return $response;
189
    }
190
191
    /**
192
     * Create a JSON encoded version of an array of parameters.
193
     *
194
     * @param array $parameters Request parameters
195
     *
196
     * @return null|string
197
     */
198
    protected function createJsonBody(array $parameters)
199
    {
200
        return (count($parameters) === 0) ? null : json_encode($parameters, empty($parameters) ? JSON_FORCE_OBJECT : 0);
201
    }
202
}
203