This project does not seem to handle request data directly as such no vulnerable execution paths were found.
include
, or for example
via PHP's auto-loading mechanism.
1 | <?php |
||||||
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 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 | * @package module::newbb |
||||||
13 | */ |
||||||
14 | |||||||
15 | |||||||
16 | |||||||
17 | \defined('NEWBB_FUNCTIONS_INI') || require __DIR__ . '/functions.ini.php'; |
||||||
18 | |||||||
19 | \define('NEWBB_STATS_TYPE_TOPIC', 1); |
||||||
20 | \define('NEWBB_STATS_TYPE_POST', 2); |
||||||
21 | \define('NEWBB_STATS_TYPE_DIGEST', 3); |
||||||
22 | \define('NEWBB_STATS_TYPE_VIEW', 4); |
||||||
23 | |||||||
24 | \define('NEWBB_STATS_PERIOD_TOTAL', 1); |
||||||
25 | \define('NEWBB_STATS_PERIOD_DAY', 2); |
||||||
26 | \define('NEWBB_STATS_PERIOD_WEEK', 3); |
||||||
27 | \define('NEWBB_STATS_PERIOD_MONTH', 4); |
||||||
28 | |||||||
29 | /** |
||||||
30 | * Stats for forum |
||||||
31 | */ |
||||||
32 | class StatsHandler |
||||||
33 | { |
||||||
34 | public $db; |
||||||
35 | public $table; |
||||||
36 | public $param = [ |
||||||
37 | 'type' => ['topic', 'post', 'digest', 'view'], |
||||||
38 | 'period' => ['total', 'day', 'week', 'month'], |
||||||
39 | ]; |
||||||
40 | |||||||
41 | /** |
||||||
42 | * @param null|\XoopsDatabase $db |
||||||
43 | */ |
||||||
44 | public function __construct(\XoopsDatabase $db = null) |
||||||
0 ignored issues
–
show
|
|||||||
45 | { |
||||||
46 | //$this->db = $db; |
||||||
47 | //if (!$db || !($db instanceof \XoopsDatabase)) { |
||||||
48 | $this->db = $GLOBALS['xoopsDB']; |
||||||
49 | //} |
||||||
50 | $this->table = $this->db->prefix('newbb_stats'); |
||||||
51 | } |
||||||
52 | |||||||
53 | /** |
||||||
54 | * @param null|\XoopsDatabase $db |
||||||
55 | * @return StatsHandler |
||||||
56 | */ |
||||||
57 | public static function getInstance(\XoopsDatabase $db = null) |
||||||
58 | { |
||||||
59 | static $instance; |
||||||
60 | if (null === $instance) { |
||||||
61 | $instance = new static($db); |
||||||
62 | } |
||||||
63 | |||||||
64 | return $instance; |
||||||
65 | } |
||||||
66 | |||||||
67 | /** |
||||||
68 | * @param $id |
||||||
69 | * @param $type |
||||||
70 | * @param int $increment |
||||||
71 | * @return bool |
||||||
72 | */ |
||||||
73 | public function update($id, $type, $increment = 1) |
||||||
74 | { |
||||||
75 | $id = (int)$id; |
||||||
76 | $increment = (int)$increment; |
||||||
77 | |||||||
78 | if (empty($increment) || false === ($type = \array_search($type, $this->param['type'], true))) { |
||||||
79 | return false; |
||||||
80 | } |
||||||
81 | |||||||
82 | $sql = " UPDATE {$this->table}" |
||||||
83 | . ' SET stats_value = CASE ' |
||||||
84 | . " WHEN time_format = '' OR DATE_FORMAT(time_update, time_format) = DATE_FORMAT(NOW(), time_format) THEN stats_value + '{$increment}' " |
||||||
85 | . " ELSE '{$increment}' " |
||||||
86 | . ' END, ' |
||||||
87 | . ' time_update = NOW()' |
||||||
88 | . ' WHERE ' |
||||||
89 | . " (stats_id = '0' OR stats_id = '{$id}') " |
||||||
90 | . " AND stats_type='{$type}' "; |
||||||
91 | $result = $this->db->queryF($sql); |
||||||
0 ignored issues
–
show
|
|||||||
92 | $rows = $this->db->getAffectedRows(); |
||||||
93 | if (0 == $rows) { |
||||||
94 | $sql = " INSERT INTO {$this->table}" |
||||||
95 | . ' (`stats_id`, `stats_value`, `stats_type`, `stats_period`, `time_update`, `time_format`) ' |
||||||
96 | . ' VALUES ' |
||||||
97 | . " ('0', '{$increment}', '{$type}', '" |
||||||
98 | . \array_search('total', $this->param['period'], true) |
||||||
0 ignored issues
–
show
Are you sure
array_search('total', $t...>param['period'], true) of type false|integer|string can be used in concatenation ?
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
![]() |
|||||||
99 | . "', NOW(), ''), " |
||||||
100 | . " ('0', '{$increment}', '{$type}', '" |
||||||
101 | . \array_search('day', $this->param['period'], true) |
||||||
0 ignored issues
–
show
Are you sure
array_search('day', $this->param['period'], true) of type false|integer|string can be used in concatenation ?
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
![]() |
|||||||
102 | . "', NOW(), '%Y%j'), " |
||||||
103 | . " ('0', '{$increment}', '{$type}', '" |
||||||
104 | . \array_search('week', $this->param['period'], true) |
||||||
0 ignored issues
–
show
Are you sure
array_search('week', $th...>param['period'], true) of type false|integer|string can be used in concatenation ?
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
![]() |
|||||||
105 | . "', NOW(), '%Y%u'), " |
||||||
106 | . " ('0', '{$increment}', '{$type}', '" |
||||||
107 | . \array_search('month', $this->param['period'], true) |
||||||
0 ignored issues
–
show
Are you sure
array_search('month', $t...>param['period'], true) of type false|integer|string can be used in concatenation ?
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
![]() |
|||||||
108 | . "', NOW(), '%Y%m')"; |
||||||
109 | $result = $this->db->queryF($sql); |
||||||
110 | } |
||||||
111 | if ($rows < 2 * \count($this->param['period']) && !empty($id)) { |
||||||
112 | $sql = " INSERT INTO {$this->table}" |
||||||
113 | . ' (`stats_id`, `stats_value`, `stats_type`, `stats_period`, `time_update`, `time_format`) ' |
||||||
114 | . ' VALUES ' |
||||||
115 | . " ('{$id}', '{$increment}', '{$type}', '" |
||||||
116 | . \array_search('total', $this->param['period'], true) |
||||||
117 | . "', NOW(), ''), " |
||||||
118 | . " ('{$id}', '{$increment}', '{$type}', '" |
||||||
119 | . \array_search('day', $this->param['period'], true) |
||||||
120 | . "', NOW(), '%Y%j'), " |
||||||
121 | . " ('{$id}', '{$increment}', '{$type}', '" |
||||||
122 | . \array_search('week', $this->param['period'], true) |
||||||
123 | . "', NOW(), '%Y%u'), " |
||||||
124 | . " ('{$id}', '{$increment}', '{$type}', '" |
||||||
125 | . \array_search('month', $this->param['period'], true) |
||||||
126 | . "', NOW(), '%Y%m')"; |
||||||
127 | $result = $this->db->queryF($sql); |
||||||
128 | } |
||||||
129 | } |
||||||
130 | |||||||
131 | /** |
||||||
132 | * Get stats of "Today" |
||||||
133 | * |
||||||
134 | * @param array $ids ID of forum: > 0, forum; 0 - global; empty - all |
||||||
135 | * @param array $types type of stats items: 1 - topic; 2 - post; 3 - digest; 4 - click; empty - all |
||||||
136 | * @param array $periods time period: 1 - all time; 2 - today; 3 - this week; 4 - this month; empty - all |
||||||
137 | * @return array |
||||||
138 | */ |
||||||
139 | public function getStats(array $ids, array $types = [], array $periods = []) |
||||||
140 | { |
||||||
141 | $ret = []; |
||||||
142 | |||||||
143 | $_types = []; |
||||||
144 | foreach ($types as $type) { |
||||||
145 | $_types[] = \array_search($type, $this->param['type'], true); |
||||||
146 | } |
||||||
147 | $_periods = []; |
||||||
148 | foreach ($periods as $period) { |
||||||
149 | $_periods[] = \array_search($period, $this->param['period'], true); |
||||||
150 | } |
||||||
151 | $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( |
||||||
152 | ', ', |
||||||
153 | \array_map( |
||||||
154 | '\intval', |
||||||
155 | $ids |
||||||
156 | ) |
||||||
157 | ) . ')') . ' ' . (empty($_types) ? '' : 'AND stats_type IN (' . \implode(', ', $_types) . ')') . ' ' . (empty($_periods) ? '' : 'AND stats_period IN (' . \implode(', ', $_periods) . ')'); |
||||||
158 | $result = $this->db->query($sql); |
||||||
159 | |||||||
160 | while (false !== ($row = $this->db->fetchArray($result))) { |
||||||
161 | $ret[(string)$row['stats_id']][$this->param['type'][$row['stats_type']]][$this->param['period'][$row['stats_period']]] = $row['stats_value']; |
||||||
162 | } |
||||||
163 | |||||||
164 | return $ret; |
||||||
165 | } |
||||||
166 | |||||||
167 | public function reset() |
||||||
168 | { |
||||||
169 | $this->db->queryF('TRUNCATE TABLE ' . $this->table); |
||||||
170 | $now = \time(); |
||||||
171 | $time_start = [ |
||||||
172 | 'day' => '%Y%j', |
||||||
173 | 'week' => '%Y%u', |
||||||
174 | 'month' => '%Y%m', |
||||||
175 | ]; |
||||||
176 | $counts = []; |
||||||
177 | |||||||
178 | $sql = ' SELECT forum_id' . ' FROM ' . $this->db->prefix('newbb_forums'); |
||||||
179 | $ret = $this->db->query($sql); |
||||||
180 | while (list($forum_id) = $this->db->fetchRow($ret)) { |
||||||
181 | $sql = ' SELECT COUNT(*), SUM(topic_views)' . ' FROM ' . $this->db->prefix('newbb_topics') . " WHERE approved=1 AND forum_id = {$forum_id}"; |
||||||
182 | $result = $this->db->query($sql); |
||||||
183 | [$topics, $views] = $this->db->fetchRow($result); |
||||||
184 | $this->update($forum_id, 'topic', $topics); |
||||||
185 | $this->update($forum_id, 'view', $views); |
||||||
186 | |||||||
187 | $sql = ' SELECT COUNT(*)' . ' FROM ' . $this->db->prefix('newbb_topics') . " WHERE approved=1 AND topic_digest >0 AND forum_id = {$forum_id}"; |
||||||
188 | $result = $this->db->query($sql); |
||||||
189 | [$digests] = $this->db->fetchRow($result); |
||||||
190 | $this->update($forum_id, 'digest', $digests); |
||||||
191 | |||||||
192 | $sql = ' SELECT COUNT(*)' . ' FROM ' . $this->db->prefix('newbb_posts') . " WHERE approved=1 AND forum_id = {$forum_id}"; |
||||||
193 | $result = $this->db->query($sql); |
||||||
194 | [$posts] = $this->db->fetchRow($result); |
||||||
195 | $this->update($forum_id, 'post', $posts); |
||||||
196 | |||||||
197 | foreach ($time_start as $period => $format) { |
||||||
198 | $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}')"; |
||||||
199 | $result = $this->db->query($sql); |
||||||
200 | [$topics, $views] = $this->db->fetchRow($result); |
||||||
201 | $views = empty($views) ? 0 : $views; // null check |
||||||
202 | $this->db->queryF( |
||||||
203 | " 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( |
||||||
0 ignored issues
–
show
Are you sure
array_search($period, $t...>param['period'], true) of type false|integer|string can be used in concatenation ?
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
![]() Are you sure
array_search('topic', $this->param['type'], true) of type false|integer|string can be used in concatenation ?
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
![]() |
|||||||
204 | $period, |
||||||
205 | $this->param['period'], |
||||||
206 | true |
||||||
207 | ) . "', NOW(), '{$format}')" |
||||||
208 | ); |
||||||
209 | $this->db->queryF( |
||||||
210 | " 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( |
||||||
0 ignored issues
–
show
Are you sure
array_search('view', $this->param['type'], true) of type false|integer|string can be used in concatenation ?
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
![]() |
|||||||
211 | $period, |
||||||
212 | $this->param['period'], |
||||||
213 | true |
||||||
214 | ) . "', NOW(), '{$format}')" |
||||||
215 | ); |
||||||
216 | @$counts['topic'][$period] += $topics; |
||||||
217 | @$counts['view'][$period] += $views; |
||||||
218 | |||||||
219 | $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}')"; |
||||||
220 | $result = $this->db->query($sql); |
||||||
221 | [$digests] = $this->db->fetchRow($result); |
||||||
222 | $this->db->queryF( |
||||||
223 | " 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( |
||||||
0 ignored issues
–
show
Are you sure
array_search('digest', $...s->param['type'], true) of type false|integer|string can be used in concatenation ?
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
![]() |
|||||||
224 | $period, |
||||||
225 | $this->param['period'], |
||||||
226 | true |
||||||
227 | ) . "', NOW(), '{$format}')" |
||||||
228 | ); |
||||||
229 | @$counts['digest'][$period] += $digests; |
||||||
230 | |||||||
231 | $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}')"; |
||||||
232 | $result = $this->db->query($sql); |
||||||
233 | [$posts] = $this->db->fetchRow($result); |
||||||
234 | $this->db->queryF( |
||||||
235 | " 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( |
||||||
0 ignored issues
–
show
Are you sure
array_search('post', $this->param['type'], true) of type false|integer|string can be used in concatenation ?
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
![]() |
|||||||
236 | $period, |
||||||
237 | $this->param['period'], |
||||||
238 | true |
||||||
239 | ) . "', NOW(), '{$format}')" |
||||||
240 | ); |
||||||
241 | @$counts['post'][$period] += $posts; |
||||||
242 | } |
||||||
243 | } |
||||||
244 | |||||||
245 | $this->db->queryF(" DELETE FROM {$this->table}" . " WHERE stats_id = '0' AND stats_period <> " . \array_search('total', $this->param['period'], true)); |
||||||
0 ignored issues
–
show
Are you sure
array_search('total', $t...>param['period'], true) of type false|integer|string can be used in concatenation ?
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
![]() |
|||||||
246 | foreach ($time_start as $period => $format) { |
||||||
247 | foreach (\array_keys($counts) as $type) { |
||||||
248 | $this->db->queryF( |
||||||
249 | " 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( |
||||||
0 ignored issues
–
show
Are you sure
array_search($type, $this->param['type'], true) of type false|integer|string can be used in concatenation ?
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
![]() |
|||||||
250 | $period, |
||||||
251 | $this->param['period'], |
||||||
252 | true |
||||||
253 | ) . "', NOW(), '{$format}')" |
||||||
254 | ); |
||||||
255 | } |
||||||
256 | } |
||||||
257 | } |
||||||
258 | } |
||||||
259 |
This check looks for parameters that have been defined for a function or method, but which are not used in the method body.