Passed
Pull Request — develop (#1077)
by Marco
02:09
created

Telegram::addCommandsPaths()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 7
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 4
CRAP Score 2

Importance

Changes 0
Metric Value
eloc 3
dl 0
loc 7
ccs 4
cts 4
cp 1
rs 10
c 0
b 0
f 0
cc 2
nc 2
nop 2
crap 2
1
<?php
2
3
/**
4
 * This file is part of the TelegramBot package.
5
 *
6
 * (c) Avtandil Kikabidze aka LONGMAN <[email protected]>
7
 *
8
 * For the full copyright and license information, please view the LICENSE
9
 * file that was distributed with this source code.
10
 */
11
12
namespace PhpTelegramBot\Core;
13
14 1
defined('TB_BASE_PATH') || define('TB_BASE_PATH', __DIR__);
15 1
defined('TB_BASE_COMMANDS_PATH') || define('TB_BASE_COMMANDS_PATH', TB_BASE_PATH . '/Commands');
16
17
use Exception;
18
use PhpTelegramBot\Core\Commands\Command;
19
use PhpTelegramBot\Core\Entities\ServerResponse;
20
use PhpTelegramBot\Core\Entities\Update;
21
use PhpTelegramBot\Core\Exception\TelegramException;
22
use PDO;
23
use RecursiveDirectoryIterator;
24
use RecursiveIteratorIterator;
25
use RegexIterator;
26
27
class Telegram
28
{
29
    /**
30
     * Version
31
     *
32
     * @var string
33
     */
34
    protected $version = '0.62.0';
35
36
    /**
37
     * Telegram API key
38
     *
39
     * @var string
40
     */
41
    protected $api_key = '';
42
43
    /**
44
     * Telegram Bot username
45
     *
46
     * @var string
47
     */
48
    protected $bot_username = '';
49
50
    /**
51
     * Telegram Bot id
52
     *
53
     * @var string
54
     */
55
    protected $bot_id = '';
56
57
    /**
58
     * Raw request data (json) for webhook methods
59
     *
60
     * @var string
61
     */
62
    protected $input;
63
64
    /**
65
     * Custom commands paths
66
     *
67
     * @var array
68
     */
69
    protected $commands_paths = [];
70
71
    /**
72
     * Current Update object
73
     *
74
     * @var Update
75
     */
76
    protected $update;
77
78
    /**
79
     * Upload path
80
     *
81
     * @var string
82
     */
83
    protected $upload_path;
84
85
    /**
86
     * Download path
87
     *
88
     * @var string
89
     */
90
    protected $download_path;
91
92
    /**
93
     * MySQL integration
94
     *
95
     * @var bool
96
     */
97
    protected $mysql_enabled = false;
98
99
    /**
100
     * PDO object
101
     *
102
     * @var PDO
103
     */
104
    protected $pdo;
105
106
    /**
107
     * Commands config
108
     *
109
     * @var array
110
     */
111
    protected $commands_config = [];
112
113
    /**
114
     * Admins list
115
     *
116
     * @var array
117
     */
118
    protected $admins_list = [];
119
120
    /**
121
     * ServerResponse of the last Command execution
122
     *
123
     * @var ServerResponse
124
     */
125
    protected $last_command_response;
126
127
    /**
128
     * Check if runCommands() is running in this session
129
     *
130
     * @var bool
131
     */
132
    protected $run_commands = false;
133
134
    /**
135
     * Is running getUpdates without DB enabled
136
     *
137
     * @var bool
138
     */
139
    protected $getupdates_without_database = false;
140
141
    /**
142
     * Last update ID
143
     * Only used when running getUpdates without a database
144
     *
145
     * @var integer
146
     */
147
    protected $last_update_id = null;
148
149
    /**
150
     * The command to be executed when there's a new message update and nothing more suitable is found
151
     */
152
    const GENERIC_MESSAGE_COMMAND = 'genericmessage';
153
154
    /**
155
     * The command to be executed by default (when no other relevant commands are applicable)
156
     */
157
    const GENERIC_COMMAND = 'generic';
158
159
    /**
160
     * Telegram constructor.
161
     *
162
     * @param string $api_key
163
     * @param string $bot_username
164
     *
165
     * @throws TelegramException
166
     */
167 29
    public function __construct($api_key, $bot_username = '')
168
    {
169 29
        if (empty($api_key)) {
170 1
            throw new TelegramException('API KEY not defined!');
171
        }
172 29
        preg_match('/(\d+)\:[\w\-]+/', $api_key, $matches);
173 29
        if (!isset($matches[1])) {
174 1
            throw new TelegramException('Invalid API KEY defined!');
175
        }
176 29
        $this->bot_id  = $matches[1];
177 29
        $this->api_key = $api_key;
178
179 29
        if (!empty($bot_username)) {
180 29
            $this->bot_username = $bot_username;
181
        }
182
183
        //Add default system commands path
184 29
        $this->addCommandsPath(TB_BASE_COMMANDS_PATH . '/SystemCommands');
185
186 29
        Request::initialize($this);
187 29
    }
188
189
    /**
190
     * Initialize Database connection
191
     *
192
     * @param array  $credential
193
     * @param string $table_prefix
194
     * @param string $encoding
195
     *
196
     * @return Telegram
197
     * @throws TelegramException
198
     */
199 9
    public function enableMySql(array $credential, $table_prefix = null, $encoding = 'utf8mb4')
200
    {
201 9
        $this->pdo = DB::initialize($credential, $this, $table_prefix, $encoding);
202 9
        ConversationDB::initializeConversation();
203 9
        $this->mysql_enabled = true;
204
205 9
        return $this;
206
    }
207
208
    /**
209
     * Initialize Database external connection
210
     *
211
     * @param PDO    $external_pdo_connection PDO database object
212
     * @param string $table_prefix
213
     *
214
     * @return Telegram
215
     * @throws TelegramException
216
     */
217
    public function enableExternalMySql($external_pdo_connection, $table_prefix = null)
218
    {
219
        $this->pdo = DB::externalInitialize($external_pdo_connection, $this, $table_prefix);
220
        ConversationDB::initializeConversation();
221
        $this->mysql_enabled = true;
222
223
        return $this;
224
    }
225
226
    /**
227
     * Get commands list
228
     *
229
     * @return array $commands
230
     * @throws TelegramException
231
     */
232 1
    public function getCommandsList()
233
    {
234 1
        $commands = [];
235
236 1
        foreach ($this->commands_paths as $path) {
237
            try {
238
                //Get all "*Command.php" files
239 1
                $files = new RegexIterator(
240 1
                    new RecursiveIteratorIterator(
241 1
                        new RecursiveDirectoryIterator($path)
242
                    ),
243 1
                    '/^.+Command.php$/'
244
                );
245
246 1
                foreach ($files as $file) {
247
                    //Remove "Command.php" from filename
248 1
                    $command      = $this->sanitizeCommand(substr($file->getFilename(), 0, -11));
249 1
                    $command_name = mb_strtolower($command);
250
251 1
                    if (array_key_exists($command_name, $commands)) {
252
                        continue;
253
                    }
254
255 1
                    require_once $file->getPathname();
256
257 1
                    $command_obj = $this->getCommandObject($command);
258 1
                    if ($command_obj instanceof Command) {
259 1
                        $commands[$command_name] = $command_obj;
260
                    }
261
                }
262
            } catch (Exception $e) {
263
                throw new TelegramException('Error getting commands from path: ' . $path, $e);
0 ignored issues
show
Bug introduced by
$e of type Exception is incompatible with the type integer expected by parameter $code of PhpTelegramBot\Core\Exce...xception::__construct(). ( Ignorable by Annotation )

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

263
                throw new TelegramException('Error getting commands from path: ' . $path, /** @scrutinizer ignore-type */ $e);
Loading history...
264
            }
265
        }
266
267 1
        return $commands;
268
    }
269
270
    /**
271
     * Get an object instance of the passed command
272
     *
273
     * @param string $command
274
     *
275
     * @return Command|null
276
     */
277 1
    public function getCommandObject($command)
278
    {
279 1
        $which = ['System'];
280 1
        $this->isAdmin() && $which[] = 'Admin';
281 1
        $which[] = 'User';
282
283 1
        foreach ($which as $auth) {
284 1
            $command_namespace = __NAMESPACE__ . '\\Commands\\' . $auth . 'Commands\\' . $this->ucfirstUnicode($command) . 'Command';
285 1
            if (class_exists($command_namespace)) {
286 1
                return new $command_namespace($this, $this->update);
287
            }
288
        }
289
290
        return null;
291
    }
292
293
    /**
294
     * Set custom input string for debug purposes
295
     *
296
     * @param string $input (json format)
297
     *
298
     * @return Telegram
299
     */
300
    public function setCustomInput($input)
301
    {
302
        $this->input = $input;
303
304
        return $this;
305
    }
306
307
    /**
308
     * Get custom input string for debug purposes
309
     *
310
     * @return string
311
     */
312
    public function getCustomInput()
313
    {
314
        return $this->input;
315
    }
316
317
    /**
318
     * Get the ServerResponse of the last Command execution
319
     *
320
     * @return ServerResponse
321
     */
322
    public function getLastCommandResponse()
323
    {
324
        return $this->last_command_response;
325
    }
326
327
    /**
328
     * Handle getUpdates method
329
     *
330
     * @param int|null $limit
331
     * @param int|null $timeout
332
     *
333
     * @return ServerResponse
334
     * @throws TelegramException
335
     */
336
    public function handleGetUpdates($limit = null, $timeout = null)
337
    {
338
        if (empty($this->bot_username)) {
339
            throw new TelegramException('Bot Username is not defined!');
340
        }
341
342
        if (!DB::isDbConnected() && !$this->getupdates_without_database) {
343
            return new ServerResponse(
344
                [
345
                    'ok'          => false,
346
                    'description' => 'getUpdates needs MySQL connection! (This can be overridden - see documentation)',
347
                ],
348
                $this->bot_username
349
            );
350
        }
351
352
        $offset = 0;
353
354
        //Take custom input into account.
355
        if ($custom_input = $this->getCustomInput()) {
356
            $response = new ServerResponse(json_decode($custom_input, true), $this->bot_username);
357
        } else {
358
            if (DB::isDbConnected() && $last_update = DB::selectTelegramUpdate(1)) {
359
                //Get last update id from the database
360
                $last_update = reset($last_update);
361
362
                $this->last_update_id = isset($last_update['id']) ? $last_update['id'] : null;
363
            }
364
365
            if ($this->last_update_id !== null) {
366
                $offset = $this->last_update_id + 1;    //As explained in the telegram bot API documentation
367
            }
368
369
            $response = Request::getUpdates(
370
                [
371
                    'offset'  => $offset,
372
                    'limit'   => $limit,
373
                    'timeout' => $timeout,
374
                ]
375
            );
376
        }
377
378
        if ($response->isOk()) {
379
            $results = $response->getResult();
380
381
            //Process all updates
382
            /** @var Update $result */
383
            foreach ($results as $result) {
384
                $this->processUpdate($result);
385
            }
386
387
            if (!DB::isDbConnected() && !$custom_input && $this->last_update_id !== null && $offset === 0) {
388
                //Mark update(s) as read after handling
389
                Request::getUpdates(
390
                    [
391
                        'offset'  => $this->last_update_id + 1,
392
                        'limit'   => 1,
393
                        'timeout' => $timeout,
394
                    ]
395
                );
396
            }
397
        }
398
399
        return $response;
400
    }
401
402
    /**
403
     * Handle bot request from webhook
404
     *
405
     * @return bool
406
     *
407
     * @throws TelegramException
408
     */
409
    public function handle()
410
    {
411
        if (empty($this->bot_username)) {
412
            throw new TelegramException('Bot Username is not defined!');
413
        }
414
415
        $this->input = Request::getInput();
416
417
        if (empty($this->input)) {
418
            throw new TelegramException('Input is empty!');
419
        }
420
421
        $post = json_decode($this->input, true);
422
        if (empty($post)) {
423
            throw new TelegramException('Invalid JSON!');
424
        }
425
426
        if ($response = $this->processUpdate(new Update($post, $this->bot_username))) {
427
            return $response->isOk();
428
        }
429
430
        return false;
431
    }
432
433
    /**
434
     * Get the command name from the command type
435
     *
436
     * @param string $type
437
     *
438
     * @return string
439
     */
440
    protected function getCommandFromType($type)
441
    {
442
        return $this->ucfirstUnicode(str_replace('_', '', $type));
443
    }
444
445
    /**
446
     * Process bot Update request
447
     *
448
     * @param Update $update
449
     *
450
     * @return ServerResponse
451
     * @throws TelegramException
452
     */
453
    public function processUpdate(Update $update)
454
    {
455
        $this->update         = $update;
456
        $this->last_update_id = $update->getUpdateId();
457
458
        //Load admin commands
459
        if ($this->isAdmin()) {
460
            $this->addCommandsPath(TB_BASE_COMMANDS_PATH . '/AdminCommands', false);
461
        }
462
463
        //Make sure we have an up-to-date command list
464
        //This is necessary to "require" all the necessary command files!
465
        $this->getCommandsList();
466
467
        //If all else fails, it's a generic message.
468
        $command = self::GENERIC_MESSAGE_COMMAND;
469
470
        $update_type = $this->update->getUpdateType();
471
        if ($update_type === 'message') {
472
            $message = $this->update->getMessage();
473
            $type    = $message->getType();
474
475
            // Let's check if the message object has the type field we're looking for...
476
            $command_tmp = $type === 'command' ? $message->getCommand() : $this->getCommandFromType($type);
477
            // ...and if a fitting command class is available.
478
            $command_obj = $this->getCommandObject($command_tmp);
479
480
            // Empty usage string denotes a non-executable command.
481
            // @see https://github.com/php-telegram-bot/core/issues/772#issuecomment-388616072
482
            if (
483
                ($command_obj === null && $type === 'command')
484
                || ($command_obj !== null && $command_obj->getUsage() !== '')
485
            ) {
486
                $command = $command_tmp;
487
            }
488
        } else {
489
            $command = $this->getCommandFromType($update_type);
490
        }
491
492
        //Make sure we don't try to process update that was already processed
493
        $last_id = DB::selectTelegramUpdate(1, $this->update->getUpdateId());
494
        if ($last_id && count($last_id) === 1) {
495
            TelegramLog::debug('Duplicate update received, processing aborted!');
496
            return Request::emptyResponse();
497
        }
498
499
        DB::insertRequest($this->update);
500
501
        return $this->executeCommand($command);
502
    }
503
504
    /**
505
     * Execute /command
506
     *
507
     * @param string $command
508
     *
509
     * @return ServerResponse
510
     * @throws TelegramException
511
     */
512
    public function executeCommand($command)
513
    {
514
        $command     = mb_strtolower($command);
515
        $command_obj = $this->getCommandObject($command);
516
517
        if (!$command_obj || !$command_obj->isEnabled()) {
518
            //Failsafe in case the Generic command can't be found
519
            if ($command === self::GENERIC_COMMAND) {
520
                throw new TelegramException('Generic command missing!');
521
            }
522
523
            //Handle a generic command or non existing one
524
            $this->last_command_response = $this->executeCommand(self::GENERIC_COMMAND);
525
        } else {
526
            //execute() method is executed after preExecute()
527
            //This is to prevent executing a DB query without a valid connection
528
            $this->last_command_response = $command_obj->preExecute();
529
        }
530
531
        return $this->last_command_response;
532
    }
533
534
    /**
535
     * Sanitize Command
536
     *
537
     * @param string $command
538
     *
539
     * @return string
540
     */
541 1
    protected function sanitizeCommand($command)
542
    {
543 1
        return str_replace(' ', '', $this->ucwordsUnicode(str_replace('_', ' ', $command)));
544
    }
545
546
    /**
547
     * Enable a single Admin account
548
     *
549
     * @param integer $admin_id Single admin id
550
     *
551
     * @return Telegram
552
     */
553 1
    public function enableAdmin($admin_id)
554
    {
555 1
        if (!is_int($admin_id) || $admin_id <= 0) {
0 ignored issues
show
introduced by
The condition is_int($admin_id) is always true.
Loading history...
556 1
            TelegramLog::error('Invalid value "' . $admin_id . '" for admin.');
557 1
        } elseif (!in_array($admin_id, $this->admins_list, true)) {
558 1
            $this->admins_list[] = $admin_id;
559
        }
560
561 1
        return $this;
562
    }
563
564
    /**
565
     * Enable a list of Admin Accounts
566
     *
567
     * @param array $admin_ids List of admin ids
568
     *
569
     * @return Telegram
570
     */
571 1
    public function enableAdmins(array $admin_ids)
572
    {
573 1
        foreach ($admin_ids as $admin_id) {
574 1
            $this->enableAdmin($admin_id);
575
        }
576
577 1
        return $this;
578
    }
579
580
    /**
581
     * Get list of admins
582
     *
583
     * @return array
584
     */
585 1
    public function getAdminList()
586
    {
587 1
        return $this->admins_list;
588
    }
589
590
    /**
591
     * Check if the passed user is an admin
592
     *
593
     * If no user id is passed, the current update is checked for a valid message sender.
594
     *
595
     * @param int|null $user_id
596
     *
597
     * @return bool
598
     */
599 1
    public function isAdmin($user_id = null)
600
    {
601 1
        if ($user_id === null && $this->update !== null) {
602
            //Try to figure out if the user is an admin
603
            $update_methods = [
604
                'getMessage',
605
                'getEditedMessage',
606
                'getChannelPost',
607
                'getEditedChannelPost',
608
                'getInlineQuery',
609
                'getChosenInlineResult',
610
                'getCallbackQuery',
611
            ];
612
            foreach ($update_methods as $update_method) {
613
                $object = call_user_func([$this->update, $update_method]);
614
                if ($object !== null && $from = $object->getFrom()) {
615
                    $user_id = $from->getId();
616
                    break;
617
                }
618
            }
619
        }
620
621 1
        return ($user_id === null) ? false : in_array($user_id, $this->admins_list, true);
622
    }
623
624
    /**
625
     * Check if user required the db connection
626
     *
627
     * @return bool
628
     */
629
    public function isDbEnabled()
630
    {
631
        if ($this->mysql_enabled) {
632
            return true;
633
        } else {
634
            return false;
635
        }
636
    }
637
638
    /**
639
     * Add a single custom commands path
640
     *
641
     * @param string $path   Custom commands path to add
642
     * @param bool   $before If the path should be prepended or appended to the list
643
     *
644
     * @return Telegram
645
     */
646 29
    public function addCommandsPath($path, $before = true)
647
    {
648 29
        if (!is_dir($path)) {
649 1
            TelegramLog::error('Commands path "' . $path . '" does not exist.');
650 29
        } elseif (!in_array($path, $this->commands_paths, true)) {
651 29
            if ($before) {
652 29
                array_unshift($this->commands_paths, $path);
653
            } else {
654
                $this->commands_paths[] = $path;
655
            }
656
        }
657
658 29
        return $this;
659
    }
660
661
    /**
662
     * Add multiple custom commands paths
663
     *
664
     * @param array $paths  Custom commands paths to add
665
     * @param bool  $before If the paths should be prepended or appended to the list
666
     *
667
     * @return Telegram
668
     */
669 1
    public function addCommandsPaths(array $paths, $before = true)
670
    {
671 1
        foreach ($paths as $path) {
672 1
            $this->addCommandsPath($path, $before);
673
        }
674
675 1
        return $this;
676
    }
677
678
    /**
679
     * Return the list of commands paths
680
     *
681
     * @return array
682
     */
683 1
    public function getCommandsPaths()
684
    {
685 1
        return $this->commands_paths;
686
    }
687
688
    /**
689
     * Set custom upload path
690
     *
691
     * @param string $path Custom upload path
692
     *
693
     * @return Telegram
694
     */
695
    public function setUploadPath($path)
696
    {
697
        $this->upload_path = $path;
698
699
        return $this;
700
    }
701
702
    /**
703
     * Get custom upload path
704
     *
705
     * @return string
706
     */
707
    public function getUploadPath()
708
    {
709
        return $this->upload_path;
710
    }
711
712
    /**
713
     * Set custom download path
714
     *
715
     * @param string $path Custom download path
716
     *
717
     * @return Telegram
718
     */
719
    public function setDownloadPath($path)
720
    {
721
        $this->download_path = $path;
722
723
        return $this;
724
    }
725
726
    /**
727
     * Get custom download path
728
     *
729
     * @return string
730
     */
731
    public function getDownloadPath()
732
    {
733
        return $this->download_path;
734
    }
735
736
    /**
737
     * Set command config
738
     *
739
     * Provide further variables to a particular commands.
740
     * For example you can add the channel name at the command /sendtochannel
741
     * Or you can add the api key for external service.
742
     *
743
     * @param string $command
744
     * @param array  $config
745
     *
746
     * @return Telegram
747
     */
748 13
    public function setCommandConfig($command, array $config)
749
    {
750 13
        $this->commands_config[$command] = $config;
751
752 13
        return $this;
753
    }
754
755
    /**
756
     * Get command config
757
     *
758
     * @param string $command
759
     *
760
     * @return array
761
     */
762 14
    public function getCommandConfig($command)
763
    {
764 14
        return isset($this->commands_config[$command]) ? $this->commands_config[$command] : [];
765
    }
766
767
    /**
768
     * Get API key
769
     *
770
     * @return string
771
     */
772 1
    public function getApiKey()
773
    {
774 1
        return $this->api_key;
775
    }
776
777
    /**
778
     * Get Bot name
779
     *
780
     * @return string
781
     */
782 1
    public function getBotUsername()
783
    {
784 1
        return $this->bot_username;
785
    }
786
787
    /**
788
     * Get Bot Id
789
     *
790
     * @return string
791
     */
792
    public function getBotId()
793
    {
794
        return $this->bot_id;
795
    }
796
797
    /**
798
     * Get Version
799
     *
800
     * @return string
801
     */
802
    public function getVersion()
803
    {
804
        return $this->version;
805
    }
806
807
    /**
808
     * Set Webhook for bot
809
     *
810
     * @param string $url
811
     * @param array  $data Optional parameters.
812
     *
813
     * @return ServerResponse
814
     * @throws TelegramException
815
     */
816
    public function setWebhook($url, array $data = [])
817
    {
818
        if (empty($url)) {
819
            throw new TelegramException('Hook url is empty!');
820
        }
821
822
        $data        = array_intersect_key($data, array_flip([
823
            'certificate',
824
            'max_connections',
825
            'allowed_updates',
826
        ]));
827
        $data['url'] = $url;
828
829
        // If the certificate is passed as a path, encode and add the file to the data array.
830
        if (!empty($data['certificate']) && is_string($data['certificate'])) {
831
            $data['certificate'] = Request::encodeFile($data['certificate']);
832
        }
833
834
        $result = Request::setWebhook($data);
835
836
        if (!$result->isOk()) {
837
            throw new TelegramException(
838
                'Webhook was not set! Error: ' . $result->getErrorCode() . ' ' . $result->getDescription()
839
            );
840
        }
841
842
        return $result;
843
    }
844
845
    /**
846
     * Delete any assigned webhook
847
     *
848
     * @return mixed
849
     * @throws TelegramException
850
     */
851
    public function deleteWebhook()
852
    {
853
        $result = Request::deleteWebhook();
854
855
        if (!$result->isOk()) {
856
            throw new TelegramException(
857
                'Webhook was not deleted! Error: ' . $result->getErrorCode() . ' ' . $result->getDescription()
858
            );
859
        }
860
861
        return $result;
862
    }
863
864
    /**
865
     * Replace function `ucwords` for UTF-8 characters in the class definition and commands
866
     *
867
     * @param string $str
868
     * @param string $encoding (default = 'UTF-8')
869
     *
870
     * @return string
871
     */
872 1
    protected function ucwordsUnicode($str, $encoding = 'UTF-8')
873
    {
874 1
        return mb_convert_case($str, MB_CASE_TITLE, $encoding);
875
    }
876
877
    /**
878
     * Replace function `ucfirst` for UTF-8 characters in the class definition and commands
879
     *
880
     * @param string $str
881
     * @param string $encoding (default = 'UTF-8')
882
     *
883
     * @return string
884
     */
885 1
    protected function ucfirstUnicode($str, $encoding = 'UTF-8')
886
    {
887 1
        return mb_strtoupper(mb_substr($str, 0, 1, $encoding), $encoding)
888 1
               . mb_strtolower(mb_substr($str, 1, mb_strlen($str), $encoding), $encoding);
889
    }
890
891
    /**
892
     * Enable requests limiter
893
     *
894
     * @param array $options
895
     *
896
     * @return Telegram
897
     * @throws TelegramException
898
     */
899
    public function enableLimiter(array $options = [])
900
    {
901
        Request::setLimiter(true, $options);
902
903
        return $this;
904
    }
905
906
    /**
907
     * Run provided commands
908
     *
909
     * @param array $commands
910
     *
911
     * @throws TelegramException
912
     */
913
    public function runCommands($commands)
914
    {
915
        if (!is_array($commands) || empty($commands)) {
0 ignored issues
show
introduced by
The condition is_array($commands) is always true.
Loading history...
916
            throw new TelegramException('No command(s) provided!');
917
        }
918
919
        $this->run_commands = true;
920
921
        $result = Request::getMe();
922
923
        if ($result->isOk()) {
924
            $result = $result->getResult();
925
926
            $bot_id       = $result->getId();
927
            $bot_name     = $result->getFirstName();
928
            $bot_username = $result->getUsername();
929
        } else {
930
            $bot_id       = $this->getBotId();
931
            $bot_name     = $this->getBotUsername();
932
            $bot_username = $this->getBotUsername();
933
        }
934
935
936
        $this->enableAdmin($bot_id);    // Give bot access to admin commands
937
        $this->getCommandsList();       // Load full commands list
938
939
        foreach ($commands as $command) {
940
            $this->update = new Update(
941
                [
942
                    'update_id' => 0,
943
                    'message'   => [
944
                        'message_id' => 0,
945
                        'from'       => [
946
                            'id'         => $bot_id,
947
                            'first_name' => $bot_name,
948
                            'username'   => $bot_username,
949
                        ],
950
                        'date'       => time(),
951
                        'chat'       => [
952
                            'id'   => $bot_id,
953
                            'type' => 'private',
954
                        ],
955
                        'text'       => $command,
956
                    ],
957
                ]
958
            );
959
960
            $this->executeCommand($this->update->getMessage()->getCommand());
961
        }
962
    }
963
964
    /**
965
     * Is this session initiated by runCommands()
966
     *
967
     * @return bool
968
     */
969
    public function isRunCommands()
970
    {
971
        return $this->run_commands;
972
    }
973
974
    /**
975
     * Switch to enable running getUpdates without a database
976
     *
977
     * @param bool $enable
978
     */
979
    public function useGetUpdatesWithoutDatabase($enable = true)
980
    {
981
        $this->getupdates_without_database = $enable;
982
    }
983
984
    /**
985
     * Return last update id
986
     *
987
     * @return int
988
     */
989
    public function getLastUpdateId()
990
    {
991
        return $this->last_update_id;
992
    }
993
}
994