Test Failed
Push — master ( 398493...d4ef72 )
by Michael
11:04
created

XoopsUserUtility   F

Complexity

Total Complexity 78

Size/Duplication

Total Lines 304
Duplicated Lines 0 %

Importance

Changes 0
Metric Value
wmc 78
dl 0
loc 304
rs 2.1126
c 0
b 0
f 0

5 Methods

Rating   Name   Duplication   Size   Complexity  
D getUnameFromIds() 0 32 9
C getIP() 0 33 11
C getUnameFromId() 0 25 7
C sendWelcome() 0 40 12
F validate() 0 126 39

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
0 ignored issues
show
Coding Style Compatibility introduced by
For compatibility and reusability of your code, PSR1 recommends that a file should introduce either new symbols (like classes, functions, etc.) or have side-effects (like outputting something, or including other files), but not both at the same time. The first symbol is defined on line 27 and the first side effect is on line 19.

The PSR-1: Basic Coding Standard recommends that a file should either introduce new symbols, that is classes, functions, constants or similar, or have side effects. Side effects are anything that executes logic, like for example printing output, changing ini settings or writing to a file.

The idea behind this recommendation is that merely auto-loading a class should not change the state of an application. It also promotes a cleaner style of programming and makes your code less prone to errors, because the logic is not spread out all over the place.

To learn more about the PSR-1, please see the PHP-FIG site on the PSR-1.

Loading history...
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 (http://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;
0 ignored issues
show
Compatibility Best Practice introduced by
Use of global functionality is not recommended; it makes your code harder to test, and less reusable.

Instead of relying on global state, we recommend one of these alternatives:

1. Pass all data via parameters

function myFunction($a, $b) {
    // Do something
}

2. Create a class that maintains your state

class MyClass {
    private $a;
    private $b;

    public function __construct($a, $b) {
        $this->a = $a;
        $this->b = $b;
    }

    public function myFunction() {
        // Do something
    }
}
Loading history...
39
40
        if (empty($xoopsConfigUser)) {
41
            /* @var $config_handler XoopsConfigHandler  */
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 $member_handler XoopsMemberHandler */
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;
0 ignored issues
show
Compatibility Best Practice introduced by
Use of global functionality is not recommended; it makes your code harder to test, and less reusable.

Instead of relying on global state, we recommend one of these alternatives:

1. Pass all data via parameters

function myFunction($a, $b) {
    // Do something
}

2. Create a class that maintains your state

class MyClass {
    private $a;
    private $b;

    public function __construct($a, $b) {
        $this->a = $a;
        $this->b = $b;
    }

    public function myFunction() {
        // Do something
    }
}
Loading history...
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 $config_handler XoopsConfigHandler  */
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
        $xoopsDB = XoopsDatabaseFactory::getDatabaseConnection();
182
        // Check if uname/email already exists if the user is a new one
183
        $uid    = is_object($user) ? $user->getVar('uid') : 0;
184
        $sql    = 'SELECT COUNT(*) FROM `' . $xoopsDB->prefix('users') . '` WHERE `uname` = ' . $xoopsDB->quote(addslashes($uname)) . (($uid > 0) ? " AND `uid` <> {$uid}" : '');
0 ignored issues
show
Bug introduced by
The method quote() does not exist on XoopsDatabase. Since it exists in all sub-types, consider adding an abstract or default implementation to XoopsDatabase. ( Ignorable by Annotation )

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

184
        $sql    = 'SELECT COUNT(*) FROM `' . $xoopsDB->prefix('users') . '` WHERE `uname` = ' . $xoopsDB->/** @scrutinizer ignore-call */ quote(addslashes($uname)) . (($uid > 0) ? " AND `uid` <> {$uid}" : '');
Loading history...
185
        $result = $xoopsDB->query($sql);
0 ignored issues
show
Bug introduced by
The method query() does not exist on XoopsDatabase. Since it exists in all sub-types, consider adding an abstract or default implementation to XoopsDatabase. ( Ignorable by Annotation )

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

185
        /** @scrutinizer ignore-call */ 
186
        $result = $xoopsDB->query($sql);
Loading history...
186
        list($count) = $xoopsDB->fetchRow($result);
0 ignored issues
show
Bug introduced by
The method fetchRow() does not exist on XoopsDatabase. Since it exists in all sub-types, consider adding an abstract or default implementation to XoopsDatabase. ( Ignorable by Annotation )

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

186
        /** @scrutinizer ignore-call */ 
187
        list($count) = $xoopsDB->fetchRow($result);
Loading history...
187
        if ($count > 0) {
188
            $stop .= _US_NICKNAMETAKEN . '<br>';
189
        }
190
        $sql    = 'SELECT COUNT(*) FROM `' . $xoopsDB->prefix('users') . '` WHERE `email` = ' . $xoopsDB->quote(addslashes($email)) . (($uid > 0) ? " AND `uid` <> {$uid}" : '');
191
        $result = $xoopsDB->query($sql);
192
        list($count) = $xoopsDB->fetchRow($result);
193
        if ($count > 0) {
194
            $stop .= _US_EMAILTAKEN . '<br>';
195
        }
196
        // If password is not set, skip password validation
197
        if ($pass === null && $vpass === null) {
198
            return $stop;
199
        }
200
201
        if (!isset($pass) || $pass == '' || !isset($vpass) || $vpass == '') {
202
            $stop .= _US_ENTERPWD . '<br>';
203
        }
204
        if (isset($pass) && ($pass != $vpass)) {
205
            $stop .= _US_PASSNOTSAME . '<br>';
206
        } elseif (($pass != '') && (strlen($pass) < $xoopsConfigUser['minpass'])) {
207
            $stop .= sprintf(_US_PWDTOOSHORT, $xoopsConfigUser['minpass']) . '<br>';
208
        }
209
210
        return $stop;
211
    }
212
213
    /**
214
     * Get client IP
215
     *
216
     * Adapted from PMA_getIp() [phpmyadmin project]
217
     *
218
     * @param  bool $asString requiring integer or dotted string
219
     * @return mixed string or integer value for the IP
220
     */
221
    public static function getIP($asString = false)
222
    {
223
        // Gets the proxy ip sent by the user
224
        $proxy_ip = '';
225
        if (!empty($_SERVER['HTTP_X_FORWARDED_FOR'])) {
226
            $proxy_ip = $_SERVER['HTTP_X_FORWARDED_FOR'];
227
        } elseif (!empty($_SERVER['HTTP_X_FORWARDED'])) {
228
            $proxy_ip = $_SERVER['HTTP_X_FORWARDED'];
229
        } elseif (!empty($_SERVER['HTTP_FORWARDED_FOR'])) {
230
            $proxy_ip = $_SERVER['HTTP_FORWARDED_FOR'];
231
        } elseif (!empty($_SERVER['HTTP_FORWARDED'])) {
232
            $proxy_ip = $_SERVER['HTTP_FORWARDED'];
233
        } elseif (!empty($_SERVER['HTTP_VIA'])) {
234
            $proxy_ip = $_SERVER['HTTP_VIA'];
235
        } elseif (!empty($_SERVER['HTTP_X_COMING_FROM'])) {
236
            $proxy_ip = $_SERVER['HTTP_X_COMING_FROM'];
237
        } elseif (!empty($_SERVER['HTTP_COMING_FROM'])) {
238
            $proxy_ip = $_SERVER['HTTP_COMING_FROM'];
239
        }
240
        if (!empty($proxy_ip)) {
241
            $ip = new \Xmf\IPAddress($proxy_ip);
242
            if (false === $ip->asReadable()) {
0 ignored issues
show
introduced by
The condition false === $ip->asReadable() is always false.
Loading history...
243
                $ip = \Xmf\IPAddress::fromRequest();
244
            }
245
        } else {
246
            $ip = \Xmf\IPAddress::fromRequest();
247
        }
248
249
        // this really should return $ip->asBinary() instead of ip2long, but for IPv6, this will
250
        // return false when the ip2long() fails. Callers are not expecting binary strings.
251
        $the_IP = $asString ? $ip->asReadable() : ip2long($ip->asReadable());
252
253
        return $the_IP;
254
    }
255
256
    /**
257
     * XoopsUserUtility::getUnameFromIds()
258
     *
259
     * @param  mixed $uid
260
     * @param  mixed $usereal
261
     * @param  mixed $linked
262
     * @return array
263
     */
264
    public static function getUnameFromIds($uid, $usereal = false, $linked = false)
265
    {
266
        if (!is_array($uid)) {
267
            $uid = array($uid);
268
        }
269
        $userid = array_map('intval', array_filter($uid));
270
271
        $myts  = MyTextSanitizer::getInstance();
272
        $users = array();
273
        if (count($userid) > 0) {
274
            $xoopsDB = XoopsDatabaseFactory::getDatabaseConnection();
275
            $sql     = 'SELECT uid, uname, name FROM ' . $xoopsDB->prefix('users') . ' WHERE level > 0 AND uid IN(' . implode(',', array_unique($userid)) . ')';
276
            if (!$result = $xoopsDB->query($sql)) {
277
                return $users;
278
            }
279
            while (false !== ($row = $xoopsDB->fetchArray($result))) {
0 ignored issues
show
Bug introduced by
The method fetchArray() does not exist on XoopsDatabase. Since it exists in all sub-types, consider adding an abstract or default implementation to XoopsDatabase. ( Ignorable by Annotation )

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

279
            while (false !== ($row = $xoopsDB->/** @scrutinizer ignore-call */ fetchArray($result))) {
Loading history...
280
                $uid = $row['uid'];
281
                if ($usereal && $row['name']) {
282
                    $users[$uid] = $myts->htmlSpecialChars($row['name']);
283
                } else {
284
                    $users[$uid] = $myts->htmlSpecialChars($row['uname']);
285
                }
286
                if ($linked) {
287
                    $users[$uid] = '<a href="' . XOOPS_URL . '/userinfo.php?uid=' . $uid . '" title="' . $users[$uid] . '">' . $users[$uid] . '</a>';
288
                }
289
            }
290
        }
291
        if (in_array(0, $users, true)) {
292
            $users[0] = $myts->htmlSpecialChars($GLOBALS['xoopsConfig']['anonymous']);
293
        }
294
295
        return $users;
296
    }
297
298
    /**
299
     * XoopsUserUtility::getUnameFromId()
300
     *
301
     * @param  mixed $userid
302
     * @param  mixed $usereal
303
     * @param  mixed $linked
304
     * @return string
305
     */
306
    public static function getUnameFromId($userid, $usereal = false, $linked = false)
307
    {
308
        $myts     = MyTextSanitizer::getInstance();
309
        $userid   = (int)$userid;
310
        $username = '';
311
        if ($userid > 0) {
312
            /* @var $member_handler XoopsMemberHandler */
313
            $member_handler = xoops_getHandler('member');
314
            $user           = $member_handler->getUser($userid);
315
            if (is_object($user)) {
316
                if ($usereal && $user->getVar('name')) {
317
                    $username = $user->getVar('name');
318
                } else {
319
                    $username = $user->getVar('uname');
320
                }
321
                if (!empty($linked)) {
322
                    $username = '<a href="' . XOOPS_URL . '/userinfo.php?uid=' . $userid . '" title="' . $username . '">' . $username . '</a>';
323
                }
324
            }
325
        }
326
        if (empty($username)) {
327
            $username = $myts->htmlSpecialChars($GLOBALS['xoopsConfig']['anonymous']);
328
        }
329
330
        return $username;
331
    }
332
}
333