DB::selectChats()   F
last analyzed

Complexity

Conditions 19
Paths 4754

Size

Total Lines 92
Code Lines 60

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 380

Importance

Changes 0
Metric Value
c 0
b 0
f 0
dl 0
loc 92
ccs 0
cts 51
cp 0
rs 2
cc 19
eloc 60
nc 4754
nop 7
crap 380

How to fix   Long Method    Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
/**
3
 * This file is part of the TelegramBot package.
4
 *
5
 * (c) Avtandil Kikabidze aka LONGMAN <[email protected]>
6
 *
7
 * For the full copyright and license information, please view the LICENSE
8
 * file that was distributed with this source code.
9
 * Written by Marco Boretto <[email protected]>
10
 */
11
12
namespace Longman\TelegramBot;
13
14
use Longman\TelegramBot\Entities\CallbackQuery;
15
use Longman\TelegramBot\Entities\Chat;
16
use Longman\TelegramBot\Entities\ChosenInlineResult;
17
use Longman\TelegramBot\Entities\InlineQuery;
18
use Longman\TelegramBot\Entities\Message;
19
use Longman\TelegramBot\Entities\ReplyToMessage;
20
use Longman\TelegramBot\Entities\Update;
21
use Longman\TelegramBot\Entities\User;
22
use Longman\TelegramBot\Exception\TelegramException;
23
use PDO;
24
use PDOException;
25
26
class DB
27
{
28
    /**
29
     * MySQL credentials
30
     *
31
     * @var array
32
     */
33
    static protected $mysql_credentials = [];
34
35
    /**
36
     * PDO object
37
     *
38
     * @var PDO
39
     */
40
    static protected $pdo;
41
42
    /**
43
     * Table prefix
44
     *
45
     * @var string
46
     */
47
    static protected $table_prefix;
48
49
    /**
50
     * Telegram class object
51
     *
52
     * @var \Longman\TelegramBot\Telegram
53
     */
54
    static protected $telegram;
55
56
    /**
57
     * Initialize
58
     *
59
     * @param array                         $credentials  Database connection details
60
     * @param \Longman\TelegramBot\Telegram $telegram     Telegram object to connect with this object
61
     * @param string                        $table_prefix Table prefix
62
     * @param string                        $encoding     Database character encoding
63
     *
64
     * @return PDO PDO database object
65
     * @throws \Longman\TelegramBot\Exception\TelegramException
66
     */
67 9
    public static function initialize(
68
        array $credentials,
69
        Telegram $telegram,
70
        $table_prefix = null,
71
        $encoding = 'utf8mb4'
72
    ) {
73 9
        if (empty($credentials)) {
74
            throw new TelegramException('MySQL credentials not provided!');
75
        }
76
77 9
        $dsn     = 'mysql:host=' . $credentials['host'] . ';dbname=' . $credentials['database'];
78 9
        $options = [PDO::MYSQL_ATTR_INIT_COMMAND => 'SET NAMES ' . $encoding];
79
        try {
80 9
            $pdo = new PDO($dsn, $credentials['user'], $credentials['password'], $options);
81 9
            $pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_WARNING);
82
        } catch (PDOException $e) {
83
            throw new TelegramException($e->getMessage());
84
        }
85
86 9
        self::$pdo               = $pdo;
87 9
        self::$telegram          = $telegram;
88 9
        self::$mysql_credentials = $credentials;
89 9
        self::$table_prefix      = $table_prefix;
90
91 9
        self::defineTables();
92
93 9
        return self::$pdo;
94
    }
95
96
    /**
97
     * External Initialize
98
     *
99
     * Let you use the class with an external already existing Pdo Mysql connection.
100
     *
101
     * @param PDO                           $external_pdo_connection PDO database object
102
     * @param \Longman\TelegramBot\Telegram $telegram                Telegram object to connect with this object
103
     * @param string                        $table_prefix            Table prefix
104
     *
105
     * @return PDO PDO database object
106
     * @throws \Longman\TelegramBot\Exception\TelegramException
107
     */
108
    public static function externalInitialize(
109
        $external_pdo_connection,
110
        Telegram $telegram,
111
        $table_prefix = null
112
    ) {
113
        if ($external_pdo_connection === null) {
114
            throw new TelegramException('MySQL external connection not provided!');
115
        }
116
117
        self::$pdo               = $external_pdo_connection;
118
        self::$telegram          = $telegram;
119
        self::$mysql_credentials = [];
120
        self::$table_prefix      = $table_prefix;
121
122
        self::defineTables();
123
124
        return self::$pdo;
125
    }
126
127
    /**
128
     * Define all the tables with the proper prefix
129
     */
130 9
    protected static function defineTables()
131
    {
132
        $tables = [
133 9
            'callback_query',
134
            'chat',
135
            'chosen_inline_result',
136
            'edited_message',
137
            'inline_query',
138
            'message',
139
            'request_limiter',
140
            'telegram_update',
141
            'user',
142
            'user_chat',
143
        ];
144 9
        foreach ($tables as $table) {
145 9
            $table_name = 'TB_' . strtoupper($table);
146 9
            if (!defined($table_name)) {
147 9
                define($table_name, self::$table_prefix . $table);
148
            }
149
        }
150 9
    }
151
152
    /**
153
     * Check if database connection has been created
154
     *
155
     * @return bool
156
     */
157 9
    public static function isDbConnected()
158
    {
159 9
        return self::$pdo !== null;
160
    }
161
162
    /**
163
     * Get the PDO object of the connected database
164
     *
165
     * @return \PDO
166
     */
167
    public static function getPdo()
168
    {
169
        return self::$pdo;
170
    }
171
172
    /**
173
     * Fetch update(s) from DB
174
     *
175
     * @param int $limit Limit the number of updates to fetch
176
     *
177
     * @return array|bool Fetched data or false if not connected
178
     * @throws \Longman\TelegramBot\Exception\TelegramException
179
     */
180 View Code Duplication
    public static function selectTelegramUpdate($limit = 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...
181
    {
182
        if (!self::isDbConnected()) {
183
            return false;
184
        }
185
186
        try {
187
            $sql = '
188
                SELECT `id`
189
                FROM `' . TB_TELEGRAM_UPDATE . '`
190
                ORDER BY `id` DESC
191
            ';
192
193
            if ($limit !== null) {
194
                $sql .= 'LIMIT :limit';
195
            }
196
197
            $sth = self::$pdo->prepare($sql);
198
            $sth->bindParam(':limit', $limit, PDO::PARAM_INT);
199
            $sth->execute();
200
201
            return $sth->fetchAll(PDO::FETCH_ASSOC);
202
        } catch (PDOException $e) {
203
            throw new TelegramException($e->getMessage());
204
        }
205
    }
206
207
    /**
208
     * Fetch message(s) from DB
209
     *
210
     * @param int $limit Limit the number of messages to fetch
211
     *
212
     * @return array|bool Fetched data or false if not connected
213
     * @throws \Longman\TelegramBot\Exception\TelegramException
214
     */
215 View Code Duplication
    public static function selectMessages($limit = 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...
216
    {
217
        if (!self::isDbConnected()) {
218
            return false;
219
        }
220
221
        try {
222
            $sql = '
223
                SELECT *
224
                FROM `' . TB_MESSAGE . '`
225
                WHERE `update_id` != 0
226
                ORDER BY `message_id` DESC
227
            ';
228
229
            if ($limit !== null) {
230
                $sql .= 'LIMIT :limit';
231
            }
232
233
            $sth = self::$pdo->prepare($sql);
234
            $sth->bindParam(':limit', $limit, PDO::PARAM_INT);
235
            $sth->execute();
236
237
            return $sth->fetchAll(PDO::FETCH_ASSOC);
238
        } catch (PDOException $e) {
239
            throw new TelegramException($e->getMessage());
240
        }
241
    }
242
243
    /**
244
     * Convert from unix timestamp to timestamp
245
     *
246
     * @param int $time Unix timestamp (if null, current timestamp is used)
247
     *
248
     * @return string
249
     */
250 7
    protected static function getTimestamp($time = null)
251
    {
252 7
        if ($time === null) {
253 6
            $time = time();
254
        }
255
256 7
        return date('Y-m-d H:i:s', $time);
257
    }
258
259
    /**
260
     * Convert array of Entity items to a JSON array
261
     *
262
     * @todo Find a better way, as json_* functions are very heavy
263
     *
264
     * @param array|null $entities
265
     * @param mixed      $default
266
     *
267
     * @return mixed
268
     */
269 6
    public static function entitiesArrayToJson($entities, $default = null)
270
    {
271 6
        if (!is_array($entities)) {
272 6
            return $default;
273
        }
274
275
        //Convert each Entity item into an object based on its JSON reflection
276
        $json_entities = array_map(function ($entity) {
277
            return json_decode($entity, true);
278
        }, $entities);
279
280
        return json_encode($json_entities);
281
    }
282
283
    /**
284
     * Insert entry to telegram_update table
285
     *
286
     * @param int $id
287
     * @param int $chat_id
288
     * @param int $message_id
289
     * @param int $inline_query_id
290
     * @param int $chosen_inline_result_id
291
     * @param int $callback_query_id
292
     * @param int $edited_message_id
293
     *
294
     * @return bool If the insert was successful
295
     * @throws \Longman\TelegramBot\Exception\TelegramException
296
     */
297
    public static function insertTelegramUpdate(
298
        $id,
299
        $chat_id,
300
        $message_id,
301
        $inline_query_id,
302
        $chosen_inline_result_id,
303
        $callback_query_id,
304
        $edited_message_id
305
    ) {
306
        if ($message_id === null && $inline_query_id === null && $chosen_inline_result_id === null && $callback_query_id === null && $edited_message_id === null) {
307
            throw new TelegramException('message_id, inline_query_id, chosen_inline_result_id, callback_query_id, edited_message_id are all null');
308
        }
309
310
        if (!self::isDbConnected()) {
311
            return false;
312
        }
313
314
        try {
315
            $sth = self::$pdo->prepare('
316
                INSERT IGNORE INTO `' . TB_TELEGRAM_UPDATE . '`
317
                (`id`, `chat_id`, `message_id`, `inline_query_id`, `chosen_inline_result_id`, `callback_query_id`, `edited_message_id`)
318
                VALUES
319
                (:id, :chat_id, :message_id, :inline_query_id, :chosen_inline_result_id, :callback_query_id, :edited_message_id)
320
            ');
321
322
            $sth->bindParam(':id', $id, PDO::PARAM_INT);
323
            $sth->bindParam(':chat_id', $chat_id, PDO::PARAM_INT);
324
            $sth->bindParam(':message_id', $message_id, PDO::PARAM_INT);
325
            $sth->bindParam(':inline_query_id', $inline_query_id, PDO::PARAM_INT);
326
            $sth->bindParam(':chosen_inline_result_id', $chosen_inline_result_id, PDO::PARAM_INT);
327
            $sth->bindParam(':callback_query_id', $callback_query_id, PDO::PARAM_INT);
328
            $sth->bindParam(':edited_message_id', $edited_message_id, PDO::PARAM_INT);
329
330
            return $sth->execute();
331
        } catch (PDOException $e) {
332
            throw new TelegramException($e->getMessage());
333
        }
334
    }
335
336
    /**
337
     * Insert users and save their connection to chats
338
     *
339
     * @param  \Longman\TelegramBot\Entities\User $user
340
     * @param  string                             $date
341
     * @param  \Longman\TelegramBot\Entities\Chat $chat
342
     *
343
     * @return bool If the insert was successful
344
     * @throws \Longman\TelegramBot\Exception\TelegramException
345
     */
346 6
    public static function insertUser(User $user, $date, Chat $chat = null)
347
    {
348 6
        if (!self::isDbConnected()) {
349
            return false;
350
        }
351
352 6
        $user_id    = $user->getId();
353 6
        $username   = $user->getUsername();
354 6
        $first_name = $user->getFirstName();
355 6
        $last_name  = $user->getLastName();
356
357
        try {
358 6
            $sth = self::$pdo->prepare('
359 6
                INSERT INTO `' . TB_USER . '`
360
                (`id`, `username`, `first_name`, `last_name`, `created_at`, `updated_at`)
361
                VALUES
362
                (:id, :username, :first_name, :last_name, :date, :date)
363
                ON DUPLICATE KEY UPDATE
364
                    `username`   = :username,
365
                    `first_name` = :first_name,
366
                    `last_name`  = :last_name,
367
                    `updated_at` = :date
368 6
            ');
369
370 6
            $sth->bindParam(':id', $user_id, PDO::PARAM_INT);
371 6
            $sth->bindParam(':username', $username, PDO::PARAM_STR, 255);
372 6
            $sth->bindParam(':first_name', $first_name, PDO::PARAM_STR, 255);
373 6
            $sth->bindParam(':last_name', $last_name, PDO::PARAM_STR, 255);
374 6
            $sth->bindParam(':date', $date, PDO::PARAM_STR);
375
376 6
            $status = $sth->execute();
377
        } catch (PDOException $e) {
378
            throw new TelegramException($e->getMessage());
379
        }
380
381
        //insert also the relationship to the chat into user_chat table
382 6
        if ($chat instanceof Chat) {
383 6
            $chat_id = $chat->getId();
384
            try {
385 6
                $sth = self::$pdo->prepare('
386 6
                    INSERT IGNORE INTO `' . TB_USER_CHAT . '`
387
                    (`user_id`, `chat_id`)
388
                    VALUES
389
                    (:user_id, :chat_id)
390 6
                ');
391
392 6
                $sth->bindParam(':user_id', $user_id, PDO::PARAM_INT);
393 6
                $sth->bindParam(':chat_id', $chat_id, PDO::PARAM_INT);
394
395 6
                $status = $sth->execute();
396
            } catch (PDOException $e) {
397
                throw new TelegramException($e->getMessage());
398
            }
399
        }
400
401 6
        return $status;
402
    }
403
404
    /**
405
     * Insert chat
406
     *
407
     * @param  \Longman\TelegramBot\Entities\Chat $chat
408
     * @param  string                             $date
409
     * @param  int                                $migrate_to_chat_id
410
     *
411
     * @return bool If the insert was successful
412
     * @throws \Longman\TelegramBot\Exception\TelegramException
413
     */
414 6
    public static function insertChat(Chat $chat, $date, $migrate_to_chat_id = null)
415
    {
416 6
        if (!self::isDbConnected()) {
417
            return false;
418
        }
419
420 6
        $chat_id                             = $chat->getId();
421 6
        $chat_title                          = $chat->getTitle();
422 6
        $chat_username                       = $chat->getUsername();
423 6
        $chat_type                           = $chat->getType();
424 6
        $chat_all_members_are_administrators = $chat->getAllMembersAreAdministrators();
425
426
        try {
427 6
            $sth = self::$pdo->prepare('
428 6
                INSERT IGNORE INTO `' . TB_CHAT . '`
429
                (`id`, `type`, `title`, `username`, `all_members_are_administrators`, `created_at` ,`updated_at`, `old_id`)
430
                VALUES
431
                (:id, :type, :title, :username, :all_members_are_administrators, :date, :date, :oldid)
432
                ON DUPLICATE KEY UPDATE
433
                    `type`                           = :type,
434
                    `title`                          = :title,
435
                    `username`                       = :username,
436
                    `all_members_are_administrators` = :all_members_are_administrators,
437
                    `updated_at`                     = :date
438 6
            ');
439
440 6
            if ($migrate_to_chat_id) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $migrate_to_chat_id of type integer|null is loosely compared to true; this is ambiguous if the integer can be zero. You might want to explicitly use !== null instead.

In PHP, under loose comparison (like ==, or !=, or switch conditions), values of different types might be equal.

For integer values, zero is a special case, in particular the following results might be unexpected:

0   == false // true
0   == null  // true
123 == false // false
123 == null  // false

// It is often better to use strict comparison
0 === false // false
0 === null  // false
Loading history...
441
                $chat_type = 'supergroup';
442
443
                $sth->bindParam(':id', $migrate_to_chat_id, PDO::PARAM_INT);
444
                $sth->bindParam(':oldid', $chat_id, PDO::PARAM_INT);
445
            } else {
446 6
                $sth->bindParam(':id', $chat_id, PDO::PARAM_INT);
447 6
                $sth->bindParam(':oldid', $migrate_to_chat_id, PDO::PARAM_INT);
448
            }
449
450 6
            $sth->bindParam(':type', $chat_type, PDO::PARAM_INT);
451 6
            $sth->bindParam(':title', $chat_title, PDO::PARAM_STR, 255);
452 6
            $sth->bindParam(':username', $chat_username, PDO::PARAM_STR, 255);
453 6
            $sth->bindParam(':all_members_are_administrators', $chat_all_members_are_administrators, PDO::PARAM_INT);
454 6
            $sth->bindParam(':date', $date, PDO::PARAM_STR);
455
456 6
            return $sth->execute();
457
        } catch (PDOException $e) {
458
            throw new TelegramException($e->getMessage());
459
        }
460
    }
461
462
    /**
463
     * Insert request into database
464
     *
465
     * @todo self::$pdo->lastInsertId() - unsafe usage if expected previous insert fails?
466
     *
467
     * @param \Longman\TelegramBot\Entities\Update $update
468
     *
469
     * @return bool
470
     * @throws \Longman\TelegramBot\Exception\TelegramException
471
     */
472
    public static function insertRequest(Update $update)
473
    {
474
        $update_id   = $update->getUpdateId();
475
        $update_type = $update->getUpdateType();
476
477
        if ($update_type === 'message') {
478
            $message = $update->getMessage();
479
480 View Code Duplication
            if (self::insertMessageRequest($message)) {
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...
481
                $message_id = $message->getMessageId();
482
                $chat_id    = $message->getChat()->getId();
483
484
                return self::insertTelegramUpdate($update_id, $chat_id, $message_id, null, null, null, null);
485
            }
486 View Code Duplication
        } elseif ($update_type === 'edited_message') {
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...
487
            $edited_message = $update->getEditedMessage();
488
489
            if (self::insertEditedMessageRequest($edited_message)) {
490
                $chat_id                 = $edited_message->getChat()->getId();
491
                $edited_message_local_id = self::$pdo->lastInsertId();
492
493
                return self::insertTelegramUpdate(
494
                    $update_id,
495
                    $chat_id,
496
                    null,
497
                    null,
498
                    null,
499
                    null,
500
                    $edited_message_local_id
501
                );
502
            }
503
        } elseif ($update_type === 'channel_post') {
504
            $channel_post = $update->getChannelPost();
505
506 View Code Duplication
            if (self::insertMessageRequest($channel_post)) {
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...
507
                $message_id = $channel_post->getMessageId();
508
                $chat_id    = $channel_post->getChat()->getId();
509
510
                return self::insertTelegramUpdate($update_id, $chat_id, $message_id, null, null, null, null);
511
            }
512 View Code Duplication
        } elseif ($update_type === 'edited_channel_post') {
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...
513
            $edited_channel_post = $update->getEditedChannelPost();
514
515
            if (self::insertEditedMessageRequest($edited_channel_post)) {
516
                $chat_id                      = $edited_channel_post->getChat()->getId();
517
                $edited_channel_post_local_id = self::$pdo->lastInsertId();
518
519
                return self::insertTelegramUpdate(
520
                    $update_id,
521
                    $chat_id,
522
                    null,
523
                    null,
524
                    null,
525
                    null,
526
                    $edited_channel_post_local_id
527
                );
528
            }
529
        } elseif ($update_type === 'inline_query') {
530
            $inline_query = $update->getInlineQuery();
531
532
            if (self::insertInlineQueryRequest($inline_query)) {
533
                $inline_query_id = $inline_query->getId();
534
535
                return self::insertTelegramUpdate($update_id, null, null, $inline_query_id, null, null, null);
536
            }
537
        } elseif ($update_type === 'chosen_inline_result') {
538
            $chosen_inline_result = $update->getChosenInlineResult();
539
540
            if (self::insertChosenInlineResultRequest($chosen_inline_result)) {
541
                $chosen_inline_result_local_id = self::$pdo->lastInsertId();
542
543
                return self::insertTelegramUpdate(
544
                    $update_id,
545
                    null,
546
                    null,
547
                    null,
548
                    $chosen_inline_result_local_id,
549
                    null,
550
                    null
551
                );
552
            }
553
        } elseif ($update_type === 'callback_query') {
554
            $callback_query = $update->getCallbackQuery();
555
556
            if (self::insertCallbackQueryRequest($callback_query)) {
557
                $callback_query_id = $callback_query->getId();
558
559
                return self::insertTelegramUpdate($update_id, null, null, null, null, $callback_query_id, null);
560
            }
561
        }
562
563
        return false;
564
    }
565
566
    /**
567
     * Insert inline query request into database
568
     *
569
     * @param \Longman\TelegramBot\Entities\InlineQuery $inline_query
570
     *
571
     * @return bool If the insert was successful
572
     * @throws \Longman\TelegramBot\Exception\TelegramException
573
     */
574 View Code Duplication
    public static function insertInlineQueryRequest(InlineQuery $inline_query)
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...
575
    {
576
        if (!self::isDbConnected()) {
577
            return false;
578
        }
579
580
        try {
581
            $sth = self::$pdo->prepare('
582
                INSERT IGNORE INTO `' . TB_INLINE_QUERY . '`
583
                (`id`, `user_id`, `location`, `query`, `offset`, `created_at`)
584
                VALUES
585
                (:inline_query_id, :user_id, :location, :query, :param_offset, :created_at)
586
            ');
587
588
            $date            = self::getTimestamp();
589
            $inline_query_id = $inline_query->getId();
590
            $from            = $inline_query->getFrom();
591
            $user_id         = null;
592
            if ($from instanceof User) {
593
                $user_id = $from->getId();
594
                self::insertUser($from, $date);
595
            }
596
597
            $location = $inline_query->getLocation();
598
            $query    = $inline_query->getQuery();
599
            $offset   = $inline_query->getOffset();
600
601
            $sth->bindParam(':inline_query_id', $inline_query_id, PDO::PARAM_INT);
602
            $sth->bindParam(':user_id', $user_id, PDO::PARAM_INT);
603
            $sth->bindParam(':location', $location, PDO::PARAM_STR);
604
            $sth->bindParam(':query', $query, PDO::PARAM_STR);
605
            $sth->bindParam(':param_offset', $offset, PDO::PARAM_STR);
606
            $sth->bindParam(':created_at', $date, PDO::PARAM_STR);
607
608
            return $sth->execute();
609
        } catch (PDOException $e) {
610
            throw new TelegramException($e->getMessage());
611
        }
612
    }
613
614
    /**
615
     * Insert chosen inline result request into database
616
     *
617
     * @param \Longman\TelegramBot\Entities\ChosenInlineResult $chosen_inline_result
618
     *
619
     * @return bool If the insert was successful
620
     * @throws \Longman\TelegramBot\Exception\TelegramException
621
     */
622 View Code Duplication
    public static function insertChosenInlineResultRequest(ChosenInlineResult $chosen_inline_result)
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...
623
    {
624
        if (!self::isDbConnected()) {
625
            return false;
626
        }
627
628
        try {
629
            $sth = self::$pdo->prepare('
630
                INSERT INTO `' . TB_CHOSEN_INLINE_RESULT . '`
631
                (`result_id`, `user_id`, `location`, `inline_message_id`, `query`, `created_at`)
632
                VALUES
633
                (:result_id, :user_id, :location, :inline_message_id, :query, :created_at)
634
            ');
635
636
            $date      = self::getTimestamp();
637
            $result_id = $chosen_inline_result->getResultId();
638
            $from      = $chosen_inline_result->getFrom();
639
            $user_id   = null;
640
            if ($from instanceof User) {
641
                $user_id = $from->getId();
642
                self::insertUser($from, $date);
643
            }
644
645
            $location          = $chosen_inline_result->getLocation();
646
            $inline_message_id = $chosen_inline_result->getInlineMessageId();
647
            $query             = $chosen_inline_result->getQuery();
648
649
            $sth->bindParam(':result_id', $result_id, PDO::PARAM_STR);
650
            $sth->bindParam(':user_id', $user_id, PDO::PARAM_INT);
651
            $sth->bindParam(':location', $location, PDO::PARAM_STR);
652
            $sth->bindParam(':inline_message_id', $inline_message_id, PDO::PARAM_STR);
653
            $sth->bindParam(':query', $query, PDO::PARAM_STR);
654
            $sth->bindParam(':created_at', $date, PDO::PARAM_STR);
655
656
            return $sth->execute();
657
        } catch (PDOException $e) {
658
            throw new TelegramException($e->getMessage());
659
        }
660
    }
661
662
    /**
663
     * Insert callback query request into database
664
     *
665
     * @param \Longman\TelegramBot\Entities\CallbackQuery $callback_query
666
     *
667
     * @return bool If the insert was successful
668
     * @throws \Longman\TelegramBot\Exception\TelegramException
669
     */
670
    public static function insertCallbackQueryRequest(CallbackQuery $callback_query)
671
    {
672
        if (!self::isDbConnected()) {
673
            return false;
674
        }
675
676
        try {
677
            $sth = self::$pdo->prepare('
678
                INSERT IGNORE INTO `' . TB_CALLBACK_QUERY . '`
679
                (`id`, `user_id`, `chat_id`, `message_id`, `inline_message_id`, `data`, `created_at`)
680
                VALUES
681
                (:callback_query_id, :user_id, :chat_id, :message_id, :inline_message_id, :data, :created_at)
682
            ');
683
684
            $date              = self::getTimestamp();
685
            $callback_query_id = $callback_query->getId();
686
            $from              = $callback_query->getFrom();
687
            $user_id           = null;
688
            if ($from instanceof User) {
689
                $user_id = $from->getId();
690
                self::insertUser($from, $date);
691
            }
692
693
            $message    = $callback_query->getMessage();
694
            $chat_id    = null;
695
            $message_id = null;
696
            if ($message instanceof Message) {
697
                $chat_id    = $message->getChat()->getId();
698
                $message_id = $message->getMessageId();
699
700
                $is_message = self::$pdo->query('
701
                    SELECT *
702
                    FROM `' . TB_MESSAGE . '`
703
                    WHERE `id` = ' . $message_id . '
704
                      AND `chat_id` = ' . $chat_id . '
705
                    LIMIT 1
706
                ')->rowCount();
707
708
                if ($is_message) {
709
                    self::insertEditedMessageRequest($message);
710
                } else {
711
                    self::insertMessageRequest($message);
712
                }
713
            }
714
715
            $inline_message_id = $callback_query->getInlineMessageId();
716
            $data              = $callback_query->getData();
717
718
            $sth->bindParam(':callback_query_id', $callback_query_id, PDO::PARAM_INT);
719
            $sth->bindParam(':user_id', $user_id, PDO::PARAM_INT);
720
            $sth->bindParam(':chat_id', $chat_id, PDO::PARAM_INT);
721
            $sth->bindParam(':message_id', $message_id, PDO::PARAM_INT);
722
            $sth->bindParam(':inline_message_id', $inline_message_id, PDO::PARAM_STR);
723
            $sth->bindParam(':data', $data, PDO::PARAM_STR);
724
            $sth->bindParam(':created_at', $date, PDO::PARAM_STR);
725
726
            return $sth->execute();
727
        } catch (PDOException $e) {
728
            throw new TelegramException($e->getMessage());
729
        }
730
    }
731
732
    /**
733
     * Insert Message request in db
734
     *
735
     * @param \Longman\TelegramBot\Entities\Message $message
736
     *
737
     * @return bool If the insert was successful
738
     * @throws \Longman\TelegramBot\Exception\TelegramException
739
     */
740 6
    public static function insertMessageRequest(Message $message)
741
    {
742 6
        if (!self::isDbConnected()) {
743
            return false;
744
        }
745
746 6
        $from = $message->getFrom();
747 6
        $chat = $message->getChat();
748
749 6
        $chat_id = $chat->getId();
750
751 6
        $date = self::getTimestamp($message->getDate());
752
753 6
        $forward_from            = $message->getForwardFrom();
754 6
        $forward_from_chat       = $message->getForwardFromChat();
755 6
        $forward_from_message_id = $message->getForwardFromMessageId();
756 6
        $photo                   = self::entitiesArrayToJson($message->getPhoto(), '');
757 6
        $entities                = self::entitiesArrayToJson($message->getEntities(), null);
758 6
        $new_chat_member         = $message->getNewChatMember();
759 6
        $new_chat_photo          = self::entitiesArrayToJson($message->getNewChatPhoto(), '');
760 6
        $left_chat_member        = $message->getLeftChatMember();
761 6
        $migrate_to_chat_id      = $message->getMigrateToChatId();
762
763
        //Insert chat, update chat id in case it migrated
764 6
        self::insertChat($chat, $date, $migrate_to_chat_id);
765
766
        //Insert user and the relation with the chat
767 6
        if (is_object($from)) {
768 6
            self::insertUser($from, $date, $chat);
769
        }
770
771
        //Insert the forwarded message user in users table
772 6
        if ($forward_from instanceof User) {
773
            $forward_date = self::getTimestamp($message->getForwardDate());
774
            self::insertUser($forward_from, $forward_date);
775
            $forward_from = $forward_from->getId();
776
        }
777
778 6
        if ($forward_from_chat instanceof Chat) {
779
            $forward_date = self::getTimestamp($message->getForwardDate());
780
            self::insertChat($forward_from_chat, $forward_date);
781
            $forward_from_chat = $forward_from_chat->getId();
782
        }
783
784
        //New and left chat member
785 6
        if ($new_chat_member instanceof User) {
786
            //Insert the new chat user
787
            self::insertUser($new_chat_member, $date, $chat);
788
            $new_chat_member = $new_chat_member->getId();
789
        } elseif ($left_chat_member instanceof User) {
790
            //Insert the left chat user
791
            self::insertUser($left_chat_member, $date, $chat);
792
            $left_chat_member = $left_chat_member->getId();
793
        }
794
795
        try {
796 6
            $sth = self::$pdo->prepare('
797 6
                INSERT IGNORE INTO `' . TB_MESSAGE . '`
798
                (
799
                    `id`, `user_id`, `chat_id`, `date`, `forward_from`, `forward_from_chat`, `forward_from_message_id`,
800
                    `forward_date`, `reply_to_chat`, `reply_to_message`, `text`, `entities`, `audio`, `document`,
801
                    `photo`, `sticker`, `video`, `voice`, `caption`, `contact`,
802
                    `location`, `venue`, `new_chat_member`, `left_chat_member`,
803
                    `new_chat_title`,`new_chat_photo`, `delete_chat_photo`, `group_chat_created`,
804
                    `supergroup_chat_created`, `channel_chat_created`,
805
                    `migrate_from_chat_id`, `migrate_to_chat_id`, `pinned_message`
806
                ) VALUES (
807
                    :message_id, :user_id, :chat_id, :date, :forward_from, :forward_from_chat, :forward_from_message_id,
808
                    :forward_date, :reply_to_chat, :reply_to_message, :text, :entities, :audio, :document,
809
                    :photo, :sticker, :video, :voice, :caption, :contact,
810
                    :location, :venue, :new_chat_member, :left_chat_member,
811
                    :new_chat_title, :new_chat_photo, :delete_chat_photo, :group_chat_created,
812
                    :supergroup_chat_created, :channel_chat_created,
813
                    :migrate_from_chat_id, :migrate_to_chat_id, :pinned_message
814
                )
815 6
            ');
816
817 6
            $message_id = $message->getMessageId();
818
819 6
            if (is_object($from)) {
820 6
                $from_id = $from->getId();
821
            } else {
822
                $from_id = null;
823
            }
824
825 6
            $reply_to_message    = $message->getReplyToMessage();
826 6
            $reply_to_message_id = null;
827 6
            if ($reply_to_message instanceof ReplyToMessage) {
828
                $reply_to_message_id = $reply_to_message->getMessageId();
829
                // please notice that, as explained in the documentation, reply_to_message don't contain other
830
                // reply_to_message field so recursion deep is 1
831
                self::insertMessageRequest($reply_to_message);
832
            }
833
834 6
            $text                    = $message->getText();
835 6
            $audio                   = $message->getAudio();
836 6
            $document                = $message->getDocument();
837 6
            $sticker                 = $message->getSticker();
838 6
            $video                   = $message->getVideo();
839 6
            $voice                   = $message->getVoice();
840 6
            $caption                 = $message->getCaption();
841 6
            $contact                 = $message->getContact();
842 6
            $location                = $message->getLocation();
843 6
            $venue                   = $message->getVenue();
844 6
            $new_chat_title          = $message->getNewChatTitle();
845 6
            $delete_chat_photo       = $message->getDeleteChatPhoto();
846 6
            $group_chat_created      = $message->getGroupChatCreated();
847 6
            $supergroup_chat_created = $message->getSupergroupChatCreated();
848 6
            $channel_chat_created    = $message->getChannelChatCreated();
849 6
            $migrate_from_chat_id    = $message->getMigrateFromChatId();
850 6
            $migrate_to_chat_id      = $message->getMigrateToChatId();
851 6
            $pinned_message          = $message->getPinnedMessage();
852
853 6
            $sth->bindParam(':chat_id', $chat_id, PDO::PARAM_INT);
854 6
            $sth->bindParam(':message_id', $message_id, PDO::PARAM_INT);
855 6
            $sth->bindParam(':user_id', $from_id, PDO::PARAM_INT);
856 6
            $sth->bindParam(':date', $date, PDO::PARAM_STR);
857 6
            $sth->bindParam(':forward_from', $forward_from, PDO::PARAM_INT);
858 6
            $sth->bindParam(':forward_from_chat', $forward_from_chat, PDO::PARAM_INT);
859 6
            $sth->bindParam(':forward_from_message_id', $forward_from_message_id, PDO::PARAM_INT);
860 6
            $sth->bindParam(':forward_date', $forward_date, PDO::PARAM_STR);
861
862 6
            $reply_to_chat_id = null;
863 6
            if ($reply_to_message_id) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $reply_to_message_id of type integer|null is loosely compared to true; this is ambiguous if the integer can be zero. You might want to explicitly use !== null instead.

In PHP, under loose comparison (like ==, or !=, or switch conditions), values of different types might be equal.

For integer values, zero is a special case, in particular the following results might be unexpected:

0   == false // true
0   == null  // true
123 == false // false
123 == null  // false

// It is often better to use strict comparison
0 === false // false
0 === null  // false
Loading history...
864
                $reply_to_chat_id = $chat_id;
865
            }
866
867 6
            $sth->bindParam(':reply_to_chat', $reply_to_chat_id, PDO::PARAM_INT);
868 6
            $sth->bindParam(':reply_to_message', $reply_to_message_id, PDO::PARAM_INT);
869 6
            $sth->bindParam(':text', $text, PDO::PARAM_STR);
870 6
            $sth->bindParam(':entities', $entities, PDO::PARAM_STR);
871 6
            $sth->bindParam(':audio', $audio, PDO::PARAM_STR);
872 6
            $sth->bindParam(':document', $document, PDO::PARAM_STR);
873 6
            $sth->bindParam(':photo', $photo, PDO::PARAM_STR);
874 6
            $sth->bindParam(':sticker', $sticker, PDO::PARAM_STR);
875 6
            $sth->bindParam(':video', $video, PDO::PARAM_STR);
876 6
            $sth->bindParam(':voice', $voice, PDO::PARAM_STR);
877 6
            $sth->bindParam(':caption', $caption, PDO::PARAM_STR);
878 6
            $sth->bindParam(':contact', $contact, PDO::PARAM_STR);
879 6
            $sth->bindParam(':location', $location, PDO::PARAM_STR);
880 6
            $sth->bindParam(':venue', $venue, PDO::PARAM_STR);
881 6
            $sth->bindParam(':new_chat_member', $new_chat_member, PDO::PARAM_INT);
882 6
            $sth->bindParam(':left_chat_member', $left_chat_member, PDO::PARAM_INT);
883 6
            $sth->bindParam(':new_chat_title', $new_chat_title, PDO::PARAM_STR);
884 6
            $sth->bindParam(':new_chat_photo', $new_chat_photo, PDO::PARAM_STR);
885 6
            $sth->bindParam(':delete_chat_photo', $delete_chat_photo, PDO::PARAM_INT);
886 6
            $sth->bindParam(':group_chat_created', $group_chat_created, PDO::PARAM_INT);
887 6
            $sth->bindParam(':supergroup_chat_created', $supergroup_chat_created, PDO::PARAM_INT);
888 6
            $sth->bindParam(':channel_chat_created', $channel_chat_created, PDO::PARAM_INT);
889 6
            $sth->bindParam(':migrate_from_chat_id', $migrate_from_chat_id, PDO::PARAM_INT);
890 6
            $sth->bindParam(':migrate_to_chat_id', $migrate_to_chat_id, PDO::PARAM_INT);
891 6
            $sth->bindParam(':pinned_message', $pinned_message, PDO::PARAM_STR);
892
893 6
            return $sth->execute();
894
        } catch (PDOException $e) {
895
            throw new TelegramException($e->getMessage());
896
        }
897
    }
898
899
    /**
900
     * Insert Edited Message request in db
901
     *
902
     * @param \Longman\TelegramBot\Entities\Message $edited_message
903
     *
904
     * @return bool If the insert was successful
905
     * @throws \Longman\TelegramBot\Exception\TelegramException
906
     */
907
    public static function insertEditedMessageRequest(Message $edited_message)
908
    {
909
        if (!self::isDbConnected()) {
910
            return false;
911
        }
912
913
        $from = $edited_message->getFrom();
914
        $chat = $edited_message->getChat();
915
916
        $chat_id = $chat->getId();
917
918
        $edit_date = self::getTimestamp($edited_message->getEditDate());
919
920
        $entities = self::entitiesArrayToJson($edited_message->getEntities(), null);
921
922
        //Insert chat
923
        self::insertChat($chat, $edit_date);
924
925
        //Insert user and the relation with the chat
926
        if (is_object($from)) {
927
            self::insertUser($from, $edit_date, $chat);
928
        }
929
930
        try {
931
            $sth = self::$pdo->prepare('
932
                INSERT IGNORE INTO `' . TB_EDITED_MESSAGE . '`
933
                (`chat_id`, `message_id`, `user_id`, `edit_date`, `text`, `entities`, `caption`)
934
                VALUES
935
                (:chat_id, :message_id, :user_id, :date, :text, :entities, :caption)
936
            ');
937
938
            $message_id = $edited_message->getMessageId();
939
940
            if (is_object($from)) {
941
                $from_id = $from->getId();
942
            } else {
943
                $from_id = null;
944
            }
945
946
            $text    = $edited_message->getText();
947
            $caption = $edited_message->getCaption();
948
949
            $sth->bindParam(':chat_id', $chat_id, PDO::PARAM_INT);
950
            $sth->bindParam(':message_id', $message_id, PDO::PARAM_INT);
951
            $sth->bindParam(':user_id', $from_id, PDO::PARAM_INT);
952
            $sth->bindParam(':date', $edit_date, PDO::PARAM_STR);
953
            $sth->bindParam(':text', $text, PDO::PARAM_STR);
954
            $sth->bindParam(':entities', $entities, PDO::PARAM_STR);
955
            $sth->bindParam(':caption', $caption, PDO::PARAM_STR);
956
957
            return $sth->execute();
958
        } catch (PDOException $e) {
959
            throw new TelegramException($e->getMessage());
960
        }
961
    }
962
963
    /**
964
     * Select Group and/or single Chats
965
     *
966
     * @param bool   $select_groups
967
     * @param bool   $select_super_groups
968
     * @param bool   $select_users
969
     * @param string $date_from
970
     * @param string $date_to
971
     * @param int    $chat_id
972
     * @param string $text
973
     *
974
     * @return array|bool (Selected chats or false if invalid arguments)
975
     * @throws \Longman\TelegramBot\Exception\TelegramException
976
     */
977
    public static function selectChats(
978
        $select_groups = true,
979
        $select_super_groups = true,
980
        $select_users = true,
981
        $date_from = null,
982
        $date_to = null,
983
        $chat_id = null,
984
        $text = null
985
    ) {
986
        if (!self::isDbConnected()) {
987
            return false;
988
        }
989
990
        if (!$select_groups && !$select_users && !$select_super_groups) {
991
            return false;
992
        }
993
994
        try {
995
            $query = '
996
                SELECT * ,
997
                ' . TB_CHAT . '.`id` AS `chat_id`,
998
                ' . TB_CHAT . '.`created_at` AS `chat_created_at`,
999
                ' . TB_CHAT . '.`updated_at` AS `chat_updated_at`
1000
            ';
1001
            if ($select_users) {
1002
                $query .= '
1003
                    , ' . TB_USER . '.`id` AS `user_id`
1004
                    FROM `' . TB_CHAT . '`
1005
                    LEFT JOIN `' . TB_USER . '`
1006
                    ON ' . TB_CHAT . '.`id`=' . TB_USER . '.`id`
1007
                ';
1008
            } else {
1009
                $query .= 'FROM `' . TB_CHAT . '`';
1010
            }
1011
1012
            //Building parts of query
1013
            $where  = [];
1014
            $tokens = [];
1015
1016
            if (!$select_groups || !$select_users || !$select_super_groups) {
1017
                $chat_or_user = [];
1018
1019
                $select_groups && $chat_or_user[] = TB_CHAT . '.`type` = "group"';
1020
                $select_super_groups && $chat_or_user[] = TB_CHAT . '.`type` = "supergroup"';
1021
                $select_users && $chat_or_user[] = TB_CHAT . '.`type` = "private"';
1022
1023
                $where[] = '(' . implode(' OR ', $chat_or_user) . ')';
1024
            }
1025
1026
            if (null !== $date_from) {
1027
                $where[]              = TB_CHAT . '.`updated_at` >= :date_from';
1028
                $tokens[':date_from'] = $date_from;
1029
            }
1030
1031
            if (null !== $date_to) {
1032
                $where[]            = TB_CHAT . '.`updated_at` <= :date_to';
1033
                $tokens[':date_to'] = $date_to;
1034
            }
1035
1036
            if (null !== $chat_id) {
1037
                $where[]            = TB_CHAT . '.`id` = :chat_id';
1038
                $tokens[':chat_id'] = $chat_id;
1039
            }
1040
1041
            if (null !== $text) {
1042
                if ($select_users) {
1043
                    $where[] = '(
1044
                        LOWER(' . TB_CHAT . '.`title`) LIKE :text
1045
                        OR LOWER(' . TB_USER . '.`first_name`) LIKE :text
1046
                        OR LOWER(' . TB_USER . '.`last_name`) LIKE :text
1047
                        OR LOWER(' . TB_USER . '.`username`) LIKE :text
1048
                    )';
1049
                } else {
1050
                    $where[] = 'LOWER(' . TB_CHAT . '.`title`) LIKE :text';
1051
                }
1052
                $tokens[':text'] = '%' . strtolower($text) . '%';
1053
            }
1054
1055
            if (!empty($where)) {
1056
                $query .= ' WHERE ' . implode(' AND ', $where);
1057
            }
1058
1059
            $query .= ' ORDER BY ' . TB_CHAT . '.`updated_at` ASC';
1060
1061
            $sth = self::$pdo->prepare($query);
1062
            $sth->execute($tokens);
1063
1064
            return $sth->fetchAll(PDO::FETCH_ASSOC);
1065
        } catch (PDOException $e) {
1066
            throw new TelegramException($e->getMessage());
1067
        }
1068
    }
1069
1070
    /**
1071
     * Get Telegram API request count for current chat / message
1072
     *
1073
     * @param integer $chat_id
1074
     * @param string  $inline_message_id
1075
     *
1076
     * @return array|bool (Array containing TOTAL and CURRENT fields or false on invalid arguments)
1077
     * @throws \Longman\TelegramBot\Exception\TelegramException
1078
     */
1079
    public static function getTelegramRequestCount($chat_id = null, $inline_message_id = null)
1080
    {
1081
        if (!self::isDbConnected()) {
1082
            return false;
1083
        }
1084
1085
        try {
1086
            $sth = self::$pdo->prepare('SELECT 
1087
                (SELECT COUNT(*) FROM `' . TB_REQUEST_LIMITER . '` WHERE `created_at` >= :date) as LIMIT_PER_SEC_ALL,
1088
                (SELECT COUNT(*) FROM `' . TB_REQUEST_LIMITER . '` WHERE ((`chat_id` = :chat_id AND `inline_message_id` IS NULL) OR (`inline_message_id` = :inline_message_id AND `chat_id` IS NULL)) AND `created_at` >= :date) as LIMIT_PER_SEC,
1089
                (SELECT COUNT(*) FROM `' . TB_REQUEST_LIMITER . '` WHERE `chat_id` = :chat_id AND `created_at` >= :date_minute) as LIMIT_PER_MINUTE
1090
            ');
1091
1092
            $date = self::getTimestamp(time());
1093
            $date_minute = self::getTimestamp(strtotime('-1 minute'));
1094
1095
            $sth->bindParam(':chat_id', $chat_id, \PDO::PARAM_STR);
1096
            $sth->bindParam(':inline_message_id', $inline_message_id, \PDO::PARAM_STR);
1097
            $sth->bindParam(':date', $date, \PDO::PARAM_STR);
1098
            $sth->bindParam(':date_minute', $date_minute, \PDO::PARAM_STR);
1099
1100
            $sth->execute();
1101
1102
            return $sth->fetch();
1103
        } catch (\Exception $e) {
1104
            throw new TelegramException($e->getMessage());
1105
        }
1106
    }
1107
1108
    /**
1109
     * Insert Telegram API request in db
1110
     *
1111
     * @param string $method
1112
     * @param array  $data
1113
     *
1114
     * @return bool If the insert was successful
1115
     * @throws \Longman\TelegramBot\Exception\TelegramException
1116
     */
1117
    public static function insertTelegramRequest($method, $data)
1118
    {
1119
        if (!self::isDbConnected()) {
1120
            return false;
1121
        }
1122
1123
        $chat_id = ((isset($data['chat_id'])) ? $data['chat_id'] : null);
1124
        $inline_message_id = (isset($data['inline_message_id']) ? $data['inline_message_id'] : null);
1125
1126
        try {
1127
            $sth = self::$pdo->prepare('INSERT INTO `' . TB_REQUEST_LIMITER . '`
1128
                (
1129
                `method`, `chat_id`, `inline_message_id`, `created_at`
1130
                )
1131
                VALUES (
1132
                :method, :chat_id, :inline_message_id, :date
1133
                );
1134
            ');
1135
1136
            $created_at = self::getTimestamp();
1137
1138
            $sth->bindParam(':chat_id', $chat_id, \PDO::PARAM_STR);
1139
            $sth->bindParam(':inline_message_id', $inline_message_id, \PDO::PARAM_STR);
1140
            $sth->bindParam(':method', $method, \PDO::PARAM_STR);
1141
            $sth->bindParam(':date', $created_at, \PDO::PARAM_STR);
1142
1143
            return $sth->execute();
1144
        } catch (\Exception $e) {
1145
            throw new TelegramException($e->getMessage());
1146
        }
1147
    }
1148
}
1149