Passed
Push — master ( 3bfee0...112fc6 )
by Nikolay
02:02
created

BotApi::getChatAdministrators()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 2
CRAP Score 1

Importance

Changes 0
Metric Value
eloc 1
dl 0
loc 3
ccs 2
cts 2
cp 1
rs 10
c 0
b 0
f 0
cc 1
nc 1
nop 1
crap 1
1
<?php
2
3
declare(strict_types=1);
4
5
namespace TgBotApi\BotApiBase;
6
7
use Symfony\Component\PropertyInfo\Extractor\PhpDocExtractor;
8
use Symfony\Component\Serializer\NameConverter\CamelCaseToSnakeCaseNameConverter;
9
use Symfony\Component\Serializer\Normalizer\ArrayDenormalizer;
10
use Symfony\Component\Serializer\Normalizer\DateTimeNormalizer;
11
use Symfony\Component\Serializer\Normalizer\ObjectNormalizer;
12
use Symfony\Component\Serializer\Serializer;
13
use TgBotApi\BotApiBase\Exception\ResponseException;
14
use TgBotApi\BotApiBase\Method\AddStickerToSetMethod;
15
use TgBotApi\BotApiBase\Method\AnswerCallbackQueryMethod;
16
use TgBotApi\BotApiBase\Method\AnswerInlineQueryMethod;
17
use TgBotApi\BotApiBase\Method\ForwardMessageMethod;
18
use TgBotApi\BotApiBase\Method\GetChatAdministratorsMethod;
19
use TgBotApi\BotApiBase\Method\GetChatMemberMethod;
20
use TgBotApi\BotApiBase\Method\GetChatMembersCountMethod;
21
use TgBotApi\BotApiBase\Method\GetChatMethod;
22
use TgBotApi\BotApiBase\Method\GetFileMethod;
23
use TgBotApi\BotApiBase\Method\GetMeMethod;
24
use TgBotApi\BotApiBase\Method\GetUpdatesMethod;
25
use TgBotApi\BotApiBase\Method\GetUserProfilePhotosMethod;
26
use TgBotApi\BotApiBase\Method\GetWebhookInfoMethod;
27
use TgBotApi\BotApiBase\Method\KickChatMemberMethod;
28
use TgBotApi\BotApiBase\Method\LeaveChatMethod;
29
use TgBotApi\BotApiBase\Method\PinChatMessageMethod;
30
use TgBotApi\BotApiBase\Method\SendAnimationMethod;
31
use TgBotApi\BotApiBase\Method\SendAudioMethod;
32
use TgBotApi\BotApiBase\Method\SendContactMethod;
33
use TgBotApi\BotApiBase\Method\SendDocumentMethod;
34
use TgBotApi\BotApiBase\Method\SendLocationMethod;
35
use TgBotApi\BotApiBase\Method\SendMediaGroupMethod;
36
use TgBotApi\BotApiBase\Method\SendMessageMethod;
37
use TgBotApi\BotApiBase\Method\SendPhotoMethod;
38
use TgBotApi\BotApiBase\Method\SendVenueMethod;
39
use TgBotApi\BotApiBase\Method\SendVideoMethod;
40
use TgBotApi\BotApiBase\Method\SendVideoNoteMethod;
41
use TgBotApi\BotApiBase\Method\SendVoiceMethod;
42
use TgBotApi\BotApiBase\Normalizer\AnswerInlineQueryNormalizer;
43
use TgBotApi\BotApiBase\Normalizer\InputFileNormalizer;
44
use TgBotApi\BotApiBase\Normalizer\InputMediaNormalizer;
45
use TgBotApi\BotApiBase\Normalizer\JsonSerializableNormalizer;
46
use TgBotApi\BotApiBase\Normalizer\MediaGroupNormalizer;
47
use TgBotApi\BotApiBase\Normalizer\UserProfilePhotosNormalizer;
48
use TgBotApi\BotApiBase\Type\ChatMemberType;
49
use TgBotApi\BotApiBase\Type\ChatType;
50
use TgBotApi\BotApiBase\Type\FileType;
51
use TgBotApi\BotApiBase\Type\MessageType;
52
use TgBotApi\BotApiBase\Type\UpdateType;
53
use TgBotApi\BotApiBase\Type\UserProfilePhotosType;
54
use TgBotApi\BotApiBase\Type\UserType;
55
use TgBotApi\BotApiBase\Type\WebhookInfoType;
56
57
/**
58
 * Class BotApi.
59
 */
60
class BotApi implements BotApiInterface
61
{
62
    /**
63
     * @var string
64
     */
65
    private $botKey;
66
67
    /**
68
     * @var ApiClientInterface
69
     */
70
    private $apiClient;
71
72
    /**
73
     * @var string
74
     */
75
    private $endPoint;
76
77
    /**
78
     * BotApi constructor.
79
     *
80
     * @param string             $botKey
81
     * @param ApiClientInterface $apiClient
82
     * @param string             $endPoint
83
     */
84 63
    public function __construct(
85
        string $botKey,
86
        ApiClientInterface $apiClient,
87
        string $endPoint = 'https://api.telegram.org'
88
    ) {
89 63
        $this->botKey = $botKey;
90 63
        $this->apiClient = $apiClient;
91 63
        $this->endPoint = $endPoint;
92
93 63
        $this->apiClient->setBotKey($botKey);
94 63
        $this->apiClient->setEndpoint($endPoint);
95 63
    }
96
97
    /**
98
     * @param $method
99
     * @param $type
100
     *
101
     * @throws ResponseException
102
     *
103
     * @return mixed
104
     */
105 63
    public function call($method, $type = null)
106
    {
107 63
        list($data, $files) = $this->encode($method);
108
109 63
        $json = $this->apiClient->send($this->getMethodName($method), $data, $files);
0 ignored issues
show
Bug introduced by
It seems like $data can also be of type boolean and double and integer and string; however, parameter $data of TgBotApi\BotApiBase\ApiClientInterface::send() does only seem to accept array, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

109
        $json = $this->apiClient->send($this->getMethodName($method), /** @scrutinizer ignore-type */ $data, $files);
Loading history...
110
111 63
        if (true !== $json->ok) {
112
            throw new ResponseException($json->description);
113
        }
114
115 63
        return $type ? $this->denormalize($json, $type) : $json->result;
116
    }
117
118
    /**
119
     * @param GetUpdatesMethod $method
120
     *
121
     * @throws ResponseException
122
     *
123
     * @return UpdateType[]
124
     */
125 6
    public function getUpdates(GetUpdatesMethod $method): array
126
    {
127 6
        return $this->call($method, UpdateType::class . '[]');
128
    }
129
130
    /**
131
     * @param GetMeMethod $method
132
     *
133
     * @throws ResponseException
134
     *
135
     * @return UserType
136
     */
137 6
    public function getMe(GetMeMethod $method): UserType
138
    {
139 6
        return $this->call($method, UserType::class);
140
    }
141
142
    /**
143
     * @param SendMessageMethod $method
144
     *
145
     * @throws ResponseException
146
     *
147
     * @return MessageType
148
     */
149 6
    public function sendMessage(SendMessageMethod $method): MessageType
150
    {
151 6
        return $this->call($method, MessageType::class);
152
    }
153
154
    /**
155
     * @param ForwardMessageMethod $method
156
     *
157
     * @throws ResponseException
158
     *
159
     * @return MessageType
160
     */
161 3
    public function sendForwardMessage(ForwardMessageMethod $method): MessageType
162
    {
163 3
        return $this->call($method, MessageType::class);
164
    }
165
166
    /**
167
     * @param SendPhotoMethod $method
168
     *
169
     * @throws ResponseException
170
     *
171
     * @return MessageType
172
     */
173 3
    public function sendPhoto(SendPhotoMethod $method): MessageType
174
    {
175 3
        return $this->call($method, MessageType::class);
176
    }
177
178
    /**
179
     * @param SendAudioMethod $method
180
     *
181
     * @throws ResponseException
182
     *
183
     * @return MessageType
184
     */
185 3
    public function sendAudio(SendAudioMethod $method): MessageType
186
    {
187 3
        return $this->call($method, MessageType::class);
188
    }
189
190
    /**
191
     * @param SendDocumentMethod $method
192
     *
193
     * @throws ResponseException
194
     *
195
     * @return MessageType
196
     */
197 3
    public function sendDocument(SendDocumentMethod $method): MessageType
198
    {
199 3
        return $this->call($method, MessageType::class);
200
    }
201
202
    /**
203
     * @param SendVideoMethod $method
204
     *
205
     * @throws ResponseException
206
     *
207
     * @return MessageType
208
     */
209 3
    public function sendVideo(SendVideoMethod $method): MessageType
210
    {
211 3
        return $this->call($method, MessageType::class);
212
    }
213
214
    /**
215
     * @param SendAnimationMethod $method
216
     *
217
     * @throws ResponseException
218
     *
219
     * @return MessageType
220
     */
221 3
    public function sendAnimation(SendAnimationMethod $method): MessageType
222
    {
223 3
        return $this->call($method, MessageType::class);
224
    }
225
226
    /**
227
     * @param SendVoiceMethod $method
228
     *
229
     * @throws ResponseException
230
     *
231
     * @return MessageType
232
     */
233 3
    public function sendVoice(SendVoiceMethod $method): MessageType
234
    {
235 3
        return $this->call($method, MessageType::class);
236
    }
237
238
    /**
239
     * @param SendVideoNoteMethod $method
240
     *
241
     * @throws ResponseException
242
     *
243
     * @return MessageType
244
     */
245 3
    public function sendVideoNote(SendVideoNoteMethod $method): MessageType
246
    {
247 3
        return $this->call($method, MessageType::class);
248
    }
249
250
    /**
251
     * @param SendMediaGroupMethod $method
252
     *
253
     * @throws ResponseException
254
     *
255
     * @return MessageType[]
256
     */
257 3
    public function sendMediaGroup(SendMediaGroupMethod $method): array
258
    {
259 3
        return $this->call($method, MessageType::class . '[]');
260
    }
261
262
    /**
263
     * @param SendLocationMethod $method
264
     *
265
     * @throws ResponseException
266
     *
267
     * @return MessageType
268
     */
269 3
    public function sendLocation(SendLocationMethod $method): MessageType
270
    {
271 3
        return $this->call($method, MessageType::class);
272
    }
273
274
    /**
275
     * @param SendVenueMethod $method
276
     *
277
     * @throws ResponseException
278
     *
279
     * @return MessageType
280
     */
281 3
    public function sendVenue(SendVenueMethod $method): MessageType
282
    {
283 3
        return $this->call($method, MessageType::class);
284
    }
285
286
    /**
287
     * @param SendContactMethod $method
288
     *
289
     * @throws ResponseException
290
     *
291
     * @return MessageType
292
     */
293 3
    public function sendContact(SendContactMethod $method): MessageType
294
    {
295 3
        return $this->call($method, MessageType::class);
296
    }
297
298
    /**
299
     * @param GetUserProfilePhotosMethod $method
300
     *
301
     * @throws ResponseException
302
     *
303
     * @return UserProfilePhotosType
304
     */
305 6
    public function getUserProfilePhotos(GetUserProfilePhotosMethod $method): UserProfilePhotosType
306
    {
307 6
        return $this->call($method, UserProfilePhotosType::class);
308
    }
309
310
    /**
311
     * @param GetWebhookInfoMethod $method
312
     *
313
     * @throws ResponseException
314
     *
315
     * @return WebhookInfoType
316
     */
317 3
    public function getWebhookInfo(GetWebhookInfoMethod $method): WebhookInfoType
318
    {
319 3
        return $this->call($method, WebhookInfoType::class);
320
    }
321
322
    /**
323
     * @param LeaveChatMethod $method
324
     *
325
     * @throws ResponseException
326
     *
327
     * @return bool
328
     */
329 3
    public function leaveChat(LeaveChatMethod $method): bool
330
    {
331 3
        return $this->call($method);
332
    }
333
334 3
    public function pinChatMessage(PinChatMessageMethod $method): bool
335
    {
336 3
        return $this->call($method);
337
    }
338
339
    /**
340
     * @todo fix this is bad
341
     *
342
     * @param GetFileMethod $method
343
     *
344
     * @throws ResponseException
345
     *
346
     * @return FileType
347
     */
348 6
    public function getFile(GetFileMethod $method): FileType
349
    {
350 6
        return $this->call($method, FileType::class);
351
    }
352
353
    /**
354
     * @param FileType $file
355
     *
356
     * @return string
357
     */
358
    public function getAbsoluteFilePath(FileType $file): string
359
    {
360
        return \sprintf('%s/file/bot%s/%s', $this->endPoint, $this->botKey, $file->filePath);
361
    }
362
363
    /**
364
     * @param GetChatMethod $method
365
     *
366
     * @throws ResponseException
367
     *
368
     * @return ChatType
369
     */
370 6
    public function getChat(GetChatMethod $method): ChatType
371
    {
372 6
        return $this->call($method, ChatType::class);
373
    }
374
375
    /**
376
     * @param GetChatAdministratorsMethod $method
377
     *
378
     * @throws ResponseException
379
     *
380
     * @return ChatMemberType[]
381
     */
382 6
    public function getChatAdministrators(GetChatAdministratorsMethod $method): array
383
    {
384 6
        return $this->call($method, ChatMemberType::class . '[]');
385
    }
386
387
    /**
388
     * @param GetChatMemberMethod $method
389
     *
390
     * @throws ResponseException
391
     *
392
     * @return ChatMemberType
393
     */
394 6
    public function getChatMember(GetChatMemberMethod $method): ChatMemberType
395
    {
396 6
        return $this->call($method, ChatMemberType::class);
397
    }
398
399
    /**
400
     * @param KickChatMemberMethod $method
401
     *
402
     * @throws ResponseException
403
     *
404
     * @return bool
405
     */
406 3
    public function kickChatMember(KickChatMemberMethod $method): bool
407
    {
408 3
        return $this->call($method);
409
    }
410
411
    /**
412
     * @param AddStickerToSetMethod $method
413
     *
414
     * @throws ResponseException
415
     *
416
     * @return bool
417
     */
418 3
    public function addStickerToSet(AddStickerToSetMethod $method): bool
419
    {
420 3
        return $this->call($method);
421
    }
422
423
    /**
424
     * @param GetChatMembersCountMethod $method
425
     *
426
     * @throws ResponseException
427
     *
428
     * @return int
429
     */
430 3
    public function getChatMembersCount(GetChatMembersCountMethod $method): int
431
    {
432 3
        return $this->call($method);
433
    }
434
435
//    public function answerInlineQuery(AnswerInlineQueryMethod $method)
436
//    {
437
//        return $this->call($method, '');
438
//    }
439
440
    /**
441
     * @param AnswerCallbackQueryMethod $method
442
     *
443
     * @throws ResponseException
444
     *
445
     * @return bool
446
     */
447 9
    public function answerCallbackQuery(AnswerCallbackQueryMethod $method): bool
448
    {
449 9
        return $this->call($method);
450
    }
451
452
    /**
453
     * @param AnswerInlineQueryMethod $method
454
     *
455
     * @throws ResponseException
456
     *
457
     * @return bool
458
     */
459 6
    public function answerInlineQuery(AnswerInlineQueryMethod $method): bool
460
    {
461 6
        return $this->call($method);
462
    }
463
464
    /**
465
     * @param $method
466
     *
467
     * @return string
468
     */
469 63
    private function getMethodName($method): string
470
    {
471 63
        return \lcfirst(\substr(
472 63
            \get_class($method),
473 63
            \strrpos(\get_class($method), '\\') + 1,
474 63
            -1 * \strlen('Method')
475
        ));
476
    }
477
478
    /**
479
     * @param $data
480
     * @param $type
481
     *
482
     * @return object|array
483
     */
484 33
    private function denormalize($data, $type)
485
    {
486 33
        $normalizer = new ObjectNormalizer(
487 33
            null,
488 33
            new CamelCaseToSnakeCaseNameConverter(),
489 33
            null,
490 33
            new PhpDocExtractor()
491
        );
492 33
        $arrayNormalizer = new ArrayDenormalizer();
493 33
        $serializer = new Serializer([
494 33
            new UserProfilePhotosNormalizer($normalizer, $arrayNormalizer),
495 33
            new DateTimeNormalizer(),
496 33
            $normalizer,
497 33
            $arrayNormalizer,
498
        ]);
499
500 33
        return $serializer->denormalize($data->result, $type, null, [DateTimeNormalizer::FORMAT_KEY => 'U']);
501
    }
502
503
    /**
504
     * @param $method
505
     *
506
     * @return array
507
     */
508 63
    private function encode($method): array
509
    {
510 63
        $files = [];
511
512 63
        $objectNormalizer = new ObjectNormalizer(null, new CamelCaseToSnakeCaseNameConverter());
513 63
        $serializer = new Serializer([
514 63
            new InputFileNormalizer($files),
515 63
            new MediaGroupNormalizer(new InputMediaNormalizer($objectNormalizer, $files), $objectNormalizer),
516 63
            new JsonSerializableNormalizer($objectNormalizer),
517 63
            new AnswerInlineQueryNormalizer($objectNormalizer),
518 63
            new DateTimeNormalizer(),
519 63
            $objectNormalizer,
520
        ]);
521
522 63
        $data = $serializer->normalize(
523 63
            $method,
524 63
            null,
525 63
            ['skip_null_values' => true, DateTimeNormalizer::FORMAT_KEY => 'U']
526
        );
527
528 63
        return [$data, $files];
529
    }
530
}
531