Completed
Push — master ( 62cb7b...4b7fdd )
by Nikolay
02:34
created

BotApi::sendForwardMessage()   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\PromoteChatMemberMethod;
31
use TgBotApi\BotApiBase\Method\RestrictChatMemberMethod;
32
use TgBotApi\BotApiBase\Method\SendAnimationMethod;
33
use TgBotApi\BotApiBase\Method\SendAudioMethod;
34
use TgBotApi\BotApiBase\Method\SendChatActionMethod;
35
use TgBotApi\BotApiBase\Method\SendContactMethod;
36
use TgBotApi\BotApiBase\Method\SendDocumentMethod;
37
use TgBotApi\BotApiBase\Method\SendGameMethod;
38
use TgBotApi\BotApiBase\Method\SendInvoiceMethod;
39
use TgBotApi\BotApiBase\Method\SendLocationMethod;
40
use TgBotApi\BotApiBase\Method\SendMediaGroupMethod;
41
use TgBotApi\BotApiBase\Method\SendMessageMethod;
42
use TgBotApi\BotApiBase\Method\SendPhotoMethod;
43
use TgBotApi\BotApiBase\Method\SendStickerMethod;
44
use TgBotApi\BotApiBase\Method\SendVenueMethod;
45
use TgBotApi\BotApiBase\Method\SendVideoMethod;
46
use TgBotApi\BotApiBase\Method\SendVideoNoteMethod;
47
use TgBotApi\BotApiBase\Method\SendVoiceMethod;
48
use TgBotApi\BotApiBase\Normalizer\AnswerInlineQueryNormalizer;
49
use TgBotApi\BotApiBase\Normalizer\InputFileNormalizer;
50
use TgBotApi\BotApiBase\Normalizer\InputMediaNormalizer;
51
use TgBotApi\BotApiBase\Normalizer\JsonSerializableNormalizer;
52
use TgBotApi\BotApiBase\Normalizer\MediaGroupNormalizer;
53
use TgBotApi\BotApiBase\Normalizer\UserProfilePhotosNormalizer;
54
use TgBotApi\BotApiBase\Type\ChatMemberType;
55
use TgBotApi\BotApiBase\Type\ChatType;
56
use TgBotApi\BotApiBase\Type\FileType;
57
use TgBotApi\BotApiBase\Type\MessageType;
58
use TgBotApi\BotApiBase\Type\UpdateType;
59
use TgBotApi\BotApiBase\Type\UserProfilePhotosType;
60
use TgBotApi\BotApiBase\Type\UserType;
61
use TgBotApi\BotApiBase\Type\WebhookInfoType;
62
63
/**
64
 * Class BotApi.
65
 */
66
class BotApi implements BotApiInterface
67
{
68
    /**
69
     * @var string
70
     */
71
    private $botKey;
72
73
    /**
74
     * @var ApiClientInterface
75
     */
76
    private $apiClient;
77
78
    /**
79
     * @var string
80
     */
81
    private $endPoint;
82
83
    /**
84
     * BotApi constructor.
85
     *
86
     * @param string             $botKey
87
     * @param ApiClientInterface $apiClient
88
     * @param string             $endPoint
89
     */
90 39
    public function __construct(
91
        string $botKey,
92
        ApiClientInterface $apiClient,
93
        string $endPoint = 'https://api.telegram.org'
94
    ) {
95 39
        $this->botKey = $botKey;
96 39
        $this->apiClient = $apiClient;
97 39
        $this->endPoint = $endPoint;
98
99 39
        $this->apiClient->setBotKey($botKey);
100 39
        $this->apiClient->setEndpoint($endPoint);
101 39
    }
102
103
    /**
104
     * @param $method
105
     * @param $type
106
     *
107
     * @throws ResponseException
108
     *
109
     * @return mixed
110
     */
111 39
    public function call($method, $type = null)
112
    {
113 39
        list($data, $files) = $this->encode($method);
114
115 39
        $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

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