Passed
Push — api-5.4 ( c96fd9...97810c )
by Armando
12:09 queued 02:07
created

DB::insertTelegramUpdate()   C

Complexity

Conditions 16
Paths 21

Size

Total Lines 64
Code Lines 26

Duplication

Lines 0
Ratio 0 %

Importance

Changes 2
Bugs 0 Features 0
Metric Value
cc 16
eloc 26
c 2
b 0
f 0
nc 21
nop 16
dl 0
loc 64
rs 5.5666

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

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

521
            $sth->bindValue(':all_members_are_administrators', /** @scrutinizer ignore-deprecated */ $chat->getAllMembersAreAdministrators(), PDO::PARAM_INT);
Loading history...
522
            $date = $date ?: self::getTimestamp();
523
            $sth->bindValue(':created_at', $date);
524
            $sth->bindValue(':updated_at', $date);
525
526
            return $sth->execute();
527
        } catch (PDOException $e) {
528
            throw new TelegramException($e->getMessage());
529
        }
530
    }
531
532
    /**
533
     * Insert request into database
534
     *
535
     * @todo self::$pdo->lastInsertId() - unsafe usage if expected previous insert fails?
536
     *
537
     * @param Update $update
538
     *
539
     * @return bool
540
     * @throws TelegramException
541
     */
542
    public static function insertRequest(Update $update): bool
543
    {
544
        if (!self::isDbConnected()) {
545
            return false;
546
        }
547
548
        $chat_id                   = null;
549
        $message_id                = null;
550
        $edited_message_id         = null;
551
        $channel_post_id           = null;
552
        $edited_channel_post_id    = null;
553
        $inline_query_id           = null;
554
        $chosen_inline_result_id   = null;
555
        $callback_query_id         = null;
556
        $shipping_query_id         = null;
557
        $pre_checkout_query_id     = null;
558
        $poll_id                   = null;
559
        $poll_answer_poll_id       = null;
560
        $my_chat_member_updated_id = null;
561
        $chat_member_updated_id    = null;
562
        $chat_join_request_id      = null;
563
564
        if (($message = $update->getMessage()) && self::insertMessageRequest($message)) {
565
            $chat_id    = $message->getChat()->getId();
566
            $message_id = $message->getMessageId();
567
        } elseif (($edited_message = $update->getEditedMessage()) && self::insertEditedMessageRequest($edited_message)) {
568
            $chat_id           = $edited_message->getChat()->getId();
569
            $edited_message_id = (int) self::$pdo->lastInsertId();
570
        } elseif (($channel_post = $update->getChannelPost()) && self::insertMessageRequest($channel_post)) {
571
            $chat_id         = $channel_post->getChat()->getId();
572
            $channel_post_id = $channel_post->getMessageId();
573
        } elseif (($edited_channel_post = $update->getEditedChannelPost()) && self::insertEditedMessageRequest($edited_channel_post)) {
574
            $chat_id                = $edited_channel_post->getChat()->getId();
575
            $edited_channel_post_id = (int) self::$pdo->lastInsertId();
576
        } elseif (($inline_query = $update->getInlineQuery()) && self::insertInlineQueryRequest($inline_query)) {
577
            $inline_query_id = $inline_query->getId();
578
        } elseif (($chosen_inline_result = $update->getChosenInlineResult()) && self::insertChosenInlineResultRequest($chosen_inline_result)) {
579
            $chosen_inline_result_id = self::$pdo->lastInsertId();
580
        } elseif (($callback_query = $update->getCallbackQuery()) && self::insertCallbackQueryRequest($callback_query)) {
581
            $callback_query_id = $callback_query->getId();
582
        } elseif (($shipping_query = $update->getShippingQuery()) && self::insertShippingQueryRequest($shipping_query)) {
583
            $shipping_query_id = $shipping_query->getId();
584
        } elseif (($pre_checkout_query = $update->getPreCheckoutQuery()) && self::insertPreCheckoutQueryRequest($pre_checkout_query)) {
585
            $pre_checkout_query_id = $pre_checkout_query->getId();
586
        } elseif (($poll = $update->getPoll()) && self::insertPollRequest($poll)) {
587
            $poll_id = $poll->getId();
588
        } elseif (($poll_answer = $update->getPollAnswer()) && self::insertPollAnswerRequest($poll_answer)) {
589
            $poll_answer_poll_id = $poll_answer->getPollId();
590
        } elseif (($my_chat_member = $update->getMyChatMember()) && self::insertChatMemberUpdatedRequest($my_chat_member)) {
591
            $my_chat_member_updated_id = self::$pdo->lastInsertId();
592
        } elseif (($chat_member = $update->getChatMember()) && self::insertChatMemberUpdatedRequest($chat_member)) {
593
            $chat_member_updated_id = self::$pdo->lastInsertId();
594
        } elseif (($chat_join_request = $update->getChatJoinRequest()) && self::insertChatJoinRequestRequest($chat_join_request)) {
595
            $chat_join_request_id = self::$pdo->lastInsertId();
596
        } else {
597
            return false;
598
        }
599
600
        return self::insertTelegramUpdate(
601
            $update->getUpdateId(),
602
            $chat_id,
603
            $message_id,
604
            $edited_message_id,
605
            $channel_post_id,
606
            $edited_channel_post_id,
607
            $inline_query_id,
608
            $chosen_inline_result_id,
609
            $callback_query_id,
610
            $shipping_query_id,
611
            $pre_checkout_query_id,
612
            $poll_id,
613
            $poll_answer_poll_id,
614
            $my_chat_member_updated_id,
615
            $chat_member_updated_id,
616
            $chat_join_request_id
617
        );
618
    }
619
620
    /**
621
     * Insert inline query request into database
622
     *
623
     * @param InlineQuery $inline_query
624
     *
625
     * @return bool If the insert was successful
626
     * @throws TelegramException
627
     */
628
    public static function insertInlineQueryRequest(InlineQuery $inline_query): bool
629
    {
630
        if (!self::isDbConnected()) {
631
            return false;
632
        }
633
634
        try {
635
            $sth = self::$pdo->prepare('
636
                INSERT IGNORE INTO `' . TB_INLINE_QUERY . '`
637
                (`id`, `user_id`, `location`, `query`, `offset`, `chat_type`, `created_at`)
638
                VALUES
639
                (:id, :user_id, :location, :query, :offset, :chat_type, :created_at)
640
            ');
641
642
            $date    = self::getTimestamp();
643
            $user_id = null;
644
645
            if ($user = $inline_query->getFrom()) {
646
                $user_id = $user->getId();
647
                self::insertUser($user, $date);
648
            }
649
650
            $sth->bindValue(':id', $inline_query->getId());
651
            $sth->bindValue(':user_id', $user_id);
652
            $sth->bindValue(':location', $inline_query->getLocation());
653
            $sth->bindValue(':query', $inline_query->getQuery());
654
            $sth->bindValue(':offset', $inline_query->getOffset());
655
            $sth->bindValue(':chat_type', $inline_query->getChatType());
656
            $sth->bindValue(':created_at', $date);
657
658
            return $sth->execute();
659
        } catch (PDOException $e) {
660
            throw new TelegramException($e->getMessage());
661
        }
662
    }
663
664
    /**
665
     * Insert chosen inline result request into database
666
     *
667
     * @param ChosenInlineResult $chosen_inline_result
668
     *
669
     * @return bool If the insert was successful
670
     * @throws TelegramException
671
     */
672
    public static function insertChosenInlineResultRequest(ChosenInlineResult $chosen_inline_result): bool
673
    {
674
        if (!self::isDbConnected()) {
675
            return false;
676
        }
677
678
        try {
679
            $sth = self::$pdo->prepare('
680
                INSERT INTO `' . TB_CHOSEN_INLINE_RESULT . '`
681
                (`result_id`, `user_id`, `location`, `inline_message_id`, `query`, `created_at`)
682
                VALUES
683
                (:result_id, :user_id, :location, :inline_message_id, :query, :created_at)
684
            ');
685
686
            $date    = self::getTimestamp();
687
            $user_id = null;
688
689
            if ($user = $chosen_inline_result->getFrom()) {
690
                $user_id = $user->getId();
691
                self::insertUser($user, $date);
692
            }
693
694
            $sth->bindValue(':result_id', $chosen_inline_result->getResultId());
695
            $sth->bindValue(':user_id', $user_id);
696
            $sth->bindValue(':location', $chosen_inline_result->getLocation());
697
            $sth->bindValue(':inline_message_id', $chosen_inline_result->getInlineMessageId());
698
            $sth->bindValue(':query', $chosen_inline_result->getQuery());
699
            $sth->bindValue(':created_at', $date);
700
701
            return $sth->execute();
702
        } catch (PDOException $e) {
703
            throw new TelegramException($e->getMessage());
704
        }
705
    }
706
707
    /**
708
     * Insert callback query request into database
709
     *
710
     * @param CallbackQuery $callback_query
711
     *
712
     * @return bool If the insert was successful
713
     * @throws TelegramException
714
     */
715
    public static function insertCallbackQueryRequest(CallbackQuery $callback_query): bool
716
    {
717
        if (!self::isDbConnected()) {
718
            return false;
719
        }
720
721
        try {
722
            $sth = self::$pdo->prepare('
723
                INSERT IGNORE INTO `' . TB_CALLBACK_QUERY . '`
724
                (`id`, `user_id`, `chat_id`, `message_id`, `inline_message_id`, `chat_instance`, `data`, `game_short_name`, `created_at`)
725
                VALUES
726
                (:id, :user_id, :chat_id, :message_id, :inline_message_id, :chat_instance, :data, :game_short_name, :created_at)
727
            ');
728
729
            $date    = self::getTimestamp();
730
            $user_id = null;
731
732
            if ($user = $callback_query->getFrom()) {
733
                $user_id = $user->getId();
734
                self::insertUser($user, $date);
735
            }
736
737
            $chat_id    = null;
738
            $message_id = null;
739
            if ($message = $callback_query->getMessage()) {
740
                $chat_id    = $message->getChat()->getId();
741
                $message_id = $message->getMessageId();
742
743
                $is_message = self::$pdo->query('
744
                    SELECT *
745
                    FROM `' . TB_MESSAGE . '`
746
                    WHERE `id` = ' . $message_id . '
747
                      AND `chat_id` = ' . $chat_id . '
748
                    LIMIT 1
749
                ')->rowCount();
750
751
                if ($is_message) {
752
                    self::insertEditedMessageRequest($message);
753
                } else {
754
                    self::insertMessageRequest($message);
755
                }
756
            }
757
758
            $sth->bindValue(':id', $callback_query->getId());
759
            $sth->bindValue(':user_id', $user_id);
760
            $sth->bindValue(':chat_id', $chat_id);
761
            $sth->bindValue(':message_id', $message_id);
762
            $sth->bindValue(':inline_message_id', $callback_query->getInlineMessageId());
763
            $sth->bindValue(':chat_instance', $callback_query->getChatInstance());
764
            $sth->bindValue(':data', $callback_query->getData());
765
            $sth->bindValue(':game_short_name', $callback_query->getGameShortName());
766
            $sth->bindValue(':created_at', $date);
767
768
            return $sth->execute();
769
        } catch (PDOException $e) {
770
            throw new TelegramException($e->getMessage());
771
        }
772
    }
773
774
    /**
775
     * Insert shipping query request into database
776
     *
777
     * @param ShippingQuery $shipping_query
778
     *
779
     * @return bool If the insert was successful
780
     * @throws TelegramException
781
     */
782
    public static function insertShippingQueryRequest(ShippingQuery $shipping_query): bool
783
    {
784
        if (!self::isDbConnected()) {
785
            return false;
786
        }
787
788
        try {
789
            $sth = self::$pdo->prepare('
790
                INSERT IGNORE INTO `' . TB_SHIPPING_QUERY . '`
791
                (`id`, `user_id`, `invoice_payload`, `shipping_address`, `created_at`)
792
                VALUES
793
                (:id, :user_id, :invoice_payload, :shipping_address, :created_at)
794
            ');
795
796
            $date    = self::getTimestamp();
797
            $user_id = null;
798
799
            if ($user = $shipping_query->getFrom()) {
800
                $user_id = $user->getId();
801
                self::insertUser($user, $date);
802
            }
803
804
            $sth->bindValue(':id', $shipping_query->getId());
805
            $sth->bindValue(':user_id', $user_id);
806
            $sth->bindValue(':invoice_payload', $shipping_query->getInvoicePayload());
807
            $sth->bindValue(':shipping_address', $shipping_query->getShippingAddress());
808
            $sth->bindValue(':created_at', $date);
809
810
            return $sth->execute();
811
        } catch (PDOException $e) {
812
            throw new TelegramException($e->getMessage());
813
        }
814
    }
815
816
    /**
817
     * Insert pre checkout query request into database
818
     *
819
     * @param PreCheckoutQuery $pre_checkout_query
820
     *
821
     * @return bool If the insert was successful
822
     * @throws TelegramException
823
     */
824
    public static function insertPreCheckoutQueryRequest(PreCheckoutQuery $pre_checkout_query): bool
825
    {
826
        if (!self::isDbConnected()) {
827
            return false;
828
        }
829
830
        try {
831
            $sth = self::$pdo->prepare('
832
                INSERT IGNORE INTO `' . TB_PRE_CHECKOUT_QUERY . '`
833
                (`id`, `user_id`, `currency`, `total_amount`, `invoice_payload`, `shipping_option_id`, `order_info`, `created_at`)
834
                VALUES
835
                (:id, :user_id, :currency, :total_amount, :invoice_payload, :shipping_option_id, :order_info, :created_at)
836
            ');
837
838
            $date    = self::getTimestamp();
839
            $user_id = null;
840
841
            if ($user = $pre_checkout_query->getFrom()) {
842
                $user_id = $user->getId();
843
                self::insertUser($user, $date);
844
            }
845
846
            $sth->bindValue(':id', $pre_checkout_query->getId());
847
            $sth->bindValue(':user_id', $user_id);
848
            $sth->bindValue(':currency', $pre_checkout_query->getCurrency());
849
            $sth->bindValue(':total_amount', $pre_checkout_query->getTotalAmount());
850
            $sth->bindValue(':invoice_payload', $pre_checkout_query->getInvoicePayload());
851
            $sth->bindValue(':shipping_option_id', $pre_checkout_query->getShippingOptionId());
852
            $sth->bindValue(':order_info', $pre_checkout_query->getOrderInfo());
853
            $sth->bindValue(':created_at', $date);
854
855
            return $sth->execute();
856
        } catch (PDOException $e) {
857
            throw new TelegramException($e->getMessage());
858
        }
859
    }
860
861
    /**
862
     * Insert poll request into database
863
     *
864
     * @param Poll $poll
865
     *
866
     * @return bool If the insert was successful
867
     * @throws TelegramException
868
     */
869
    public static function insertPollRequest(Poll $poll): bool
870
    {
871
        if (!self::isDbConnected()) {
872
            return false;
873
        }
874
875
        try {
876
            $sth = self::$pdo->prepare('
877
                INSERT INTO `' . TB_POLL . '`
878
                (`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`)
879
                VALUES
880
                (: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)
881
                ON DUPLICATE KEY UPDATE
882
                    `options`                 = VALUES(`options`),
883
                    `total_voter_count`       = VALUES(`total_voter_count`),
884
                    `is_closed`               = VALUES(`is_closed`),
885
                    `is_anonymous`            = VALUES(`is_anonymous`),
886
                    `type`                    = VALUES(`type`),
887
                    `allows_multiple_answers` = VALUES(`allows_multiple_answers`),
888
                    `correct_option_id`       = VALUES(`correct_option_id`),
889
                    `explanation`             = VALUES(`explanation`),
890
                    `explanation_entities`    = VALUES(`explanation_entities`),
891
                    `open_period`             = VALUES(`open_period`),
892
                    `close_date`              = VALUES(`close_date`)
893
            ');
894
895
            $sth->bindValue(':id', $poll->getId());
896
            $sth->bindValue(':question', $poll->getQuestion());
897
            $sth->bindValue(':options', self::entitiesArrayToJson($poll->getOptions() ?: []));
898
            $sth->bindValue(':total_voter_count', $poll->getTotalVoterCount());
899
            $sth->bindValue(':is_closed', $poll->getIsClosed(), PDO::PARAM_INT);
900
            $sth->bindValue(':is_anonymous', $poll->getIsAnonymous(), PDO::PARAM_INT);
901
            $sth->bindValue(':type', $poll->getType());
902
            $sth->bindValue(':allows_multiple_answers', $poll->getAllowsMultipleAnswers(), PDO::PARAM_INT);
903
            $sth->bindValue(':correct_option_id', $poll->getCorrectOptionId());
904
            $sth->bindValue(':explanation', $poll->getExplanation());
905
            $sth->bindValue(':explanation_entities', self::entitiesArrayToJson($poll->getExplanationEntities() ?: []));
906
            $sth->bindValue(':open_period', $poll->getOpenPeriod());
907
            $sth->bindValue(':close_date', self::getTimestamp($poll->getCloseDate()));
908
            $sth->bindValue(':created_at', self::getTimestamp());
909
910
            return $sth->execute();
911
        } catch (PDOException $e) {
912
            throw new TelegramException($e->getMessage());
913
        }
914
    }
915
916
    /**
917
     * Insert poll answer request into database
918
     *
919
     * @param PollAnswer $poll_answer
920
     *
921
     * @return bool If the insert was successful
922
     * @throws TelegramException
923
     */
924
    public static function insertPollAnswerRequest(PollAnswer $poll_answer): bool
925
    {
926
        if (!self::isDbConnected()) {
927
            return false;
928
        }
929
930
        try {
931
            $sth = self::$pdo->prepare('
932
                INSERT INTO `' . TB_POLL_ANSWER . '`
933
                (`poll_id`, `user_id`, `option_ids`, `created_at`)
934
                VALUES
935
                (:poll_id, :user_id, :option_ids, :created_at)
936
                ON DUPLICATE KEY UPDATE
937
                    `option_ids` = VALUES(`option_ids`)
938
            ');
939
940
            $date    = self::getTimestamp();
941
            $user_id = null;
942
943
            if ($user = $poll_answer->getUser()) {
944
                $user_id = $user->getId();
945
                self::insertUser($user, $date);
946
            }
947
948
            $sth->bindValue(':poll_id', $poll_answer->getPollId());
949
            $sth->bindValue(':user_id', $user_id);
950
            $sth->bindValue(':option_ids', json_encode($poll_answer->getOptionIds()));
951
            $sth->bindValue(':created_at', $date);
952
953
            return $sth->execute();
954
        } catch (PDOException $e) {
955
            throw new TelegramException($e->getMessage());
956
        }
957
    }
958
959
    /**
960
     * Insert chat member updated request into database
961
     *
962
     * @param ChatMemberUpdated $chat_member_updated
963
     *
964
     * @return bool If the insert was successful
965
     * @throws TelegramException
966
     */
967
    public static function insertChatMemberUpdatedRequest(ChatMemberUpdated $chat_member_updated): bool
968
    {
969
        if (!self::isDbConnected()) {
970
            return false;
971
        }
972
973
        try {
974
            $sth = self::$pdo->prepare('
975
                INSERT INTO `' . TB_CHAT_MEMBER_UPDATED . '`
976
                (`chat_id`, `user_id`, `date`, `old_chat_member`, `new_chat_member`, `invite_link`, `created_at`)
977
                VALUES
978
                (:chat_id, :user_id, :date, :old_chat_member, :new_chat_member, :invite_link, :created_at)
979
            ');
980
981
            $date    = self::getTimestamp();
982
            $chat_id = null;
983
            $user_id = null;
984
985
            if ($chat = $chat_member_updated->getChat()) {
986
                $chat_id = $chat->getId();
987
                self::insertChat($chat, $date);
988
            }
989
            if ($user = $chat_member_updated->getFrom()) {
990
                $user_id = $user->getId();
991
                self::insertUser($user, $date);
992
            }
993
994
            $sth->bindValue(':chat_id', $chat_id);
995
            $sth->bindValue(':user_id', $user_id);
996
            $sth->bindValue(':date', self::getTimestamp($chat_member_updated->getDate()));
997
            $sth->bindValue(':old_chat_member', $chat_member_updated->getOldChatMember());
998
            $sth->bindValue(':new_chat_member', $chat_member_updated->getNewChatMember());
999
            $sth->bindValue(':invite_link', $chat_member_updated->getInviteLink());
1000
            $sth->bindValue(':created_at', $date);
1001
1002
            return $sth->execute();
1003
        } catch (PDOException $e) {
1004
            throw new TelegramException($e->getMessage());
1005
        }
1006
    }
1007
1008
    /**
1009
     * Insert chat join request into database
1010
     *
1011
     * @param ChatJoinRequest $chat_join_request
1012
     *
1013
     * @return bool If the insert was successful
1014
     * @throws TelegramException
1015
     */
1016
    public static function insertChatJoinRequestRequest(ChatJoinRequest $chat_join_request): bool
0 ignored issues
show
Bug introduced by
The type Longman\TelegramBot\ChatJoinRequest was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
1017
    {
1018
        if (!self::isDbConnected()) {
1019
            return false;
1020
        }
1021
1022
        try {
1023
            $sth = self::$pdo->prepare('
1024
                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...
1025
                (`chat_id`, `user_id`, `date`, `bio`, `invite_link`, `created_at`)
1026
                VALUES
1027
                (:chat_id, :user_id, :date, :bio, :invite_link, :created_at)
1028
            ');
1029
1030
            $date    = self::getTimestamp();
1031
            $chat_id = null;
1032
            $user_id = null;
1033
1034
            if ($chat = $chat_join_request->getChat()) {
1035
                $chat_id = $chat->getId();
1036
                self::insertChat($chat, $date);
1037
            }
1038
            if ($user = $chat_join_request->getFrom()) {
1039
                $user_id = $user->getId();
1040
                self::insertUser($user, $date);
1041
            }
1042
1043
            $sth->bindValue(':chat_id', $chat_id);
1044
            $sth->bindValue(':user_id', $user_id);
1045
            $sth->bindValue(':date', self::getTimestamp($chat_join_request->getDate()));
1046
            $sth->bindValue(':bio', $chat_join_request->getBio());
1047
            $sth->bindValue(':invite_link', $chat_join_request->getInviteLink());
1048
            $sth->bindValue(':created_at', $date);
1049
1050
            return $sth->execute();
1051
        } catch (PDOException $e) {
1052
            throw new TelegramException($e->getMessage());
1053
        }
1054
    }
1055
1056
    /**
1057
     * Insert Message request in db
1058
     *
1059
     * @param Message $message
1060
     *
1061
     * @return bool If the insert was successful
1062
     * @throws TelegramException
1063
     */
1064
    public static function insertMessageRequest(Message $message): bool
1065
    {
1066
        if (!self::isDbConnected()) {
1067
            return false;
1068
        }
1069
1070
        $date = self::getTimestamp($message->getDate());
1071
1072
        // Insert chat, update chat id in case it migrated
1073
        $chat = $message->getChat();
1074
        self::insertChat($chat, $date, $message->getMigrateToChatId());
1075
1076
        $sender_chat_id = null;
1077
        if ($sender_chat = $message->getSenderChat()) {
1078
            self::insertChat($sender_chat);
1079
            $sender_chat_id = $sender_chat->getId();
1080
        }
1081
1082
        // Insert user and the relation with the chat
1083
        if ($user = $message->getFrom()) {
1084
            self::insertUser($user, $date, $chat);
1085
        }
1086
1087
        // Insert the forwarded message user in users table
1088
        $forward_date = $message->getForwardDate() ? self::getTimestamp($message->getForwardDate()) : null;
1089
1090
        if ($forward_from = $message->getForwardFrom()) {
1091
            self::insertUser($forward_from);
1092
            $forward_from = $forward_from->getId();
1093
        }
1094
        if ($forward_from_chat = $message->getForwardFromChat()) {
1095
            self::insertChat($forward_from_chat);
1096
            $forward_from_chat = $forward_from_chat->getId();
1097
        }
1098
1099
        $via_bot_id = null;
1100
        if ($via_bot = $message->getViaBot()) {
1101
            self::insertUser($via_bot);
1102
            $via_bot_id = $via_bot->getId();
1103
        }
1104
1105
        // New and left chat member
1106
        $new_chat_members_ids = null;
1107
        $left_chat_member_id  = null;
1108
1109
        $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

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