XoopsOnlineHandler::write()   B
last analyzed

Complexity

Conditions 7
Paths 18

Size

Total Lines 52
Code Lines 37

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 7
eloc 37
nc 18
nop 5
dl 0
loc 52
rs 8.3946
c 0
b 0
f 0

How to fix   Long Method   

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
2
/**
3
 * XOOPS Kernel Class
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-2025 XOOPS Project (https://xoops.org)
13
 * @license             GNU GPL 2 (https://www.gnu.org/licenses/gpl-2.0.html)
14
 * @package             kernel
15
 * @since               2.0.0
16
 * @author              Kazumi Ono (AKA onokazu) http://www.myweb.ne.jp/, http://jp.xoops.org/
17
 */
18
defined('XOOPS_ROOT_PATH') || exit('Restricted access');
19
20
/**
21
 * A handler for "Who is Online?" information
22
 *
23
 * @package             kernel
24
 *
25
 * @author              Kazumi Ono    <[email protected]>
26
 * @copyright       (c) 2000-2025 XOOPS Project (https://xoops.org)
27
 */
28
class XoopsOnlineHandler
29
{
30
    /**
31
     * Database connection
32
     *
33
     * @var object
34
     * @access    private
35
     */
36
    public $db;
37
38
    /**
39
     * This should be here, since this really should be a XoopsPersistableObjectHandler
40
     * Here, we fake it for future compatibility
41
     *
42
     * @var string table name
43
     */
44
    public $table;
45
46
    /**
47
     * Constructor
48
     *
49
     * @param XoopsDatabase $db {@link XoopsHandlerFactory}
50
     */
51
    public function __construct(XoopsDatabase $db)
52
    {
53
        $this->db = $db;
54
        $this->table = $this->db->prefix('online');
55
    }
56
57
    /**
58
     * Write online information to the database
59
     *
60
     * @param int    $uid    UID of the active user
61
     * @param string $uname  Username
62
     * @param int    $time   Timestamp
63
     * @param int    $module Current module id
64
     * @param string $ip     User's IP address
65
     *
66
     * @internal param string $timestamp
67
     * @return bool TRUE on success
68
     */
69
    public function write($uid, $uname, $time, $module, $ip)
70
    {
71
        $uid = (int) $uid;
72
        $uname = $this->db->quote($uname);
73
        $time = (int) $time;
74
        $module = (int) $module;
75
        $ip = $this->db->quote($ip);
76
77
        if ($uid > 0) {
78
            $sql = 'SELECT COUNT(*) FROM ' . $this->db->prefix('online') . " WHERE online_uid={$uid}";
79
        } else {
80
            $sql = 'SELECT COUNT(*) FROM ' . $this->db->prefix('online')
81
                   . " WHERE online_uid={$uid} AND online_ip={$ip}";
82
        }
83
        $result = $this->db->queryF($sql);
84
        if (!$this->db->isResultSet($result)) {
85
            throw new \RuntimeException(
86
                \sprintf(_DB_QUERY_ERROR, $sql) . $this->db->error(),
87
                E_USER_ERROR,
88
            );
89
        }
90
91
        [$count] = $this->db->fetchRow($result);
92
        if ($count > 0) {
93
            $sql = 'UPDATE ' . $this->db->prefix('online')
94
                   . " SET online_updated = {$time}, online_module = {$module} WHERE online_uid = {$uid}";
95
            if ($uid === 0) {
96
                $sql .= " AND online_ip={$ip}";
97
            }
98
        } else {
99
            if ($uid != 0) {
100
                // this condition (no entry for a real user) exists when a user first signs in
101
                // first, cleanup the uid == 0 row the user generated before signing in
102
                $loginSql = sprintf('DELETE FROM %s WHERE online_uid = 0 AND online_ip=%s', $this->db->prefix('online'), $ip);
103
                $this->db->queryF($loginSql);
104
            }
105
            $sql = sprintf(
106
                'INSERT INTO %s (online_uid, online_uname, online_updated, online_ip, online_module)'
107
                . ' VALUES (%u, %s, %u, %s, %u)',
108
                $this->db->prefix('online'),
109
                $uid,
110
                $uname,
111
                $time,
112
                $ip,
113
                $module,
114
            );
115
        }
116
        if (!$this->db->queryF($sql)) {
117
            return false;
118
        }
119
120
        return true;
121
    }
122
123
    /**
124
     * Delete online information for a user
125
     *
126
     * @param int $uid UID
127
     *
128
     * @return bool TRUE on success
129
     */
130
    public function destroy($uid)
131
    {
132
        $sql = sprintf('DELETE FROM %s WHERE online_uid = %u', $this->db->prefix('online'), $uid);
133
        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...
134
            return false;
135
        }
136
137
        return true;
138
    }
139
140
    /**
141
     * Garbage Collection
142
     *
143
     * Delete all online information that has not been updated for a certain time
144
     *
145
     * @param int $expire Expiration time in seconds
146
     */
147
    public function gc($expire)
148
    {
149
        $sql = sprintf(
150
            'DELETE FROM %s WHERE online_updated < %u',
151
            $this->db->prefix('online'),
152
            time() - (int) $expire,
153
        );
154
        $this->db->queryF($sql);
155
    }
156
157
    /**
158
     * Get an array of online information
159
     *
160
     * @param  CriteriaElement|CriteriaCompo|null $criteria {@link CriteriaElement}
161
     * @return array|false  Array of associative arrays of online information
162
     */
163
    public function getAll(?CriteriaElement $criteria = null)
164
    {
165
        $ret   = [];
166
        $limit = $start = 0;
167
        $sql   = 'SELECT * FROM ' . $this->db->prefix('online');
168
        if (is_object($criteria) && is_subclass_of($criteria, 'CriteriaElement')) {
169
            $sql .= ' ' . $criteria->renderWhere();
0 ignored issues
show
Bug introduced by
The method renderWhere() does not exist on CriteriaElement. Did you maybe mean render()? ( Ignorable by Annotation )

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

169
            $sql .= ' ' . $criteria->/** @scrutinizer ignore-call */ renderWhere();

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
170
            $limit = $criteria->getLimit();
171
            $start = $criteria->getStart();
172
        }
173
        $result = $this->db->query($sql, $limit, $start);
174
        if (!$this->db->isResultSet($result)) {
175
            return $ret;
176
        }
177
        while (false !== ($myrow = $this->db->fetchArray($result))) {
178
            $ret[] = $myrow;
179
            unset($myrow);
180
        }
181
182
        return $ret;
183
    }
184
185
    /**
186
     * Count the number of online users
187
     *
188
     * @param CriteriaElement|CriteriaCompo|null $criteria {@link CriteriaElement}
189
     *
190
     * @return int
191
     */
192
    public function getCount(?CriteriaElement $criteria = null)
193
    {
194
        $sql = 'SELECT COUNT(*) FROM ' . $this->db->prefix('online');
195
        if (is_object($criteria) && is_subclass_of($criteria, 'CriteriaElement')) {
196
            $sql .= ' ' . $criteria->renderWhere();
197
        }
198
        $result = $this->db->query($sql);
199
        if (!$this->db->isResultSet($result)) {
200
            return 0;
201
        }
202
        [$ret] = $this->db->fetchRow($result);
203
204
        return (int) $ret;
205
    }
206
}
207