Completed
Push — add_missing_db_fields ( b02735...4c98cf )
by Armando
02:45
created

DB::getTelegramRequestCount()   A

Complexity

Conditions 3
Paths 13

Size

Total Lines 30

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 12

Importance

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

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
575
    {
576
        if (!self::isDbConnected()) {
577
            return false;
578
        }
579
580
        try {
581
            $sth = self::$pdo->prepare('
582
                INSERT IGNORE INTO `' . TB_INLINE_QUERY . '`
583
                (`id`, `user_id`, `location`, `query`, `offset`, `created_at`)
584
                VALUES
585
                (:id, :user_id, :location, :query, :offset, :created_at)
586
            ');
587
588
            $date    = self::getTimestamp();
589
            $user_id = null;
590
591
            $user = $inline_query->getFrom();
592
            if ($user instanceof User) {
593
                $user_id = $user->getId();
594
                self::insertUser($user, $date);
595
            }
596
597
            $sth->bindValue(':id', $inline_query->getId());
598
            $sth->bindValue(':user_id', $user_id);
599
            $sth->bindValue(':location', $inline_query->getLocation());
600
            $sth->bindValue(':query', $inline_query->getQuery());
601
            $sth->bindValue(':offset', $inline_query->getOffset());
602
            $sth->bindValue(':created_at', $date);
603
604
            return $sth->execute();
605
        } catch (PDOException $e) {
606
            throw new TelegramException($e->getMessage());
607
        }
608
    }
609
610
    /**
611
     * Insert chosen inline result request into database
612
     *
613
     * @param ChosenInlineResult $chosen_inline_result
614
     *
615
     * @return bool If the insert was successful
616
     * @throws TelegramException
617
     */
618 View Code Duplication
    public static function insertChosenInlineResultRequest(ChosenInlineResult $chosen_inline_result)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
619
    {
620
        if (!self::isDbConnected()) {
621
            return false;
622
        }
623
624
        try {
625
            $sth = self::$pdo->prepare('
626
                INSERT INTO `' . TB_CHOSEN_INLINE_RESULT . '`
627
                (`result_id`, `user_id`, `location`, `inline_message_id`, `query`, `created_at`)
628
                VALUES
629
                (:result_id, :user_id, :location, :inline_message_id, :query, :created_at)
630
            ');
631
632
            $date    = self::getTimestamp();
633
            $user_id = null;
634
635
            $user = $chosen_inline_result->getFrom();
636
            if ($user instanceof User) {
637
                $user_id = $user->getId();
638
                self::insertUser($user, $date);
639
            }
640
641
            $sth->bindValue(':result_id', $chosen_inline_result->getResultId());
642
            $sth->bindValue(':user_id', $user_id);
643
            $sth->bindValue(':location', $chosen_inline_result->getLocation());
644
            $sth->bindValue(':inline_message_id', $chosen_inline_result->getInlineMessageId());
645
            $sth->bindValue(':query', $chosen_inline_result->getQuery());
646
            $sth->bindValue(':created_at', $date);
647
648
            return $sth->execute();
649
        } catch (PDOException $e) {
650
            throw new TelegramException($e->getMessage());
651
        }
652
    }
653
654
    /**
655
     * Insert callback query request into database
656
     *
657
     * @param CallbackQuery $callback_query
658
     *
659
     * @return bool If the insert was successful
660
     * @throws TelegramException
661
     */
662
    public static function insertCallbackQueryRequest(CallbackQuery $callback_query)
663
    {
664
        if (!self::isDbConnected()) {
665
            return false;
666
        }
667
668
        try {
669
            $sth = self::$pdo->prepare('
670
                INSERT IGNORE INTO `' . TB_CALLBACK_QUERY . '`
671
                (`id`, `user_id`, `chat_id`, `message_id`, `inline_message_id`, `chat_instance`, `data`, `game_short_name`, `created_at`)
672
                VALUES
673
                (:id, :user_id, :chat_id, :message_id, :inline_message_id, :chat_instance, :data, :game_short_name, :created_at)
674
            ');
675
676
            $date    = self::getTimestamp();
677
            $user_id = null;
678
679
            $user = $callback_query->getFrom();
680
            if ($user instanceof User) {
681
                $user_id = $user->getId();
682
                self::insertUser($user, $date);
683
            }
684
685
            $message    = $callback_query->getMessage();
686
            $chat_id    = null;
687
            $message_id = null;
688
            if ($message instanceof Message) {
689
                $chat_id    = $message->getChat()->getId();
690
                $message_id = $message->getMessageId();
691
692
                $is_message = self::$pdo->query('
693
                    SELECT *
694
                    FROM `' . TB_MESSAGE . '`
695
                    WHERE `id` = ' . $message_id . '
696
                      AND `chat_id` = ' . $chat_id . '
697
                    LIMIT 1
698
                ')->rowCount();
699
700
                if ($is_message) {
701
                    self::insertEditedMessageRequest($message);
702
                } else {
703
                    self::insertMessageRequest($message);
704
                }
705
            }
706
707
            $sth->bindValue(':id', $callback_query->getId());
708
            $sth->bindValue(':user_id', $user_id);
709
            $sth->bindValue(':chat_id', $chat_id);
710
            $sth->bindValue(':message_id', $message_id);
711
            $sth->bindValue(':inline_message_id', $callback_query->getInlineMessageId());
712
            $sth->bindValue(':chat_instance', $callback_query->getChatInstance());
713
            $sth->bindValue(':data', $callback_query->getData());
714
            $sth->bindValue(':game_short_name', $callback_query->getGameShortName());
715
            $sth->bindValue(':created_at', $date);
716
717
            return $sth->execute();
718
        } catch (PDOException $e) {
719
            throw new TelegramException($e->getMessage());
720
        }
721
    }
722
723
    /**
724
     * Insert shipping query request into database
725
     *
726
     * @param ShippingQuery $shipping_query
727
     *
728
     * @return bool If the insert was successful
729
     * @throws TelegramException
730
     */
731 View Code Duplication
    public static function insertShippingQueryRequest(ShippingQuery $shipping_query)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
732
    {
733
        if (!self::isDbConnected()) {
734
            return false;
735
        }
736
737
        try {
738
            $sth = self::$pdo->prepare('
739
                INSERT IGNORE INTO `' . TB_SHIPPING_QUERY . '`
740
                (`id`, `user_id`, `chat_id`, `invoice_payload`, `shipping_address`, `created_at`)
741
                VALUES
742
                (:id, :user_id, :chat_id, :invoice_payload, :shipping_address, :created_at)
743
            ');
744
745
            $date    = self::getTimestamp();
746
            $user_id = null;
747
748
            $user = $shipping_query->getFrom();
749
            if ($user instanceof User) {
750
                $user_id = $user->getId();
751
                self::insertUser($user, $date);
752
            }
753
754
            $sth->bindValue(':id', $shipping_query->getId());
755
            $sth->bindValue(':user_id', $user_id);
756
            $sth->bindValue(':invoice_payload', $shipping_query->getInvoicePayload());
757
            $sth->bindValue(':shipping_address', $shipping_query->getShippingAddress());
758
            $sth->bindValue(':created_at', $date);
759
760
            return $sth->execute();
761
        } catch (PDOException $e) {
762
            throw new TelegramException($e->getMessage());
763
        }
764
    }
765
766
    /**
767
     * Insert pre checkout query request into database
768
     *
769
     * @param PreCheckoutQuery $pre_checkout_query
770
     *
771
     * @return bool If the insert was successful
772
     * @throws TelegramException
773
     */
774
    public static function insertPreCheckoutQueryRequest(PreCheckoutQuery $pre_checkout_query)
775
    {
776
        if (!self::isDbConnected()) {
777
            return false;
778
        }
779
780
        try {
781
            $sth = self::$pdo->prepare('
782
                INSERT IGNORE INTO `' . TB_PRE_CHECKOUT_QUERY . '`
783
                (`id`, `user_id`, `currency`, `total_amount`, `invoice_payload`, `shipping_option_id`, `order_info`, `created_at`)
784
                VALUES
785
                (:id, :user_id, :currency, :total_amount, :invoice_payload, :shipping_option_id, :order_info, :created_at)
786
            ');
787
788
            $date    = self::getTimestamp();
789
            $user_id = null;
790
791
            $user = $pre_checkout_query->getFrom();
792
            if ($user instanceof User) {
793
                $user_id = $user->getId();
794
                self::insertUser($user, $date);
795
            }
796
797
            $sth->bindValue(':id', $pre_checkout_query->getId());
798
            $sth->bindValue(':user_id', $user_id);
799
            $sth->bindValue(':currency', $pre_checkout_query->getCurrency());
800
            $sth->bindValue(':total_amount', $pre_checkout_query->getTotalAmount());
801
            $sth->bindValue(':invoice_payload', $pre_checkout_query->getInvoicePayload());
802
            $sth->bindValue(':shipping_option_id', $pre_checkout_query->getShippingOptionId());
803
            $sth->bindValue(':order_info', $pre_checkout_query->getOrderInfo());
804
            $sth->bindValue(':created_at', $date);
805
806
            return $sth->execute();
807
        } catch (PDOException $e) {
808
            throw new TelegramException($e->getMessage());
809
        }
810
    }
811
812
    /**
813
     * Insert Message request in db
814
     *
815
     * @param Message $message
816
     *
817
     * @return bool If the insert was successful
818
     * @throws TelegramException
819
     */
820 6
    public static function insertMessageRequest(Message $message)
821
    {
822 6
        if (!self::isDbConnected()) {
823
            return false;
824
        }
825
826 6
        $date = self::getTimestamp($message->getDate());
827
828
        // Insert chat, update chat id in case it migrated
829 6
        $chat = $message->getChat();
830 6
        self::insertChat($chat, $date, $message->getMigrateToChatId());
831
832
        // Insert user and the relation with the chat
833 6
        $user = $message->getFrom();
834 6
        if ($user instanceof User) {
835 6
            self::insertUser($user, $date, $chat);
836
        }
837
838
        // Insert the forwarded message user in users table
839 6
        $forward_date = null;
840 6
        $forward_from = $message->getForwardFrom();
841 6
        if ($forward_from instanceof User) {
842
            self::insertUser($forward_from, $forward_date);
843
            $forward_from = $forward_from->getId();
844
            $forward_date = self::getTimestamp($message->getForwardDate());
845
        }
846 6
        $forward_from_chat = $message->getForwardFromChat();
847 6
        if ($forward_from_chat instanceof Chat) {
848
            self::insertChat($forward_from_chat, $forward_date);
849
            $forward_from_chat = $forward_from_chat->getId();
850
            $forward_date      = self::getTimestamp($message->getForwardDate());
851
        }
852
853
        // New and left chat member
854 6
        $new_chat_members_ids = null;
855 6
        $left_chat_member_id  = null;
856
857 6
        $new_chat_members = $message->getNewChatMembers();
858 6
        $left_chat_member = $message->getLeftChatMember();
859 6
        if (!empty($new_chat_members)) {
860
            foreach ($new_chat_members as $new_chat_member) {
861
                if ($new_chat_member instanceof User) {
862
                    // Insert the new chat user
863
                    self::insertUser($new_chat_member, $date, $chat);
864
                    $new_chat_members_ids[] = $new_chat_member->getId();
865
                }
866
            }
867
            $new_chat_members_ids = implode(',', $new_chat_members_ids);
868 6
        } elseif ($left_chat_member instanceof User) {
869
            // Insert the left chat user
870
            self::insertUser($left_chat_member, $date, $chat);
871
            $left_chat_member_id = $left_chat_member->getId();
872
        }
873
874
        try {
875 6
            $sth = self::$pdo->prepare('
876 6
                INSERT IGNORE INTO `' . TB_MESSAGE . '`
877
                (
878
                    `id`, `user_id`, `chat_id`, `date`, `forward_from`, `forward_from_chat`, `forward_from_message_id`,
879
                    `forward_signature`, `forward_date`, `reply_to_chat`, `reply_to_message`, `edit_date`, `media_group_id`, `author_signature`, `text`, `entities`, `caption_entities`, `audio`, `document`,
880
                    `animation`, `game`, `photo`, `sticker`, `video`, `voice`, `video_note`, `caption`, `contact`,
881
                    `location`, `venue`, `new_chat_members`, `left_chat_member`,
882
                    `new_chat_title`,`new_chat_photo`, `delete_chat_photo`, `group_chat_created`,
883
                    `supergroup_chat_created`, `channel_chat_created`,
884
                    `migrate_from_chat_id`, `migrate_to_chat_id`, `pinned_message`, `invoice`, `successful_payment`, `connected_website`
885
                ) VALUES (
886
                    :message_id, :user_id, :chat_id, :date, :forward_from, :forward_from_chat, :forward_from_message_id,
887
                    :forward_signature, :forward_date, :reply_to_chat, :reply_to_message, :edit_date, :media_group_id, :author_signature, :text, :entities, :caption_entities, :audio, :document,
888
                    :animation, :game, :photo, :sticker, :video, :voice, :video_note, :caption, :contact,
889
                    :location, :venue, :new_chat_members, :left_chat_member,
890
                    :new_chat_title, :new_chat_photo, :delete_chat_photo, :group_chat_created,
891
                    :supergroup_chat_created, :channel_chat_created,
892
                    :migrate_from_chat_id, :migrate_to_chat_id, :pinned_message, :invoice, :successful_payment, :connected_website
893
                )
894
            ');
895
896 6
            $user_id = null;
897 6
            if ($user instanceof User) {
898 6
                $user_id = $user->getId();
899
            }
900 6
            $chat_id = $chat->getId();
901
902 6
            $reply_to_message    = $message->getReplyToMessage();
903 6
            $reply_to_message_id = null;
904 6
            if ($reply_to_message instanceof ReplyToMessage) {
905
                $reply_to_message_id = $reply_to_message->getMessageId();
906
                // please notice that, as explained in the documentation, reply_to_message don't contain other
907
                // reply_to_message field so recursion deep is 1
908
                self::insertMessageRequest($reply_to_message);
909
            }
910
911 6
            $sth->bindValue(':message_id', $message->getMessageId());
912 6
            $sth->bindValue(':chat_id', $chat_id);
913 6
            $sth->bindValue(':user_id', $user_id);
914 6
            $sth->bindValue(':date', $date);
915 6
            $sth->bindValue(':forward_from', $forward_from);
916 6
            $sth->bindValue(':forward_from_chat', $forward_from_chat);
917 6
            $sth->bindValue(':forward_from_message_id', $message->getForwardFromMessageId());
918 6
            $sth->bindValue(':forward_signature', $message->getForwardSignature());
919 6
            $sth->bindValue(':forward_date', $forward_date);
920
921 6
            $reply_to_chat_id = null;
922 6
            if ($reply_to_message_id !== null) {
923
                $reply_to_chat_id = $chat_id;
924
            }
925 6
            $sth->bindValue(':reply_to_chat', $reply_to_chat_id);
926 6
            $sth->bindValue(':reply_to_message', $reply_to_message_id);
927
928 6
            $sth->bindValue(':edit_date', $message->getEditDate());
929 6
            $sth->bindValue(':media_group_id', $message->getMediaGroupId());
930 6
            $sth->bindValue(':author_signature', $message->getAuthorSignature());
931 6
            $sth->bindValue(':text', $message->getText());
932 6
            $sth->bindValue(':entities', self::entitiesArrayToJson($message->getEntities(), null));
933 6
            $sth->bindValue(':caption_entities', self::entitiesArrayToJson($message->getCaptionEntities(), null));
934 6
            $sth->bindValue(':audio', $message->getAudio());
935 6
            $sth->bindValue(':document', $message->getDocument());
936 6
            $sth->bindValue(':animation', $message->getAnimation());
937 6
            $sth->bindValue(':game', $message->getGame());
938 6
            $sth->bindValue(':photo', self::entitiesArrayToJson($message->getPhoto(), null));
939 6
            $sth->bindValue(':sticker', $message->getSticker());
940 6
            $sth->bindValue(':video', $message->getVideo());
941 6
            $sth->bindValue(':voice', $message->getVoice());
942 6
            $sth->bindValue(':video_note', $message->getVideoNote());
943 6
            $sth->bindValue(':caption', $message->getCaption());
944 6
            $sth->bindValue(':contact', $message->getContact());
945 6
            $sth->bindValue(':location', $message->getLocation());
946 6
            $sth->bindValue(':venue', $message->getVenue());
947 6
            $sth->bindValue(':new_chat_members', $new_chat_members_ids);
948 6
            $sth->bindValue(':left_chat_member', $left_chat_member_id);
949 6
            $sth->bindValue(':new_chat_title', $message->getNewChatTitle());
950 6
            $sth->bindValue(':new_chat_photo', self::entitiesArrayToJson($message->getNewChatPhoto(), null));
951 6
            $sth->bindValue(':delete_chat_photo', $message->getDeleteChatPhoto());
952 6
            $sth->bindValue(':group_chat_created', $message->getGroupChatCreated());
953 6
            $sth->bindValue(':supergroup_chat_created', $message->getSupergroupChatCreated());
954 6
            $sth->bindValue(':channel_chat_created', $message->getChannelChatCreated());
955 6
            $sth->bindValue(':migrate_from_chat_id', $message->getMigrateFromChatId());
956 6
            $sth->bindValue(':migrate_to_chat_id', $message->getMigrateToChatId());
957 6
            $sth->bindValue(':pinned_message', $message->getPinnedMessage());
958 6
            $sth->bindValue(':invoice', $message->getInvoice());
959 6
            $sth->bindValue(':successful_payment', $message->getSuccessfulPayment());
960 6
            $sth->bindValue(':connected_website', $message->getConnectedWebsite());
961
962 6
            return $sth->execute();
963
        } catch (PDOException $e) {
964
            throw new TelegramException($e->getMessage());
965
        }
966
    }
967
968
    /**
969
     * Insert Edited Message request in db
970
     *
971
     * @param Message $edited_message
972
     *
973
     * @return bool If the insert was successful
974
     * @throws TelegramException
975
     */
976
    public static function insertEditedMessageRequest(Message $edited_message)
977
    {
978
        if (!self::isDbConnected()) {
979
            return false;
980
        }
981
982
        try {
983
            $edit_date = self::getTimestamp($edited_message->getEditDate());
984
985
            // Insert chat
986
            $chat = $edited_message->getChat();
987
            self::insertChat($chat, $edit_date);
988
989
            // Insert user and the relation with the chat
990
            $user = $edited_message->getFrom();
991
            if ($user instanceof User) {
992
                self::insertUser($user, $edit_date, $chat);
993
            }
994
995
            $sth = self::$pdo->prepare('
996
                INSERT IGNORE INTO `' . TB_EDITED_MESSAGE . '`
997
                (`chat_id`, `message_id`, `user_id`, `edit_date`, `text`, `entities`, `caption`)
998
                VALUES
999
                (:chat_id, :message_id, :user_id, :edit_date, :text, :entities, :caption)
1000
            ');
1001
1002
            $user_id = null;
1003
            if ($user instanceof User) {
1004
                $user_id = $user->getId();
1005
            }
1006
1007
            $sth->bindValue(':chat_id', $chat->getId());
1008
            $sth->bindValue(':message_id', $edited_message->getMessageId());
1009
            $sth->bindValue(':user_id', $user_id);
1010
            $sth->bindValue(':edit_date', $edit_date);
1011
            $sth->bindValue(':text', $edited_message->getText());
1012
            $sth->bindValue(':entities', self::entitiesArrayToJson($edited_message->getEntities(), null));
1013
            $sth->bindValue(':caption', $edited_message->getCaption());
1014
1015
            return $sth->execute();
1016
        } catch (PDOException $e) {
1017
            throw new TelegramException($e->getMessage());
1018
        }
1019
    }
1020
1021
    /**
1022
     * Select Groups, Supergroups, Channels and/or single user Chats (also by ID or text)
1023
     *
1024
     * @param $select_chats_params
1025
     *
1026
     * @return array|bool
1027
     * @throws TelegramException
1028
     */
1029
    public static function selectChats($select_chats_params)
1030
    {
1031
        if (!self::isDbConnected()) {
1032
            return false;
1033
        }
1034
1035
        // Set defaults for omitted values.
1036
        $select = array_merge([
1037
            'groups'      => true,
1038
            'supergroups' => true,
1039
            'channels'    => true,
1040
            'users'       => true,
1041
            'date_from'   => null,
1042
            'date_to'     => null,
1043
            'chat_id'     => null,
1044
            'text'        => null,
1045
        ], $select_chats_params);
1046
1047
        if (!$select['groups'] && !$select['users'] && !$select['supergroups'] && !$select['channels']) {
1048
            return false;
1049
        }
1050
1051
        try {
1052
            $query = '
1053
                SELECT * ,
1054
                ' . TB_CHAT . '.`id` AS `chat_id`,
1055
                ' . TB_CHAT . '.`username` AS `chat_username`,
1056
                ' . TB_CHAT . '.`created_at` AS `chat_created_at`,
1057
                ' . TB_CHAT . '.`updated_at` AS `chat_updated_at`
1058
            ';
1059
            if ($select['users']) {
1060
                $query .= '
1061
                    , ' . TB_USER . '.`id` AS `user_id`
1062
                    FROM `' . TB_CHAT . '`
1063
                    LEFT JOIN `' . TB_USER . '`
1064
                    ON ' . TB_CHAT . '.`id`=' . TB_USER . '.`id`
1065
                ';
1066
            } else {
1067
                $query .= 'FROM `' . TB_CHAT . '`';
1068
            }
1069
1070
            // Building parts of query
1071
            $where  = [];
1072
            $tokens = [];
1073
1074
            if (!$select['groups'] || !$select['users'] || !$select['supergroups'] || !$select['channels']) {
1075
                $chat_or_user = [];
1076
1077
                $select['groups'] && $chat_or_user[] = TB_CHAT . '.`type` = "group"';
1078
                $select['supergroups'] && $chat_or_user[] = TB_CHAT . '.`type` = "supergroup"';
1079
                $select['channels'] && $chat_or_user[] = TB_CHAT . '.`type` = "channel"';
1080
                $select['users'] && $chat_or_user[] = TB_CHAT . '.`type` = "private"';
1081
1082
                $where[] = '(' . implode(' OR ', $chat_or_user) . ')';
1083
            }
1084
1085
            if (null !== $select['date_from']) {
1086
                $where[]              = TB_CHAT . '.`updated_at` >= :date_from';
1087
                $tokens[':date_from'] = $select['date_from'];
1088
            }
1089
1090
            if (null !== $select['date_to']) {
1091
                $where[]            = TB_CHAT . '.`updated_at` <= :date_to';
1092
                $tokens[':date_to'] = $select['date_to'];
1093
            }
1094
1095
            if (null !== $select['chat_id']) {
1096
                $where[]            = TB_CHAT . '.`id` = :chat_id';
1097
                $tokens[':chat_id'] = $select['chat_id'];
1098
            }
1099
1100
            if (null !== $select['text']) {
1101
                $text_like = '%' . strtolower($select['text']) . '%';
1102
                if ($select['users']) {
1103
                    $where[]          = '(
1104
                        LOWER(' . TB_CHAT . '.`title`) LIKE :text1
1105
                        OR LOWER(' . TB_USER . '.`first_name`) LIKE :text2
1106
                        OR LOWER(' . TB_USER . '.`last_name`) LIKE :text3
1107
                        OR LOWER(' . TB_USER . '.`username`) LIKE :text4
1108
                    )';
1109
                    $tokens[':text1'] = $text_like;
1110
                    $tokens[':text2'] = $text_like;
1111
                    $tokens[':text3'] = $text_like;
1112
                    $tokens[':text4'] = $text_like;
1113
                } else {
1114
                    $where[]         = 'LOWER(' . TB_CHAT . '.`title`) LIKE :text';
1115
                    $tokens[':text'] = $text_like;
1116
                }
1117
            }
1118
1119
            if (!empty($where)) {
1120
                $query .= ' WHERE ' . implode(' AND ', $where);
1121
            }
1122
1123
            $query .= ' ORDER BY ' . TB_CHAT . '.`updated_at` ASC';
1124
1125
            $sth = self::$pdo->prepare($query);
1126
            $sth->execute($tokens);
1127
1128
            return $sth->fetchAll(PDO::FETCH_ASSOC);
1129
        } catch (PDOException $e) {
1130
            throw new TelegramException($e->getMessage());
1131
        }
1132
    }
1133
1134
    /**
1135
     * Get Telegram API request count for current chat / message
1136
     *
1137
     * @param integer $chat_id
1138
     * @param string  $inline_message_id
1139
     *
1140
     * @return array|bool Array containing TOTAL and CURRENT fields or false on invalid arguments
1141
     * @throws TelegramException
1142
     */
1143
    public static function getTelegramRequestCount($chat_id = null, $inline_message_id = null)
1144
    {
1145
        if (!self::isDbConnected()) {
1146
            return false;
1147
        }
1148
1149
        try {
1150
            $sth = self::$pdo->prepare('SELECT 
1151
                (SELECT COUNT(DISTINCT `chat_id`) FROM `' . TB_REQUEST_LIMITER . '` WHERE `created_at` >= :created_at_1) AS LIMIT_PER_SEC_ALL,
1152
                (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,
1153
                (SELECT COUNT(*) FROM `' . TB_REQUEST_LIMITER . '` WHERE `created_at` >= :created_at_minute AND `chat_id` = :chat_id_2) AS LIMIT_PER_MINUTE
1154
            ');
1155
1156
            $date        = self::getTimestamp();
1157
            $date_minute = self::getTimestamp(strtotime('-1 minute'));
1158
1159
            $sth->bindValue(':chat_id_1', $chat_id);
1160
            $sth->bindValue(':chat_id_2', $chat_id);
1161
            $sth->bindValue(':inline_message_id', $inline_message_id);
1162
            $sth->bindValue(':created_at_1', $date);
1163
            $sth->bindValue(':created_at_2', $date);
1164
            $sth->bindValue(':created_at_minute', $date_minute);
1165
1166
            $sth->execute();
1167
1168
            return $sth->fetch();
1169
        } catch (Exception $e) {
1170
            throw new TelegramException($e->getMessage());
1171
        }
1172
    }
1173
1174
    /**
1175
     * Insert Telegram API request in db
1176
     *
1177
     * @param string $method
1178
     * @param array  $data
1179
     *
1180
     * @return bool If the insert was successful
1181
     * @throws TelegramException
1182
     */
1183
    public static function insertTelegramRequest($method, $data)
1184
    {
1185
        if (!self::isDbConnected()) {
1186
            return false;
1187
        }
1188
1189
        try {
1190
            $sth = self::$pdo->prepare('INSERT INTO `' . TB_REQUEST_LIMITER . '`
1191
                (`method`, `chat_id`, `inline_message_id`, `created_at`)
1192
                VALUES
1193
                (:method, :chat_id, :inline_message_id, :created_at);
1194
            ');
1195
1196
            $chat_id           = isset($data['chat_id']) ? $data['chat_id'] : null;
1197
            $inline_message_id = isset($data['inline_message_id']) ? $data['inline_message_id'] : null;
1198
1199
            $sth->bindValue(':chat_id', $chat_id);
1200
            $sth->bindValue(':inline_message_id', $inline_message_id);
1201
            $sth->bindValue(':method', $method);
1202
            $sth->bindValue(':created_at', self::getTimestamp());
1203
1204
            return $sth->execute();
1205
        } catch (Exception $e) {
1206
            throw new TelegramException($e->getMessage());
1207
        }
1208
    }
1209
1210
    /**
1211
     * Bulk update the entries of any table
1212
     *
1213
     * @param string $table
1214
     * @param array  $fields_values
1215
     * @param array  $where_fields_values
1216
     *
1217
     * @return bool
1218
     * @throws TelegramException
1219
     */
1220 3
    public static function update($table, array $fields_values, array $where_fields_values)
1221
    {
1222 3
        if (empty($fields_values) || !self::isDbConnected()) {
1223
            return false;
1224
        }
1225
1226
        try {
1227
            // Building parts of query
1228 3
            $tokens = $fields = $where = [];
1229
1230
            // Fields with values to update
1231 3 View Code Duplication
            foreach ($fields_values as $field => $value) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
1232 3
                $token          = ':' . count($tokens);
1233 3
                $fields[]       = "`{$field}` = {$token}";
1234 3
                $tokens[$token] = $value;
1235
            }
1236
1237
            // Where conditions
1238 3 View Code Duplication
            foreach ($where_fields_values as $field => $value) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
1239 3
                $token          = ':' . count($tokens);
1240 3
                $where[]        = "`{$field}` = {$token}";
1241 3
                $tokens[$token] = $value;
1242
            }
1243
1244 3
            $sql = 'UPDATE `' . $table . '` SET ' . implode(', ', $fields);
1245 3
            $sql .= count($where) > 0 ? ' WHERE ' . implode(' AND ', $where) : '';
1246
1247 3
            return self::$pdo->prepare($sql)->execute($tokens);
1248
        } catch (Exception $e) {
1249
            throw new TelegramException($e->getMessage());
1250
        }
1251
    }
1252
}
1253