Passed
Push — master ( 7f963f...620758 )
by Michael
03:34
created

StatsHandler::reset()   F

Complexity

Conditions 13
Paths 822

Size

Total Lines 107
Code Lines 86

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 13
eloc 86
nc 822
nop 0
dl 0
loc 107
rs 2.4632
c 0
b 0
f 0

How to fix   Long Method    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 5.0x,  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
\defined('NEWBB_FUNCTIONS_INI') || require __DIR__ . '/functions.ini.php';
14
15
\define('NEWBB_STATS_TYPE_TOPIC', 1);
16
\define('NEWBB_STATS_TYPE_POST', 2);
17
\define('NEWBB_STATS_TYPE_DIGEST', 3);
18
\define('NEWBB_STATS_TYPE_VIEW', 4);
19
20
\define('NEWBB_STATS_PERIOD_TOTAL', 1);
21
\define('NEWBB_STATS_PERIOD_DAY', 2);
22
\define('NEWBB_STATS_PERIOD_WEEK', 3);
23
\define('NEWBB_STATS_PERIOD_MONTH', 4);
24
25
/**
26
 * Stats for forum
27
 */
28
class StatsHandler
29
{
30
    public $db;
31
    public $table;
32
    public $param = [
33
        'type'   => ['topic', 'post', 'digest', 'view'],
34
        'period' => ['total', 'day', 'week', 'month'],
35
    ];
36
37
    /**
38
     * @param null|\XoopsDatabase $db
39
     */
40
    public function __construct(\XoopsDatabase $db = null)
0 ignored issues
show
Unused Code introduced by
The parameter $db is not used and could be removed. ( Ignorable by Annotation )

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

40
    public function __construct(/** @scrutinizer ignore-unused */ \XoopsDatabase $db = null)

This check looks for parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
41
    {
42
        //$this->db = $db;
43
        //if (!$db || !($db instanceof \XoopsDatabase)) {
44
        $this->db = $GLOBALS['xoopsDB'];
45
        //}
46
        $this->table = $this->db->prefix('newbb_stats');
47
    }
48
49
    /**
50
     * @param null|\XoopsDatabase $db
51
     * @return StatsHandler
52
     */
53
    public static function getInstance(\XoopsDatabase $db = null)
54
    {
55
        static $instance;
56
        if (null === $instance) {
57
            $instance = new static($db);
58
        }
59
60
        return $instance;
61
    }
62
63
    /**
64
     * @param       $id
65
     * @param       $type
66
     * @param int   $increment
67
     * @return bool
68
     */
69
    public function update($id, $type, $increment = 1)
70
    {
71
        $id        = (int)$id;
72
        $increment = (int)$increment;
73
74
        if (empty($increment) || false === ($type = \array_search($type, $this->param['type'], true))) {
75
            return false;
76
        }
77
78
        $sql    = "    UPDATE {$this->table}"
79
                  . '    SET stats_value = CASE '
80
                  . "                    WHEN time_format = '' OR DATE_FORMAT(time_update, time_format) = DATE_FORMAT(NOW(), time_format)  THEN stats_value + '{$increment}' "
81
                  . "                    ELSE '{$increment}' "
82
                  . '                END, '
83
                  . '        time_update = NOW()'
84
                  . '    WHERE '
85
                  . "        (stats_id = '0' OR stats_id = '{$id}') "
86
                  . "        AND stats_type='{$type}' ";
87
        $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...
88
        $rows   = $this->db->getAffectedRows();
89
        if (0 == $rows) {
90
            $sql    = "    INSERT INTO {$this->table}"
91
                      . '        (`stats_id`, `stats_value`, `stats_type`, `stats_period`, `time_update`, `time_format`) '
92
                      . '    VALUES '
93
                      . "        ('0', '{$increment}', '{$type}', '"
94
                      . \array_search('total', $this->param['period'], true)
95
                      . "', NOW(), ''), "
96
                      . "        ('0', '{$increment}', '{$type}', '"
97
                      . \array_search('day', $this->param['period'], true)
98
                      . "', NOW(), '%Y%j'), "
99
                      . "        ('0', '{$increment}', '{$type}', '"
100
                      . \array_search('week', $this->param['period'], true)
101
                      . "', NOW(), '%Y%u'), "
102
                      . "        ('0', '{$increment}', '{$type}', '"
103
                      . \array_search('month', $this->param['period'], true)
104
                      . "', NOW(), '%Y%m')";
105
            $result = $this->db->queryF($sql);
106
        }
107
        if ($rows < 2 * \count($this->param['period']) && !empty($id)) {
108
            $sql    = "    INSERT INTO {$this->table}"
109
                      . '        (`stats_id`, `stats_value`, `stats_type`, `stats_period`, `time_update`, `time_format`) '
110
                      . '    VALUES '
111
                      . "        ('{$id}', '{$increment}', '{$type}', '"
112
                      . \array_search('total', $this->param['period'], true)
113
                      . "', NOW(), ''), "
114
                      . "        ('{$id}', '{$increment}', '{$type}', '"
115
                      . \array_search('day', $this->param['period'], true)
116
                      . "', NOW(), '%Y%j'), "
117
                      . "        ('{$id}', '{$increment}', '{$type}', '"
118
                      . \array_search('week', $this->param['period'], true)
119
                      . "', NOW(), '%Y%u'), "
120
                      . "        ('{$id}', '{$increment}', '{$type}', '"
121
                      . \array_search('month', $this->param['period'], true)
122
                      . "', NOW(), '%Y%m')";
123
            $result = $this->db->queryF($sql);
124
        }
125
    }
126
127
    /**
128
     * Get stats of "Today"
129
     *
130
     * @param array $ids     ID of forum: > 0, forum; 0 - global; empty - all
131
     * @param array $types   type of stats items: 1 - topic; 2 - post; 3 - digest; 4 - click; empty - all
132
     * @param array $periods time period: 1 - all time; 2 - today; 3 - this week; 4 - this month; empty - all
133
     * @return array
134
     */
135
    public function getStats(array $ids = [], array $types = [], array $periods = [])
136
    {
137
        $ret = [];
138
139
        $_types = [];
140
        foreach ($types as $type) {
141
            $_types[] = \array_search($type, $this->param['type'], true);
142
        }
143
        $_periods = [];
144
        foreach ($periods as $period) {
145
            $_periods[] = \array_search($period, $this->param['period'], true);
146
        }
147
        $sql    = '    SELECT stats_id, stats_value, stats_type, stats_period ' . "    FROM {$this->table} " . '    WHERE ' . "        ( time_format = '' OR DATE_FORMAT(time_update, time_format) = DATE_FORMAT(NOW(), time_format) ) " . '        ' . (empty($ids) ? '' : 'AND stats_id IN (' . \implode(
148
                    ', ',
149
                    \array_map(
150
                        '\intval',
151
                        $ids
152
                    )
153
                ) . ')') . '        ' . (empty($_types) ? '' : 'AND stats_type IN (' . \implode(', ', $_types) . ')') . '        ' . (empty($_periods) ? '' : 'AND stats_period IN (' . \implode(', ', $_periods) . ')');
154
        $result = $this->db->query($sql);
155
        if ($this->db->isResultSet($result)) {
156
            while (false !== ($row = $this->db->fetchArray($result))) {
157
                $ret[(string)$row['stats_id']][$this->param['type'][$row['stats_type']]][$this->param['period'][$row['stats_period']]] = $row['stats_value'];
158
            }
159
        }
160
        return $ret;
161
    }
162
163
    public function reset(): void
164
    {
165
        $this->db->queryF('TRUNCATE TABLE ' . $this->table);
166
        $now        = \time();
167
        $time_start = [
168
            'day'   => '%Y%j',
169
            'week'  => '%Y%u',
170
            'month' => '%Y%m',
171
        ];
172
        $counts     = [];
173
174
        $sql = '    SELECT forum_id' . '    FROM ' . $this->db->prefix('newbb_forums');
175
        $ret = $this->db->query($sql);
176
        if (!$this->db->isResultSet($ret)) {
177
            \trigger_error("Query Failed! SQL: $sql- Error: " . $this->db->error(), E_USER_ERROR);
178
        }
179
        while ([$forum_id] = $this->db->fetchRow($ret)) {
180
            $sql    = '    SELECT COUNT(*), SUM(topic_views)' . '    FROM ' . $this->db->prefix('newbb_topics') . "    WHERE approved=1 AND forum_id = {$forum_id}";
181
            $result = $this->db->query($sql);
182
            if (!$this->db->isResultSet($result)) {
183
                \trigger_error("Query Failed! SQL: $sql- Error: " . $this->db->error(), E_USER_ERROR);
184
            }
185
            [$topics, $views] = $this->db->fetchRow($result);
186
            $this->update($forum_id, 'topic', $topics);
187
            $this->update($forum_id, 'view', $views);
188
189
            $sql    = '    SELECT COUNT(*)' . '    FROM ' . $this->db->prefix('newbb_topics') . "    WHERE approved=1 AND topic_digest >0 AND forum_id = {$forum_id}";
190
            $result = $this->db->query($sql);
191
            if (!$this->db->isResultSet($result)) {
192
                \trigger_error("Query Failed! SQL: $sql- Error: " . $this->db->error(), E_USER_ERROR);
193
            }
194
            [$digests] = $this->db->fetchRow($result);
195
            $this->update($forum_id, 'digest', $digests);
196
197
            $sql    = '    SELECT COUNT(*)' . '    FROM ' . $this->db->prefix('newbb_posts') . "    WHERE approved=1 AND forum_id = {$forum_id}";
198
            $result = $this->db->query($sql);
199
            if (!$this->db->isResultSet($result)) {
200
                \trigger_error("Query Failed! SQL: $sql- Error: " . $this->db->error(), E_USER_ERROR);
201
            }
202
            [$posts] = $this->db->fetchRow($result);
203
            $this->update($forum_id, 'post', $posts);
204
205
            foreach ($time_start as $period => $format) {
206
                $sql    = '    SELECT COUNT(*), SUM(topic_views)' . '    FROM ' . $this->db->prefix('newbb_topics') . "    WHERE approved=1 AND forum_id = {$forum_id}" . "        AND FROM_UNIXTIME(topic_time, '{$format}') >= FROM_UNIXTIME({$now}, '{$format}')";
207
                $result = $this->db->query($sql);
208
                if (!$this->db->isResultSet($result)) {
209
                    \trigger_error("Query Failed! SQL: $sql- Error: " . $this->db->error(), E_USER_ERROR);
210
                }
211
                [$topics, $views] = $this->db->fetchRow($result);
212
                $views = empty($views) ? 0 : $views; // null check
213
214
                $sql    = " INSERT INTO {$this->table}" . '        (`stats_id`, `stats_value`, `stats_type`, `stats_period`, `time_update`, `time_format`) ' . '    VALUES ' . "        ('{$forum_id}', '{$topics}', '" . \array_search('topic', $this->param['type'], true) . "', '" . \array_search(
215
                        $period,
216
                        $this->param['period'],
217
                        true
218
                    ) . "', NOW(), '{$format}')";
219
                $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...
220
221
                $sql    = " INSERT INTO {$this->table}" . '        (`stats_id`, `stats_value`, `stats_type`, `stats_period`, `time_update`, `time_format`) ' . '    VALUES ' . "        ('{$forum_id}', '{$views}', '" . \array_search('view', $this->param['type'], true) . "', '" . \array_search(
222
                        $period,
223
                        $this->param['period'],
224
                        true
225
                    ) . "', NOW(), '{$format}')";
226
                $result = $this->db->queryF($sql);
227
                @$counts['topic'][$period] += $topics;
228
                @$counts['view'][$period] += $views;
229
230
                $sql    = '    SELECT COUNT(*)' . '    FROM ' . $this->db->prefix('newbb_topics') . "    WHERE approved=1 AND topic_digest >0 AND forum_id = {$forum_id}" . "        AND FROM_UNIXTIME(digest_time, '{$format}') >= FROM_UNIXTIME({$now}, '{$format}')";
231
                $result = $this->db->query($sql);
232
                if (!$this->db->isResultSet($result)) {
233
                    \trigger_error("Query Failed! SQL: $sql- Error: " . $this->db->error(), E_USER_ERROR);
234
                }
235
                [$digests] = $this->db->fetchRow($result);
236
                $sql    = " INSERT INTO {$this->table}" . '        (`stats_id`, `stats_value`, `stats_type`, `stats_period`, `time_update`, `time_format`) ' . '    VALUES ' . "        ('{$forum_id}', '{$digests}', '" . \array_search('digest', $this->param['type'], true) . "', '" . \array_search(
237
                        $period,
238
                        $this->param['period'],
239
                        true
240
                    ) . "', NOW(), '{$format}')";
241
                $result = $this->db->queryF($sql);
242
                @$counts['digest'][$period] += $digests;
243
244
                $sql    = ' SELECT COUNT(*)' . '    FROM ' . $this->db->prefix('newbb_posts') . "    WHERE approved=1 AND forum_id = {$forum_id}" . "        AND FROM_UNIXTIME(post_time, '{$format}') >= FROM_UNIXTIME({$now}, '{$format}')";
245
                $result = $this->db->query($sql);
246
                if (!$this->db->isResultSet($result)) {
247
                    \trigger_error("Query Failed! SQL: $sql- Error: " . $this->db->error(), E_USER_ERROR);
248
                }
249
                [$posts] = $this->db->fetchRow($result);
250
                $sql    = " INSERT INTO {$this->table}" . '        (`stats_id`, `stats_value`, `stats_type`, `stats_period`, `time_update`, `time_format`) ' . '    VALUES ' . "        ('{$forum_id}', '{$posts}', '" . \array_search('post', $this->param['type'], true) . "', '" . \array_search(
251
                        $period,
252
                        $this->param['period'],
253
                        true
254
                    ) . "', NOW(), '{$format}')";
255
                $result = $this->db->queryF($sql);
256
                @$counts['post'][$period] += $posts;
257
            }
258
        }
259
260
        $sql    = "    DELETE FROM {$this->table}" . "    WHERE stats_id = '0' AND stats_period <> " . \array_search('total', $this->param['period'], true);
261
        $result = $this->db->queryF($sql);
262
        foreach ($time_start as $period => $format) {
263
            foreach (\array_keys($counts) as $type) {
264
                $sql    = " INSERT INTO {$this->table}" . '        (`stats_id`, `stats_value`, `stats_type`, `stats_period`, `time_update`, `time_format`) ' . '    VALUES ' . "        ('0', '{$counts[$type][$period]}', '" . \array_search($type, $this->param['type'], true) . "', '" . \array_search(
265
                        $period,
266
                        $this->param['period'],
267
                        true
268
                    ) . "', NOW(), '{$format}')";
269
                $result = $this->db->queryF($sql);
270
            }
271
        }
272
    }
273
}
274