Passed
Push — master ( 7a0709...3ff077 )
by Michael
18:54
created

ModerateHandler::verifyUser()   D

Complexity

Conditions 17
Paths 193

Size

Total Lines 48
Code Lines 29

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 17
eloc 29
nc 193
nop 3
dl 0
loc 48
rs 4.4416
c 0
b 0
f 0

How to fix   Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php declare(strict_types=1);
2
3
namespace XoopsModules\Newbb;
4
5
/**
6
 * NewBB,  the forum module for XOOPS project
7
 *
8
 * @copyright      XOOPS Project (https://xoops.org)
9
 * @license        GNU GPL 2.0 or later (https://www.gnu.org/licenses/gpl-2.0.html)
10
 * @author         Taiwen Jiang (phppp or D.J.) <[email protected]>
11
 * @since          4.00
12
 */
13
14
use Xmf\IPAddress;
15
16
/**
17
 * Class ModerateHandler
18
 */
19
class ModerateHandler extends \XoopsPersistableObjectHandler
20
{
21
    /**
22
     * @param null|\XoopsDatabase $db
23
     */
24
    public function __construct(\XoopsDatabase $db = null)
25
    {
26
        parent::__construct($db, 'newbb_moderates', Moderate::class, 'mod_id', 'uid');
27
    }
28
29
    /**
30
     * Clear garbage
31
     *
32
     * Delete all moderation information that has expired
33
     *
34
     * @param int $expire Expiration time in UNIX, 0 for time()
35
     */
36
    public function clearGarbage(int $expire = 0): void
37
    {
38
        $expire = \time() - (int)$expire;
39
        $sql    = \sprintf('DELETE FROM `%s` WHERE mod_end < %u', $this->db->prefix('newbb_moderates'), $expire);
40
        $this->db->queryF($sql);
41
    }
42
43
    /**
44
     * Check if a user is moderated, according to his uid and ip
45
     *
46
     *
47
     * @param int         $uid user id
48
     * @param string|bool $ip  user ip
49
     * @param int         $forum
50
     * @return bool true if IP is banned
51
     */
52
    public function verifyUser(int $uid = -1, $ip = '', int $forum = 0): bool
53
    {
54
        \error_reporting(\E_ALL);
55
        // if user is admin do not suspend
56
        if (\newbbIsAdmin($forum)) {
57
            return true;
58
        }
59
60
        $uid = ($uid < 0) ? (\is_object($GLOBALS['xoopsUser']) ? $GLOBALS['xoopsUser']->getVar('uid') : 0) : (int)$uid;
61
62
        $criteria      = new \CriteriaCompo(new \Criteria('uid', (int)$uid));
63
        $forumCriteria = new \CriteriaCompo(new \Criteria('forum_id', 0), 'OR');
64
        if (!empty($forum)) {
65
            $forumCriteria->add(new \Criteria('forum_id', (int)$forum), 'OR');
66
        }
67
        $criteria->add($forumCriteria);
68
        $criteria->add(new \Criteria('mod_end', \time(), '>'));
69
70
        $matches = $this->getAll($criteria);
71
72
        if (0 === (is_countable($matches) ? \count($matches) : 0)) {
73
            return true; // no matches
74
        }
75
76
        if ($uid > 0 && (is_countable($matches) ? \count($matches) : 0) > 0) {
77
            return false; // user is banned
78
        }
79
        // verify possible matches against IP address
80
        $ip = empty($ip) ? IPAddress::fromRequest()->asReadable() : $ip;
81
82
        foreach ($matches as $modMatch) {
83
            $rawModIp = \trim((string) $modMatch->getVar('ip', 'n'));
84
            if (empty($rawModIp)) {
85
                return false; // banned without IP
86
            }
87
            $parts   = \explode('/', $rawModIp);
88
            $modIp   = $parts[0];
89
            $checkIp = new IPAddress($modIp);
90
            if (false !== $checkIp->asReadable()) {
91
                $defaultMask = (6 === $checkIp->ipVersion()) ? 128 : 32;
92
                $netMask     = isset($parts[1]) ? (int)$parts[1] : $defaultMask;
93
                if ($checkIp->sameSubnet($ip, $netMask, $netMask)) {
94
                    return false; // IP is banned
95
                }
96
            }
97
        }
98
99
        return true;
100
    }
101
102
    /**
103
     * Get latest expiration for a user moderation
104
     *
105
     *
106
     * @param mixed $item user id or ip
107
     * @param bool  $isUid
108
     * @return int
109
     */
110
    public function getLatest($item, bool $isUid = true): int
111
    {
112
        $ips = [];
113
        if ($isUid) {
114
            $criteria = 'uid =' . (int)$item;
115
        } else {
116
            $ip_segs = \explode('.', (string) $item);
117
            $segs    = \min(\count($ip_segs), 4);
118
            for ($i = 1; $i <= $segs; ++$i) {
119
                $ips[] = $this->db->quoteString(\implode('.', \array_slice($ip_segs, 0, $i)));
120
            }
121
            $criteria = 'ip IN(' . \implode(',', $ips) . ')';
122
        }
123
        $sql = 'SELECT MAX(mod_end) AS expire FROM ' . $this->db->prefix('newbb_moderates') . ' WHERE ' . $criteria;
124
        $result = $this->db->query($sql);
125
        if (!$this->db->isResultSet($result)) {
126
            return -1;
127
        }
128
        $row = $this->db->fetchArray($result);
129
130
        return $row['expire'];
131
    }
132
133
    /**
134
     * clean orphan items from database
135
     *
136
     * @param string $table_link
137
     * @param string $field_link
138
     * @param string $field_object
139
     * @return bool   true on success
140
     */
141
    public function cleanOrphan($table_link = '', $field_link = '', $field_object = ''): bool //cleanOrphan()
142
    {
143
        $sql = 'DELETE FROM ' . $this->table . ' WHERE (forum_id >0 AND forum_id NOT IN ( SELECT DISTINCT forum_id FROM ' . $this->db->prefix('newbb_forums') . ') )';
144
        if (!$result = $this->db->queryF($sql)) {
0 ignored issues
show
Unused Code introduced by
The assignment to $result is dead and can be removed.
Loading history...
145
            //xoops_error($this->db->error());
146
            return false;
147
        }
148
149
        return true;
150
    }
151
}
152