Completed
Push — feature/refactor-app-design ( c863f7...166b88 )
by Avtandil
03:23
created

Telegram::getApiKey()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 2
CRAP Score 1

Importance

Changes 0
Metric Value
c 0
b 0
f 0
dl 0
loc 4
ccs 2
cts 2
cp 1
rs 10
cc 1
eloc 2
nc 1
nop 0
crap 1
1
<?php
0 ignored issues
show
Coding Style Compatibility introduced by
For compatibility and reusability of your code, PSR1 recommends that a file should introduce either new symbols (like classes, functions, etc.) or have side-effects (like outputting something, or including other files), but not both at the same time. The first symbol is defined on line 13 and the first side effect is on line 13.

The PSR-1: Basic Coding Standard recommends that a file should either introduce new symbols, that is classes, functions, constants or similar, or have side effects. Side effects are anything that executes logic, like for example printing output, changing ini settings or writing to a file.

The idea behind this recommendation is that merely auto-loading a class should not change the state of an application. It also promotes a cleaner style of programming and makes your code less prone to errors, because the logic is not spread out all over the place.

To learn more about the PSR-1, please see the PHP-FIG site on the PSR-1.

Loading history...
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 1
defined('TB_BASE_PATH') || define('TB_BASE_PATH', __DIR__);
14 1
defined('TB_BASE_COMMANDS_PATH') || define('TB_BASE_COMMANDS_PATH', TB_BASE_PATH . '/Commands');
15
16
use Exception;
17
use Illuminate\Container\Container;
18
use Longman\TelegramBot\Commands\Command;
19
use Longman\TelegramBot\Console\Kernel as ConsoleKernel;
20
use Longman\TelegramBot\Entities\Update;
21
use Longman\TelegramBot\Exception\TelegramException;
22
use Longman\TelegramBot\Http\Client;
23
use Longman\TelegramBot\Http\Kernel;
24
use Longman\TelegramBot\Http\Request;
25
use Longman\TelegramBot\Http\Response;
26
use PDO;
27
use RecursiveDirectoryIterator;
28
use RecursiveIteratorIterator;
29
use RegexIterator;
30
31
class Telegram
32
{
33
    /**
34
     * Version
35
     *
36
     * @var string
37
     */
38
    const VERSION = '0.53.0';
39
40
    /**
41
     * Telegram API key
42
     *
43
     * @var string
44
     */
45
    protected $api_key = '';
46
47
    /**
48
     * Telegram Bot username
49
     *
50
     * @var string
51
     */
52
    protected $bot_username = '';
53
54
    /**
55
     * Telegram Bot id
56
     *
57
     * @var string
58
     */
59
    protected $bot_id = '';
60
61
    /**
62
     * Container
63
     *
64
     * @var \Illuminate\Contracts\Container\Container
65
     */
66
    protected $container;
67
68
    /**
69
     * Raw request data (json) for webhook methods
70
     *
71
     * @var string
72
     */
73
    protected $input;
74
75
    /**
76
     * Custom commands paths
77
     *
78
     * @var array
79
     */
80
    protected $commands_paths = [];
81
82
    /**
83
     * Current Update object
84
     *
85
     * @var \Longman\TelegramBot\Entities\Update
86
     */
87
    protected $update;
88
89
    /**
90
     * Upload path
91
     *
92
     * @var string
93
     */
94
    protected $upload_path;
95
96
    /**
97
     * Download path
98
     *
99
     * @var string
100
     */
101
    protected $download_path;
102
103
    /**
104
     * MySQL integration
105
     *
106
     * @var boolean
107
     */
108
    protected $mysql_enabled = false;
109
110
    /**
111
     * PDO object
112
     *
113
     * @var \PDO
114
     */
115
    protected $pdo;
116
117
    /**
118
     * Commands config
119
     *
120
     * @var array
121
     */
122
    protected $commands_config = [];
123
124
    /**
125
     * Admins list
126
     *
127
     * @var array
128
     */
129
    protected $admins_list = [];
130
131
    /**
132
     * ServerResponse of the last Command execution
133
     *
134
     * @var \Longman\TelegramBot\Http\Response
135
     */
136
    protected $last_command_response;
137
138
    /**
139
     * Botan.io integration
140
     *
141
     * @var boolean
142
     */
143
    protected $botan_enabled = false;
144
145
    /**
146
     * Check if runCommands() is running in this session
147
     *
148
     * @var boolean
149
     */
150
    protected $run_commands = false;
151
152
    /**
153
     * Is running getUpdates without DB enabled
154
     *
155
     * @var bool
156
     */
157
    public $getupdates_without_database = false;
158
159
    /**
160
     * Last update ID
161
     * Only used when running getUpdates without a database
162
     *
163
     * @var integer
164
     */
165
    public $last_update_id = null;
166
167
    /**
168
     * Telegram constructor.
169
     *
170
     * @param string $api_key
171
     * @param string $bot_username
172
     *
173
     * @throws \Longman\TelegramBot\Exception\TelegramException
174
     */
175 33
    public function __construct($api_key, $bot_username = '')
176
    {
177 33
        if (empty($api_key)) {
178 1
            throw new TelegramException('API KEY not defined!');
179
        }
180 33
        preg_match('/(\d+)\:[\w\-]+/', $api_key, $matches);
181 33
        if (! isset($matches[1])) {
182 1
            throw new TelegramException('Invalid API KEY defined!');
183
        }
184 33
        $this->bot_id = $matches[1];
185 33
        $this->api_key = $api_key;
186
187 33
        if (! empty($bot_username)) {
188 33
            $this->bot_username = $bot_username;
189
        }
190
191 33
        $this->registerContainer();
192
193
        //Add default system commands path
194 33
        $this->addCommandsPath(TB_BASE_COMMANDS_PATH . '/SystemCommands');
195
196 33
        Client::initialize($this);
197 33
    }
198
199
    /**
200
     * Register the container.
201
     *
202
     * @return void
203
     */
204 33
    protected function registerContainer()
205
    {
206 33
        $this->container = Container::getInstance();
207
208 33
        $this->container->instance(Telegram::class, $this);
209 33
    }
210
211
    /**
212
     * Get container instance.
213
     *
214
     * @return \Illuminate\Container\Container
215
     */
216 3
    public function getContainer()
217
    {
218 3
        return $this->container;
219
    }
220
221
    /**
222
     * Initialize Database connection
223
     *
224
     * @param array $credential
225
     * @param string $table_prefix
226
     * @param string $encoding
227
     *
228
     * @return \Longman\TelegramBot\Telegram
229
     * @throws \Longman\TelegramBot\Exception\TelegramException
230
     */
231 9 View Code Duplication
    public function enableMySql(array $credential, $table_prefix = null, $encoding = 'utf8mb4')
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...
232
    {
233 9
        $this->pdo = DB::initialize($credential, $this, $table_prefix, $encoding);
234 9
        ConversationDB::initializeConversation();
235 9
        $this->mysql_enabled = true;
236
237 9
        return $this;
238
    }
239
240
    /**
241
     * Initialize Database external connection
242
     *
243
     * @param PDO $external_pdo_connection PDO database object
244
     * @param string $table_prefix
245
     *
246
     * @return \Longman\TelegramBot\Telegram
247
     * @throws \Longman\TelegramBot\Exception\TelegramException
248
     */
249 View Code Duplication
    public function enableExternalMySql($external_pdo_connection, $table_prefix = 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...
250
    {
251
        $this->pdo = DB::externalInitialize($external_pdo_connection, $this, $table_prefix);
252
        ConversationDB::initializeConversation();
253
        $this->mysql_enabled = true;
254
255
        return $this;
256
    }
257
258
    /**
259
     * Get commands list
260
     *
261
     * @return array $commands
262
     * @throws \Longman\TelegramBot\Exception\TelegramException
263
     */
264 3
    public function getCommandsList()
265
    {
266 3
        $commands = [];
267
268 3
        foreach ($this->commands_paths as $path) {
269
            try {
270
                //Get all "*Command.php" files
271 3
                $files = new RegexIterator(
272 3
                    new RecursiveIteratorIterator(
273 3
                        new RecursiveDirectoryIterator($path)
274
                    ),
275 3
                    '/^.+Command.php$/'
276
                );
277
278 3
                foreach ($files as $file) {
279
                    //Remove "Command.php" from filename
280 3
                    $command = $this->sanitizeCommand(substr($file->getFilename(), 0, -11));
281 3
                    $command_name = strtolower($command);
282
283 3
                    if (array_key_exists($command_name, $commands)) {
284
                        continue;
285
                    }
286
287 3
                    require_once $file->getPathname();
288
289 3
                    $command_obj = $this->getCommandObject($command);
290 3
                    if ($command_obj instanceof Command) {
291 3
                        $commands[$command_name] = $command_obj;
292
                    }
293
                }
294
            } catch (Exception $e) {
295 3
                throw new TelegramException('Error getting commands from path: ' . $path);
296
            }
297
        }
298
299 3
        return $commands;
300
    }
301
302
    /**
303
     * Get an object instance of the passed command
304
     *
305
     * @param string $command
306
     *
307
     * @return \Longman\TelegramBot\Commands\Command|null
308
     */
309 3
    public function getCommandObject($command)
310
    {
311 3
        $which = ['System'];
312 3
        $this->isAdmin() && $which[] = 'Admin';
313 3
        $which[] = 'User';
314
315 3
        foreach ($which as $auth) {
316 3
            $command_namespace = __NAMESPACE__ . '\\Commands\\' . $auth . 'Commands\\' . $this->ucfirstUnicode($command) . 'Command';
317 3
            if (class_exists($command_namespace)) {
318 3
                return new $command_namespace($this, $this->update);
319
            }
320
        }
321
322 2
        return null;
323
    }
324
325
    /**
326
     * Set custom input string for debug purposes
327
     *
328
     * @param string $input (json format)
329
     *
330
     * @return \Longman\TelegramBot\Telegram
331
     */
332
    public function setCustomInput($input)
333
    {
334
        $this->input = $input;
335
336
        return $this;
337
    }
338
339
    /**
340
     * Get custom input string for debug purposes
341
     *
342
     * @return string
343
     */
344
    public function getCustomInput()
345
    {
346
        return $this->input;
347
    }
348
349
    /**
350
     * Get the ServerResponse of the last Command execution
351
     *
352
     * @return \Longman\TelegramBot\Http\Response
353
     */
354
    public function getLastCommandResponse()
355
    {
356
        return $this->last_command_response;
357
    }
358
359
    /**
360
     * Handle getUpdates method
361
     *
362
     * @param int|null $limit
363
     * @param int|null $timeout
364
     *
365
     * @return \Longman\TelegramBot\Http\Response
366
     * @throws \Longman\TelegramBot\Exception\TelegramException
367
     */
368
    public function handleGetUpdates($limit = null, $timeout = null)
369
    {
370
        if (empty($this->bot_username)) {
371
            throw new TelegramException('Bot Username is not defined!');
372
        }
373
374
        /** @var \Longman\TelegramBot\Console\Kernel $kernel */
375
        $kernel = $this->getContainer()->make(ConsoleKernel::class);
376
377
        $response = $kernel->handle(Request::capture(), $limit, $timeout);
0 ignored issues
show
Bug introduced by
It seems like $limit defined by parameter $limit on line 368 can also be of type integer; however, Longman\TelegramBot\Console\Kernel::handle() does only seem to accept null, maybe add an additional type check?

This check looks at variables that have been passed in as parameters and are passed out again to other methods.

If the outgoing method call has stricter type requirements than the method itself, an issue is raised.

An additional type check may prevent trouble.

Loading history...
Bug introduced by
It seems like $timeout defined by parameter $timeout on line 368 can also be of type integer; however, Longman\TelegramBot\Console\Kernel::handle() does only seem to accept null, maybe add an additional type check?

This check looks at variables that have been passed in as parameters and are passed out again to other methods.

If the outgoing method call has stricter type requirements than the method itself, an issue is raised.

An additional type check may prevent trouble.

Loading history...
378
379
        return $response;
380
    }
381
382
    /**
383
     * Handle bot request from webhook
384
     *
385
     * @return \Longman\TelegramBot\Http\Response
386
     *
387
     * @throws \Longman\TelegramBot\Exception\TelegramException
388
     */
389 2
    public function handle()
390
    {
391 2
        if (empty($this->bot_username)) {
392
            throw new TelegramException('Bot Username is not defined!');
393
        }
394
395
        /** @var \Longman\TelegramBot\Http\Kernel $kernel */
396 2
        $kernel = $this->getContainer()->make(Kernel::class);
397
398 2
        $response = $kernel->handle(Request::capture());
399
400 2
        return $response;
401
    }
402
403
    /**
404
     * Get the command name from the command type
405
     *
406
     * @param string $type
407
     *
408
     * @return string
409
     */
410 2
    protected function getCommandFromType($type)
411
    {
412 2
        return $this->ucfirstUnicode(str_replace('_', '', $type));
413
    }
414
415
    /**
416
     * Process bot Update request
417
     *
418
     * @param \Longman\TelegramBot\Entities\Update $update
419
     *
420
     * @return \Longman\TelegramBot\Http\Response
421
     * @throws \Longman\TelegramBot\Exception\TelegramException
422
     */
423 2
    public function processUpdate(Update $update)
424
    {
425 2
        $this->update = $update;
426 2
        $this->last_update_id = $update->getUpdateId();
427
428
        // If all else fails, it's a generic message.
429 2
        $command = 'genericmessage';
430
431 2
        $update_type = $this->update->getUpdateType();
432 2
        if ($update_type === 'message') {
433
            $message = $this->update->getMessage();
434
435
            // Load admin commands
436
            if ($this->isAdmin()) {
437
                $this->addCommandsPath(TB_BASE_COMMANDS_PATH . '/AdminCommands', false);
438
            }
439
440
            $type = $message->getType();
441
            if ($type === 'command') {
442
                $command = $message->getCommand();
443
            } else if (in_array($type, [
444
                'new_chat_members',
445
                'left_chat_member',
446
                'new_chat_title',
447
                'new_chat_photo',
448
                'delete_chat_photo',
449
                'group_chat_created',
450
                'supergroup_chat_created',
451
                'channel_chat_created',
452
                'migrate_to_chat_id',
453
                'migrate_from_chat_id',
454
                'pinned_message',
455
                'invoice',
456
                'successful_payment',
457
            ], true)
458
            ) {
459
                $command = $this->getCommandFromType($type);
460
            }
461
        } else {
462 2
            $command = $this->getCommandFromType($update_type);
463
        }
464
465
        // Make sure we have an up-to-date command list
466
        // This is necessary to "require" all the necessary command files!
467 2
        $this->getCommandsList();
468
469
        // Make sure we don't try to process update that was already processed
470 2
        $last_id = DB::selectTelegramUpdate(1, $this->update->getUpdateId());
471 2
        if ($last_id && count($last_id) === 1) {
472
            TelegramLog::debug('Duplicate update received, processing aborted!');
473
474
            return new Response(['ok' => true, 'result' => true]);
475
        }
476
477 2
        DB::insertRequest($this->update);
478
479 2
        return $this->executeCommand($command);
480
    }
481
482
    /**
483
     * Execute /command
484
     *
485
     * @param string $command
486
     *
487
     * @return mixed
488
     * @throws \Longman\TelegramBot\Exception\TelegramException
489
     */
490 2
    public function executeCommand($command)
491
    {
492 2
        $command = strtolower($command);
493 2
        $command_obj = $this->getCommandObject($command);
494
495 2
        if (! $command_obj || ! $command_obj->isEnabled()) {
496
            // Failsafe in case the Generic command can't be found
497 2
            if ($command === 'generic') {
498
                throw new TelegramException('Generic command missing!');
499
            }
500
501
            // Handle a generic command or non existing one
502 2
            $this->last_command_response = $this->executeCommand('generic');
503
        } else {
504
            // Botan.io integration, make sure only the actual command user executed is reported
505 2
            if ($this->botan_enabled) {
506
                Botan::lock($command);
507
            }
508
509
            // execute() method is executed after preExecute()
510
            // This is to prevent executing a DB query without a valid connection
511 2
            $this->last_command_response = $command_obj->preExecute();
512
513
            // Botan.io integration, send report after executing the command
514 2
            if ($this->botan_enabled) {
515
                Botan::track($this->update, $command);
516
            }
517
        }
518
519 2
        return $this->last_command_response;
520
    }
521
522
    /**
523
     * Sanitize Command
524
     *
525
     * @param string $command
526
     *
527
     * @return string
528
     */
529 3
    protected function sanitizeCommand($command)
530
    {
531 3
        return str_replace(' ', '', $this->ucwordsUnicode(str_replace('_', ' ', $command)));
532
    }
533
534
    /**
535
     * Enable a single Admin account
536
     *
537
     * @param integer $admin_id Single admin id
538
     *
539
     * @return \Longman\TelegramBot\Telegram
540
     */
541 1
    public function enableAdmin($admin_id)
542
    {
543 1
        if (! is_int($admin_id) || $admin_id <= 0) {
544 1
            TelegramLog::error('Invalid value "%s" for admin.', $admin_id);
545 1
        } else if (! in_array($admin_id, $this->admins_list, true)) {
546 1
            $this->admins_list[] = $admin_id;
547
        }
548
549 1
        return $this;
550
    }
551
552
    /**
553
     * Enable a list of Admin Accounts
554
     *
555
     * @param array $admin_ids List of admin ids
556
     *
557
     * @return \Longman\TelegramBot\Telegram
558
     */
559 1
    public function enableAdmins(array $admin_ids)
560
    {
561 1
        foreach ($admin_ids as $admin_id) {
562 1
            $this->enableAdmin($admin_id);
563
        }
564
565 1
        return $this;
566
    }
567
568
    /**
569
     * Get list of admins
570
     *
571
     * @return array
572
     */
573 1
    public function getAdminList()
574
    {
575 1
        return $this->admins_list;
576
    }
577
578
    /**
579
     * Check if the passed user is an admin
580
     *
581
     * If no user id is passed, the current update is checked for a valid message sender.
582
     *
583
     * @param int|null $user_id
584
     *
585
     * @return bool
586
     */
587 3
    public function isAdmin($user_id = null)
588
    {
589 3
        if ($user_id === null && $this->update !== null) {
590
            //Try to figure out if the user is an admin
591
            $update_methods = [
592 2
                'getMessage',
593
                'getEditedMessage',
594
                'getChannelPost',
595
                'getEditedChannelPost',
596
                'getInlineQuery',
597
                'getChosenInlineResult',
598
                'getCallbackQuery',
599
            ];
600 2
            foreach ($update_methods as $update_method) {
601 2
                $object = call_user_func([$this->update, $update_method]);
602 2
                if ($object !== null && $from = $object->getFrom()) {
603
                    $user_id = $from->getId();
604 2
                    break;
605
                }
606
            }
607
        }
608
609 3
        return ($user_id === null) ? false : in_array($user_id, $this->admins_list, true);
610
    }
611
612
    /**
613
     * Check if user required the db connection
614
     *
615
     * @return bool
616
     */
617
    public function isDbEnabled()
618
    {
619
        if ($this->mysql_enabled) {
620
            return true;
621
        } else {
622
            return false;
623
        }
624
    }
625
626
    /**
627
     * Add a single custom commands path
628
     *
629
     * @param string $path Custom commands path to add
630
     * @param bool $before If the path should be prepended or appended to the list
631
     *
632
     * @return \Longman\TelegramBot\Telegram
633
     */
634 33
    public function addCommandsPath($path, $before = true)
635
    {
636 33
        if (! is_dir($path)) {
637 1
            TelegramLog::error('Commands path "%s" does not exist.', $path);
638 33
        } else if (! in_array($path, $this->commands_paths, true)) {
639 33
            if ($before) {
640 33
                array_unshift($this->commands_paths, $path);
641
            } else {
642
                $this->commands_paths[] = $path;
643
            }
644
        }
645
646 33
        return $this;
647
    }
648
649
    /**
650
     * Add multiple custom commands paths
651
     *
652
     * @param array $paths Custom commands paths to add
653
     * @param bool $before If the paths should be prepended or appended to the list
654
     *
655
     * @return \Longman\TelegramBot\Telegram
656
     */
657 1
    public function addCommandsPaths(array $paths, $before = true)
658
    {
659 1
        foreach ($paths as $path) {
660 1
            $this->addCommandsPath($path, $before);
661
        }
662
663 1
        return $this;
664
    }
665
666
    /**
667
     * Return the list of commands paths
668
     *
669
     * @return array
670
     */
671 1
    public function getCommandsPaths()
672
    {
673 1
        return $this->commands_paths;
674
    }
675
676
    /**
677
     * Set custom upload path
678
     *
679
     * @param string $path Custom upload path
680
     *
681
     * @return \Longman\TelegramBot\Telegram
682
     */
683
    public function setUploadPath($path)
684
    {
685
        $this->upload_path = $path;
686
687
        return $this;
688
    }
689
690
    /**
691
     * Get custom upload path
692
     *
693
     * @return string
694
     */
695
    public function getUploadPath()
696
    {
697
        return $this->upload_path;
698
    }
699
700
    /**
701
     * Set custom download path
702
     *
703
     * @param string $path Custom download path
704
     *
705
     * @return \Longman\TelegramBot\Telegram
706
     */
707
    public function setDownloadPath($path)
708
    {
709
        $this->download_path = $path;
710
711
        return $this;
712
    }
713
714
    /**
715
     * Get custom download path
716
     *
717
     * @return string
718
     */
719
    public function getDownloadPath()
720
    {
721
        return $this->download_path;
722
    }
723
724
    /**
725
     * Set command config
726
     *
727
     * Provide further variables to a particular commands.
728
     * For example you can add the channel name at the command /sendtochannel
729
     * Or you can add the api key for external service.
730
     *
731
     * @param string $command
732
     * @param array $config
733
     *
734
     * @return \Longman\TelegramBot\Telegram
735
     */
736 14
    public function setCommandConfig($command, array $config)
737
    {
738 14
        $this->commands_config[$command] = $config;
739
740 14
        return $this;
741
    }
742
743
    /**
744
     * Get command config
745
     *
746
     * @param string $command
747
     *
748
     * @return array
749
     */
750 17
    public function getCommandConfig($command)
751
    {
752 17
        return isset($this->commands_config[$command]) ? $this->commands_config[$command] : [];
753
    }
754
755
    /**
756
     * Get API key
757
     *
758
     * @return string
759
     */
760 1
    public function getApiKey()
761
    {
762 1
        return $this->api_key;
763
    }
764
765
    /**
766
     * Get Bot name
767
     *
768
     * @return string
769
     */
770 3
    public function getBotUsername()
771
    {
772 3
        return $this->bot_username;
773
    }
774
775
    /**
776
     * Get Bot Id
777
     *
778
     * @return string
779
     */
780
    public function getBotId()
781
    {
782
        return $this->bot_id;
783
    }
784
785
    /**
786
     * Get Version
787
     *
788
     * @return string
789
     */
790
    public function getVersion()
791
    {
792
        return self::VERSION;
793
    }
794
795
    /**
796
     * Set Webhook for bot
797
     *
798
     * @param string $url
799
     * @param array $data Optional parameters.
800
     *
801
     * @return \Longman\TelegramBot\Http\Response
802
     * @throws \Longman\TelegramBot\Exception\TelegramException
803
     */
804
    public function setWebhook($url, array $data = [])
805
    {
806
        if (empty($url)) {
807
            throw new TelegramException('Hook url is empty!');
808
        }
809
810
        $data = array_intersect_key($data, array_flip([
811
            'certificate',
812
            'max_connections',
813
            'allowed_updates',
814
        ]));
815
        $data['url'] = $url;
816
817
        // If the certificate is passed as a path, encode and add the file to the data array.
818
        if (! empty($data['certificate']) && is_string($data['certificate'])) {
819
            $data['certificate'] = Client::encodeFile($data['certificate']);
820
        }
821
822
        $result = Client::setWebhook($data);
823
824 View Code Duplication
        if (! $result->isOk()) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across 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...
825
            throw new TelegramException(
826
                'Webhook was not set! Error: ' . $result->getErrorCode() . ' ' . $result->getDescription()
827
            );
828
        }
829
830
        return $result;
831
    }
832
833
    /**
834
     * Delete any assigned webhook
835
     *
836
     * @return mixed
837
     * @throws \Longman\TelegramBot\Exception\TelegramException
838
     */
839
    public function deleteWebhook()
840
    {
841
        $result = Client::deleteWebhook();
842
843 View Code Duplication
        if (! $result->isOk()) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across 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...
844
            throw new TelegramException(
845
                'Webhook was not deleted! Error: ' . $result->getErrorCode() . ' ' . $result->getDescription()
846
            );
847
        }
848
849
        return $result;
850
    }
851
852
    /**
853
     * Replace function `ucwords` for UTF-8 characters in the class definition and commands
854
     *
855
     * @param string $str
856
     * @param string $encoding (default = 'UTF-8')
857
     *
858
     * @return string
859
     */
860 3
    protected function ucwordsUnicode($str, $encoding = 'UTF-8')
861
    {
862 3
        return mb_convert_case($str, MB_CASE_TITLE, $encoding);
863
    }
864
865
    /**
866
     * Replace function `ucfirst` for UTF-8 characters in the class definition and commands
867
     *
868
     * @param string $str
869
     * @param string $encoding (default = 'UTF-8')
870
     *
871
     * @return string
872
     */
873 3
    protected function ucfirstUnicode($str, $encoding = 'UTF-8')
874
    {
875 3
        return mb_strtoupper(mb_substr($str, 0, 1, $encoding), $encoding)
876 3
            . mb_strtolower(mb_substr($str, 1, mb_strlen($str), $encoding), $encoding);
877
    }
878
879
    /**
880
     * Enable Botan.io integration
881
     *
882
     * @param  string $token
883
     * @param  array $options
884
     *
885
     * @return \Longman\TelegramBot\Telegram
886
     * @throws \Longman\TelegramBot\Exception\TelegramException
887
     */
888
    public function enableBotan($token, array $options = [])
889
    {
890
        Botan::initializeBotan($token, $options);
891
        $this->botan_enabled = true;
892
893
        return $this;
894
    }
895
896
    /**
897
     * Enable requests limiter
898
     *
899
     * @param  array $options
900
     *
901
     * @return \Longman\TelegramBot\Telegram
902
     */
903
    public function enableLimiter(array $options = [])
904
    {
905
        Client::setLimiter(true, $options);
906
907
        return $this;
908
    }
909
910
    /**
911
     * Run provided commands
912
     *
913
     * @param array $commands
914
     *
915
     * @throws TelegramException
916
     */
917
    public function runCommands($commands)
918
    {
919
        if (! is_array($commands) || empty($commands)) {
920
            throw new TelegramException('No command(s) provided!');
921
        }
922
923
        $this->run_commands = true;
924
        $this->botan_enabled = false;   // Force disable Botan.io integration, we don't want to track self-executed commands!
925
926
        $result = Client::getMe();
927
928
        if ($result->isOk()) {
929
            $result = $result->getResult();
930
931
            $bot_id = $result->getId();
932
            $bot_name = $result->getFirstName();
933
            $bot_username = $result->getUsername();
934
        } else {
935
            $bot_id = $this->getBotId();
936
            $bot_name = $this->getBotUsername();
937
            $bot_username = $this->getBotUsername();
938
        }
939
940
        $this->enableAdmin($bot_id);    // Give bot access to admin commands
941
        $this->getCommandsList();       // Load full commands list
942
943
        foreach ($commands as $command) {
944
            $this->update = new Update(
945
                [
946
                    'update_id' => 0,
947
                    'message'   => [
948
                        'message_id' => 0,
949
                        'from'       => [
950
                            'id'         => $bot_id,
951
                            'first_name' => $bot_name,
952
                            'username'   => $bot_username,
953
                        ],
954
                        'date'       => time(),
955
                        'chat'       => [
956
                            'id'   => $bot_id,
957
                            'type' => 'private',
958
                        ],
959
                        'text'       => $command,
960
                    ],
961
                ]
962
            );
963
964
            $this->executeCommand($this->update->getMessage()->getCommand());
965
        }
966
    }
967
968
    /**
969
     * Is this session initiated by runCommands()
970
     *
971
     * @return bool
972
     */
973
    public function isRunCommands()
974
    {
975
        return $this->run_commands;
976
    }
977
978
    /**
979
     * Switch to enable running getUpdates without a database
980
     *
981
     * @param bool $enable
982
     */
983
    public function useGetUpdatesWithoutDatabase($enable = true)
984
    {
985
        $this->getupdates_without_database = $enable;
986
    }
987
988
    /**
989
     * Return last update id
990
     *
991
     * @return int
992
     */
993
    public function getLastUpdateId()
994
    {
995
        return $this->last_update_id;
996
    }
997
}
998