XoopsUserUtility   F
last analyzed

Complexity

Total Complexity 80

Size/Duplication

Total Lines 318
Duplicated Lines 0 %

Importance

Changes 0
Metric Value
eloc 177
dl 0
loc 318
rs 2
c 0
b 0
f 0
wmc 80

5 Methods

Rating   Name   Duplication   Size   Complexity  
C sendWelcome() 0 40 12
B getIP() 0 33 11
F validate() 0 137 41
B getUnameFromIds() 0 35 9
B getUnameFromId() 0 25 7

How to fix   Complexity   

Complex Class

Complex classes like XoopsUserUtility often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

While breaking up the class, it is a good idea to analyze how other classes use XoopsUserUtility, and based on these observations, apply Extract Interface, too.

1
<?php
2
/**
3
 *  Xoops Form Class Elements
4
 *
5
 * You may not change or alter any portion of this comment or credits
6
 * of supporting developers from this source code or any supporting source code
7
 * which is considered copyrighted (c) material of the original comment or credit authors.
8
 * This program is distributed in the hope that it will be useful,
9
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
11
 *
12
 * @copyright       (c) 2000-2016 XOOPS Project (www.xoops.org)
13
 * @license             GNU GPL 2 (https://www.gnu.org/licenses/gpl-2.0.html)
14
 * @package             kernel
15
 * @since               2.3.0
16
 * @author              Taiwen Jiang <[email protected]>
17
 */
18
19
defined('XOOPS_ROOT_PATH') || exit('Restricted access');
20
21
/**
22
 * XoopsUserUtility
23
 *
24
 * @package Kernel
25
 * @author  Taiwen Jiang <[email protected]>
26
 */
27
class XoopsUserUtility
28
{
29
    /**
30
     * XoopsUserUtility::sendWelcome
31
     *
32
     * @param mixed $user
33
     *
34
     * @return bool
35
     */
36
    public static function sendWelcome($user)
37
    {
38
        global $xoopsConfigUser, $xoopsConfig;
39
40
        if (empty($xoopsConfigUser)) {
41
            /** @var XoopsConfigHandler $config_handler */
42
            $config_handler  = xoops_getHandler('config');
43
            $xoopsConfigUser = $config_handler->getConfigsByCat(XOOPS_CONF_USER);
44
        }
45
        if (empty($xoopsConfigUser['welcome_type'])) {
46
            return true;
47
        }
48
49
        if (!empty($user) && !is_object($user)) {
50
            /** @var XoopsMemberHandler $member_handler */
51
            $member_handler = xoops_getHandler('member');
52
            $user           = $member_handler->getUser($user);
53
        }
54
        if (!is_object($user)) {
55
            return false;
56
        }
57
58
        xoops_loadLanguage('user');
59
        $xoopsMailer = xoops_getMailer();
60
        if ($xoopsConfigUser['welcome_type'] == 1 || $xoopsConfigUser['welcome_type'] == 3) {
61
            $xoopsMailer->useMail();
62
        }
63
        if ($xoopsConfigUser['welcome_type'] == 2 || $xoopsConfigUser['welcome_type'] == 3) {
64
            $xoopsMailer->usePM();
65
        }
66
        $xoopsMailer->setTemplate('welcome.tpl');
67
        $xoopsMailer->setSubject(sprintf(_US_WELCOME_SUBJECT, $xoopsConfig['sitename']));
68
        $xoopsMailer->setToUsers($user);
69
        if ($xoopsConfigUser['reg_dispdsclmr'] && $xoopsConfigUser['reg_disclaimer']) {
70
            $xoopsMailer->assign('TERMSOFUSE', $xoopsConfigUser['reg_disclaimer']);
71
        } else {
72
            $xoopsMailer->assign('TERMSOFUSE', '');
73
        }
74
75
        return $xoopsMailer->send();
76
    }
77
    /**
78
     * $uname, $email, $pass = null, $vpass = null
79
     */
80
    /**
81
     * XoopsUserUtility::validate
82
     *
83
     * @return bool|string
84
     */
85
    public static function validate()
86
    {
87
        global $xoopsUser;
88
89
        $args     = func_get_args();
90
        $args_num = func_num_args();
91
92
        $user  = null;
93
        $uname = null;
94
        $email = null;
95
        $pass  = null;
96
        $vpass = null;
97
98
        switch ($args_num) {
99
            case 1:
100
                $user = $args[0];
101
                break;
102
            case 2:
103
                list($uname, $email) = $args;
104
                break;
105
            case 3:
106
                list($user, $pass, $vpass) = $args;
107
                break;
108
            case 4:
109
                list($uname, $email, $pass, $vpass) = $args;
110
                break;
111
            default:
112
                return false;
113
        }
114
        if (is_object($user)) {
115
            $uname = $user->getVar('uname', 'n');
116
            $email = $user->getVar('email', 'n');
117
        }
118
        /** @var XoopsConfigHandler $config_handler */
119
        $config_handler  = xoops_getHandler('config');
120
        $xoopsConfigUser = $config_handler->getConfigsByCat(XOOPS_CONF_USER);
121
122
        xoops_loadLanguage('user');
123
        $myts = \MyTextSanitizer::getInstance();
0 ignored issues
show
Unused Code introduced by
The assignment to $myts is dead and can be removed.
Loading history...
124
125
        $xoopsUser_isAdmin = is_object($xoopsUser) && $xoopsUser->isAdmin();
126
        $stop              = '';
127
        // Invalid email address
128
        if (!checkEmail($email)) {
129
            $stop .= _US_INVALIDMAIL . '<br>';
130
        }
131
        if (strrpos($email, ' ') > 0) {
132
            $stop .= _US_EMAILNOSPACES . '<br>';
133
        }
134
        // Check forbidden email address if current operator is not an administrator
135
        if (!$xoopsUser_isAdmin) {
136
            foreach ($xoopsConfigUser['bad_emails'] as $be) {
137
                if (!empty($be) && preg_match('/' . $be . '/i', $email)) {
138
                    $stop .= _US_INVALIDMAIL . '<br>';
139
                    break;
140
                }
141
            }
142
        }
143
        $uname = xoops_trim($uname);
144
        switch ($xoopsConfigUser['uname_test_level']) {
145
            case 0:
146
                // strict
147
                $restriction = '/[^a-zA-Z0-9\_\-]/';
148
                break;
149
            case 1:
150
                // medium
151
                $restriction = '/[^a-zA-Z0-9\_\-\<\>\,\.\$\%\#\@\!\\\'\']/';
152
                break;
153
            case 2:
154
                // loose
155
                $restriction = '/[\000-\040]/';
156
                break;
157
        }
158
        if (empty($uname) || preg_match($restriction, $uname)) {
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $restriction does not seem to be defined for all execution paths leading up to this point.
Loading history...
159
            $stop .= _US_INVALIDNICKNAME . '<br>';
160
        }
161
        // Check uname settings if current operator is not an administrator
162
        if (!$xoopsUser_isAdmin) {
163
            if (strlen($uname) > $xoopsConfigUser['maxuname']) {
164
                $stop .= sprintf(_US_NICKNAMETOOLONG, $xoopsConfigUser['maxuname']) . '<br>';
165
            }
166
            if (strlen($uname) < $xoopsConfigUser['minuname']) {
167
                $stop .= sprintf(_US_NICKNAMETOOSHORT, $xoopsConfigUser['minuname']) . '<br>';
168
            }
169
            foreach ($xoopsConfigUser['bad_unames'] as $bu) {
170
                if (!empty($bu) && preg_match('/' . $bu . '/i', $uname)) {
171
                    $stop .= _US_NAMERESERVED . '<br>';
172
                    break;
173
                }
174
            }
175
            /**
176
             * if (strrpos($uname, ' ') > 0) {
177
             * $stop .= _US_NICKNAMENOSPACES . '<br>';
178
             * }
179
             */
180
        }
181
        /** @var XoopsMySQLDatabase $xoopsDB */
182
        $xoopsDB = XoopsDatabaseFactory::getDatabaseConnection();
183
        // Check if uname/email already exists if the user is a new one
184
        $uid    = is_object($user) ? $user->getVar('uid') : 0;
185
        $sql    = 'SELECT COUNT(*) FROM `' . $xoopsDB->prefix('users') . '` WHERE `uname` = ' . $xoopsDB->quote(addslashes($uname)) . (($uid > 0) ? " AND `uid` <> {$uid}" : '');
186
        $result = $xoopsDB->query($sql);
187
        if (!$xoopsDB->isResultSet($result)) {
188
            throw new \RuntimeException(
189
                \sprintf(_DB_QUERY_ERROR, $sql) . $xoopsDB->error(), E_USER_ERROR
190
            );
191
        }
192
        list($count) = $xoopsDB->fetchRow($result);
0 ignored issues
show
Bug introduced by
It seems like $result can also be of type boolean; however, parameter $result of XoopsMySQLDatabase::fetchRow() does only seem to accept mysqli_result, 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

192
        list($count) = $xoopsDB->fetchRow(/** @scrutinizer ignore-type */ $result);
Loading history...
193
        if ((int)$count > 0) {
194
            $stop .= _US_NICKNAMETAKEN . '<br>';
195
        }
196
        $sql    = 'SELECT COUNT(*) FROM `' . $xoopsDB->prefix('users') . '` WHERE `email` = ' . $xoopsDB->quote(addslashes($email)) . (($uid > 0) ? " AND `uid` <> {$uid}" : '');
197
        $result = $xoopsDB->query($sql);
198
        if (!$xoopsDB->isResultSet($result)) {
199
            throw new \RuntimeException(
200
                \sprintf(_DB_QUERY_ERROR, $sql) . $xoopsDB->error(), E_USER_ERROR
201
            );
202
        }
203
        list($count) = $xoopsDB->fetchRow($result);
204
        if ((int)$count > 0) {
205
            $stop .= _US_EMAILTAKEN . '<br>';
206
        }
207
        // If password is not set, skip password validation
208
        if ($pass === null && $vpass === null) {
209
            return $stop;
210
        }
211
212
        if (!isset($pass) || $pass == '' || !isset($vpass) || $vpass == '') {
213
            $stop .= _US_ENTERPWD . '<br>';
214
        }
215
        if (isset($pass) && ($pass != $vpass)) {
216
            $stop .= _US_PASSNOTSAME . '<br>';
217
        } elseif (($pass != '') && (strlen($pass) < $xoopsConfigUser['minpass'])) {
218
            $stop .= sprintf(_US_PWDTOOSHORT, $xoopsConfigUser['minpass']) . '<br>';
219
        }
220
221
        return $stop;
222
    }
223
224
    /**
225
     * Get client IP
226
     *
227
     * Adapted from PMA_getIp() [phpmyadmin project]
228
     *
229
     * @param  bool $asString requiring integer or dotted string
230
     * @return mixed string or integer value for the IP
231
     */
232
    public static function getIP($asString = false)
233
    {
234
        // Gets the proxy ip sent by the user
235
        $proxy_ip = '';
236
        if (!empty($_SERVER['HTTP_X_FORWARDED_FOR'])) {
237
            $proxy_ip = $_SERVER['HTTP_X_FORWARDED_FOR'];
238
        } elseif (!empty($_SERVER['HTTP_X_FORWARDED'])) {
239
            $proxy_ip = $_SERVER['HTTP_X_FORWARDED'];
240
        } elseif (!empty($_SERVER['HTTP_FORWARDED_FOR'])) {
241
            $proxy_ip = $_SERVER['HTTP_FORWARDED_FOR'];
242
        } elseif (!empty($_SERVER['HTTP_FORWARDED'])) {
243
            $proxy_ip = $_SERVER['HTTP_FORWARDED'];
244
        } elseif (!empty($_SERVER['HTTP_VIA'])) {
245
            $proxy_ip = $_SERVER['HTTP_VIA'];
246
        } elseif (!empty($_SERVER['HTTP_X_COMING_FROM'])) {
247
            $proxy_ip = $_SERVER['HTTP_X_COMING_FROM'];
248
        } elseif (!empty($_SERVER['HTTP_COMING_FROM'])) {
249
            $proxy_ip = $_SERVER['HTTP_COMING_FROM'];
250
        }
251
        if (!empty($proxy_ip)) {
252
            $ip = new \Xmf\IPAddress($proxy_ip);
253
            if (false === $ip->asReadable()) {
0 ignored issues
show
introduced by
The condition false === $ip->asReadable() is always false.
Loading history...
254
                $ip = \Xmf\IPAddress::fromRequest();
255
            }
256
        } else {
257
            $ip = \Xmf\IPAddress::fromRequest();
258
        }
259
260
        // this really should return $ip->asBinary() instead of ip2long, but for IPv6, this will
261
        // return false when the ip2long() fails. Callers are not expecting binary strings.
262
        $the_IP = $asString ? $ip->asReadable() : ip2long($ip->asReadable());
263
264
        return $the_IP;
265
    }
266
267
    /**
268
     * XoopsUserUtility::getUnameFromIds()
269
     *
270
     * @param  mixed $uid
271
     * @param  mixed $usereal
272
     * @param  mixed $linked
273
     * @return array
274
     */
275
    public static function getUnameFromIds($uid, $usereal = false, $linked = false)
276
    {
277
        if (!is_array($uid)) {
278
            $uid = array($uid);
279
        }
280
        $userid = array_map('intval', array_filter($uid));
281
282
        $myts  = \MyTextSanitizer::getInstance();
283
        $users = array();
284
        if (count($userid) > 0) {
285
            /** @var XoopsMySQLDatabase $xoopsDB */
286
            $xoopsDB = XoopsDatabaseFactory::getDatabaseConnection();
287
            $sql     = 'SELECT uid, uname, name FROM ' . $xoopsDB->prefix('users') . ' WHERE level > 0 AND uid IN(' . implode(',', array_unique($userid)) . ')';
288
            $result = $xoopsDB->query($sql);
289
            if (!$xoopsDB->isResultSet($result)) {
290
                return $users;
291
            }
292
293
            while (false !== ($row = $xoopsDB->fetchArray($result))) {
0 ignored issues
show
Bug introduced by
It seems like $result can also be of type boolean; however, parameter $result of XoopsMySQLDatabase::fetchArray() does only seem to accept mysqli_result, 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

293
            while (false !== ($row = $xoopsDB->fetchArray(/** @scrutinizer ignore-type */ $result))) {
Loading history...
294
                $uid = $row['uid'];
295
                if ($usereal && $row['name']) {
296
                    $users[$uid] = $myts->htmlSpecialChars($row['name']);
297
                } else {
298
                    $users[$uid] = $myts->htmlSpecialChars($row['uname']);
299
                }
300
                if ($linked) {
301
                    $users[$uid] = '<a href="' . XOOPS_URL . '/userinfo.php?uid=' . $uid . '" title="' . $users[$uid] . '">' . $users[$uid] . '</a>';
302
                }
303
            }
304
        }
305
        if (in_array(0, $users, true)) {
306
            $users[0] = $myts->htmlSpecialChars($GLOBALS['xoopsConfig']['anonymous']);
307
        }
308
309
        return $users;
310
    }
311
312
    /**
313
     * XoopsUserUtility::getUnameFromId()
314
     *
315
     * @param  mixed $userid
316
     * @param  mixed $usereal
317
     * @param  mixed $linked
318
     * @return string
319
     */
320
    public static function getUnameFromId($userid, $usereal = false, $linked = false)
321
    {
322
        $myts     = \MyTextSanitizer::getInstance();
323
        $userid   = (int)$userid;
324
        $username = '';
325
        if ($userid > 0) {
326
            /** @var XoopsMemberHandler $member_handler */
327
            $member_handler = xoops_getHandler('member');
328
            $user           = $member_handler->getUser($userid);
329
            if (is_object($user)) {
330
                if ($usereal && $user->getVar('name')) {
331
                    $username = $user->getVar('name');
332
                } else {
333
                    $username = $user->getVar('uname');
334
                }
335
                if (!empty($linked)) {
336
                    $username = '<a href="' . XOOPS_URL . '/userinfo.php?uid=' . $userid . '" title="' . $username . '">' . $username . '</a>';
337
                }
338
            }
339
        }
340
        if (empty($username)) {
341
            $username = $myts->htmlSpecialChars($GLOBALS['xoopsConfig']['anonymous']);
342
        }
343
344
        return $username;
345
    }
346
}
347