Completed
Push — develop ( b6ea35...0b92b7 )
by Armando
15s queued 12s
created

DB::insertUser()   B

Complexity

Conditions 6
Paths 18

Size

Total Lines 56
Code Lines 27

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 21
CRAP Score 6.256

Importance

Changes 2
Bugs 0 Features 0
Metric Value
cc 6
eloc 27
c 2
b 0
f 0
nc 18
nop 3
dl 0
loc 56
ccs 21
cts 26
cp 0.8077
crap 6.256
rs 8.8657

How to fix   Long Method   

Long Method

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

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

Commonly applied refactorings include:

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

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

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