Completed
Pull Request — master (#59)
by Rick
02:24
created

TgLog   A

Complexity

Total Complexity 7

Size/Duplication

Total Lines 141
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 9

Test Coverage

Coverage 61.53%

Importance

Changes 0
Metric Value
wmc 7
lcom 1
cbo 9
dl 0
loc 141
ccs 24
cts 39
cp 0.6153
rs 10
c 0
b 0
f 0

6 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 14 2
A performApiRequest() 0 10 1
A downloadFile() 0 19 1
A sendRequestToTelegram() 0 5 1
A resetObjectValues() 0 5 1
A composeApiMethodUrl() 0 8 1
1
<?php
2
3
declare(strict_types=1);
4
5
namespace unreal4u\TelegramAPI;
6
7
use Psr\Log\LoggerInterface;
8
use React\Promise\Deferred;
9
use React\Promise\PromiseInterface;
10
use unreal4u\TelegramAPI\Abstracts\TelegramMethods;
11
use unreal4u\TelegramAPI\InternalFunctionality\DummyLogger;
12
use unreal4u\TelegramAPI\InternalFunctionality\PostOptionsConstructor;
13
use unreal4u\TelegramAPI\InternalFunctionality\TelegramDocument;
14
use unreal4u\TelegramAPI\InternalFunctionality\TelegramResponse;
15
use unreal4u\TelegramAPI\Telegram\Types\File;
16
17
/**
18
 * The main API which does it all
19
 */
20
class TgLog
21
{
22
    /**
23
     * @var RequestHandlerInterface
24
     */
25
    protected $requestHandler;
26
27
    /**
28
     * @var PostOptionsConstructor
29
     */
30
    protected $formConstructor;
31
32
    /**
33
     * Stores the token
34
     * @var string
35
     */
36
    private $botToken;
37
38
    /**
39
     * Contains an instance to a PSR-3 compatible logger
40
     * @var LoggerInterface
41
     */
42
    protected $logger;
43
44
    /**
45
     * Stores the API URL from Telegram
46
     * @var string
47
     */
48
    private $apiUrl = '';
49
50
    /**
51
     * @var string
52
     */
53
    protected $methodName = '';
54
55
    /**
56
     * TelegramLog constructor.
57
     *
58
     * @param string $botToken
59
     * @param RequestHandlerInterface $handler
60
     * @param LoggerInterface $logger
61
     */
62 40
    public function __construct(string $botToken, RequestHandlerInterface $handler, LoggerInterface $logger = null)
63
    {
64 40
        $this->botToken = $botToken;
65
66
        // Initialize new dummy logger (PSR-3 compatible) if not injected
67 40
        if ($logger === null) {
68 40
            $logger = new DummyLogger();
69
        }
70 40
        $this->logger = $logger;
71
72 40
        $this->requestHandler = $handler;
73 40
        $this->formConstructor = new PostOptionsConstructor();
74 40
        $this->apiUrl = 'https://api.telegram.org/bot' . $this->botToken . '/';
75 40
    }
76
77
    /**
78
     * @param TelegramMethods $method
79
     *
80
     * @return PromiseInterface
81
     */
82 31
    public function performApiRequest(TelegramMethods $method)
83
    {
84 31
        $this->logger->debug('Request for async API call, resetting internal values', [get_class($method)]);
85 31
        $this->resetObjectValues();
86 31
        $option = $this->formConstructor->constructOptions($method);
87 29
        return $this->sendRequestToTelegram($method, $option)
88
            ->then(function (TelegramResponse $response) use ($method) {
89 24
                return $method::bindToObject($response, $this->logger);
90 24
            });
91
    }
92
93
    /**
94
     * @param File $file
95
     *
96
     * @return PromiseInterface
97
     */
98
    public function downloadFile(File $file): PromiseInterface
99
    {
100
        $this->logger->debug('Downloading file async from Telegram, creating URL');
101
        $url = 'https://api.telegram.org/file/bot' . $this->botToken . '/' . $file->file_path;
102
        $this->logger->debug('About to perform request to begin downloading file');
103
104
        $deferred = new Deferred();
105
106
        $this->requestHandler->get($url)->then(
107
            function (TelegramResponse $rawData) use ($deferred) {
108
                $deferred->resolve(new TelegramDocument($rawData));
109
            },
110
            function (\Exception $exception) use ($deferred) {
111
                $deferred->reject($exception);
112
            }
113
        );
114
        
115
        return $deferred->promise();
116
    }
117
118
    /**
119
     * @param TelegramMethods $method
120
     * @param array $formData
121
     *
122
     * @return PromiseInterface
123
     */
124
    protected function sendRequestToTelegram(TelegramMethods $method, array $formData): PromiseInterface
125
    {
126
        $this->logger->debug('About to perform async HTTP call to Telegram\'s API');
127
        return $this->requestHandler->post($this->composeApiMethodUrl($method), $formData);
128
    }
129
130
    /**
131
     * Resets everything to the default values
132
     *
133
     * @return TgLog
134
     */
135 31
    private function resetObjectValues(): TgLog
136
    {
137 31
        $this->formConstructor->formType = 'application/x-www-form-urlencoded';
138 31
        return $this;
139
    }
140
141
    /**
142
     * Builds up the URL with which we can work with
143
     *
144
     * All methods in the Bot API are case-insensitive.
145
     * All queries must be made using UTF-8.
146
     *
147
     * @see https://core.telegram.org/bots/api#making-requests
148
     *
149
     * @param TelegramMethods $call
150
     * @return string
151
     */
152 30
    protected function composeApiMethodUrl(TelegramMethods $call): string
153
    {
154 30
        $completeClassName = get_class($call);
155 30
        $this->methodName = substr($completeClassName, strrpos($completeClassName, '\\') + 1);
156 30
        $this->logger->info('About to perform API request', ['method' => $this->methodName]);
157
158 30
        return $this->apiUrl . $this->methodName;
159
    }
160
}
161