Completed
Push — master ( 20b0b4...0ce164 )
by Camilo
13s
created

GuzzleRequestHandler::post()   B

Complexity

Conditions 5
Paths 18

Size

Total Lines 23
Code Lines 16

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 9
CRAP Score 6.6

Importance

Changes 0
Metric Value
dl 0
loc 23
ccs 9
cts 15
cp 0.6
rs 8.5906
c 0
b 0
f 0
cc 5
eloc 16
nc 18
nop 2
crap 6.6
1
<?php
2
3
declare(strict_types=1);
4
5
namespace unreal4u\TelegramAPI;
6
7
use GuzzleHttp\Client;
8
use GuzzleHttp\ClientInterface;
9
use GuzzleHttp\Exception\ClientException;
10
use GuzzleHttp\Exception\RequestException;
11
use Psr\Http\Message\ResponseInterface;
12
use Psr\Log\LoggerInterface;
13
use React\Promise\Deferred;
14
use React\Promise\PromiseInterface;
15
use unreal4u\TelegramAPI\InternalFunctionality\DummyLogger;
16
use unreal4u\TelegramAPI\InternalFunctionality\TelegramRawData;
17
18
class GuzzleRequestHandler implements RequestHandlerInterface
19
{
20
    /**
21
     * @var LoggerInterface
22
     */
23
    protected $logger;
24
25
    /**
26
     * @var ClientInterface
27
     */
28
    protected $httpClient;
29
30
    /**
31
     * GuzzleRequestHandler constructor.
32
     *
33
     * @param ClientInterface $client
34
     * @param LoggerInterface $logger
35
     */
36 40
    public function __construct(ClientInterface $client = null, LoggerInterface $logger = null)
37
    {
38 40
        if ($logger === null) {
39 24
            $logger = new DummyLogger();
40
        }
41 40
        $this->logger = $logger;
42
43 40
        if ($client === null) {
44 40
            $client = new Client();
45
        }
46 40
        $this->httpClient = $client;
47 40
    }
48
49
    /**
50
     * @param string $uri
51
     *
52
     * @return ResponseInterface
53
     */
54
    public function get(string $uri): ResponseInterface
55
    {
56
        return $this->httpClient->get($uri);
57
    }
58
59
    /**
60
     * This is the method that actually makes the call,
61
     * which can be easily overwritten so that our unit tests can work
62
     *
63
     * @param string $uri
64
     * @param array $formData
65
     *
66
     * @return TelegramRawData
67
     */
68 24
    public function post(string $uri, array $formData = []): TelegramRawData
69
    {
70 24
        if (!empty($formData['headers']['Content-Type']) &&
71 24
            $formData['headers']['Content-Type'] == 'multipart/form-data') {
72
            $formData = [
73 4
                'multipart' => $formData['body']
74
            ];
75
        }
76 24
        $e = null;
77 24
        $this->logger->debug('About to perform HTTP call to Telegram\'s API');
78
        try {
79 24
            $response = $this->httpClient->post($uri, $formData);
80 24
            $this->logger->debug('Got response back from Telegram, applying json_decode');
81
        } catch (ClientException $e) {
82
            $response = $e->getResponse();
83
            // It can happen that we have a network problem, in such case, we can't do nothing about it, so rethrow
84
            if (empty($response)) {
85
                throw $e;
86
            }
87
        } finally {
88 24
            return new TelegramRawData((string)$response->getBody(), $e);
89
        }
90
    }
91
92
    /**
93
     * @param string $uri
94
     * @param array $formData
95
     *
96
     * @return PromiseInterface
97
     */
98
    public function postAsync(string $uri, array $formData = []): PromiseInterface
99
    {
100
        $this->logger->debug('About to perform async HTTP call to Telegram\'s API');
101
        $deferred = new Deferred();
102
103
        $promise = $this->httpClient->postAsync($uri, $formData);
104
        $promise->then(
105
            function (ResponseInterface $response) use ($deferred) {
106
                $deferred->resolve(new TelegramRawData((string)$response->getBody()));
107
            },
108
            function (RequestException $exception) use ($deferred) {
109
                if (!empty($exception->getResponse()->getBody())) {
110
                    $deferred->resolve(new TelegramRawData((string)$exception->getResponse()
111
                        ->getBody(), $exception));
112
                } else {
113
                    $deferred->reject($exception);
114
                }
115
            }
116
        );
117
118
        return $deferred->promise();
119
    }
120
121
    /**
122
     * @param string $uri
123
     *
124
     * @return PromiseInterface
125
     */
126
    public function getAsync(string $uri): PromiseInterface
127
    {
128
        $this->logger->debug('About to perform async HTTP call to Telegram\'s API');
129
        $deferred = new Deferred();
130
131
        $promise = $this->httpClient->getAsync($uri);
132
        $promise->then(
133
            function (ResponseInterface $response) use ($deferred) {
134
                $deferred->resolve(new TelegramRawData((string)$response->getBody()));
135
            },
136
            function (RequestException $exception) use ($deferred) {
137
                if (!empty($exception->getResponse()->getBody())) {
138
                    $deferred->resolve(new TelegramRawData((string)$exception->getResponse()
139
                        ->getBody(), $exception));
140
                } else {
141
                    $deferred->reject($exception);
142
                }
143
            }
144
        );
145
146
        return $deferred->promise();
147
    }
148
}
149