HttpClient::send()   A
last analyzed

Complexity

Conditions 2
Paths 4

Size

Total Lines 13

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 13
rs 9.8333
c 0
b 0
f 0
cc 2
nc 4
nop 3
1
<?php
2
3
namespace Bencoderus\Webhook\Http\Clients;
4
5
use Bencoderus\Webhook\Exceptions\WebhookException;
6
use Exception;
7
use GuzzleHttp\Client;
8
use GuzzleHttp\Exception\ClientException;
9
use GuzzleHttp\Exception\ConnectException;
10
use GuzzleHttp\Exception\GuzzleException;
11
use GuzzleHttp\Exception\RequestException;
12
use GuzzleHttp\Exception\ServerException;
13
use GuzzleHttp\Handler\MockHandler;
14
use GuzzleHttp\HandlerStack;
15
use GuzzleHttp\Psr7\Response;
16
17
class HttpClient
18
{
19
    /**
20
     *  instance of the request headers.
21
     */
22
    private $headers;
23
24
    /**
25
     * An instance of the HTTP response.
26
     */
27
    private $response;
28
29
    /**
30
     * An instance of Guzzle Http Client.
31
     *
32
     * @var \GuzzleHttp\Client
33
     */
34
    private $client;
35
36
37
    /**
38
     * Create a new request instance.
39
     */
40
    public function __construct()
41
    {
42
        $this->client = (config('app.env') === "testing") ? $this->mockClient() : new Client(['timeout' => 15.0]);
43
    }
44
45
    /**
46
     * Mock HTTP request.
47
     *
48
     * @param int $statusCode
49
     * @param string $body
50
     * @param array $headers
51
     *
52
     * @return \GuzzleHttp\Client
53
     */
54
    private function mockClient(int $statusCode = 200, string $body = 'success', $headers = []): Client
55
    {
56
        $mock = new MockHandler([
57
            new Response($statusCode, $headers, $body),
58
        ]);
59
60
        $handlerStack = HandlerStack::create($mock);
61
62
        return new Client(['handler' => $handlerStack]);
63
    }
64
65
    /**
66
     * Set request headers.
67
     *
68
     * @param array $headers
69
     *
70
     * @return $this
71
     */
72
    public function withHeaders(array $headers)
73
    {
74
        $this->headers = $headers;
75
76
        return $this;
77
    }
78
79
    /**
80
     * Enable mocking for request.
81
     *
82
     * @param int $statusCode
83
     * @param string $body
84
     * @param array $headers
85
     *
86
     * @return $this
87
     */
88
    public function mock(int $statusCode = 200, string $body = '', $headers = []): self
89
    {
90
        $this->client = $this->mockClient($statusCode, $body, $headers);
91
92
        return $this;
93
    }
94
95
    /**
96
     * Send a POST request
97
     *
98
     * @param string $url
99
     * @param array $data
100
     *
101
     * @return $this
102
     * @throws \Exception
103
     */
104
    public function post(string $url, array $data = []): self
105
    {
106
        $this->response = $this->send("POST", $url, $data);
107
108
        return $this;
109
    }
110
111
    /**
112
     * Send a request
113
     *
114
     * @param string $method
115
     * @param string $url
116
     * @param array $data
117
     *
118
     * @return \Psr\Http\Message\ResponseInterface
119
     * @throws \Exception
120
     */
121
    public function send(string $method, string $url, array $data)
122
    {
123
        try {
124
            $requestData = [];
125
126
            $requestData['json'] = $data;
127
            $requestData['headers'] = $this->headers;
128
129
            return $this->client->request($method, $url, $requestData);
130
        } catch (GuzzleException $exception) {
131
            return $this->handleException($exception);
0 ignored issues
show
Documentation introduced by
$exception is of type object<GuzzleHttp\Exception\GuzzleException>, but the function expects a object<Exception>.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
132
        }
133
    }
134
135
    /**
136
     * Handle possible request exceptions.
137
     *
138
     * @param Exception $exception
139
     *
140
     * @return mixed
141
     * @throws Exception
142
     */
143
    private function handleException(Exception $exception)
144
    {
145
        if ($exception instanceof RequestException && $exception->hasResponse()) {
146
            return $exception->getResponse();
147
        }
148
149
        if ($exception instanceof ConnectException) {
150
            throw new WebhookException("URL is currently unavailable");
151
        }
152
        if ($exception instanceof ClientException || $exception instanceof ServerException) {
153
            throw new WebhookException("URL is invalid or broken");
154
        }
155
156
        throw new WebhookException($exception->getMessage());
157
    }
158
159
    /**
160
     * Send a GET request
161
     *
162
     * @param string $url
163
     * @param array $data
164
     *
165
     * @return $this
166
     * @throws \Exception
167
     */
168
    public function get(string $url, array $data = []): self
169
    {
170
        $this->response = $this->send("GET", $url, $data);
171
172
        return $this;
173
    }
174
175
    /**
176
     * Send a PUT request
177
     *
178
     * @param string $url
179
     * @param array $data
180
     *
181
     * @return $this
182
     * @throws \Exception
183
     */
184
    public function put(string $url, array $data = []): self
185
    {
186
        $this->response = $this->send("PUT", $url, $data);
187
188
        return $this;
189
    }
190
191
    /**
192
     * Send a DELETE request
193
     *
194
     * @param string $url
195
     * @param array $data
196
     *
197
     * @return $this
198
     * @throws \Exception
199
     */
200
    public function delete(string $url, array $data = []): self
201
    {
202
        $this->response = $this->send("DELETE", $url, $data);
203
204
        return $this;
205
    }
206
207
    /**
208
     * Send a PATCH request
209
     *
210
     * @param string $url
211
     * @param array $data
212
     *
213
     * @return $this
214
     * @throws \Exception
215
     */
216
    public function patch(string $url, array $data = []): self
217
    {
218
        $this->response = $this->send("PATCH", $url, $data);
219
220
        return $this;
221
    }
222
223
    /**
224
     * Return response as an array.
225
     *
226
     * @return array
227
     */
228
    public function json()
229
    {
230
        return json_decode($this->response->getBody()->getContents(), true);
231
    }
232
233
    /**
234
     * Return response status code.
235
     *
236
     * @return int
237
     */
238
    public function statusCode(): int
239
    {
240
        return $this->response->getStatusCode();
241
    }
242
}
243