Completed
Pull Request — master (#55)
by Rick
08:13
created

TgLog::downloadFileAsync()   A

Complexity

Conditions 3
Paths 1

Size

Total Lines 21
Code Lines 13

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 12

Importance

Changes 0
Metric Value
dl 0
loc 21
ccs 0
cts 12
cp 0
rs 9.3142
c 0
b 0
f 0
cc 3
eloc 13
nc 1
nop 1
crap 12

1 Method

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