Completed
Pull Request — master (#51)
by Rick
02:01
created

GuzzleRequestHandler::__construct()   A

Complexity

Conditions 3
Paths 4

Size

Total Lines 14
Code Lines 7

Duplication

Lines 0
Ratio 0 %

Importance

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