Passed
Push — main ( 7044f1...4122b8 )
by Miaad
01:31
created

is::isCloudFlare()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 8
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 5
c 1
b 0
f 0
dl 0
loc 8
rs 10
cc 3
nc 3
nop 1
1
<?php
2
3
namespace BPT\tools;
4
5
use BPT\api\request;
6
use BPT\api\telegram;
7
use BPT\constants\chatMemberStatus;
8
use BPT\tools;
9
use BPT\types\user;
10
11
trait is {
12
    /**
13
     * Check the given username format
14
     *
15
     * e.g. => tools::isUsername('BPT_CH');
16
     *
17
     * e.g. => tools::isUsername(username: 'BPT_CH');
18
     *
19
     * @param string $username Your text to be check is it username or not , @ is not needed
20
     *
21
     * @return bool
22
     */
23
    public static function isUsername (string $username): bool {
24
        $length = strlen($username);
25
        return !str_contains($username, '__') && $length >= 5 && $length <= 33 && preg_match('/^@?([a-zA-Z])(\w{4,31})$/', $username);
26
    }
27
28
    /**
29
     * Check given IP is in the given IP range or not
30
     *
31
     * e.g. => tools::ipInRange('192.168.1.1','149.154.160.0/20');
32
     *
33
     * e.g. => tools::ipInRange(ip: '192.168.1.1',range: '149.154.160.0/20');
34
     *
35
     * @param string $ip    Your ip
36
     * @param string $range Your range ip for check , if you didn't specify the block , it will be 32
37
     *
38
     * @return bool
39
     */
40
    public static function ipInRange (string $ip, string $range): bool {
41
        if (!str_contains($range, '/')) {
42
            $range .= '/32';
43
        }
44
        $range_full = explode('/', $range, 2);
45
        $netmask_decimal = ~(pow(2, (32 - $range_full[1])) - 1);
46
        return (ip2long($ip) & $netmask_decimal) == (ip2long($range_full[0]) & $netmask_decimal);
47
    }
48
49
    /**
50
     * Check the given IP is from telegram or not
51
     *
52
     * e.g. => tools::isTelegram('192.168.1.1');
53
     *
54
     * e.g. => tools::isTelegram(ip: '192.168.1.1');
55
     *
56
     * @param string $ip Your ip to be check is telegram or not e.g. '192.168.1.1'
57
     *
58
     * @return bool
59
     */
60
    public static function isTelegram (string $ip): bool {
61
        return tools::ipInRange($ip, '149.154.160.0/20') || tools::ipInRange($ip, '91.108.4.0/22');
62
    }
63
64
    /**
65
     * Check the given IP is from CloudFlare or not
66
     *
67
     * e.g. => tools::isCloudFlare('192.168.1.1');
68
     *
69
     * e.g. =>tools::isCloudFlare(ip: '192.168.1.1');
70
     *
71
     * @param string $ip Your ip to be check is CloudFlare or not
72
     *
73
     * @return bool
74
     */
75
    public static function isCloudFlare (string $ip): bool {
76
        $cf_ips = ['173.245.48.0/20', '103.21.244.0/22', '103.22.200.0/22', '103.31.4.0/22', '141.101.64.0/18', '108.162.192.0/18', '190.93.240.0/20', '188.114.96.0/20', '197.234.240.0/22', '198.41.128.0/17', '162.158.0.0/15', '104.16.0.0/12', '172.64.0.0/13', '131.0.72.0/22'];
77
        foreach ($cf_ips as $cf_ip) {
78
            if (self::ipInRange($ip,$cf_ip)) {
79
                return true;
80
            }
81
        }
82
        return false;
83
    }
84
85
    /**
86
     * Check the given token format
87
     *
88
     * if you want to verify token with telegram , you should set `verify` parameter => true.
89
     * in that case , if token was right , you will receive getMe result , otherwise you will receive false
90
     *
91
     * e.g. => tools::isToken('123123123:abcabcabcabc');
92
     *
93
     * @param string $token  your token e.g. => '123123123:abcabcabcabc'
94
     * @param bool   $verify check token with telegram or not
95
     *
96
     * @return bool|user return array when verify is active and token is true array of telegram getMe result
97
     */
98
    public static function isToken (string $token, bool $verify = false): bool|user {
99
        if (preg_match('/^(\d{8,10}):[\w\-]{35}$/', $token)) {
100
            if ($verify){
101
                $res = telegram::me($token);
102
                if (telegram::$status) {
103
                    return $res;
104
                }
105
                return false;
106
            }
107
            return true;
108
        }
109
        return false;
110
    }
111
112
    /**
113
     * check user joined in channels or not
114
     *
115
     * this method only return true or false, if user join in all channels true, and if user not joined in one channel false
116
     *
117
     * this method does not care about not founded channel and count them as joined channel
118
     *
119
     * ids parameter can be array for multi channels or can be string for one channel
120
     *
121
     * NOTE : each channel will decrease speed a little(because of request count)
122
     *
123
     * e.g. => tools::isJoined('BPT_CH','442109602');
124
     *
125
     * e.g. => tools::isJoined(['BPT_CH','-1005465465454']);
126
     *
127
     * @param array|string|int $ids     could be username or id, you can pass multi or single id
128
     * @param int|null         $user_id if not set , will generate by request::catchFields method
129
     *
130
     * @return bool
131
     */
132
    public static function isJoined (array|string|int $ids , int|null $user_id = null): bool {
133
        if (!is_array($ids)) {
0 ignored issues
show
introduced by
The condition is_array($ids) is always true.
Loading history...
134
            $ids = [$ids];
135
        }
136
        $user_id = $user_id ?? request::catchFields('user_id');
137
138
        foreach ($ids as $id) {
139
            $check = telegram::getChatMember($id,$user_id);
140
            if (telegram::$status) {
141
                $check = $check->status;
142
                if ($check === chatMemberStatus::LEFT || $check === chatMemberStatus::KICKED) {
143
                    return false;
144
                }
145
            }
146
        }
147
        return true;
148
    }
149
150
    /**
151
     * check user joined in channels or not
152
     *
153
     * ids parameter can be array for multi channels or can be string for one channel
154
     *
155
     * NOTE : each channel will decrease speed a little(because of request count)
156
     *
157
     * e.g. => tools::joinChecker('BPT_CH','442109602');
158
     *
159
     * e.g. => tools::joinChecker(['BPT_CH','-1005465465454']);
160
     *
161
     * @param array|string|int $ids     could be username or id, you can pass multi or single id
162
     * @param int|null         $user_id if not set , will generate by request::catchFields method
163
     *
164
     * @return array keys will be id and values will be bool(null for not founded ids)
165
     */
166
    public static function joinChecker (array|string|int $ids , int|null $user_id = null): array {
167
        if (!is_array($ids)) {
0 ignored issues
show
introduced by
The condition is_array($ids) is always true.
Loading history...
168
            $ids = [$ids];
169
        }
170
        $user_id = $user_id ?? request::catchFields('user_id');
171
172
        $result = [];
173
        foreach ($ids as $id) {
174
            $check = telegram::getChatMember($id,$user_id);
175
            if (telegram::$status) {
176
                $check = $check->status;
177
                $result[$id] = $check !== chatMemberStatus::LEFT && $check !== chatMemberStatus::KICKED;
178
            }
179
            else $result[$id] = null;
180
        }
181
        return $result;
182
    }
183
}