Passed
Pull Request — develop (#1445)
by
unknown
08:42
created

DB::insertTelegramUpdate()   C

Complexity

Conditions 17
Paths 22

Size

Total Lines 65
Code Lines 27

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 2
CRAP Score 250.2098

Importance

Changes 0
Metric Value
cc 17
eloc 27
nc 22
nop 16
dl 0
loc 65
ccs 2
cts 29
cp 0.069
crap 250.2098
rs 5.2166
c 0
b 0
f 0

How to fix   Long Method    Complexity    Many Parameters   

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:

Many Parameters

Methods with many parameters are not only hard to understand, but their parameters also often become inconsistent when you need more, or different data.

There are several approaches to avoid long parameter lists:

1
<?php
2
3
/**
4
 * This file is part of the TelegramBot package.
5
 *
6
 * (c) Avtandil Kikabidze aka LONGMAN <[email protected]>
7
 *
8
 * For the full copyright and license information, please view the LICENSE
9
 * file that was distributed with this source code.
10
 * Written by Marco Boretto <[email protected]>
11
 */
12
13
namespace Longman\TelegramBot;
14
15
use Longman\TelegramBot\Entities\CallbackQuery;
16
use Longman\TelegramBot\Entities\Chat;
17
use Longman\TelegramBot\Entities\ChatJoinRequest;
18
use Longman\TelegramBot\Entities\ChatMemberUpdated;
19
use Longman\TelegramBot\Entities\ChosenInlineResult;
20
use Longman\TelegramBot\Entities\InlineQuery;
21
use Longman\TelegramBot\Entities\Message;
22
use Longman\TelegramBot\Entities\Payments\PreCheckoutQuery;
23
use Longman\TelegramBot\Entities\Payments\ShippingQuery;
24
use Longman\TelegramBot\Entities\Poll;
25
use Longman\TelegramBot\Entities\PollAnswer;
26
use Longman\TelegramBot\Entities\Update;
27
use Longman\TelegramBot\Entities\User;
28
use Longman\TelegramBot\Exception\TelegramException;
29
use PDO;
30
use PDOException;
31
32
class DB
33
{
34
    /**
35
     * MySQL credentials
36
     *
37
     * @var array
38
     */
39
    protected static $mysql_credentials = [];
40
41
    /**
42
     * PDO object
43
     *
44
     * @var PDO
45
     */
46
    protected static $pdo;
47
48
    /**
49
     * Table prefix
50
     *
51
     * @var string
52
     */
53
    protected static $table_prefix;
54
55
    /**
56
     * Telegram class object
57
     *
58
     * @var Telegram
59
     */
60
    protected static $telegram;
61
62
    private static $enterprise_id;
63
    /**
64
     * Initialize
65
     *
66
     * @param array    $credentials  Database connection details
67
     * @param Telegram $telegram     Telegram object to connect with this object
68
     * @param string   $table_prefix Table prefix
69
     * @param string   $encoding     Database character encoding
70
     *
71
     * @return PDO PDO database object
72
     * @throws TelegramException
73 9
     */
74
    public static function initialize(
75
        array $credentials,
76
        Telegram $telegram,
77
        $enterprise_id = 0,
78
        $table_prefix = '',
79 9
        $encoding = 'utf8mb4'
80
    ): PDO {
81
        if (empty($credentials)) {
82 9
            throw new TelegramException('MySQL credentials not provided!');
83
        }
84
        if (isset($credentials['unix_socket'])) {
85 9
            $dsn = 'mysql:unix_socket=' . $credentials['unix_socket'];
86
        } else {
87 9
            $dsn = 'mysql:host=' . $credentials['host'];
88
        }
89 9
        $dsn .= ';dbname=' . $credentials['database'];
90 9
91
        if (!empty($credentials['port'])) {
92
            $dsn .= ';port=' . $credentials['port'];
93 9
        }
94
95 9
        $options = [PDO::MYSQL_ATTR_INIT_COMMAND => 'SET NAMES ' . $encoding];
96 9
        try {
97
            $pdo = new PDO($dsn, $credentials['user'], $credentials['password'], $options);
98
            $pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_WARNING);
99
        } catch (PDOException $e) {
100
            throw new TelegramException($e->getMessage());
101 9
        }
102 9
103 9
        self::$pdo               = $pdo;
104 9
        self::$telegram          = $telegram;
105
        self::$mysql_credentials = $credentials;
106 9
        self::$table_prefix      = $table_prefix;
107
        self::$enterprise_id     = $enterprise_id;
108 9
109
        self::defineTables();
110
        return self::$pdo;
111
    }
112
113
    /**
114
     * External Initialize
115
     *
116
     * Let you use the class with an external already existing Pdo Mysql connection.
117
     *
118
     * @param PDO      $external_pdo_connection PDO database object
119
     * @param Telegram $telegram                Telegram object to connect with this object
120
     * @param string   $table_prefix            Table prefix
121
     *
122
     * @return PDO PDO database object
123
     * @throws TelegramException
124
     */
125
    public static function externalInitialize(
126
        PDO $external_pdo_connection,
127
        Telegram $telegram,
128
        string $table_prefix = ''
129
    ): PDO {
130
        if ($external_pdo_connection === null) {
131
            throw new TelegramException('MySQL external connection not provided!');
132
        }
133
134
        self::$pdo               = $external_pdo_connection;
135
        self::$telegram          = $telegram;
136
        self::$mysql_credentials = [];
137
        self::$table_prefix      = $table_prefix;
138
139
        self::defineTables();
140
141
        return self::$pdo;
142
    }
143
144
    /**
145 9
     * Define all the tables with the proper prefix
146
     */
147 9
    protected static function defineTables(): void
148 9
    {
149 9
        $tables = [
150 9
            'callback_query',
151 9
            'chat',
152 9
            'chat_join_request',
153 9
            'chat_member_updated',
154 9
            'chosen_inline_result',
155 9
            'edited_message',
156 9
            'inline_query',
157 9
            'message',
158 9
            'poll',
159 9
            'poll_answer',
160 9
            'pre_checkout_query',
161 9
            'request_limiter',
162 9
            'shipping_query',
163 9
            'telegram_update',
164 9
            'user',
165 9
            'user_chat',
166 9
        ];
167 9
        foreach ($tables as $table) {
168 1
            $table_name = 'TB_' . strtoupper($table);
169
            if (!defined($table_name)) {
170
                define($table_name, self::$table_prefix . $table);
171
            }
172
        }
173
    }
174
175
    /**
176
     * Check if database connection has been created
177
     *
178 9
     * @return bool
179
     */
180 9
    public static function isDbConnected(): bool
181
    {
182
        return self::$pdo !== null;
183
    }
184
185
    /**
186
     * Get the PDO object of the connected database
187
     *
188
     * @return PDO|null
189
     */
190
    public static function getPdo(): ?PDO
191
    {
192
        return self::$pdo;
193
    }
194
195
    /**
196
     * Fetch update(s) from DB
197
     *
198
     * @param int    $limit Limit the number of updates to fetch
199
     * @param string $id    Check for unique update id
200
     *
201
     * @return array|bool Fetched data or false if not connected
202
     * @throws TelegramException
203
     */
204
    public static function selectTelegramUpdate(int $limit = 0, string $id = '')
205
    {
206
        if (!self::isDbConnected()) {
207
            return false;
208
        }
209
210
        try {
211
            $sql = '
212
                SELECT `id`
213
                FROM `' . TB_TELEGRAM_UPDATE . '`  WHERE 1=1
0 ignored issues
show
Bug introduced by
The constant Longman\TelegramBot\TB_TELEGRAM_UPDATE was not found. Maybe you did not declare it correctly or list all dependencies?
Loading history...
214
            ';
215
216
            if (self::$enterprise_id > 0) {
217
                $sql .= ' AND `enterprise_id` = :enterprise_id';
218
            }
219
            if ($id !== '') {
220
                $sql .= ' AND `id` = :id';
221
            } else {
222
                $sql .= ' ORDER BY `id` DESC';
223
            }
224
225
            if ($limit > 0) {
226
                $sql .= ' LIMIT :limit';
227
            }
228
229
            $sth = self::$pdo->prepare($sql);
230
231
            if ($limit > 0) {
232
                $sth->bindValue(':limit', $limit, PDO::PARAM_INT);
233
            }
234
            if (self::$enterprise_id > 0) {
235
                $sth->bindValue(':enterprise_id', self::$enterprise_id);
236
            }
237
            if ($id !== '') {
238
                $sth->bindValue(':id', $id);
239
            }
240
241
            $sth->execute();
242
243
            return $sth->fetchAll(PDO::FETCH_ASSOC);
244
        } catch (PDOException $e) {
245
            throw new TelegramException($e->getMessage());
246
        }
247
    }
248
249
    /**
250
     * Fetch message(s) from DB
251
     *
252
     * @param int $limit Limit the number of messages to fetch
253
     *
254
     * @return array|bool Fetched data or false if not connected
255
     * @throws TelegramException
256
     */
257
    public static function selectMessages(int $limit = 0)
258
    {
259
        if (!self::isDbConnected()) {
260
            return false;
261
        }
262
263
        try {
264
            $sql = '
265
                SELECT *
266
                FROM `' . TB_MESSAGE . '`
0 ignored issues
show
Bug introduced by
The constant Longman\TelegramBot\TB_MESSAGE was not found. Maybe you did not declare it correctly or list all dependencies?
Loading history...
267
                WHERE 1=1
268
            ';
269
270
            if (self::$enterprise_id > 0) {
271
                $sql .= ' AND `enterprise_id` = :enterprise_id';
272
            }
273
            $sql .= ' ORDER BY `id` DESC';
274
275
            if ($limit > 0) {
276
                $sql .= ' LIMIT :limit';
277
            }
278
279
            $sth = self::$pdo->prepare($sql);
280
281
            if (self::$enterprise_id > 0) {
282
                $sth->bindValue(':enterprise_id', self::$enterprise_id);
283
            }
284
285
            if ($limit > 0) {
286
                $sth->bindValue(':limit', $limit, PDO::PARAM_INT);
287 7
            }
288
289 7
            $sth->execute();
290
291
            return $sth->fetchAll(PDO::FETCH_ASSOC);
292
        } catch (PDOException $e) {
293
            throw new TelegramException($e->getMessage());
294
        }
295
    }
296
297
    /**
298
     * Convert from unix timestamp to timestamp
299
     *
300
     * @param ?int $unixtime Unix timestamp (if empty, current timestamp is used)
301
     *
302 6
     * @return string
303
     */
304 6
    protected static function getTimestamp(?int $unixtime = null): string
305 6
    {
306
        return date('Y-m-d H:i:s', $unixtime ?? time());
307
    }
308
309
    /**
310
     * Convert array of Entity items to a JSON array
311
     *
312
     * @todo Find a better way, as json_* functions are very heavy
313
     *
314
     * @param array $entities
315
     * @param mixed $default
316
     *
317
     * @return mixed
318
     */
319
    public static function entitiesArrayToJson(array $entities, $default = null)
320
    {
321
        if (empty($entities)) {
322
            return $default;
323
        }
324
325
        // Convert each Entity item into an object based on its JSON reflection
326
        $json_entities = array_map(function ($entity) {
327
            return json_decode($entity, true);
328
        }, $entities);
329
330
        return json_encode($json_entities);
331
    }
332
333
    /**
334
     * Insert entry to telegram_update table
335
     *
336
     * @param int         $update_id
337
     * @param int|null    $chat_id
338
     * @param int|null    $message_id
339
     * @param int|null    $edited_message_id
340
     * @param int|null    $channel_post_id
341
     * @param int|null    $edited_channel_post_id
342
     * @param string|null $inline_query_id
343
     * @param string|null $chosen_inline_result_id
344
     * @param string|null $callback_query_id
345
     * @param string|null $shipping_query_id
346
     * @param string|null $pre_checkout_query_id
347
     * @param string|null $poll_id
348
     * @param string|null $poll_answer_poll_id
349
     * @param string|null $my_chat_member_updated_id
350
     * @param string|null $chat_member_updated_id
351
     *
352
     * @return bool If the insert was successful
353
     * @throws TelegramException
354
     */
355
    protected static function insertTelegramUpdate(
356
        int $update_id,
357
        ?int $chat_id = null,
358
        ?int $message_id = null,
359
        ?int $edited_message_id = null,
360
        ?int $channel_post_id = null,
361
        ?int $edited_channel_post_id = null,
362
        ?string $inline_query_id = null,
363
        ?string $chosen_inline_result_id = null,
364
        ?string $callback_query_id = null,
365
        ?string $shipping_query_id = null,
366
        ?string $pre_checkout_query_id = null,
367
        ?string $poll_id = null,
368
        ?string $poll_answer_poll_id = null,
369
        ?string $my_chat_member_updated_id = null,
370
        ?string $chat_member_updated_id = null,
371
        ?string $chat_join_request_id = null
372
    ): ?bool {
373
        if ($message_id === null && $edited_message_id === null && $channel_post_id === null && $edited_channel_post_id === null && $inline_query_id === null && $chosen_inline_result_id === null && $callback_query_id === null && $shipping_query_id === null && $pre_checkout_query_id === null && $poll_id === null && $poll_answer_poll_id === null && $my_chat_member_updated_id === null && $chat_member_updated_id === null && $chat_join_request_id === null) {
374
            throw new TelegramException('message_id, edited_message_id, channel_post_id, edited_channel_post_id, inline_query_id, chosen_inline_result_id, callback_query_id, shipping_query_id, pre_checkout_query_id, poll_id, poll_answer_poll_id, my_chat_member_updated_id, chat_member_updated_id are all null');
375
        }
376
377
        if (!self::isDbConnected()) {
378
            return false;
379
        }
380
381
        try {
382
            $sth = self::$pdo->prepare('
383
                INSERT IGNORE INTO `' . TB_TELEGRAM_UPDATE . '`
384
                (
385
                    `id`, `chat_id`, `message_id`, `edited_message_id`,
386
                    `channel_post_id`, `edited_channel_post_id`, `inline_query_id`, `chosen_inline_result_id`,
387
                    `callback_query_id`, `shipping_query_id`, `pre_checkout_query_id`,
388
                    `poll_id`, `poll_answer_poll_id`, `my_chat_member_updated_id`, `chat_member_updated_id`,
389
                    `chat_join_request_id`,`enterprise_id`
390
                ) VALUES (
391
                    :id, :chat_id, :message_id, :edited_message_id,
392
                    :channel_post_id, :edited_channel_post_id, :inline_query_id, :chosen_inline_result_id,
393
                    :callback_query_id, :shipping_query_id, :pre_checkout_query_id,
394
                    :poll_id, :poll_answer_poll_id, :my_chat_member_updated_id, :chat_member_updated_id,
395
                    :chat_join_request_id,:enterprise_id
396
                )
397
            ');
398
399
            $sth->bindValue(':id', $update_id);
400
            $sth->bindValue(':chat_id', $chat_id);
401
            $sth->bindValue(':message_id', $message_id);
402
            $sth->bindValue(':edited_message_id', $edited_message_id);
403
            $sth->bindValue(':channel_post_id', $channel_post_id);
404
            $sth->bindValue(':edited_channel_post_id', $edited_channel_post_id);
405
            $sth->bindValue(':inline_query_id', $inline_query_id);
406
            $sth->bindValue(':chosen_inline_result_id', $chosen_inline_result_id);
407
            $sth->bindValue(':callback_query_id', $callback_query_id);
408
            $sth->bindValue(':shipping_query_id', $shipping_query_id);
409
            $sth->bindValue(':pre_checkout_query_id', $pre_checkout_query_id);
410
            $sth->bindValue(':poll_id', $poll_id);
411
            $sth->bindValue(':poll_answer_poll_id', $poll_answer_poll_id);
412
            $sth->bindValue(':my_chat_member_updated_id', $my_chat_member_updated_id);
413
            $sth->bindValue(':chat_member_updated_id', $chat_member_updated_id);
414
            $sth->bindValue(':chat_join_request_id', $chat_join_request_id);
415 6
            $sth->bindValue(':enterprise_id', self::$enterprise_id);
416
417 6
            return $sth->execute();
418
        } catch (PDOException $e) {
419
            throw new TelegramException($e->getMessage());
420
        }
421
    }
422 6
423 6
    /**
424
     * Insert users and save their connection to chats
425
     *
426
     * @param User        $user
427
     * @param string|null $date
428
     * @param Chat|null   $chat
429
     *
430
     * @return bool If the insert was successful
431
     * @throws TelegramException
432
     */
433
    public static function insertUser(User $user, ?string $date = null, ?Chat $chat = null): bool
434
    {
435
        if (!self::isDbConnected()) {
436 6
            return false;
437
        }
438 6
439 6
        try {
440 6
            $sth = self::$pdo->prepare('
441 6
                INSERT INTO `' . TB_USER . '`
442 6
                (`id`, `is_bot`, `username`, `first_name`, `last_name`, `language_code`, `is_premium`, `added_to_attachment_menu`, `created_at`, `updated_at`,`enterprise_id`)
443 6
                VALUES
444 6
                (:id, :is_bot, :username, :first_name, :last_name, :language_code, :is_premium, :added_to_attachment_menu, :created_at, :updated_at,:enterprise_id)
445 6
                ON DUPLICATE KEY UPDATE
446 6
                    `is_bot`                   = VALUES(`is_bot`),
447 6
                    `username`                 = VALUES(`username`),
448 6
                    `first_name`               = VALUES(`first_name`),
449
                    `last_name`                = VALUES(`last_name`),
450 6
                    `language_code`            = VALUES(`language_code`),
451
                    `is_premium`               = VALUES(`is_premium`),
452
                    `added_to_attachment_menu` = VALUES(`added_to_attachment_menu`),
453
                    `enterprise_id`            = VALUES(`enterprise_id`),
454
                    `updated_at`               = VALUES(`updated_at`)
455
            ');
456 6
457
            $sth->bindValue(':id', $user->getId());
458 6
            $sth->bindValue(':is_bot', $user->getIsBot(), PDO::PARAM_INT);
459 6
            $sth->bindValue(':username', $user->getUsername());
460
            $sth->bindValue(':first_name', $user->getFirstName());
461
            $sth->bindValue(':last_name', $user->getLastName());
462
            $sth->bindValue(':language_code', $user->getLanguageCode());
463 6
            $sth->bindValue(':is_premium', $user->getIsPremium(), PDO::PARAM_INT);
464
            $sth->bindValue(':added_to_attachment_menu', $user->getAddedToAttachmentMenu(), PDO::PARAM_INT);
465 6
            $date = $date ?: self::getTimestamp();
466 6
            $sth->bindValue(':created_at', $date);
467
            $sth->bindValue(':updated_at', $date);
468 6
            $sth->bindValue(':enterprise_id', self::$enterprise_id);
469
470
            $status = $sth->execute();
471
        } catch (PDOException $e) {
472
            throw new TelegramException($e->getMessage());
473
        }
474 6
475
        // Also insert the relationship to the chat into the user_chat table
476
        if ($chat) {
477
            try {
478
                $sth = self::$pdo->prepare('
479
                    INSERT IGNORE INTO `' . TB_USER_CHAT . '`
480
                    (`user_id`, `chat_id`, `enterprise_id`)
481
                    VALUES
482
                    (:user_id, :chat_id, :enterprise_id)
483
                ');
484
485
                $sth->bindValue(':user_id', $user->getId());
486
                $sth->bindValue(':chat_id', $chat->getId());
487 6
                $sth->bindValue(':enterprise_id', self::$enterprise_id);
488
489 6
                $status = $sth->execute();
490
            } catch (PDOException $e) {
491
                throw new TelegramException($e->getMessage());
492
            }
493
        }
494 6
495 6
        return $status;
496
    }
497
498
    /**
499
     * Insert chat
500
     *
501
     * @param Chat        $chat
502
     * @param string|null $date
503
     * @param int|null    $migrate_to_chat_id
504
     *
505
     * @return bool If the insert was successful
506
     * @throws TelegramException
507 6
     */
508
    public static function insertChat(Chat $chat, ?string $date = null, ?int $migrate_to_chat_id = null): ?bool
509 6
    {
510 6
        if (!self::isDbConnected()) {
511
            return false;
512 6
        }
513
514
        try {
515
            $sth = self::$pdo->prepare('
516
                INSERT IGNORE INTO `' . TB_CHAT . '`
517
                (`id`, `type`, `title`, `username`, `first_name`, `last_name`, `is_forum`, `created_at` ,`updated_at`, `old_id`, `enterprise_id`)
518 6
                VALUES
519 6
                (:id, :type, :title, :username, :first_name, :last_name, :is_forum, :created_at, :updated_at, :old_id, :enterprise_id)
520
                ON DUPLICATE KEY UPDATE
521
                    `type`                           = VALUES(`type`),
522 6
                    `title`                          = VALUES(`title`),
523 6
                    `username`                       = VALUES(`username`),
524 6
                    `first_name`                     = VALUES(`first_name`),
525 6
                    `last_name`                      = VALUES(`last_name`),
526 6
                    `is_forum`                       = VALUES(`is_forum`),
527 6
                    `enterprise_id`                  = VALUES(`enterprise_id`),
528 6
                    `updated_at`                     = VALUES(`updated_at`)
529 6
            ');
530 6
531
            $chat_id   = $chat->getId();
532 6
            $chat_type = $chat->getType();
533
534
            if ($migrate_to_chat_id !== null) {
535
                $chat_type = 'supergroup';
536
537
                $sth->bindValue(':id', $migrate_to_chat_id);
538
                $sth->bindValue(':old_id', $chat_id);
539
            } else {
540
                $sth->bindValue(':id', $chat_id);
541
                $sth->bindValue(':old_id', $migrate_to_chat_id);
542
            }
543
544
            $sth->bindValue(':type', $chat_type);
545
            $sth->bindValue(':title', $chat->getTitle());
546
            $sth->bindValue(':username', $chat->getUsername());
547
            $sth->bindValue(':first_name', $chat->getFirstName());
548
            $sth->bindValue(':last_name', $chat->getLastName());
549
            $sth->bindValue(':is_forum', $chat->getIsForum());
550
            $date = $date ?: self::getTimestamp();
551
            $sth->bindValue(':created_at', $date);
552
            $sth->bindValue(':enterprise_id', self::$enterprise_id);
553
            $sth->bindValue(':updated_at', $date);
554
555
            return $sth->execute();
556
        } catch (PDOException $e) {
557
            throw new TelegramException($e->getMessage());
558
        }
559
    }
560
561
    /**
562
     * Insert request into database
563
     *
564
     * @param Update $update
565
     * @param int $enterprise_id
566
     * @return bool
567
     * @throws TelegramException
568
     *
569
     */
570
    public static function insertRequest(Update $update, int $enterprise_id = 0): bool
0 ignored issues
show
Unused Code introduced by
The parameter $enterprise_id is not used and could be removed. ( Ignorable by Annotation )

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

570
    public static function insertRequest(Update $update, /** @scrutinizer ignore-unused */ int $enterprise_id = 0): bool

This check looks for parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
571
    {
572
        if (!self::isDbConnected()) {
573
            return false;
574
        }
575
576
        $chat_id                   = null;
577
        $message_id                = null;
578
        $edited_message_id         = null;
579
        $channel_post_id           = null;
580
        $edited_channel_post_id    = null;
581
        $inline_query_id           = null;
582
        $chosen_inline_result_id   = null;
583
        $callback_query_id         = null;
584
        $shipping_query_id         = null;
585
        $pre_checkout_query_id     = null;
586
        $poll_id                   = null;
587
        $poll_answer_poll_id       = null;
588
        $my_chat_member_updated_id = null;
589
        $chat_member_updated_id    = null;
590
        $chat_join_request_id      = null;
591
592
        if (($message = $update->getMessage()) && self::insertMessageRequest($message)) {
593
            $chat_id    = $message->getChat()->getId();
594
            $message_id = $message->getMessageId();
595
        } elseif (($edited_message = $update->getEditedMessage()) && self::insertEditedMessageRequest($edited_message)) {
596
            $chat_id           = $edited_message->getChat()->getId();
597
            $edited_message_id = (int) self::$pdo->lastInsertId();
598
        } elseif (($channel_post = $update->getChannelPost()) && self::insertMessageRequest($channel_post)) {
599
            $chat_id         = $channel_post->getChat()->getId();
600
            $channel_post_id = $channel_post->getMessageId();
601
        } elseif (($edited_channel_post = $update->getEditedChannelPost()) && self::insertEditedMessageRequest($edited_channel_post)) {
602
            $chat_id                = $edited_channel_post->getChat()->getId();
603
            $edited_channel_post_id = (int) self::$pdo->lastInsertId();
604
        } elseif (($inline_query = $update->getInlineQuery()) && self::insertInlineQueryRequest($inline_query)) {
605
            $inline_query_id = $inline_query->getId();
606
        } elseif (($chosen_inline_result = $update->getChosenInlineResult()) && self::insertChosenInlineResultRequest($chosen_inline_result)) {
607
            $chosen_inline_result_id = self::$pdo->lastInsertId();
608
        } elseif (($callback_query = $update->getCallbackQuery()) && self::insertCallbackQueryRequest($callback_query)) {
609
            $callback_query_id = $callback_query->getId();
610
        } elseif (($shipping_query = $update->getShippingQuery()) && self::insertShippingQueryRequest($shipping_query)) {
611
            $shipping_query_id = $shipping_query->getId();
612
        } elseif (($pre_checkout_query = $update->getPreCheckoutQuery()) && self::insertPreCheckoutQueryRequest($pre_checkout_query)) {
613
            $pre_checkout_query_id = $pre_checkout_query->getId();
614
        } elseif (($poll = $update->getPoll()) && self::insertPollRequest($poll)) {
615
            $poll_id = $poll->getId();
616
        } elseif (($poll_answer = $update->getPollAnswer()) && self::insertPollAnswerRequest($poll_answer)) {
617
            $poll_answer_poll_id = $poll_answer->getPollId();
618
        } elseif (($my_chat_member = $update->getMyChatMember()) && self::insertChatMemberUpdatedRequest($my_chat_member)) {
619
            $my_chat_member_updated_id = self::$pdo->lastInsertId();
620
        } elseif (($chat_member = $update->getChatMember()) && self::insertChatMemberUpdatedRequest($chat_member)) {
621
            $chat_member_updated_id = self::$pdo->lastInsertId();
622
        } elseif (($chat_join_request = $update->getChatJoinRequest()) && self::insertChatJoinRequestRequest($chat_join_request)) {
623
            $chat_join_request_id = self::$pdo->lastInsertId();
624
        } else {
625
            return false;
626
        }
627
628
        return self::insertTelegramUpdate(
629
            $update->getUpdateId(),
630
            $chat_id,
631
            $message_id,
632
            $edited_message_id,
633
            $channel_post_id,
634
            $edited_channel_post_id,
635
            $inline_query_id,
636
            $chosen_inline_result_id,
637
            $callback_query_id,
638
            $shipping_query_id,
639
            $pre_checkout_query_id,
640
            $poll_id,
641
            $poll_answer_poll_id,
642
            $my_chat_member_updated_id,
643
            $chat_member_updated_id,
644
            $chat_join_request_id
645
        );
646
    }
647
648
    /**
649
     * Insert inline query request into database
650
     *
651
     * @param InlineQuery $inline_query
652
     *
653
     * @return bool If the insert was successful
654
     * @throws TelegramException
655
     */
656
    public static function insertInlineQueryRequest(InlineQuery $inline_query): bool
657
    {
658
        if (!self::isDbConnected()) {
659
            return false;
660
        }
661
662
        try {
663
            $sth = self::$pdo->prepare('
664
                INSERT IGNORE INTO `' . TB_INLINE_QUERY . '`
665
                (`id`, `user_id`, `location`, `query`, `offset`, `chat_type`, `created_at`, `enterprise_id`)
666
                VALUES
667
                (:id, :user_id, :location, :query, :offset, :chat_type, :created_at,:enterprise_id)
668
            ');
669
670
            $date    = self::getTimestamp();
671
            $user_id = null;
672
673
            if ($user = $inline_query->getFrom()) {
674
                $user_id = $user->getId();
675
                self::insertUser($user, $date);
676
            }
677
678
            $sth->bindValue(':id', $inline_query->getId());
679
            $sth->bindValue(':user_id', $user_id);
680
            $sth->bindValue(':location', $inline_query->getLocation());
681
            $sth->bindValue(':query', $inline_query->getQuery());
682
            $sth->bindValue(':offset', $inline_query->getOffset());
683
            $sth->bindValue(':chat_type', $inline_query->getChatType());
684
            $sth->bindValue(':created_at', $date);
685
            $sth->bindValue(':enterprise_id', self::$enterprise_id);
686
687
            return $sth->execute();
688
        } catch (PDOException $e) {
689
            throw new TelegramException($e->getMessage());
690
        }
691
    }
692
693
    /**
694
     * Insert chosen inline result request into database
695
     *
696
     * @param ChosenInlineResult $chosen_inline_result
697
     *
698
     * @return bool If the insert was successful
699
     * @throws TelegramException
700
     */
701
    public static function insertChosenInlineResultRequest(ChosenInlineResult $chosen_inline_result): bool
702
    {
703
        if (!self::isDbConnected()) {
704
            return false;
705
        }
706
707
        try {
708
            $sth = self::$pdo->prepare('
709
                INSERT INTO `' . TB_CHOSEN_INLINE_RESULT . '`
710
                (`result_id`, `user_id`, `location`, `inline_message_id`, `query`, `created_at`, `enterprise_id`)
711
                VALUES
712
                (:result_id, :user_id, :location, :inline_message_id, :query, :created_at, :enterprise_id)
713
            ');
714
715
            $date    = self::getTimestamp();
716
            $user_id = null;
717
718
            if ($user = $chosen_inline_result->getFrom()) {
719
                $user_id = $user->getId();
720
                self::insertUser($user, $date);
721
            }
722
723
            $sth->bindValue(':result_id', $chosen_inline_result->getResultId());
724
            $sth->bindValue(':user_id', $user_id);
725
            $sth->bindValue(':location', $chosen_inline_result->getLocation());
726
            $sth->bindValue(':inline_message_id', $chosen_inline_result->getInlineMessageId());
727
            $sth->bindValue(':query', $chosen_inline_result->getQuery());
728
            $sth->bindValue(':created_at', $date);
729
            $sth->bindValue(':enterprise_id', self::$enterprise_id);
730
731
            return $sth->execute();
732
        } catch (PDOException $e) {
733
            throw new TelegramException($e->getMessage());
734
        }
735
    }
736
737
    /**
738
     * Insert callback query request into database
739
     *
740
     * @param CallbackQuery $callback_query
741
     *
742
     * @return bool If the insert was successful
743
     * @throws TelegramException
744
     */
745
    public static function insertCallbackQueryRequest(CallbackQuery $callback_query): bool
746
    {
747
        if (!self::isDbConnected()) {
748
            return false;
749
        }
750
751
        try {
752
            $sth = self::$pdo->prepare('
753
                INSERT IGNORE INTO `' . TB_CALLBACK_QUERY . '`
754
                (`id`, `user_id`, `chat_id`, `message_id`, `inline_message_id`, `chat_instance`, `data`, `game_short_name`, `created_at`, `enterprise_id`)
755
                VALUES
756
                (:id, :user_id, :chat_id, :message_id, :inline_message_id, :chat_instance, :data, :game_short_name, :created_at, :enterprise_id)
757
            ');
758
759
            $date    = self::getTimestamp();
760
            $user_id = null;
761
762
            if ($user = $callback_query->getFrom()) {
763
                $user_id = $user->getId();
764
                self::insertUser($user, $date);
765
            }
766
767
            $chat_id    = null;
768
            $message_id = null;
769
            if ($message = $callback_query->getMessage()) {
770
                $chat_id    = $message->getChat()->getId();
771
                $message_id = $message->getMessageId();
772
773
                $is_message = self::$pdo->query('
774
                    SELECT *
775
                    FROM `' . TB_MESSAGE . '`
776
                    WHERE `id` = ' . $message_id . '
777
                      AND `chat_id` = ' . $chat_id . '
778
                    LIMIT 1
779
                ')->rowCount();
780
781
                if ($is_message) {
782
                    self::insertEditedMessageRequest($message);
783
                } else {
784
                    self::insertMessageRequest($message);
785
                }
786
            }
787
788
            $sth->bindValue(':id', $callback_query->getId());
789
            $sth->bindValue(':user_id', $user_id);
790
            $sth->bindValue(':chat_id', $chat_id);
791
            $sth->bindValue(':message_id', $message_id);
792
            $sth->bindValue(':inline_message_id', $callback_query->getInlineMessageId());
793
            $sth->bindValue(':chat_instance', $callback_query->getChatInstance());
794
            $sth->bindValue(':data', $callback_query->getData());
795
            $sth->bindValue(':game_short_name', $callback_query->getGameShortName());
796
            $sth->bindValue(':created_at', $date);
797
            $sth->bindValue(':enterprise_id', self::$enterprise_id);
798
799
            return $sth->execute();
800
        } catch (PDOException $e) {
801
            throw new TelegramException($e->getMessage());
802
        }
803
    }
804
805
    /**
806
     * Insert shipping query request into database
807
     *
808
     * @param ShippingQuery $shipping_query
809
     *
810
     * @return bool If the insert was successful
811
     * @throws TelegramException
812
     */
813
    public static function insertShippingQueryRequest(ShippingQuery $shipping_query): bool
814
    {
815
        if (!self::isDbConnected()) {
816
            return false;
817
        }
818
819
        try {
820
            $sth = self::$pdo->prepare('
821
                INSERT IGNORE INTO `' . TB_SHIPPING_QUERY . '`
822
                (`id`, `user_id`, `invoice_payload`, `shipping_address`, `created_at`, `enterprise_id`)
823
                VALUES
824
                (:id, :user_id, :invoice_payload, :shipping_address, :created_at, :enterprise_id)
825
            ');
826
827
            $date    = self::getTimestamp();
828
            $user_id = null;
829
830
            if ($user = $shipping_query->getFrom()) {
831
                $user_id = $user->getId();
832
                self::insertUser($user, $date);
833
            }
834
835
            $sth->bindValue(':id', $shipping_query->getId());
836
            $sth->bindValue(':user_id', $user_id);
837
            $sth->bindValue(':invoice_payload', $shipping_query->getInvoicePayload());
838
            $sth->bindValue(':shipping_address', $shipping_query->getShippingAddress());
839
            $sth->bindValue(':created_at', $date);
840
            $sth->bindValue(':enterprise_id', self::$enterprise_id);
841
842
            return $sth->execute();
843
        } catch (PDOException $e) {
844
            throw new TelegramException($e->getMessage());
845
        }
846
    }
847
848
    /**
849
     * Insert pre checkout query request into database
850
     *
851
     * @param PreCheckoutQuery $pre_checkout_query
852
     *
853
     * @return bool If the insert was successful
854
     * @throws TelegramException
855
     */
856
    public static function insertPreCheckoutQueryRequest(PreCheckoutQuery $pre_checkout_query): bool
857
    {
858
        if (!self::isDbConnected()) {
859
            return false;
860
        }
861
862
        try {
863
            $sth = self::$pdo->prepare('
864
                INSERT IGNORE INTO `' . TB_PRE_CHECKOUT_QUERY . '`
865
                (`id`, `user_id`, `currency`, `total_amount`, `invoice_payload`, `shipping_option_id`, `order_info`, `created_at`, `enterprise_id`)
866
                VALUES
867
                (:id, :user_id, :currency, :total_amount, :invoice_payload, :shipping_option_id, :order_info, :created_at, :enterprise_id)
868
            ');
869
870
            $date    = self::getTimestamp();
871
            $user_id = null;
872
873
            if ($user = $pre_checkout_query->getFrom()) {
874
                $user_id = $user->getId();
875
                self::insertUser($user, $date);
876
            }
877
878
            $sth->bindValue(':id', $pre_checkout_query->getId());
879
            $sth->bindValue(':user_id', $user_id);
880
            $sth->bindValue(':currency', $pre_checkout_query->getCurrency());
881
            $sth->bindValue(':total_amount', $pre_checkout_query->getTotalAmount());
882
            $sth->bindValue(':invoice_payload', $pre_checkout_query->getInvoicePayload());
883
            $sth->bindValue(':shipping_option_id', $pre_checkout_query->getShippingOptionId());
884
            $sth->bindValue(':order_info', $pre_checkout_query->getOrderInfo());
885
            $sth->bindValue(':created_at', $date);
886
            $sth->bindValue(':enterprise_id', self::$enterprise_id);
887
888
            return $sth->execute();
889
        } catch (PDOException $e) {
890
            throw new TelegramException($e->getMessage());
891
        }
892
    }
893
894
    /**
895
     * Insert poll request into database
896
     *
897
     * @param Poll $poll
898
     *
899
     * @return bool If the insert was successful
900
     * @throws TelegramException
901
     */
902
    public static function insertPollRequest(Poll $poll): bool
903
    {
904
        if (!self::isDbConnected()) {
905
            return false;
906
        }
907
908
        try {
909
            $sth = self::$pdo->prepare('
910
                INSERT INTO `' . TB_POLL . '`
911
                (`id`, `question`, `options`, `total_voter_count`, `is_closed`, `is_anonymous`, `type`, `allows_multiple_answers`, `correct_option_id`, `explanation`, `explanation_entities`, `open_period`, `close_date`, `created_at`, `enterprise_id`)
912
                VALUES
913
                (:id, :question, :options, :total_voter_count, :is_closed, :is_anonymous, :type, :allows_multiple_answers, :correct_option_id, :explanation, :explanation_entities, :open_period, :close_date, :created_at, :enterprise_id)
914
                ON DUPLICATE KEY UPDATE
915
                    `options`                 = VALUES(`options`),
916
                    `total_voter_count`       = VALUES(`total_voter_count`),
917
                    `is_closed`               = VALUES(`is_closed`),
918
                    `is_anonymous`            = VALUES(`is_anonymous`),
919
                    `type`                    = VALUES(`type`),
920
                    `allows_multiple_answers` = VALUES(`allows_multiple_answers`),
921
                    `correct_option_id`       = VALUES(`correct_option_id`),
922
                    `explanation`             = VALUES(`explanation`),
923
                    `explanation_entities`    = VALUES(`explanation_entities`),
924
                    `open_period`             = VALUES(`open_period`),
925
                    `close_date`              = VALUES(`close_date`)
926
            ');
927
928
            $sth->bindValue(':id', $poll->getId());
929
            $sth->bindValue(':question', $poll->getQuestion());
930
            $sth->bindValue(':options', self::entitiesArrayToJson($poll->getOptions() ?: []));
931
            $sth->bindValue(':total_voter_count', $poll->getTotalVoterCount());
932
            $sth->bindValue(':is_closed', $poll->getIsClosed(), PDO::PARAM_INT);
933
            $sth->bindValue(':is_anonymous', $poll->getIsAnonymous(), PDO::PARAM_INT);
934
            $sth->bindValue(':type', $poll->getType());
935
            $sth->bindValue(':allows_multiple_answers', $poll->getAllowsMultipleAnswers(), PDO::PARAM_INT);
936
            $sth->bindValue(':correct_option_id', $poll->getCorrectOptionId());
937
            $sth->bindValue(':explanation', $poll->getExplanation());
938
            $sth->bindValue(':explanation_entities', self::entitiesArrayToJson($poll->getExplanationEntities() ?: []));
939
            $sth->bindValue(':open_period', $poll->getOpenPeriod());
940
            $sth->bindValue(':close_date', self::getTimestamp($poll->getCloseDate()));
941
            $sth->bindValue(':created_at', self::getTimestamp());
942
            $sth->bindValue(':enterprise_id', self::$enterprise_id);
943
944
            return $sth->execute();
945
        } catch (PDOException $e) {
946
            throw new TelegramException($e->getMessage());
947
        }
948
    }
949
950
    /**
951
     * Insert poll answer request into database
952
     *
953
     * @param PollAnswer $poll_answer
954
     *
955
     * @return bool If the insert was successful
956
     * @throws TelegramException
957
     */
958
    public static function insertPollAnswerRequest(PollAnswer $poll_answer): bool
959
    {
960
        if (!self::isDbConnected()) {
961
            return false;
962
        }
963
964
        try {
965
            $sth = self::$pdo->prepare('
966
                INSERT INTO `' . TB_POLL_ANSWER . '`
967
                (`poll_id`, `user_id`, `option_ids`, `created_at`, `enterprise_id`)
968
                VALUES
969
                (:poll_id, :user_id, :option_ids, :created_at, :enterprise_id)
970
                ON DUPLICATE KEY UPDATE
971
                    `option_ids` = VALUES(`option_ids`)
972
            ');
973
974
            $date    = self::getTimestamp();
975
            $user_id = null;
976
977
            if ($user = $poll_answer->getUser()) {
978
                $user_id = $user->getId();
979
                self::insertUser($user, $date);
980
            }
981
982
            $sth->bindValue(':poll_id', $poll_answer->getPollId());
983
            $sth->bindValue(':user_id', $user_id);
984
            $sth->bindValue(':option_ids', json_encode($poll_answer->getOptionIds()));
985
            $sth->bindValue(':created_at', $date);
986
            $sth->bindValue(':enterprise_id', self::$enterprise_id);
987
            return $sth->execute();
988
        } catch (PDOException $e) {
989
            throw new TelegramException($e->getMessage());
990
        }
991
    }
992
993
    /**
994
     * Insert chat member updated request into database
995
     *
996
     * @param ChatMemberUpdated $chat_member_updated
997
     *
998
     * @return bool If the insert was successful
999
     * @throws TelegramException
1000
     */
1001
    public static function insertChatMemberUpdatedRequest(ChatMemberUpdated $chat_member_updated): bool
1002
    {
1003
        if (!self::isDbConnected()) {
1004
            return false;
1005
        }
1006
1007
        try {
1008
            $sth = self::$pdo->prepare('
1009
                INSERT INTO `' . TB_CHAT_MEMBER_UPDATED . '`
0 ignored issues
show
Bug introduced by
The constant Longman\TelegramBot\TB_CHAT_MEMBER_UPDATED was not found. Maybe you did not declare it correctly or list all dependencies?
Loading history...
1010
                (`chat_id`, `user_id`, `date`, `old_chat_member`, `new_chat_member`, `invite_link`, `created_at`, `enterprise_id`)
1011
                VALUES
1012
                (:chat_id, :user_id, :date, :old_chat_member, :new_chat_member, :invite_link, :created_at, :enterprise_id)
1013
            ');
1014
1015
            $date    = self::getTimestamp();
1016
            $chat_id = null;
1017
            $user_id = null;
1018
1019
            if ($chat = $chat_member_updated->getChat()) {
1020
                $chat_id = $chat->getId();
1021
                self::insertChat($chat, $date);
1022
            }
1023
            if ($user = $chat_member_updated->getFrom()) {
1024
                $user_id = $user->getId();
1025
                self::insertUser($user, $date);
1026
            }
1027
1028
            $sth->bindValue(':chat_id', $chat_id);
1029
            $sth->bindValue(':user_id', $user_id);
1030
            $sth->bindValue(':date', self::getTimestamp($chat_member_updated->getDate()));
1031
            $sth->bindValue(':old_chat_member', $chat_member_updated->getOldChatMember());
1032
            $sth->bindValue(':new_chat_member', $chat_member_updated->getNewChatMember());
1033
            $sth->bindValue(':invite_link', $chat_member_updated->getInviteLink());
1034
            $sth->bindValue(':created_at', $date);
1035
            $sth->bindValue(':enterprise_id', self::$enterprise_id);
1036
1037
            return $sth->execute();
1038
        } catch (PDOException $e) {
1039
            throw new TelegramException($e->getMessage());
1040
        }
1041
    }
1042
1043
    /**
1044
     * Insert chat join request into database
1045
     *
1046
     * @param ChatJoinRequest $chat_join_request
1047
     *
1048
     * @return bool If the insert was successful
1049
     * @throws TelegramException
1050
     */
1051
    public static function insertChatJoinRequestRequest(ChatJoinRequest $chat_join_request): bool
1052
    {
1053
        if (!self::isDbConnected()) {
1054
            return false;
1055
        }
1056
1057
        try {
1058
            $sth = self::$pdo->prepare('
1059
                INSERT INTO `' . TB_CHAT_JOIN_REQUEST . '`
0 ignored issues
show
Bug introduced by
The constant Longman\TelegramBot\TB_CHAT_JOIN_REQUEST was not found. Maybe you did not declare it correctly or list all dependencies?
Loading history...
1060
                (`chat_id`, `user_id`, `date`, `bio`, `invite_link`, `created_at`, `enterprise_id`)
1061
                VALUES
1062
                (:chat_id, :user_id, :date, :bio, :invite_link, :created_at, :enterprise_id)
1063
            ');
1064
1065
            $date    = self::getTimestamp();
1066
            $chat_id = null;
1067
            $user_id = null;
1068
1069
            if ($chat = $chat_join_request->getChat()) {
1070 6
                $chat_id = $chat->getId();
1071
                self::insertChat($chat, $date);
1072 6
            }
1073
            if ($user = $chat_join_request->getFrom()) {
1074
                $user_id = $user->getId();
1075
                self::insertUser($user, $date);
1076 6
            }
1077
1078
            $sth->bindValue(':chat_id', $chat_id);
1079 6
            $sth->bindValue(':user_id', $user_id);
1080 6
            $sth->bindValue(':date', self::getTimestamp($chat_join_request->getDate()));
1081
            $sth->bindValue(':bio', $chat_join_request->getBio());
1082 6
            $sth->bindValue(':invite_link', $chat_join_request->getInviteLink());
1083 6
            $sth->bindValue(':created_at', $date);
1084
            $sth->bindValue(':enterprise_id', self::$enterprise_id);
1085
1086
            return $sth->execute();
1087
        } catch (PDOException $e) {
1088
            throw new TelegramException($e->getMessage());
1089 6
        }
1090 6
    }
1091
1092
    /**
1093
     * Insert Message request in db
1094 6
     *
1095
     * @param Message $message
1096 6
     *
1097
     * @return bool If the insert was successful
1098
     * @throws TelegramException
1099
     */
1100 6
    public static function insertMessageRequest(Message $message): bool
1101
    {
1102
        if (!self::isDbConnected()) {
1103
            return false;
1104
        }
1105 6
1106 6
        $date = self::getTimestamp($message->getDate());
1107
1108
        // Insert chat, update chat id in case it migrated
1109
        $chat = $message->getChat();
1110
        self::insertChat($chat, $date, $message->getMigrateToChatId());
1111
1112 6
        $sender_chat_id = null;
1113 6
        if ($sender_chat = $message->getSenderChat()) {
1114
            self::insertChat($sender_chat);
1115 6
            $sender_chat_id = $sender_chat->getId();
1116 6
        }
1117 6
1118
        // Insert user and the relation with the chat
1119
        if ($user = $message->getFrom()) {
1120
            self::insertUser($user, $date, $chat);
1121
        }
1122
1123
        // Insert the forwarded message user in users table
1124
        $forward_date = $message->getForwardDate() ? self::getTimestamp($message->getForwardDate()) : null;
1125
1126 6
        if ($forward_from = $message->getForwardFrom()) {
1127
            self::insertUser($forward_from);
1128
            $forward_from = $forward_from->getId();
1129
        }
1130
        if ($forward_from_chat = $message->getForwardFromChat()) {
1131
            self::insertChat($forward_from_chat);
1132
            $forward_from_chat = $forward_from_chat->getId();
1133 6
        }
1134 6
1135
        $via_bot_id = null;
1136
        if ($via_bot = $message->getViaBot()) {
1137
            self::insertUser($via_bot);
1138
            $via_bot_id = $via_bot->getId();
1139
        }
1140
1141
        // New and left chat member
1142
        $new_chat_members_ids = null;
1143
        $left_chat_member_id  = null;
1144
1145
        $new_chat_members = $message->getNewChatMembers();
0 ignored issues
show
Bug introduced by
The method getNewChatMembers() does not exist on Longman\TelegramBot\Entities\Message. Since you implemented __call, consider adding a @method annotation. ( Ignorable by Annotation )

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

1145
        /** @scrutinizer ignore-call */ 
1146
        $new_chat_members = $message->getNewChatMembers();
Loading history...
1146
        $left_chat_member = $message->getLeftChatMember();
1147
        if (!empty($new_chat_members)) {
1148
            foreach ($new_chat_members as $new_chat_member) {
1149
                if ($new_chat_member instanceof User) {
1150
                    // Insert the new chat user
1151
                    self::insertUser($new_chat_member, $date, $chat);
1152
                    $new_chat_members_ids[] = $new_chat_member->getId();
1153
                }
1154
            }
1155
            $new_chat_members_ids = implode(',', $new_chat_members_ids);
1156
        } elseif ($left_chat_member) {
0 ignored issues
show
introduced by
$left_chat_member is of type Longman\TelegramBot\Entities\User, thus it always evaluated to true.
Loading history...
1157
            // Insert the left chat user
1158 6
            self::insertUser($left_chat_member, $date, $chat);
1159
            $left_chat_member_id = $left_chat_member->getId();
1160 6
        }
1161 6
1162
        try {
1163 6
            $sth = self::$pdo->prepare('
1164 6
                INSERT IGNORE INTO `' . TB_MESSAGE . '`
1165
                (
1166
                    `id`, `user_id`, `chat_id`, `message_thread_id`, `sender_chat_id`, `date`, `forward_from`, `forward_from_chat`, `forward_from_message_id`,
1167
                    `forward_signature`, `forward_sender_name`, `forward_date`, `is_topic_message`,
1168
                    `reply_to_chat`, `reply_to_message`, `via_bot`, `edit_date`, `media_group_id`, `author_signature`, `text`, `entities`, `caption_entities`,
1169
                    `audio`, `document`, `animation`, `game`, `photo`, `sticker`, `story`, `video`, `voice`, `video_note`, `caption`, `has_media_spoiler`, `contact`,
1170
                    `location`, `venue`, `poll`, `dice`, `new_chat_members`, `left_chat_member`,
1171 6
                    `new_chat_title`, `new_chat_photo`, `delete_chat_photo`, `group_chat_created`,
1172 6
                    `supergroup_chat_created`, `channel_chat_created`, `message_auto_delete_timer_changed`, `migrate_to_chat_id`, `migrate_from_chat_id`,
1173 6
                    `pinned_message`, `invoice`, `successful_payment`, `user_shared`, `chat_shared`, `connected_website`, `write_access_allowed`, `passport_data`, `proximity_alert_triggered`,
1174 6
                    `forum_topic_created`, `forum_topic_edited`, `forum_topic_closed`, `forum_topic_reopened`, `general_forum_topic_hidden`, `general_forum_topic_unhidden`,
1175 6
                    `video_chat_scheduled`, `video_chat_started`, `video_chat_ended`, `video_chat_participants_invited`, `web_app_data`, `reply_markup`, `enterprise_id`
1176 6
                ) VALUES (
1177 6
                    :message_id, :user_id, :chat_id, :message_thread_id, :sender_chat_id, :date, :forward_from, :forward_from_chat, :forward_from_message_id,
1178 6
                    :forward_signature, :forward_sender_name, :forward_date, :is_topic_message,
1179 6
                    :reply_to_chat, :reply_to_message, :via_bot, :edit_date, :media_group_id, :author_signature, :text, :entities, :caption_entities,
1180 6
                    :audio, :document, :animation, :game, :photo, :sticker, :story, :video, :voice, :video_note, :caption, :has_media_spoiler, :contact,
1181 6
                    :location, :venue, :poll, :dice, :new_chat_members, :left_chat_member,
1182 6
                    :new_chat_title, :new_chat_photo, :delete_chat_photo, :group_chat_created,
1183 6
                    :supergroup_chat_created, :channel_chat_created, :message_auto_delete_timer_changed, :migrate_to_chat_id, :migrate_from_chat_id,
1184
                    :pinned_message, :invoice, :successful_payment, :user_shared, :chat_shared, :connected_website, :write_access_allowed, :passport_data, :proximity_alert_triggered,
1185 6
                    :forum_topic_created, :forum_topic_edited, :forum_topic_closed, :forum_topic_reopened, :general_forum_topic_hidden, :general_forum_topic_unhidden,
1186 6
                    :video_chat_scheduled, :video_chat_started, :video_chat_ended, :video_chat_participants_invited, :web_app_data, :reply_markup, :enterprise_id
1187
                )
1188
            ');
1189 6
1190 6
            $user_id = $user ? $user->getId() : null;
0 ignored issues
show
introduced by
$user is of type Longman\TelegramBot\Entities\User, thus it always evaluated to true.
Loading history...
1191
            $chat_id = $chat->getId();
1192 6
1193 6
            $reply_to_message_id = null;
1194 6
            if ($reply_to_message = $message->getReplyToMessage()) {
1195 6
                $reply_to_message_id = $reply_to_message->getMessageId();
1196 6
                // please notice that, as explained in the documentation, reply_to_message don't contain other
1197 6
                // reply_to_message field so recursion deep is 1
1198 6
                self::insertMessageRequest($reply_to_message);
1199 6
            }
1200 6
1201 6
            $sth->bindValue(':message_id', $message->getMessageId());
1202 6
            $sth->bindValue(':chat_id', $chat_id);
1203 6
            $sth->bindValue(':sender_chat_id', $sender_chat_id);
1204 6
            $sth->bindValue(':message_thread_id', $message->getMessageThreadId());
1205 6
            $sth->bindValue(':user_id', $user_id);
1206 6
            $sth->bindValue(':date', $date);
1207 6
            $sth->bindValue(':forward_from', $forward_from);
1208 6
            $sth->bindValue(':forward_from_chat', $forward_from_chat);
1209 6
            $sth->bindValue(':forward_from_message_id', $message->getForwardFromMessageId());
1210 6
            $sth->bindValue(':forward_signature', $message->getForwardSignature());
1211 6
            $sth->bindValue(':forward_sender_name', $message->getForwardSenderName());
1212 6
            $sth->bindValue(':forward_date', $forward_date);
1213 6
            $sth->bindValue(':is_topic_message', $message->getIsTopicMessage());
1214 6
1215 6
            $reply_to_chat_id = null;
1216 6
            if ($reply_to_message_id !== null) {
1217 6
                $reply_to_chat_id = $chat_id;
1218 6
            }
1219 6
            $sth->bindValue(':reply_to_chat', $reply_to_chat_id);
1220 6
            $sth->bindValue(':reply_to_message', $reply_to_message_id);
1221 6
1222 6
            $sth->bindValue(':via_bot', $via_bot_id);
1223 6
            $sth->bindValue(':edit_date', self::getTimestamp($message->getEditDate()));
1224 6
            $sth->bindValue(':media_group_id', $message->getMediaGroupId());
1225 6
            $sth->bindValue(':author_signature', $message->getAuthorSignature());
1226 6
            $sth->bindValue(':text', $message->getText());
1227 6
            $sth->bindValue(':entities', self::entitiesArrayToJson($message->getEntities() ?: []));
1228 6
            $sth->bindValue(':caption_entities', self::entitiesArrayToJson($message->getCaptionEntities() ?: []));
1229 6
            $sth->bindValue(':audio', $message->getAudio());
1230 6
            $sth->bindValue(':document', $message->getDocument());
1231 6
            $sth->bindValue(':animation', $message->getAnimation());
1232 6
            $sth->bindValue(':game', $message->getGame());
1233 6
            $sth->bindValue(':photo', self::entitiesArrayToJson($message->getPhoto() ?: []));
1234 6
            $sth->bindValue(':sticker', $message->getSticker());
1235 6
            $sth->bindValue(':story', $message->getStory());
1236 6
            $sth->bindValue(':video', $message->getVideo());
1237 6
            $sth->bindValue(':voice', $message->getVoice());
1238 6
            $sth->bindValue(':video_note', $message->getVideoNote());
1239 6
            $sth->bindValue(':caption', $message->getCaption());
1240 6
            $sth->bindValue(':has_media_spoiler', $message->getHasMediaSpoiler());
1241 6
            $sth->bindValue(':contact', $message->getContact());
1242 6
            $sth->bindValue(':location', $message->getLocation());
1243 6
            $sth->bindValue(':venue', $message->getVenue());
1244 6
            $sth->bindValue(':poll', $message->getPoll());
1245 6
            $sth->bindValue(':dice', $message->getDice());
1246 6
            $sth->bindValue(':new_chat_members', $new_chat_members_ids);
1247 6
            $sth->bindValue(':left_chat_member', $left_chat_member_id);
1248
            $sth->bindValue(':new_chat_title', $message->getNewChatTitle());
1249 6
            $sth->bindValue(':new_chat_photo', self::entitiesArrayToJson($message->getNewChatPhoto() ?: []));
1250
            $sth->bindValue(':delete_chat_photo', $message->getDeleteChatPhoto());
1251
            $sth->bindValue(':group_chat_created', $message->getGroupChatCreated());
1252
            $sth->bindValue(':supergroup_chat_created', $message->getSupergroupChatCreated());
1253
            $sth->bindValue(':channel_chat_created', $message->getChannelChatCreated());
1254
            $sth->bindValue(':message_auto_delete_timer_changed', $message->getMessageAutoDeleteTimerChanged());
1255
            $sth->bindValue(':migrate_to_chat_id', $message->getMigrateToChatId());
1256
            $sth->bindValue(':migrate_from_chat_id', $message->getMigrateFromChatId());
1257
            $sth->bindValue(':pinned_message', $message->getPinnedMessage());
1258
            $sth->bindValue(':invoice', $message->getInvoice());
1259
            $sth->bindValue(':successful_payment', $message->getSuccessfulPayment());
1260
            $sth->bindValue(':user_shared', $message->getUserShared());
1261
            $sth->bindValue(':chat_shared', $message->getChatShared());
1262
            $sth->bindValue(':connected_website', $message->getConnectedWebsite());
1263
            $sth->bindValue(':write_access_allowed', $message->getWriteAccessAllowed());
1264
            $sth->bindValue(':passport_data', $message->getPassportData());
1265
            $sth->bindValue(':proximity_alert_triggered', $message->getProximityAlertTriggered());
1266
            $sth->bindValue(':forum_topic_created', $message->getForumTopicCreated());
1267
            $sth->bindValue(':forum_topic_edited', $message->getForumTopicEdited());
1268
            $sth->bindValue(':forum_topic_closed', $message->getForumTopicClosed());
1269
            $sth->bindValue(':forum_topic_reopened', $message->getForumTopicReopened());
1270
            $sth->bindValue(':general_forum_topic_hidden', $message->getGeneralForumTopicHidden());
1271
            $sth->bindValue(':general_forum_topic_unhidden', $message->getGeneralForumTopicUnhidden());
1272
            $sth->bindValue(':video_chat_scheduled', $message->getVideoChatScheduled());
1273
            $sth->bindValue(':video_chat_started', $message->getVideoChatStarted());
1274
            $sth->bindValue(':video_chat_ended', $message->getVideoChatEnded());
1275
            $sth->bindValue(':video_chat_participants_invited', $message->getVideoChatParticipantsInvited());
1276
            $sth->bindValue(':web_app_data', $message->getWebAppData());
1277
            $sth->bindValue(':reply_markup', $message->getReplyMarkup());
1278
            $sth->bindValue(':enterprise_id', self::$enterprise_id);
1279
1280
            return $sth->execute();
1281
        } catch (PDOException $e) {
1282
            throw new TelegramException($e->getMessage());
1283
        }
1284
    }
1285
1286
    /**
1287
     * Insert Edited Message request in db
1288
     *
1289
     * @param Message $edited_message
1290
     *
1291
     * @return bool If the insert was successful
1292
     * @throws TelegramException
1293
     */
1294
    public static function insertEditedMessageRequest(Message $edited_message): bool
1295
    {
1296
        if (!self::isDbConnected()) {
1297
            return false;
1298
        }
1299
1300
        try {
1301
            $edit_date = self::getTimestamp($edited_message->getEditDate());
1302
1303
            // Insert chat
1304
            $chat = $edited_message->getChat();
1305
            self::insertChat($chat, $edit_date);
1306
1307
            // Insert user and the relation with the chat
1308
            if ($user = $edited_message->getFrom()) {
1309
                self::insertUser($user, $edit_date, $chat);
1310
            }
1311
1312
            $sth = self::$pdo->prepare('
1313
                INSERT IGNORE INTO `' . TB_EDITED_MESSAGE . '`
1314
                (`chat_id`, `message_id`, `user_id`, `edit_date`, `text`, `entities`, `caption`,`enterprise_id`)
1315
                VALUES
1316
                (:chat_id, :message_id, :user_id, :edit_date, :text, :entities, :caption, :enterprise_id)
1317
            ');
1318
1319
            $user_id = $user ? $user->getId() : null;
0 ignored issues
show
introduced by
$user is of type Longman\TelegramBot\Entities\User, thus it always evaluated to true.
Loading history...
1320
1321
            $sth->bindValue(':chat_id', $chat->getId());
1322
            $sth->bindValue(':message_id', $edited_message->getMessageId());
1323
            $sth->bindValue(':user_id', $user_id);
1324
            $sth->bindValue(':edit_date', $edit_date);
1325
            $sth->bindValue(':text', $edited_message->getText());
1326
            $sth->bindValue(':entities', self::entitiesArrayToJson($edited_message->getEntities() ?: []));
1327
            $sth->bindValue(':caption', $edited_message->getCaption());
1328
            $sth->bindValue(':enterprise_id', self::$enterprise_id);
1329
1330
            return $sth->execute();
1331
        } catch (PDOException $e) {
1332
            throw new TelegramException($e->getMessage());
1333
        }
1334
    }
1335
1336
    /**
1337
     * Select Groups, Supergroups, Channels and/or single user Chats (also by ID or text)
1338
     *
1339
     * @param $select_chats_params
1340
     *
1341
     * @return array|bool
1342
     * @throws TelegramException
1343
     */
1344
    public static function selectChats($select_chats_params)
1345
    {
1346
        if (!self::isDbConnected()) {
1347
            return false;
1348
        }
1349
1350
        // Set defaults for omitted values.
1351
        $select = array_merge([
1352
            'groups'      => true,
1353
            'supergroups' => true,
1354
            'channels'    => true,
1355
            'users'       => true,
1356
            'date_from'   => null,
1357
            'date_to'     => null,
1358
            'chat_id'     => null,
1359
            'text'        => null,
1360
            'language'    => null,
1361
        ], $select_chats_params);
1362
1363
        if (!$select['groups'] && !$select['users'] && !$select['supergroups'] && !$select['channels']) {
1364
            return false;
1365
        }
1366
1367
        try {
1368
            $query = '
1369
                SELECT * ,
1370
                ' . TB_CHAT . '.`id` AS `chat_id`,
1371
                ' . TB_CHAT . '.`username` AS `chat_username`,
1372
                ' . TB_CHAT . '.`created_at` AS `chat_created_at`,
1373
                ' . TB_CHAT . '.`updated_at` AS `chat_updated_at`
1374
            ';
1375
            if ($select['users']) {
1376
                $query .= '
1377
                    , ' . TB_USER . '.`id` AS `user_id`
1378
                    FROM `' . TB_CHAT . '`
1379
                    LEFT JOIN `' . TB_USER . '`
1380
                    ON ' . TB_CHAT . '.`id`=' . TB_USER . '.`id`
1381
                ';
1382
            } else {
1383
                $query .= 'FROM `' . TB_CHAT . '`';
1384
            }
1385
1386
            // Building parts of query
1387
            $where  = [];
1388
            $tokens = [];
1389
1390
            if (!$select['groups'] || !$select['users'] || !$select['supergroups'] || !$select['channels']) {
1391
                $chat_or_user = [];
1392
1393
                $select['groups'] && $chat_or_user[] = TB_CHAT . '.`type` = "group"';
1394
                $select['supergroups'] && $chat_or_user[] = TB_CHAT . '.`type` = "supergroup"';
1395
                $select['channels'] && $chat_or_user[] = TB_CHAT . '.`type` = "channel"';
1396
                $select['users'] && $chat_or_user[] = TB_CHAT . '.`type` = "private"';
1397
1398
                $where[] = '(' . implode(' OR ', $chat_or_user) . ')';
1399
            }
1400
1401
            if (null !== $select['date_from']) {
1402
                $where[]              = TB_CHAT . '.`updated_at` >= :date_from';
1403
                $tokens[':date_from'] = $select['date_from'];
1404
            }
1405
1406
            if (null !== $select['date_to']) {
1407
                $where[]            = TB_CHAT . '.`updated_at` <= :date_to';
1408
                $tokens[':date_to'] = $select['date_to'];
1409
            }
1410
1411
            if (null !== $select['chat_id']) {
1412
                $where[]            = TB_CHAT . '.`id` = :chat_id';
1413
                $tokens[':chat_id'] = $select['chat_id'];
1414
            }
1415
1416
            if ($select['users'] && null !== $select['language']) {
1417
                $where[]             = TB_USER . '.`language_code` = :language';
1418
                $tokens[':language'] = $select['language'];
1419
            }
1420
1421
            if (null !== $select['text']) {
1422
                $text_like = '%' . strtolower($select['text']) . '%';
1423
                if ($select['users']) {
1424
                    $where[]          = '(
1425
                        LOWER(' . TB_CHAT . '.`title`) LIKE :text1
1426
                        OR LOWER(' . TB_USER . '.`first_name`) LIKE :text2
1427
                        OR LOWER(' . TB_USER . '.`last_name`) LIKE :text3
1428
                        OR LOWER(' . TB_USER . '.`username`) LIKE :text4
1429
                    )';
1430
                    $tokens[':text1'] = $text_like;
1431
                    $tokens[':text2'] = $text_like;
1432
                    $tokens[':text3'] = $text_like;
1433
                    $tokens[':text4'] = $text_like;
1434
                } else {
1435
                    $where[]         = 'LOWER(' . TB_CHAT . '.`title`) LIKE :text';
1436
                    $tokens[':text'] = $text_like;
1437
                }
1438
            }
1439
1440
            if (self::$enterprise_id > 0) {
1441
                $where[] = TB_CHAT . '.`enterprise_id` = :enterprise_id';
1442
            }
1443
1444
            if (!empty($where)) {
1445
                $query .= ' WHERE ' . implode(' AND ', $where);
1446
            }
1447
1448
            $query .= ' ORDER BY ' . TB_CHAT . '.`updated_at` ASC';
1449
1450
            $sth = self::$pdo->prepare($query);
1451
            $sth->execute($tokens);
1452
1453
            return $sth->fetchAll(PDO::FETCH_ASSOC);
1454
        } catch (PDOException $e) {
1455
            throw new TelegramException($e->getMessage());
1456
        }
1457
    }
1458
1459
    /**
1460
     * Get Telegram API request count for current chat / message
1461
     *
1462
     * @param int|string|null $chat_id
1463
     * @param string|null     $inline_message_id
1464
     *
1465
     * @return array|bool Array containing TOTAL and CURRENT fields or false on invalid arguments
1466
     * @throws TelegramException
1467
     */
1468
    public static function getTelegramRequestCount($chat_id = null, string $inline_message_id = null)
1469
    {
1470
        if (!self::isDbConnected()) {
1471
            return false;
1472
        }
1473
1474
        try {
1475
            $sth = self::$pdo->prepare('SELECT
1476
                (SELECT COUNT(DISTINCT `chat_id`) FROM `' . TB_REQUEST_LIMITER . '` WHERE `created_at` >= :created_at_1) AS LIMIT_PER_SEC_ALL,
1477
                (SELECT COUNT(*) FROM `' . TB_REQUEST_LIMITER . '` WHERE `created_at` >= :created_at_2 AND ((`chat_id` = :chat_id_1 AND `inline_message_id` IS NULL) OR (`inline_message_id` = :inline_message_id AND `chat_id` IS NULL))) AS LIMIT_PER_SEC,
1478
                (SELECT COUNT(*) FROM `' . TB_REQUEST_LIMITER . '` WHERE `created_at` >= :created_at_minute AND `chat_id` = :chat_id_2) AS LIMIT_PER_MINUTE
1479
            ');
1480
1481
            $date        = self::getTimestamp();
1482
            $date_minute = self::getTimestamp(strtotime('-1 minute'));
1483
1484
            $sth->bindValue(':chat_id_1', $chat_id);
1485
            $sth->bindValue(':chat_id_2', $chat_id);
1486
            $sth->bindValue(':inline_message_id', $inline_message_id);
1487
            $sth->bindValue(':created_at_1', $date);
1488
            $sth->bindValue(':created_at_2', $date);
1489
            $sth->bindValue(':created_at_minute', $date_minute);
1490
1491
            $sth->execute();
1492
1493
            return $sth->fetch();
1494
        } catch (PDOException $e) {
1495
            throw new TelegramException($e->getMessage());
1496
        }
1497
    }
1498
1499
    /**
1500
     * Insert Telegram API request in db
1501
     *
1502
     * @param string $method
1503
     * @param array  $data
1504
     *
1505
     * @return bool If the insert was successful
1506
     * @throws TelegramException
1507
     */
1508
    public static function insertTelegramRequest(string $method, array $data): bool
1509 3
    {
1510
        if (!self::isDbConnected()) {
1511 3
            return false;
1512
        }
1513
1514
        try {
1515
            $sth = self::$pdo->prepare('INSERT INTO `' . TB_REQUEST_LIMITER . '`
1516
                (`method`, `chat_id`, `inline_message_id`, `created_at`, `enterprise_id`)
1517 3
                VALUES
1518
                (:method, :chat_id, :inline_message_id, :created_at, :enterprise_id);
1519
            ');
1520 3
1521 3
            $chat_id           = $data['chat_id'] ?? null;
1522 3
            $inline_message_id = $data['inline_message_id'] ?? null;
1523 3
1524
            $sth->bindValue(':chat_id', $chat_id);
1525
            $sth->bindValue(':inline_message_id', $inline_message_id);
1526
            $sth->bindValue(':method', $method);
1527 3
            $sth->bindValue(':created_at', self::getTimestamp());
1528 3
            $sth->bindValue(':enterprise_id', self::$enterprise_id);
1529 3
1530 3
            return $sth->execute();
1531
        } catch (PDOException $e) {
1532
            throw new TelegramException($e->getMessage());
1533 3
        }
1534 3
    }
1535
1536 3
    /**
1537
     * Bulk update the entries of any table
1538
     *
1539
     * @param string $table
1540
     * @param array  $fields_values
1541
     * @param array  $where_fields_values
1542
     *
1543
     * @return bool
1544
     * @throws TelegramException
1545
     */
1546
    public static function update(string $table, array $fields_values, array $where_fields_values): bool
1547
    {
1548
        if (empty($fields_values) || !self::isDbConnected()) {
1549
            return false;
1550
        }
1551
1552
        try {
1553
            // Building parts of query
1554
            $tokens = $fields = $where = [];
1555
1556
            // Fields with values to update
1557
            foreach ($fields_values as $field => $value) {
1558
                $token          = ':' . count($tokens);
1559
                $fields[]       = "`{$field}` = {$token}";
1560
                $tokens[$token] = $value;
1561
            }
1562
1563
            // Where conditions
1564
            foreach ($where_fields_values as $field => $value) {
1565
                $token          = ':' . count($tokens);
1566
                $where[]        = "`{$field}` = {$token}";
1567
                $tokens[$token] = $value;
1568
            }
1569
1570
            $sql = 'UPDATE `' . $table . '` SET ' . implode(', ', $fields);
1571
            $sql .= count($where) > 0 ? ' WHERE ' . implode(' AND ', $where) : '';
1572
1573
            return self::$pdo->prepare($sql)->execute($tokens);
1574
        } catch (PDOException $e) {
1575
            throw new TelegramException($e->getMessage());
1576
        }
1577
    }
1578
}
1579