Completed
Push — feature/refactor-app-design ( 84f9ff...b18d21 )
by Avtandil
04:09
created

Telegram::deleteWebhook()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 12
Code Lines 6

Duplication

Lines 5
Ratio 41.67 %

Code Coverage

Tests 0
CRAP Score 6

Importance

Changes 0
Metric Value
c 0
b 0
f 0
dl 5
loc 12
ccs 0
cts 6
cp 0
rs 9.4285
cc 2
eloc 6
nc 2
nop 0
crap 6
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\Extensions\Botan\Botan;
23
use Longman\TelegramBot\Http\Client;
24
use Longman\TelegramBot\Http\Kernel;
25
use Longman\TelegramBot\Http\Request;
26
use Longman\TelegramBot\Http\Response;
27
use PDO;
28
use RecursiveDirectoryIterator;
29
use RecursiveIteratorIterator;
30
use RegexIterator;
31
32
class Telegram
33
{
34
    /**
35
     * Version
36
     *
37
     * @var string
38
     */
39
    const VERSION = '0.53.0';
40
41
    /**
42
     * Telegram API key
43
     *
44
     * @var string
45
     */
46
    protected $api_key = '';
47
48
    /**
49
     * Telegram Bot username
50
     *
51
     * @var string
52
     */
53
    protected $bot_username = '';
54
55
    /**
56
     * Telegram Bot id
57
     *
58
     * @var string
59
     */
60
    protected $bot_id = '';
61
62
    /**
63
     * Container
64
     *
65
     * @var \Illuminate\Contracts\Container\Container
66
     */
67
    protected $container;
68
69
    /**
70
     * Current Update object
71
     *
72
     * @var \Longman\TelegramBot\Entities\Update
73
     */
74
    protected $update;
75
76
    /**
77
     * Upload path
78
     *
79
     * @var string
80
     */
81
    protected $upload_path;
82
83
    /**
84
     * Download path
85
     *
86
     * @var string
87
     */
88
    protected $download_path;
89
90
    /**
91
     * MySQL integration
92
     *
93
     * @var boolean
94
     */
95
    protected $mysql_enabled = false;
96
97
    /**
98
     * PDO object
99
     *
100
     * @var \PDO
101
     */
102
    protected $pdo;
103
104
    /**
105
     * Commands config
106
     *
107
     * @var array
108
     */
109
    protected $commands_config = [];
110
111
    /**
112
     * ServerResponse of the last Command execution
113
     *
114
     * @var \Longman\TelegramBot\Http\Response
115
     */
116
    protected $last_command_response;
117
118
    /**
119
     * Check if runCommands() is running in this session
120
     *
121
     * @var boolean
122
     */
123
    protected $run_commands = false;
124
125
    /**
126
     * Is running getUpdates without DB enabled
127
     *
128
     * @var bool
129
     */
130
    public $getupdates_without_database = false;
131
132
    /**
133
     * Last update ID
134
     * Only used when running getUpdates without a database
135
     *
136
     * @var integer
137
     */
138
    public $last_update_id = null;
139
140
    /**
141
     * Telegram constructor.
142
     *
143
     * @param string $api_key
144
     * @param string $bot_username
145
     *
146
     * @throws \Longman\TelegramBot\Exception\TelegramException
147
     */
148 34
    public function __construct($api_key, $bot_username = '')
149
    {
150 34
        if (empty($api_key)) {
151 1
            throw new TelegramException('API KEY not defined!');
152
        }
153 34
        preg_match('/(\d+)\:[\w\-]+/', $api_key, $matches);
154 34
        if (! isset($matches[1])) {
155 1
            throw new TelegramException('Invalid API KEY defined!');
156
        }
157 34
        $this->bot_id = $matches[1];
158 34
        $this->api_key = $api_key;
159
160 34
        if (! empty($bot_username)) {
161 34
            $this->bot_username = $bot_username;
162
        }
163
164 34
        $this->registerContainer();
165
166 34
        $this->initializeConfig();
167
168
        // Add default system commands path
169 34
        $this->addCommandsPath(TB_BASE_COMMANDS_PATH . '/SystemCommands');
170
171 34
        Client::initialize($this);
172 34
    }
173
174
    /**
175
     * Register the container.
176
     *
177
     * @return void
178
     */
179 34
    protected function registerContainer()
180
    {
181 34
        $this->container = Container::getInstance();
182
183 34
        $this->container->instance(Telegram::class, $this);
184 34
    }
185
186
    /**
187
     * Initialize config.
188
     *
189
     * @return void
190
     */
191 34
    protected function initializeConfig()
192
    {
193 34
        $config = new Config();
194
195 34
        $this->container->instance(Config::class, $config);
196 34
    }
197
198
    /**
199
     * Get config.
200
     *
201
     * @return \Longman\TelegramBot\Config
202
     */
203 34
    public function getConfig()
204
    {
205 34
        return $this->container->make(Config::class);
206
    }
207
208
    /**
209
     * Get container instance.
210
     *
211
     * @return \Illuminate\Container\Container
212
     */
213 4
    public function getContainer()
214
    {
215 4
        return $this->container;
216
    }
217
218
    /**
219
     * Initialize Database connection
220
     *
221
     * @param array $credential
222
     * @param string $table_prefix
223
     * @param string $encoding
224
     *
225
     * @return \Longman\TelegramBot\Telegram
226
     * @throws \Longman\TelegramBot\Exception\TelegramException
227
     */
228 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...
229
    {
230 9
        $this->pdo = DB::initialize($credential, $this, $table_prefix, $encoding);
231 9
        ConversationDB::initializeConversation();
232 9
        $this->mysql_enabled = true;
233
234 9
        return $this;
235
    }
236
237
    /**
238
     * Initialize Database external connection
239
     *
240
     * @param PDO $external_pdo_connection PDO database object
241
     * @param string $table_prefix
242
     *
243
     * @return \Longman\TelegramBot\Telegram
244
     * @throws \Longman\TelegramBot\Exception\TelegramException
245
     */
246 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...
247
    {
248
        $this->pdo = DB::externalInitialize($external_pdo_connection, $this, $table_prefix);
249
        ConversationDB::initializeConversation();
250
        $this->mysql_enabled = true;
251
252
        return $this;
253
    }
254
255
    /**
256
     * Get commands list
257
     *
258
     * @return array $commands
259
     * @throws \Longman\TelegramBot\Exception\TelegramException
260
     */
261 3
    public function getCommandsList()
262
    {
263 3
        $commands = [];
264
265 3
        $command_paths = $this->getConfig()->getCommandsPaths();
266 3
        foreach ($command_paths as $path) {
267
            try {
268
                // Get all "*Command.php" files
269 3
                $files = new RegexIterator(
270 3
                    new RecursiveIteratorIterator(
271 3
                        new RecursiveDirectoryIterator($path)
272
                    ),
273 3
                    '/^.+Command.php$/'
274
                );
275
276 3
                foreach ($files as $file) {
277
                    //Remove "Command.php" from filename
278 3
                    $command = $this->sanitizeCommand(substr($file->getFilename(), 0, -11));
279 3
                    $command_name = strtolower($command);
280
281 3
                    if (array_key_exists($command_name, $commands)) {
282
                        continue;
283
                    }
284
285 3
                    require_once $file->getPathname();
286
287 3
                    $command_obj = $this->createCommandObject($command);
288 3
                    if ($command_obj instanceof Command) {
289 3
                        $commands[$command_name] = $command_obj;
290
                    }
291
                }
292
            } catch (Exception $e) {
293 3
                throw new TelegramException('Error getting commands from path: ' . $path);
294
            }
295
        }
296
297 3
        return $commands;
298
    }
299
300
    /**
301
     * Get an object instance of the passed command
302
     *
303
     * @param string $command
304
     *
305
     * @return \Longman\TelegramBot\Commands\Command|null
306
     */
307 3
    public function createCommandObject($command)
308
    {
309 3
        $which = ['System'];
310 3
        if ($this->isAdmin()) {
311
            $which[] = 'Admin';
312
        }
313 3
        $which[] = 'User';
314
315 3
        $command_name = $this->ucfirstUnicode($command);
316 3
        foreach ($which as $auth) {
317 3
            $command_namespace = __NAMESPACE__ . '\\Commands\\' . $auth . 'Commands\\' . $command_name . 'Command';
318
319 3
            if (class_exists($command_namespace)) {
320 3
                return new $command_namespace($this, $this->update);
321
            }
322
        }
323
324 2
        return null;
325
    }
326
327
    /**
328
     * Get the ServerResponse of the last Command execution
329
     *
330
     * @return \Longman\TelegramBot\Http\Response
331
     */
332
    public function getLastCommandResponse()
333
    {
334
        return $this->last_command_response;
335
    }
336
337
    /**
338
     * Handle getUpdates method
339
     *
340
     * @param \Longman\TelegramBot\Http\Request|null $request
341
     * @param int|null $limit
342
     * @param int|null $timeout
343
     *
344
     * @return \Longman\TelegramBot\Http\Response
345
     * @throws \Longman\TelegramBot\Exception\TelegramException
346
     */
347 1
    public function handleGetUpdates(Request $request = null, $limit = null, $timeout = null)
348
    {
349 1
        if (empty($this->bot_username)) {
350
            throw new TelegramException('Bot Username is not defined!');
351
        }
352
353
        /** @var \Longman\TelegramBot\Console\Kernel $kernel */
354 1
        $kernel = $this->getContainer()->make(ConsoleKernel::class);
355
356 1
        if (is_null($request)) {
357 1
            $request = Request::capture();
358
        }
359
360 1
        $this->container->instance(Request::class, $request);
361
362 1
        $response = $kernel->handle($request, $limit, $timeout);
0 ignored issues
show
Bug introduced by
It seems like $limit defined by parameter $limit on line 347 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 347 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...
363
364 1
        return $response;
365
    }
366
367
    /**
368
     * Handle bot request from webhook
369
     *
370
     * @param \Longman\TelegramBot\Http\Request|null $request
371
     * @return \Longman\TelegramBot\Http\Response
372
     *
373
     * @throws \Longman\TelegramBot\Exception\TelegramException
374
     */
375 2
    public function handle(Request $request = null)
376
    {
377 2
        if (empty($this->getBotUsername())) {
378
            throw new TelegramException('Bot Username is not defined!');
379
        }
380
381
        /** @var \Longman\TelegramBot\Http\Kernel $kernel */
382 2
        $kernel = $this->getContainer()->make(Kernel::class);
383
384 2
        if (is_null($request)) {
385 2
            $request = Request::capture();
386
        }
387
388 2
        $this->container->instance(Request::class, $request);
389
390 2
        $response = $kernel->handle($request);
391
392 2
        return $response;
393
    }
394
395
    /**
396
     * Get the command name from the command type
397
     *
398
     * @param string $type
399
     *
400
     * @return string
401
     */
402 2
    protected function getCommandFromType($type)
403
    {
404 2
        return $this->ucfirstUnicode(str_replace('_', '', $type));
405
    }
406
407
    /**
408
     * Process bot Update request
409
     *
410
     * @param \Longman\TelegramBot\Entities\Update $update
411
     *
412
     * @return \Longman\TelegramBot\Http\Response
413
     * @throws \Longman\TelegramBot\Exception\TelegramException
414
     */
415 2
    public function processUpdate(Update $update)
416
    {
417 2
        $this->update = $update;
418 2
        $this->last_update_id = $update->getUpdateId();
419
420
        // If all else fails, it's a generic message.
421 2
        $command = 'genericmessage';
422
423 2
        $update_type = $update->getUpdateType();
424 2
        if ($update_type === Update::TYPE_MESSAGE) {
425
            $message = $update->getMessage();
426
427
            // Load admin commands
428
            if ($this->isAdmin()) {
429
                $this->addCommandsPath(TB_BASE_COMMANDS_PATH . '/AdminCommands', false);
430
            }
431
432
            $type = $message->getType();
433
            if ($type === 'command') {
434
                $command = $message->getCommand();
435
            } else if (in_array($type, [
436
                'new_chat_members',
437
                'left_chat_member',
438
                'new_chat_title',
439
                'new_chat_photo',
440
                'delete_chat_photo',
441
                'group_chat_created',
442
                'supergroup_chat_created',
443
                'channel_chat_created',
444
                'migrate_to_chat_id',
445
                'migrate_from_chat_id',
446
                'pinned_message',
447
                'invoice',
448
                'successful_payment',
449
            ], true)
450
            ) {
451
                $command = $this->getCommandFromType($type);
452
            }
453
        } else {
454 2
            $command = $this->getCommandFromType($update_type);
455
        }
456
457
        // Make sure we have an up-to-date command list
458
        // This is necessary to "require" all the necessary command files!
459 2
        $this->getCommandsList();
460
461
        // Make sure we don't try to process update that was already processed
462 2
        $last_id = DB::selectTelegramUpdate(1, $update->getUpdateId());
463 2
        if ($last_id && count($last_id) === 1) {
464
            TelegramLog::debug('Duplicate update received, processing aborted!');
465
466
            return new Response(['ok' => true, 'result' => true]);
467
        }
468
469 2
        DB::insertRequest($update);
470
471 2
        return $this->executeCommand($command);
472
    }
473
474
    /**
475
     * Execute /command
476
     *
477
     * @param string $command
478
     *
479
     * @return mixed
480
     * @throws \Longman\TelegramBot\Exception\TelegramException
481
     */
482 2
    public function executeCommand($command)
483
    {
484 2
        $command = strtolower($command);
485 2
        $command_obj = $this->createCommandObject($command);
486
487 2
        if (! $command_obj || ! $command_obj->isEnabled()) {
488
            // Failsafe in case the Generic command can't be found
489 2
            if ($command === 'generic') {
490
                throw new TelegramException('Generic command missing!');
491
            }
492
493
            // Handle a generic command or non existing one
494 2
            $this->last_command_response = $this->executeCommand('generic');
495
        } else {
496
            // Botan.io integration, make sure only the actual command user executed is reported
497 2
            if (Botan::isEnabled()) {
498
                Botan::lock($command);
499
            }
500
501
            // execute() method is executed after preExecute()
502
            // This is to prevent executing a DB query without a valid connection
503 2
            $this->last_command_response = $command_obj->preExecute();
504
505
            // Botan.io integration, send report after executing the command
506 2
            if (Botan::isEnabled()) {
507
                Botan::track($this->update, $command);
508
            }
509
        }
510
511 2
        return $this->last_command_response;
512
    }
513
514
    /**
515
     * Sanitize Command
516
     *
517
     * @param string $command
518
     *
519
     * @return string
520
     */
521 3
    protected function sanitizeCommand($command)
522
    {
523 3
        return str_replace(' ', '', $this->ucwordsUnicode(str_replace('_', ' ', $command)));
524
    }
525
526
    /**
527
     * Enable a single Admin account
528
     *
529
     * @param integer $admin_id Single admin id
530
     *
531
     * @return \Longman\TelegramBot\Telegram
532
     */
533 1
    public function enableAdmin($admin_id)
534
    {
535 1
        $this->getConfig()->addAdmin($admin_id);
536
537 1
        return $this;
538
    }
539
540
    /**
541
     * Enable a list of Admin Accounts
542
     *
543
     * @param array $admin_ids List of admin ids
544
     *
545
     * @return \Longman\TelegramBot\Telegram
546
     */
547 1
    public function enableAdmins(array $admin_ids)
548
    {
549 1
        $this->getConfig()->addAdmins($admin_ids);
550
551 1
        return $this;
552
    }
553
554
    /**
555
     * Get list of admins
556
     *
557
     * @return array
558
     */
559 1
    public function getAdminList()
560
    {
561 1
        return $this->getConfig()->getAdmins();
562
    }
563
564
    /**
565
     * Check if the passed user is an admin
566
     *
567
     * If no user id is passed, the current update is checked for a valid message sender.
568
     *
569
     * @param int|null $user_id
570
     *
571
     * @return bool
572
     */
573 3
    public function isAdmin($user_id = null)
574
    {
575 3
        if ($user_id === null && $this->update !== null) {
576
            //Try to figure out if the user is an admin
577
            $update_methods = [
578 2
                'getMessage',
579
                'getEditedMessage',
580
                'getChannelPost',
581
                'getEditedChannelPost',
582
                'getInlineQuery',
583
                'getChosenInlineResult',
584
                'getCallbackQuery',
585
            ];
586 2
            foreach ($update_methods as $update_method) {
587 2
                $object = call_user_func([$this->update, $update_method]);
588 2
                if ($object !== null && $from = $object->getFrom()) {
589
                    $user_id = $from->getId();
590 2
                    break;
591
                }
592
            }
593
        }
594
595 3
        $admins = $this->getConfig()->getAdmins();
596 3
        return ($user_id === null) ? false : in_array($user_id, $admins, true);
597
    }
598
599
    /**
600
     * Check if user required the db connection
601
     *
602
     * @return bool
603
     */
604
    public function isDbEnabled()
605
    {
606
        if ($this->mysql_enabled) {
607
            return true;
608
        } else {
609
            return false;
610
        }
611
    }
612
613
    /**
614
     * Add a single custom commands path
615
     *
616
     * @param string $path Custom commands path to add
617
     * @param bool $before If the path should be prepended or appended to the list
618
     *
619
     * @return \Longman\TelegramBot\Telegram
620
     */
621 34
    public function addCommandsPath($path, $before = true)
622
    {
623 34
        $this->getConfig()->addCommandsPath($path, $before);
624
625 34
        return $this;
626
    }
627
628
    /**
629
     * Add multiple custom commands paths
630
     *
631
     * @param array $paths Custom commands paths to add
632
     * @param bool $before If the paths should be prepended or appended to the list
633
     *
634
     * @return \Longman\TelegramBot\Telegram
635
     */
636 1
    public function addCommandsPaths(array $paths, $before = true)
637
    {
638 1
        $this->getConfig()->addCommandsPaths($paths, $before);
639
640 1
        return $this;
641
    }
642
643
    /**
644
     * Return the list of commands paths
645
     *
646
     * @return array
647
     */
648 1
    public function getCommandsPaths()
649
    {
650
651 1
        return $this->getConfig()->getCommandsPaths();
652
    }
653
654
    /**
655
     * Set custom upload path
656
     *
657
     * @param string $path Custom upload path
658
     *
659
     * @return \Longman\TelegramBot\Telegram
660
     */
661
    public function setUploadPath($path)
662
    {
663
        $this->upload_path = $path;
664
665
        return $this;
666
    }
667
668
    /**
669
     * Get custom upload path
670
     *
671
     * @return string
672
     */
673
    public function getUploadPath()
674
    {
675
        return $this->upload_path;
676
    }
677
678
    /**
679
     * Set custom download path
680
     *
681
     * @param string $path Custom download path
682
     *
683
     * @return \Longman\TelegramBot\Telegram
684
     */
685
    public function setDownloadPath($path)
686
    {
687
        $this->download_path = $path;
688
689
        return $this;
690
    }
691
692
    /**
693
     * Get custom download path
694
     *
695
     * @return string
696
     */
697
    public function getDownloadPath()
698
    {
699
        return $this->download_path;
700
    }
701
702
    /**
703
     * Set command config
704
     *
705
     * Provide further variables to a particular commands.
706
     * For example you can add the channel name at the command /sendtochannel
707
     * Or you can add the api key for external service.
708
     *
709
     * @param string $command
710
     * @param array $config
711
     *
712
     * @return \Longman\TelegramBot\Telegram
713
     */
714 14
    public function setCommandConfig($command, array $config)
715
    {
716 14
        $this->commands_config[$command] = $config;
717
718 14
        return $this;
719
    }
720
721
    /**
722
     * Get command config
723
     *
724
     * @param string $command
725
     *
726
     * @return array
727
     */
728 17
    public function getCommandConfig($command)
729
    {
730 17
        return isset($this->commands_config[$command]) ? $this->commands_config[$command] : [];
731
    }
732
733
    /**
734
     * Get API key
735
     *
736
     * @return string
737
     */
738 1
    public function getApiKey()
739
    {
740 1
        return $this->api_key;
741
    }
742
743
    /**
744
     * Get Bot name
745
     *
746
     * @return string
747
     */
748 4
    public function getBotUsername()
749
    {
750 4
        return $this->bot_username;
751
    }
752
753
    /**
754
     * Get Bot Id
755
     *
756
     * @return string
757
     */
758
    public function getBotId()
759
    {
760
        return $this->bot_id;
761
    }
762
763
    /**
764
     * Get Version
765
     *
766
     * @return string
767
     */
768
    public function getVersion()
769
    {
770
        return self::VERSION;
771
    }
772
773
    /**
774
     * Set Webhook for bot
775
     *
776
     * @param string $url
777
     * @param array $parameters Optional parameters.
778
     *
779
     * @return \Longman\TelegramBot\Http\Response
780
     * @throws \Longman\TelegramBot\Exception\TelegramException
781
     */
782
    public function setWebhook($url, array $parameters = [])
783
    {
784
        if (empty($url)) {
785
            throw new TelegramException('Hook url is empty!');
786
        }
787
788
        $parameters = array_intersect_key($parameters, array_flip([
789
            'certificate',
790
            'max_connections',
791
            'allowed_updates',
792
        ]));
793
        $parameters['url'] = $url;
794
795
        // If the certificate is passed as a path, encode and add the file to the data array.
796
        if (! empty($parameters['certificate']) && is_string($parameters['certificate'])) {
797
            $parameters['certificate'] = Client::encodeFile($parameters['certificate']);
798
        }
799
800
        $result = Client::setWebhook($parameters);
801
802 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...
803
            throw new TelegramException(
804
                'Webhook was not set! Error: ' . $result->getErrorCode() . ' ' . $result->getDescription()
805
            );
806
        }
807
808
        return $result;
809
    }
810
811
    /**
812
     * Delete any assigned webhook
813
     *
814
     * @return mixed
815
     * @throws \Longman\TelegramBot\Exception\TelegramException
816
     */
817
    public function deleteWebhook()
818
    {
819
        $result = Client::deleteWebhook();
820
821 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...
822
            throw new TelegramException(
823
                'Webhook was not deleted! Error: ' . $result->getErrorCode() . ' ' . $result->getDescription()
824
            );
825
        }
826
827
        return $result;
828
    }
829
830
    /**
831
     * Replace function `ucwords` for UTF-8 characters in the class definition and commands
832
     *
833
     * @param string $str
834
     * @param string $encoding (default = 'UTF-8')
835
     *
836
     * @return string
837
     */
838 3
    protected function ucwordsUnicode($str, $encoding = 'UTF-8')
839
    {
840 3
        return mb_convert_case($str, MB_CASE_TITLE, $encoding);
841
    }
842
843
    /**
844
     * Replace function `ucfirst` for UTF-8 characters in the class definition and commands
845
     *
846
     * @param string $str
847
     * @param string $encoding (default = 'UTF-8')
848
     *
849
     * @return string
850
     */
851 3
    protected function ucfirstUnicode($str, $encoding = 'UTF-8')
852
    {
853 3
        return mb_strtoupper(mb_substr($str, 0, 1, $encoding), $encoding)
854 3
            . mb_strtolower(mb_substr($str, 1, mb_strlen($str), $encoding), $encoding);
855
    }
856
857
    /**
858
     * Enable Botan.io integration
859
     *
860
     * @param  string $token
861
     * @param  array $options
862
     *
863
     * @return \Longman\TelegramBot\Telegram
864
     * @throws \Longman\TelegramBot\Exception\TelegramException
865
     */
866
    public function enableBotan($token, array $options = [])
867
    {
868
        Botan::initializeBotan($token, $options);
869
        Botan::setEnabled(true);
870
871
        return $this;
872
    }
873
874
    /**
875
     * Enable requests limiter
876
     *
877
     * @param  array $options
878
     *
879
     * @return \Longman\TelegramBot\Telegram
880
     */
881
    public function enableLimiter(array $options = [])
882
    {
883
        Client::setLimiter(true, $options);
884
885
        return $this;
886
    }
887
888
    /**
889
     * Run provided commands
890
     *
891
     * @param array $commands
892
     *
893
     * @throws TelegramException
894
     */
895
    public function runCommands($commands)
896
    {
897
        if (! is_array($commands) || empty($commands)) {
898
            throw new TelegramException('No command(s) provided!');
899
        }
900
901
        $this->run_commands = true;
902
        Botan::setEnabled(false);   // Force disable Botan.io integration, we don't want to track self-executed commands!
903
904
        $result = Client::getMe();
905
906
        if ($result->isOk()) {
907
            $result = $result->getResult();
908
909
            $bot_id = $result->getId();
0 ignored issues
show
Bug introduced by
The method getId cannot be called on $result (of type array).

Methods can only be called on objects. This check looks for methods being called on variables that have been inferred to never be objects.

Loading history...
910
            $bot_name = $result->getFirstName();
0 ignored issues
show
Bug introduced by
The method getFirstName cannot be called on $result (of type array).

Methods can only be called on objects. This check looks for methods being called on variables that have been inferred to never be objects.

Loading history...
911
            $bot_username = $result->getUsername();
0 ignored issues
show
Bug introduced by
The method getUsername cannot be called on $result (of type array).

Methods can only be called on objects. This check looks for methods being called on variables that have been inferred to never be objects.

Loading history...
912
        } else {
913
            $bot_id = $this->getBotId();
914
            $bot_name = $this->getBotUsername();
915
            $bot_username = $this->getBotUsername();
916
        }
917
918
        $this->enableAdmin($bot_id);    // Give bot access to admin commands
919
        $this->getCommandsList();       // Load full commands list
920
921
        foreach ($commands as $command) {
922
            $this->update = new Update(
923
                [
924
                    'update_id' => 0,
925
                    'message'   => [
926
                        'message_id' => 0,
927
                        'from'       => [
928
                            'id'         => $bot_id,
929
                            'first_name' => $bot_name,
930
                            'username'   => $bot_username,
931
                        ],
932
                        'date'       => time(),
933
                        'chat'       => [
934
                            'id'   => $bot_id,
935
                            'type' => 'private',
936
                        ],
937
                        'text'       => $command,
938
                    ],
939
                ]
940
            );
941
942
            $this->executeCommand($this->update->getMessage()->getCommand());
943
        }
944
    }
945
946
    /**
947
     * Is this session initiated by runCommands()
948
     *
949
     * @return bool
950
     */
951
    public function isRunCommands()
952
    {
953
        return $this->run_commands;
954
    }
955
956
    /**
957
     * Switch to enable running getUpdates without a database
958
     *
959
     * @param bool $enable
960
     */
961
    public function useGetUpdatesWithoutDatabase($enable = true)
962
    {
963
        $this->getupdates_without_database = $enable;
964
    }
965
966
    /**
967
     * Return last update id
968
     *
969
     * @return int
970
     */
971
    public function getLastUpdateId()
972
    {
973
        return $this->last_update_id;
974
    }
975
}
976