Issues (236)

src/receiver/receiver.php (3 issues)

1
<?php
2
3
namespace BPT\receiver;
4
5
use BPT\BPT;
6
use BPT\constants\fields;
7
use BPT\constants\loggerTypes;
8
use BPT\database\db;
9
use BPT\logger;
10
use BPT\settings;
11
use BPT\telegram\telegram;
12
use BPT\tools\tools;
13
use BPT\types\update;
14
use stdClass;
15
16
/**
17
 * receiver class , will be used in webhook and getUpdates classes
18
 */
19
class receiver {
20
    private static array $handlers = [
21
        'message' => null,
22
        'edited_message' => null,
23
        'channel_post' => null,
24
        'edited_channel_post' => null,
25
        'inline_query' => null,
26
        'callback_query' => null,
27
        'my_chat_member' => null,
28
        'chat_member' => null,
29
        'chat_join_request' => null,
30
        'something_else' => null
31
    ];
32
33
    protected static function telegramVerify(string $ip = null): void {
34
        if (settings::$telegram_verify) {
35
            $ip = $ip ?? tools::remoteIP();
36
            if (!tools::isTelegram($ip)) {
37
                if (!callback::process()) {
38
                    logger::write('not authorized access denied. IP : '. $ip ?? 'unknown',loggerTypes::WARNING);
39
                    BPT::exit();
40
                }
41
                die('callback handler stole the process :(');
0 ignored issues
show
Using exit here is not recommended.

In general, usage of exit should be done with care and only when running in a scripting context like a CLI script.

Loading history...
42
            }
43
        }
44
    }
45
46
    protected static function processUpdate(string|stdClass|update $update = null): void {
47
        if (!is_object($update)) {
48
            $update = json_decode($update ?? file_get_contents('php://input'));
49
            if (!$update) {
50
                BPT::exit();
51
            }
52
        }
53
54
        if (settings::$ignore_updates_older_then > 0) {
55
            if (time() - settings::$ignore_updates_older_then > telegram::catchFields(fields::UPDATE_DATE)) {
56
                logger::write('Update is old, Ignored.');
57
                return;
58
            }
59
        }
60
61
        if (settings::$use_types_classes && !is_a($update,'update')) {
62
            $update = new update($update);
0 ignored issues
show
It seems like $update can also be of type string; however, parameter $object of BPT\types\update::__construct() does only seem to accept null|stdClass, maybe add an additional type check? ( Ignorable by Annotation )

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

62
            $update = new update(/** @scrutinizer ignore-type */ $update);
Loading history...
63
        }
64
65
        self::setMessageExtra($update);
0 ignored issues
show
It seems like $update can also be of type null and string; however, parameter $update of BPT\receiver\receiver::setMessageExtra() does only seem to accept BPT\types\update|stdClass, maybe add an additional type check? ( Ignorable by Annotation )

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

65
        self::setMessageExtra(/** @scrutinizer ignore-type */ $update);
Loading history...
66
        BPT::$update = $update;
67
        db::process();
68
        self::processHandler();
69
        db::save();
70
    }
71
72
    protected static function setMessageExtra (stdClass|update &$update): void {
73
        if (!isset($update->message->text) && !isset($update->edited_message->text)) {
74
            return;
75
        }
76
        $type = isset($update->message) ? 'message' : 'edited_message';
77
        $text = &$update->{$type}->text;
78
        if (settings::$security) {
79
            $text = tools::clearText($text);
80
        }
81
        if (str_starts_with($text, '/')) {
82
            preg_match('/\/([a-zA-Z_0-9]{1,64})(@[a-zA-Z]\w{1,28}bot)?( [\S]{1,64})?/', $text, $result);
83
            if (isset($result[1])) {
84
                $update->{$type}->command = $result[1];
85
            }
86
            if (isset($result[2])) {
87
                $update->{$type}->command_username = $result[2];
88
            }
89
            if (isset($result[3])) {
90
                $update->{$type}->command_payload = trim($result[3]);
91
            }
92
        }
93
    }
94
95
    private static function processHandler(): void {
96
        if (!settings::$handler) {
97
            return;
98
        }
99
        if (isset(BPT::$update->message)) {
100
            if (self::handlerExist('message')) {
101
                BPT::$handler->message(BPT::$update->message);
102
            }
103
        }
104
        elseif (isset(BPT::$update->edited_message)) {
105
            if (self::handlerExist('edited_message')) {
106
                BPT::$handler->edited_message(BPT::$update->edited_message);
107
            }
108
        }
109
        elseif (isset(BPT::$update->channel_post)) {
110
            if (self::handlerExist('channel_post')) {
111
                BPT::$handler->channel_post(BPT::$update->channel_post);
112
            }
113
        }
114
        elseif (isset(BPT::$update->edited_channel_post)) {
115
            if (self::handlerExist('edited_channel_post')) {
116
                BPT::$handler->edited_channel_post(BPT::$update->edited_channel_post);
117
            }
118
        }
119
        elseif (isset(BPT::$update->inline_query)) {
120
            if (self::handlerExist('inline_query')) {
121
                BPT::$handler->inline_query(BPT::$update->inline_query);
122
            }
123
        }
124
        elseif (isset(BPT::$update->callback_query)) {
125
            if (self::handlerExist('callback_query')) {
126
                BPT::$handler->callback_query(BPT::$update->callback_query);
127
            }
128
        }
129
        elseif (isset(BPT::$update->my_chat_member)) {
130
            if (self::handlerExist('my_chat_member')) {
131
                BPT::$handler->my_chat_member(BPT::$update->my_chat_member);
132
            }
133
        }
134
        elseif (isset(BPT::$update->chat_member)) {
135
            if (self::handlerExist('chat_member')) {
136
                BPT::$handler->chat_member(BPT::$update->chat_member);
137
            }
138
        }
139
        elseif (isset(BPT::$update->chat_join_request)) {
140
            if (self::handlerExist('chat_join_request')) {
141
                BPT::$handler->chat_join_request(BPT::$update->chat_join_request);
142
            }
143
        }
144
        elseif (self::handlerExist('something_else')) {
145
            BPT::$handler->something_else(BPT::$update);
146
        }
147
        else {
148
            logger::write('Update received but handlers are not set',loggerTypes::WARNING);
149
        }
150
    }
151
152
    private static function handlerExist(string $handler): bool {
153
        if (empty(self::$handlers[$handler])) {
154
            self::$handlers[$handler] = method_exists(BPT::$handler, $handler);
155
        }
156
        return self::$handlers[$handler];
157
    }
158
}