Completed
Pull Request — master (#313)
by
unknown
03:21
created

Request::getWebhookInfo()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 4
rs 10
c 0
b 0
f 0
cc 1
eloc 2
nc 1
nop 0
1
<?php
2
/**
3
 * This file is part of the TelegramBot package.
4
 *
5
 * (c) Avtandil Kikabidze aka LONGMAN <[email protected]>
6
 *
7
 * For the full copyright and license information, please view the LICENSE
8
 * file that was distributed with this source code.
9
 */
10
11
namespace Longman\TelegramBot;
12
13
use GuzzleHttp\Client;
14
use GuzzleHttp\Exception\RequestException;
15
use Longman\TelegramBot\Entities\File;
16
use Longman\TelegramBot\Entities\ServerResponse;
17
use Longman\TelegramBot\Exception\TelegramException;
18
19
class Request
20
{
21
    /**
22
     * Telegram object
23
     *
24
     * @var Telegram
25
     */
26
    private static $telegram;
27
28
    /**
29
     * URI of the Telegram API
30
     *
31
     * @var string
32
     */
33
    private static $api_base_uri = 'https://api.telegram.org';
34
35
    /**
36
     * Guzzle Client object
37
     *
38
     * @var \GuzzleHttp\Client
39
     */
40
    private static $client;
41
42
    /**
43
     * Input value of the request
44
     *
45
     * @var string
46
     */
47
    private static $input;
48
49
    /**
50
     * Available actions to send
51
     *
52
     * @var array
53
     */
54
    private static $actions = [
55
        'getUpdates',
56
        'setWebhook',
57
        'getMe',
58
        'sendMessage',
59
        'forwardMessage',
60
        'sendPhoto',
61
        'sendAudio',
62
        'sendDocument',
63
        'sendSticker',
64
        'sendVideo',
65
        'sendVoice',
66
        'sendLocation',
67
        'sendVenue',
68
        'sendContact',
69
        'sendChatAction',
70
        'getUserProfilePhotos',
71
        'getFile',
72
        'kickChatMember',
73
        'leaveChat',
74
        'unbanChatMember',
75
        'getChat',
76
        'getChatAdministrators',
77
        'getChatMember',
78
        'getChatMembersCount',
79
        'answerCallbackQuery',
80
        'answerInlineQuery',
81
        'editMessageText',
82
        'editMessageCaption',
83
        'editMessageReplyMarkup',
84
        'getWebhookInfo',
85
    ];
86
87
    /**
88
     * Initialize
89
     *
90
     * @param Telegram $telegram
91
     */
92
    public static function initialize(Telegram $telegram)
93
    {
94
        if (is_object($telegram)) {
95
            self::$telegram = $telegram;
96
            self::$client = new Client(['base_uri' => self::$api_base_uri]);
97
        } else {
98
            throw new TelegramException('Telegram pointer is empty!');
99
        }
100
    }
101
102
    /**
103
     * Set input from custom input or stdin and return it
104
     *
105
     * @return string
106
     */
107
    public static function getInput()
108
    {
109
        // First check if a custom input has been set, else get the PHP input.
110
        if (!($input = self::$telegram->getCustomInput())) {
111
            $input = file_get_contents('php://input');
112
        }
113
114
        // Make sure we have a string to work with.
115
        if (is_string($input)) {
116
            self::$input = $input;
117
        } else {
118
            throw new TelegramException('Input must be a string!');
119
        }
120
121
        TelegramLog::update(self::$input);
122
        return self::$input;
123
    }
124
125
    /**
126
     * Generate general fake server response
127
     *
128
     * @param array $data Data to add to fake response
129
     *
130
     * @return array Fake response data
131
     */
132
    public static function generateGeneralFakeServerResponse(array $data = null)
133
    {
134
        //PARAM BINDED IN PHPUNIT TEST FOR TestServerResponse.php
135
        //Maybe this is not the best possible implementation
136
137
        //No value set in $data ie testing setWebhook
138
        //Provided $data['chat_id'] ie testing sendMessage
139
140
        $fake_response = ['ok' => true]; // :)
141
142
        if (!isset($data)) {
143
            $fake_response['result'] = true;
144
        }
145
146
        //some data to let iniatilize the class method SendMessage
147
        if (isset($data['chat_id'])) {
148
            $data['message_id'] = '1234';
149
            $data['date'] = '1441378360';
150
            $data['from'] = [
151
                'id'         => 123456789,
152
                'first_name' => 'botname',
153
                'username'   => 'namebot',
154
            ];
155
            $data['chat'] = ['id' => $data['chat_id']];
156
157
            $fake_response['result'] = $data;
158
        }
159
160
        return $fake_response;
161
    }
162
163
    /**
164
     * Execute HTTP Request
165
     *
166
     * @param string     $action Action to execute
167
     * @param array|null $data   Data to attach to the execution
168
     *
169
     * @return mixed Result of the HTTP Request
170
     */
171
    public static function execute($action, array $data = null)
172
    {
173
        $debug_handle = TelegramLog::getDebugLogTempStream();
174
175
        //Fix so that the keyboard markup is a string, not an object
176
        if (isset($data['reply_markup']) && !is_string($data['reply_markup'])) {
177
            $data['reply_markup'] = (string)$data['reply_markup'];
178
        }
179
180
        $request_params = ['debug' => $debug_handle];
181
182
        //Check for resources in data
183
        $contains_resource = false;
184
        foreach ($data as $item) {
185
            if (is_resource($item)) {
186
                $contains_resource = true;
187
                break;
188
            }
189
        }
190
191
        //Reformat data array in multipart way
192
        if ($contains_resource) {
193
            foreach ($data as $key => $item) {
194
                $request_params['multipart'][] = array('name' => $key, 'contents' => $item);
195
            }
196
        } else {
197
            $request_params['form_params'] = $data;
198
        }
199
200
        try {
201
            $response = self::$client->post(
202
                '/bot' . self::$telegram->getApiKey() . '/' . $action,
203
                $request_params
204
            );
205
        } catch (RequestException $e) {
206
            throw new TelegramException($e->getMessage());
207
        } finally {
208
            //Logging verbose debug output
209
            TelegramLog::endDebugLogTempStream("Verbose HTTP Request output:\n%s\n");
210
        }
211
212
        $result = $response->getBody();
213
214
        //Logging getUpdates Update
215
        if ($action === 'getUpdates') {
216
            TelegramLog::update($result);
217
        }
218
219
        return $result;
220
    }
221
222
    /**
223
     * Download file
224
     *
225
     * @param Entities\File $file
226
     *
227
     * @return boolean
228
     */
229
    public static function downloadFile(File $file)
230
    {
231
        $path = $file->getFilePath();
232
233
        //Create the directory
234
        $loc_path = self::$telegram->getDownloadPath() . '/' . $path;
235
236
        $dirname = dirname($loc_path);
237
        if (!is_dir($dirname) && !mkdir($dirname, 0755, true)) {
238
            throw new TelegramException('Directory ' . $dirname . ' can\'t be created');
239
        }
240
241
        $debug_handle = TelegramLog::getDebugLogTempStream();
242
243
        try {
244
            $response = self::$client->get(
0 ignored issues
show
Unused Code introduced by
$response is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
245
                '/file/bot' . self::$telegram->getApiKey() . '/' . $path,
246
                ['debug' => $debug_handle, 'sink' => $loc_path]
247
            );
248
        } catch (RequestException $e) {
249
            throw new TelegramException($e->getMessage());
250
        } finally {
251
            //Logging verbose debug output
252
            TelegramLog::endDebugLogTempStream("Verbose HTTP File Download Request output:\n%s\n");
253
        }
254
255
        return (filesize($loc_path) > 0);
256
    }
257
258
    /**
259
     * Encode file
260
     *
261
     * @param string $file
262
     *
263
     * @return resource
264
     */
265
    protected static function encodeFile($file)
266
    {
267
        $fp = fopen($file, 'r');
268
        if ($fp === false) {
269
            throw new TelegramException('Cannot open ' . $file . ' for reading');
270
        }
271
        return $fp;
272
    }
273
274
    /**
275
     * Send command
276
     *
277
     * @todo Fake response doesn't need json encoding?
278
     *
279
     * @param string     $action
280
     * @param array|null $data
281
     *
282
     * @return Entities\ServerResponse
283
     */
284
    public static function send($action, array $data = null)
285
    {
286
        if (!in_array($action, self::$actions)) {
287
            throw new TelegramException('The action ' . $action . ' doesn\'t exist!');
288
        }
289
290
        $bot_name = self::$telegram->getBotName();
291
292
        if (defined('PHPUNIT_TESTSUITE')) {
293
            $fake_response = self::generateGeneralFakeServerResponse($data);
294
            return new ServerResponse($fake_response, $bot_name);
295
        }
296
297
        $response = json_decode(self::execute($action, $data), true);
298
299
        if (is_null($response)) {
300
            throw new TelegramException('Telegram returned an invalid response! Please your bot name and api token.');
301
        }
302
303
        return new ServerResponse($response, $bot_name);
304
    }
305
306
    /**
307
     * Get me
308
     *
309
     * @return mixed
310
     */
311
    public static function getMe()
312
    {
313
        // Added fake parameter, because of some cURL version failed POST request without parameters
314
        // see https://github.com/akalongman/php-telegram-bot/pull/228
315
        return self::send('getMe', ['whoami']);
316
    }
317
318
    /**
319
     * Send message
320
     *
321
     * @todo Could do with some cleaner recursion
322
     *
323
     * @param array $data
324
     *
325
     * @return mixed
326
     */
327
    public static function sendMessage(array $data)
328
    {
329
        if (empty($data)) {
330
            throw new TelegramException('Data is empty!');
331
        }
332
        $text = $data['text'];
333
        $string_len_utf8 = mb_strlen($text, 'UTF-8');
334
        if ($string_len_utf8 > 4096) {
335
            $data['text'] = mb_substr($text, 0, 4096);
336
            self::send('sendMessage', $data);
337
            $data['text'] = mb_substr($text, 4096, $string_len_utf8);
338
            return self::sendMessage($data);
339
        }
340
        return self::send('sendMessage', $data);
341
    }
342
343
    /**
344
     * Forward message
345
     *
346
     * @param array $data
347
     *
348
     * @return mixed
349
     */
350
    public static function forwardMessage(array $data)
351
    {
352
        if (empty($data)) {
353
            throw new TelegramException('Data is empty!');
354
        }
355
356
        return self::send('forwardMessage', $data);
357
    }
358
359
    /**
360
     * Send photo
361
     *
362
     * @param array $data
363
     * @param string $file
364
     *
365
     * @return mixed
366
     */
367 View Code Duplication
    public static function sendPhoto(array $data, $file = null)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
368
    {
369
        if (empty($data)) {
370
            throw new TelegramException('Data is empty!');
371
        }
372
373
        if (!is_null($file)) {
374
            $data['photo'] = self::encodeFile($file);
375
        }
376
377
        return self::send('sendPhoto', $data);
378
    }
379
380
    /**
381
     * Send audio
382
     *
383
     * @param array  $data
384
     * @param string $file
385
     *
386
     * @return mixed
387
     */
388 View Code Duplication
    public static function sendAudio(array $data, $file = null)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
389
    {
390
        if (empty($data)) {
391
            throw new TelegramException('Data is empty!');
392
        }
393
394
        if (!is_null($file)) {
395
            $data['audio'] = self::encodeFile($file);
396
        }
397
398
        return self::send('sendAudio', $data);
399
    }
400
401
    /**
402
     * Send document
403
     *
404
     * @param array  $data
405
     * @param string $file
406
     *
407
     * @return mixed
408
     */
409 View Code Duplication
    public static function sendDocument(array $data, $file = null)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
410
    {
411
        if (empty($data)) {
412
            throw new TelegramException('Data is empty!');
413
        }
414
415
        if (!is_null($file)) {
416
            $data['document'] = self::encodeFile($file);
417
        }
418
419
        return self::send('sendDocument', $data);
420
    }
421
422
    /**
423
     * Send sticker
424
     *
425
     * @param array  $data
426
     * @param string $file
427
     *
428
     * @return mixed
429
     */
430 View Code Duplication
    public static function sendSticker(array $data, $file = null)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
431
    {
432
        if (empty($data)) {
433
            throw new TelegramException('Data is empty!');
434
        }
435
436
        if (!is_null($file)) {
437
            $data['sticker'] = self::encodeFile($file);
438
        }
439
440
        return self::send('sendSticker', $data);
441
    }
442
443
    /**
444
     * Send video
445
     *
446
     * @param array  $data
447
     * @param string $file
448
     *
449
     * @return mixed
450
     */
451 View Code Duplication
    public static function sendVideo(array $data, $file = null)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
452
    {
453
        if (empty($data)) {
454
            throw new TelegramException('Data is empty!');
455
        }
456
457
        if (!is_null($file)) {
458
            $data['video'] = self::encodeFile($file);
459
        }
460
461
        return self::send('sendVideo', $data);
462
    }
463
464
    /**
465
     * Send voice
466
     *
467
     * @param array  $data
468
     * @param string $file
469
     *
470
     * @return mixed
471
     */
472 View Code Duplication
    public static function sendVoice(array $data, $file = null)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
473
    {
474
        if (empty($data)) {
475
            throw new TelegramException('Data is empty!');
476
        }
477
478
        if (!is_null($file)) {
479
            $data['voice'] = self::encodeFile($file);
480
        }
481
482
        return self::send('sendVoice', $data);
483
    }
484
485
    /**
486
     * Send location
487
     *
488
     * @param array $data
489
     *
490
     * @return mixed
491
     */
492
    public static function sendLocation(array $data)
493
    {
494
        if (empty($data)) {
495
            throw new TelegramException('Data is empty!');
496
        }
497
498
        return self::send('sendLocation', $data);
499
    }
500
501
    /**
502
     * Send venue
503
     *
504
     * @param array $data
505
     *
506
     * @return mixed
507
     */
508
    public static function sendVenue(array $data)
509
    {
510
        if (empty($data)) {
511
            throw new TelegramException('Data is empty!');
512
        }
513
514
        return self::send('sendVenue', $data);
515
    }
516
517
    /**
518
     * Send contact
519
     *
520
     * @param array $data
521
     *
522
     * @return mixed
523
     */
524
    public static function sendContact(array $data)
525
    {
526
        if (empty($data)) {
527
            throw new TelegramException('Data is empty!');
528
        }
529
530
        return self::send('sendContact', $data);
531
    }
532
533
    /**
534
     * Send chat action
535
     *
536
     * @param array $data
537
     *
538
     * @return mixed
539
     */
540
    public static function sendChatAction(array $data)
541
    {
542
        if (empty($data)) {
543
            throw new TelegramException('Data is empty!');
544
        }
545
546
        return self::send('sendChatAction', $data);
547
    }
548
549
    /**
550
     * Get user profile photos
551
     *
552
     * @param array $data
553
     *
554
     * @return mixed
555
     */
556
    public static function getUserProfilePhotos(array $data)
557
    {
558
        if (empty($data)) {
559
            throw new TelegramException('Data is empty!');
560
        }
561
562
        if (!isset($data['user_id'])) {
563
            throw new TelegramException('User id is empty!');
564
        }
565
566
        return self::send('getUserProfilePhotos', $data);
567
    }
568
569
    /**
570
     * Get updates
571
     *
572
     * @param array $data
573
     *
574
     * @return mixed
575
     */
576
    public static function getUpdates(array $data)
577
    {
578
        return self::send('getUpdates', $data);
579
    }
580
581
    /**
582
     * Set webhook
583
     *
584
     * @param string $url
585
     * @param string $file
586
     *
587
     * @return mixed
588
     */
589
    public static function setWebhook($url = '', $file = null)
590
    {
591
        $data = ['url' => $url];
592
593
        if (!is_null($file)) {
594
            $data['certificate'] = self::encodeFile($file);
595
        }
596
597
        return self::send('setWebhook', $data);
598
    }
599
600
    /**
601
     * Get file
602
     *
603
     * @param array $data
604
     *
605
     * @return mixed
606
     */
607
    public static function getFile(array $data)
608
    {
609
        if (empty($data)) {
610
            throw new TelegramException('Data is empty!');
611
        }
612
613
        return self::send('getFile', $data);
614
    }
615
616
    /**
617
     * Kick Chat Member
618
     *
619
     * @param array $data
620
     *
621
     * @return mixed
622
     */
623
    public static function kickChatMember(array $data)
624
    {
625
        if (empty($data)) {
626
            throw new TelegramException('Data is empty!');
627
        }
628
629
        return self::send('kickChatMember', $data);
630
    }
631
632
    /**
633
     * Leave Chat
634
     *
635
     * @param array $data
636
     *
637
     * @return mixed
638
     */
639
    public static function leaveChat(array $data)
640
    {
641
        if (empty($data)) {
642
            throw new TelegramException('Data is empty!');
643
        }
644
645
        return self::send('leaveChat', $data);
646
    }
647
648
    /**
649
     * Unban Chat Member
650
     *
651
     * @param array $data
652
     *
653
     * @return mixed
654
     */
655
    public static function unbanChatMember(array $data)
656
    {
657
        if (empty($data)) {
658
            throw new TelegramException('Data is empty!');
659
        }
660
661
        return self::send('unbanChatMember', $data);
662
    }
663
664
    /**
665
     * Get Chat
666
     *
667
     * @todo add get response in ServerResponse.php?
668
     *
669
     * @param array $data
670
     *
671
     * @return mixed
672
     */
673
    public static function getChat(array $data)
674
    {
675
        if (empty($data)) {
676
            throw new TelegramException('Data is empty!');
677
        }
678
679
        return self::send('getChat', $data);
680
    }
681
682
    /**
683
     * Get Chat Administrators
684
     *
685
     * @todo add get response in ServerResponse.php?
686
     *
687
     * @param array $data
688
     *
689
     * @return mixed
690
     */
691
    public static function getChatAdministrators(array $data)
692
    {
693
        if (empty($data)) {
694
            throw new TelegramException('Data is empty!');
695
        }
696
697
        return self::send('getChatAdministrators', $data);
698
    }
699
700
    /**
701
     * Get Chat Members Count
702
     *
703
     * @todo add get response in ServerResponse.php?
704
     *
705
     * @param array $data
706
     *
707
     * @return mixed
708
     */
709
    public static function getChatMembersCount(array $data)
710
    {
711
        if (empty($data)) {
712
            throw new TelegramException('Data is empty!');
713
        }
714
715
        return self::send('getChatMembersCount', $data);
716
    }
717
718
    /**
719
     * Get Chat Member
720
     *
721
     * @todo add get response in ServerResponse.php?
722
     *
723
     * @param array $data
724
     *
725
     * @return mixed
726
     */
727
    public static function getChatMember(array $data)
728
    {
729
        if (empty($data)) {
730
            throw new TelegramException('Data is empty!');
731
        }
732
733
        return self::send('getChatMember', $data);
734
    }
735
736
    /**
737
     * Answer callback query
738
     *
739
     * @param array $data
740
     *
741
     * @return mixed
742
     */
743
    public static function answerCallbackQuery(array $data)
744
    {
745
        if (empty($data)) {
746
            throw new TelegramException('Data is empty!');
747
        }
748
749
        return self::send('answerCallbackQuery', $data);
750
    }
751
752
    /**
753
     * Answer inline query
754
     *
755
     * @param array $data
756
     *
757
     * @return mixed
758
     */
759
    public static function answerInlineQuery(array $data)
760
    {
761
        if (empty($data)) {
762
            throw new TelegramException('Data is empty!');
763
        }
764
765
        return self::send('answerInlineQuery', $data);
766
    }
767
768
    /**
769
     * Edit message text
770
     *
771
     * @param array $data
772
     *
773
     * @return mixed
774
     */
775
    public static function editMessageText(array $data)
776
    {
777
        if (empty($data)) {
778
            throw new TelegramException('Data is empty!');
779
        }
780
781
        return self::send('editMessageText', $data);
782
    }
783
784
    /**
785
     * Edit message caption
786
     *
787
     * @param array $data
788
     *
789
     * @return mixed
790
     */
791
    public static function editMessageCaption(array $data)
792
    {
793
        if (empty($data)) {
794
            throw new TelegramException('Data is empty!');
795
        }
796
797
        return self::send('editMessageCaption', $data);
798
    }
799
800
    /**
801
     * Edit message reply markup
802
     *
803
     * @param array $data
804
     *
805
     * @return mixed
806
     */
807
    public static function editMessageReplyMarkup(array $data)
808
    {
809
        if (empty($data)) {
810
            throw new TelegramException('Data is empty!');
811
        }
812
813
        return self::send('editMessageReplyMarkup', $data);
814
    }
815
816
    /**
817
     * Return an empty Server Response
818
     *
819
     * No request to telegram are sent, this function is used in commands that
820
     * don't need to fire a message after execution
821
     *
822
     * @return Entities\ServerResponse
823
     */
824
    public static function emptyResponse()
825
    {
826
        return new ServerResponse(['ok' => true, 'result' => true], null);
827
    }
828
829
    /**
830
     * Send message to all active chats
831
     *
832
     * @param string  $callback_function
833
     * @param array   $data
834
     * @param boolean $send_groups
835
     * @param boolean $send_super_groups
836
     * @param boolean $send_users
837
     * @param string  $date_from
838
     * @param string  $date_to
839
     *
840
     * @return array
841
     */
842
    public static function sendToActiveChats(
843
        $callback_function,
844
        array $data,
845
        $send_groups = true,
846
        $send_super_groups = true,
847
        $send_users = true,
848
        $date_from = null,
849
        $date_to = null
850
    ) {
851
        $callback_path = __NAMESPACE__ . '\Request';
852
        if (!method_exists($callback_path, $callback_function)) {
853
            throw new TelegramException('Method "' . $callback_function . '" not found in class Request.');
854
        }
855
856
        $chats = DB::selectChats($send_groups, $send_super_groups, $send_users, $date_from, $date_to);
857
858
        $results = [];
859
        foreach ($chats as $row) {
0 ignored issues
show
Bug introduced by
The expression $chats of type false|array is not guaranteed to be traversable. How about adding an additional type check?

There are different options of fixing this problem.

  1. If you want to be on the safe side, you can add an additional type-check:

    $collection = json_decode($data, true);
    if ( ! is_array($collection)) {
        throw new \RuntimeException('$collection must be an array.');
    }
    
    foreach ($collection as $item) { /** ... */ }
    
  2. If you are sure that the expression is traversable, you might want to add a doc comment cast to improve IDE auto-completion and static analysis:

    /** @var array $collection */
    $collection = json_decode($data, true);
    
    foreach ($collection as $item) { /** .. */ }
    
  3. Mark the issue as a false-positive: Just hover the remove button, in the top-right corner of this issue for more options.

Loading history...
860
            $data['chat_id'] = $row['chat_id'];
861
            $results[] = call_user_func_array($callback_path . '::' . $callback_function, [$data]);
862
        }
863
864
        return $results;
865
    }
866
867
    /**
868
     * Use this method to get current webhook status.
869
     *
870
     * @return Entities\ServerResponse
871
     */
872
    public static function getWebhookInfo()
873
    {
874
        return self::send('getWebhookInfo');
875
    }
876
}
877