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.
These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more
1 | <?php |
||
2 | /* |
||
3 | You may not change or alter any portion of this comment or credits |
||
4 | of supporting developers from this source code or any supporting source code |
||
5 | which is considered copyrighted (c) material of the original comment or credit authors. |
||
6 | |||
7 | This program is distributed in the hope that it will be useful, |
||
8 | but WITHOUT ANY WARRANTY; without even the implied warranty of |
||
9 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. |
||
10 | */ |
||
11 | |||
12 | /** |
||
13 | * userlog module |
||
14 | * |
||
15 | * @copyright XOOPS Project (https://xoops.org) |
||
16 | * @license GNU GPL 2 (http://www.gnu.org/licenses/old-licenses/gpl-2.0.html) |
||
17 | * @package userlog class |
||
18 | * @since 1 |
||
19 | * @author irmtfan ([email protected]) |
||
20 | * @author XOOPS Project <www.xoops.org> <www.xoops.ir> |
||
21 | */ |
||
22 | |||
23 | use Xmf\Request; |
||
24 | |||
25 | defined('XOOPS_ROOT_PATH') || exit('Restricted access.'); |
||
26 | require_once __DIR__ . '/../include/common.php'; |
||
27 | |||
28 | /** |
||
29 | * Class UserlogLog |
||
30 | */ |
||
31 | class UserlogLog extends XoopsObject |
||
32 | { |
||
33 | /** |
||
34 | * @var string |
||
35 | */ |
||
36 | public $userlog = null; |
||
37 | |||
38 | public $store = 0; // store: 0,1->db 2->file 3->both |
||
0 ignored issues
–
show
|
|||
39 | |||
40 | public $sourceJSON = [ |
||
41 | 'zget', |
||
42 | 'post', |
||
43 | 'request', |
||
44 | 'files', |
||
45 | 'env', |
||
46 | 'session', |
||
47 | 'cookie', |
||
48 | 'header', |
||
49 | 'logger' |
||
50 | ];// json_encoded fields |
||
51 | |||
52 | /** |
||
53 | * constructor |
||
54 | */ |
||
55 | public function __construct() |
||
56 | { |
||
57 | $this->userlog = Userlog::getInstance(); |
||
58 | $this->initVar('log_id', XOBJ_DTYPE_INT, null, false); |
||
59 | $this->initVar('log_time', XOBJ_DTYPE_INT, null, true); |
||
60 | $this->initVar('uid', XOBJ_DTYPE_INT, null, false); |
||
61 | $this->initVar('uname', XOBJ_DTYPE_TXTBOX, null, false, 50); |
||
62 | $this->initVar('admin', XOBJ_DTYPE_INT, null, false); |
||
63 | $this->initVar('groups', XOBJ_DTYPE_TXTBOX, null, false, 100); |
||
64 | $this->initVar('last_login', XOBJ_DTYPE_INT, null, true); |
||
65 | $this->initVar('user_ip', XOBJ_DTYPE_TXTBOX, null, true, 15); |
||
66 | $this->initVar('user_agent', XOBJ_DTYPE_TXTBOX, null, true, 255); |
||
67 | $this->initVar('url', XOBJ_DTYPE_TXTBOX, null, true, 255); |
||
68 | $this->initVar('script', XOBJ_DTYPE_TXTBOX, null, true, 50); |
||
69 | $this->initVar('referer', XOBJ_DTYPE_TXTBOX, null, true, 255); |
||
70 | $this->initVar('pagetitle', XOBJ_DTYPE_TXTBOX, null, false, 255); |
||
71 | $this->initVar('pageadmin', XOBJ_DTYPE_INT, null, false); |
||
72 | $this->initVar('module', XOBJ_DTYPE_TXTBOX, null, true, 25); |
||
73 | $this->initVar('module_name', XOBJ_DTYPE_TXTBOX, null, true, 50); |
||
74 | $this->initVar('item_name', XOBJ_DTYPE_TXTBOX, null, false, 10); |
||
75 | $this->initVar('item_id', XOBJ_DTYPE_INT, null, false); |
||
76 | $this->initVar('request_method', XOBJ_DTYPE_TXTBOX, null, false, 20); |
||
77 | $this->initVar('zget', XOBJ_DTYPE_SOURCE); |
||
78 | $this->initVar('post', XOBJ_DTYPE_SOURCE); |
||
79 | $this->initVar('request', XOBJ_DTYPE_SOURCE); |
||
80 | $this->initVar('files', XOBJ_DTYPE_SOURCE); |
||
81 | $this->initVar('env', XOBJ_DTYPE_SOURCE); |
||
82 | $this->initVar('session', XOBJ_DTYPE_SOURCE); |
||
83 | $this->initVar('cookie', XOBJ_DTYPE_SOURCE); |
||
84 | $this->initVar('header', XOBJ_DTYPE_SOURCE); |
||
85 | $this->initVar('logger', XOBJ_DTYPE_SOURCE); |
||
86 | } |
||
87 | |||
88 | /** |
||
89 | * @param string $method |
||
90 | * @param array $args |
||
91 | * |
||
92 | * @return mixed |
||
93 | */ |
||
94 | public function __call($method, $args) |
||
95 | { |
||
96 | $arg = isset($args[0]) ? $args[0] : null; |
||
97 | |||
98 | return $this->getVar($method, $arg); |
||
99 | } |
||
100 | |||
101 | /** |
||
102 | * @return UserlogLog |
||
103 | */ |
||
104 | public static function getInstance() |
||
105 | { |
||
106 | static $instance; |
||
107 | if (null === $instance) { |
||
108 | $instance = new static(); |
||
109 | } |
||
110 | |||
111 | return $instance; |
||
112 | } |
||
113 | |||
114 | /** |
||
115 | * @return mixed |
||
116 | */ |
||
117 | public function getLogTime() |
||
118 | { |
||
119 | return $this->userlog->formatTime($this->getVar('log_time')); |
||
120 | } |
||
121 | |||
122 | /** |
||
123 | * @return bool|string |
||
124 | */ |
||
125 | public function last_login() |
||
126 | { |
||
127 | return $this->userlog->formatTime($this->getVar('last_login')); |
||
128 | } |
||
129 | |||
130 | /** |
||
131 | * @return array|mixed |
||
132 | */ |
||
133 | public function post() |
||
134 | { |
||
135 | $post = $this->getVar('post'); |
||
136 | |||
137 | return is_array($post) ? $post : json_decode($post, true); |
||
138 | } |
||
139 | |||
140 | /** |
||
141 | * @param int $limit |
||
142 | * @param int $start |
||
143 | * @param string $sort |
||
144 | * @param string $order |
||
145 | * @param array $modules |
||
146 | * @param int $since |
||
147 | * @param array $users |
||
148 | * @param array $groups |
||
149 | * |
||
150 | * @return array |
||
151 | */ |
||
152 | public function getViews( |
||
153 | $limit = 10, |
||
154 | $start = 0, |
||
155 | $sort = 'count', |
||
156 | $order = 'DESC', |
||
157 | $modules = [], |
||
158 | $since = 0, |
||
159 | $users = [], |
||
160 | $groups = [] |
||
161 | ) { |
||
162 | if (!empty($modules)) { |
||
163 | $criteriaModule = new CriteriaCompo(); |
||
164 | foreach ($modules as $module_dir => $items) { |
||
165 | $criteriaItem = new CriteriaCompo(); |
||
166 | $criteriaItem->add(new Criteria('module', $module_dir)); |
||
167 | $criteriaItemName = new CriteriaCompo(); |
||
168 | if (!empty($items['item_name'])) { |
||
169 | foreach ($items['item_name'] as $item_name) { |
||
170 | // why we cannot use this $criteriaItemName->add(new Criteria('item_name', $items, "IN")); |
||
0 ignored issues
–
show
Unused Code
Comprehensibility
introduced
by
49% of this comment could be valid code. Did you maybe forget this after debugging?
Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it. The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production. This check looks for comments that seem to be mostly valid code and reports them. ![]() |
|||
171 | $criteriaItemName->add(new Criteria('item_name', $item_name), 'OR'); |
||
172 | } |
||
173 | } |
||
174 | $criteriaItem->add($criteriaItemName); |
||
175 | $criteriaScript = new CriteriaCompo(); |
||
176 | if (!empty($items['script'])) { |
||
177 | foreach ($items['script'] as $script_name) { |
||
178 | $criteriaScript->add(new Criteria('script', $script_name), 'OR'); |
||
179 | } |
||
180 | } |
||
181 | $criteriaItem->add($criteriaScript); |
||
182 | $criteriaModule->add($criteriaItem, 'OR'); |
||
183 | unset($criteriaItem, $criteriaItemName, $criteriaScript); |
||
184 | } |
||
185 | } |
||
186 | |||
187 | View Code Duplication | if (!empty($since)) { |
|
188 | $starttime = time() - $this->userlog->getSinceTime($since); |
||
189 | $criteriaSince = new CriteriaCompo(); |
||
190 | $criteriaSince->add(new Criteria('log_time', $starttime, '>')); |
||
191 | } |
||
192 | |||
193 | View Code Duplication | if (!empty($users)) { |
|
194 | $criteriaUser = new CriteriaCompo(); |
||
195 | $criteriaUser->add(new Criteria('uid', '(' . implode(',', $users) . ')', 'IN')); |
||
196 | } |
||
197 | View Code Duplication | if (!empty($groups)) { |
|
198 | $criteriaGroup = new CriteriaCompo(); |
||
199 | foreach ($groups as $group) { |
||
200 | $criteriaGroup->add(new Criteria('groups', '%g' . $group . '%', 'LIKE'), 'OR'); |
||
201 | } |
||
202 | } |
||
203 | |||
204 | // add all criterias |
||
205 | $criteria = new CriteriaCompo(); |
||
206 | if (!empty($criteriaModule)) { |
||
207 | $criteria->add($criteriaModule); |
||
208 | } |
||
209 | if (!empty($criteriaSince)) { |
||
210 | $criteria->add($criteriaSince); |
||
211 | } |
||
212 | if (!empty($criteriaUser)) { |
||
213 | $criteria->add($criteriaUser); |
||
214 | } |
||
215 | if (!empty($criteriaGroup)) { |
||
216 | $criteria->add($criteriaGroup); |
||
217 | } |
||
218 | $criteria->setLimit($limit); |
||
219 | $criteria->setStart($start); |
||
220 | $sortItem = ('module_count' === $sort) ? 'module_name' : $sort; |
||
221 | $criteria->setSort($sortItem); |
||
222 | $criteria->setOrder($order); |
||
223 | $fields = [ |
||
224 | 'uid', |
||
225 | 'groups', |
||
226 | 'pagetitle', |
||
227 | 'pageadmin', |
||
228 | 'module', |
||
229 | 'module_name', |
||
230 | 'script', |
||
231 | 'item_name', |
||
232 | 'item_id' |
||
233 | ]; |
||
234 | $criteria->setGroupBy('pageadmin, module, script, item_name, item_id'); |
||
235 | |||
236 | list($loglogsObj, $itemViews) = $this->userlog->getHandler('log')->getLogsCounts($criteria, $fields); |
||
237 | $criteria->setGroupBy('module'); |
||
238 | $criteria->setSort(('module_count' === $sort) ? 'count' : 'module'); |
||
239 | $moduleViews = $this->userlog->getHandler('log')->getCounts($criteria); |
||
240 | unset($criteria); |
||
241 | // initializing |
||
242 | $items = []; // very important!!! |
||
0 ignored issues
–
show
Unused Code
Comprehensibility
introduced
by
43% of this comment could be valid code. Did you maybe forget this after debugging?
Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it. The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production. This check looks for comments that seem to be mostly valid code and reports them. ![]() |
|||
243 | foreach ($loglogsObj as $key => $loglogObj) { |
||
244 | $module_dirname = $loglogObj->module(); |
||
245 | $item_id = $loglogObj->item_id(); |
||
246 | if (!empty($item_id)) { |
||
247 | $link = 'modules/' . $module_dirname . '/' . $loglogObj->script() . '?' . $loglogObj->item_name() . '=' . $item_id; |
||
248 | } elseif ('system-root' !== $module_dirname) { |
||
249 | $link = 'modules/' . $module_dirname . (('system' !== $module_dirname |
||
250 | && $loglogObj->pageadmin()) ? '/admin/' : '/') . $loglogObj->script(); |
||
251 | } else { |
||
252 | $link = $loglogObj->script(); |
||
253 | } |
||
254 | $items[$link] = []; |
||
255 | $items[$link]['count'] = $itemViews[$key]; |
||
256 | $items[$link]['pagetitle'] = $loglogObj->pagetitle(); |
||
257 | $items[$link]['module'] = $module_dirname; |
||
258 | $items[$link]['module_name'] = $loglogObj->module_name(); |
||
259 | $items[$link]['module_count'] = $moduleViews[$module_dirname]; |
||
260 | } |
||
261 | foreach ($items as $link => $item) { |
||
262 | $col1[$link] = $item[$sort]; |
||
263 | $col2[$link] = $item['count'];//second sort by |
||
264 | } |
||
265 | if (!empty($items)) { |
||
266 | array_multisort($col1, ('ASC' === $order) ? SORT_ASC : SORT_DESC, $col2, SORT_DESC, $items); |
||
267 | } |
||
268 | |||
269 | return $items; |
||
270 | } |
||
271 | |||
272 | /** |
||
273 | * @param $tolog |
||
274 | * @param bool $force |
||
275 | * |
||
276 | * @return bool |
||
277 | */ |
||
278 | public function store($tolog, $force = true) |
||
279 | { |
||
280 | if ($this->store > 1) { |
||
281 | $this->storeFile($tolog); |
||
282 | } // store file |
||
283 | if (2 == $this->store) { |
||
284 | return true; |
||
285 | } // do not store db |
||
286 | $this->storeDb($tolog, $force); |
||
287 | |||
288 | return null; |
||
289 | } |
||
290 | |||
291 | /** |
||
292 | * @param $tolog |
||
293 | * @param bool $force |
||
294 | * |
||
295 | * @return mixed |
||
296 | */ |
||
297 | public function storeDb($tolog, $force = true) |
||
298 | { |
||
299 | // set vars |
||
300 | foreach ($tolog as $option => $logvalue) { |
||
301 | if (!empty($logvalue)) { |
||
302 | // value array to string. use json_encode |
||
303 | if (is_array($logvalue) && count($logvalue) > 0) { |
||
304 | $logvalue = json_encode($logvalue, (PHP_VERSION > '5.4.0') ? JSON_UNESCAPED_UNICODE : 0); |
||
305 | } |
||
306 | switch ($option) { |
||
307 | // update referral in stats table |
||
308 | case 'referer': |
||
309 | if (false === strpos($logvalue, XOOPS_URL)) { |
||
310 | $statsObj = UserlogStats::getInstance(); |
||
311 | $statsObj->update('referral', 0, 1, true, parse_url($logvalue, PHP_URL_HOST)); // auto increment 1 |
||
312 | } |
||
313 | break; |
||
314 | // update browser and OS in stats table |
||
315 | case 'user_agent': |
||
316 | $statsObj = UserlogStats::getInstance(); |
||
317 | $browserArr = $this->userlog->getBrowsCap()->getBrowser($logvalue, true); |
||
318 | $statsObj->update('browser', 0, 1, true, !empty($browserArr['Parent']) ? (!empty($browserArr['Crawler']) ? 'crawler: ' : '') . $browserArr['Parent'] : 'unknown'); // auto increment 1 |
||
319 | $statsObj->update('OS', 0, 1, true, $browserArr['Platform']); // auto increment 1 |
||
320 | break; |
||
321 | } |
||
322 | $this->setVar($option, $logvalue); |
||
323 | } |
||
324 | } |
||
325 | $ret = $this->userlog->getHandler('log')->insert($this, $force); |
||
326 | $this->unsetNew(); |
||
327 | |||
328 | return $ret; |
||
329 | } |
||
330 | |||
331 | /** |
||
332 | * @param $logs |
||
333 | * @param array $skips |
||
334 | * |
||
335 | * @return mixed |
||
336 | */ |
||
337 | public function arrayToDisplay($logs, $skips = []) |
||
338 | { |
||
339 | foreach ($logs as $log_id => $log) { |
||
340 | $logs[$log_id]['log_time'] = $this->userlog->formatTime($logs[$log_id]['log_time']); |
||
341 | $logs[$log_id]['last_login'] = $this->userlog->formatTime($logs[$log_id]['last_login']); |
||
342 | if (!empty($logs[$log_id]['groups'])) { |
||
343 | // change g1g2 to Webmasters, Registered Users |
||
344 | $groups = explode('g', substr($logs[$log_id]['groups'], 1)); // remove the first "g" from string |
||
345 | $userGroupNames = $this->userlog->getFromKeys($this->userlog->getGroupList(), $groups); |
||
346 | $logs[$log_id]['groups'] = implode(',', $userGroupNames); |
||
347 | } |
||
348 | foreach ($this->sourceJSON as $option) { |
||
349 | // if value is not string it was decoded in file |
||
350 | if (!is_string($logs[$log_id][$option])) { |
||
351 | continue; |
||
352 | } |
||
353 | $logArr = json_decode($logs[$log_id][$option], true); |
||
354 | if ($logArr) { |
||
355 | $logs[$log_id][$option] = var_export($logArr, true); |
||
356 | } |
||
357 | } |
||
358 | // merge all request_method to one column - possibility to log methods when user dont set to log request_method itself |
||
359 | $logs[$log_id]['request_method'] = empty($logs[$log_id]['request_method']) ? '' : $logs[$log_id]['request_method'] . "\n"; |
||
360 | foreach ($this->sourceJSON as $option) { |
||
361 | if (!empty($logs[$log_id][$option])) { |
||
362 | $logs[$log_id]['request_method'] .= '$_' . strtoupper($option) . ' ' . $logs[$log_id][$option] . "\n"; |
||
363 | } |
||
364 | if ('env' === $option) { |
||
365 | break; |
||
366 | } // only $sourceJSON = array("zget","post","request","files","env" |
||
0 ignored issues
–
show
Unused Code
Comprehensibility
introduced
by
67% of this comment could be valid code. Did you maybe forget this after debugging?
Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it. The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production. This check looks for comments that seem to be mostly valid code and reports them. ![]() |
|||
367 | } |
||
368 | foreach ($skips as $option) { |
||
369 | unset($logs[$log_id][$option]); |
||
370 | } |
||
371 | } |
||
372 | |||
373 | return $logs; |
||
374 | } |
||
375 | |||
376 | /** |
||
377 | * @param $tolog |
||
378 | * |
||
379 | * @return bool |
||
380 | */ |
||
381 | public function storeFile($tolog) |
||
382 | { |
||
383 | $log_file = $this->userlog->getWorkingFile(); |
||
384 | // file create/open/write |
||
385 | $fileHandler = XoopsFile::getHandler(); |
||
386 | $fileHandler->__construct($log_file, false); |
||
387 | if ($fileHandler->size() > $this->userlog->getConfig('maxlogfilesize')) { |
||
388 | $log_file_name = $this->userlog->getConfig('logfilepath') . '/' . USERLOG_DIRNAME . '/' . $this->userlog->getConfig('logfilename'); |
||
389 | $old_file = $log_file_name . '_' . date('Y-m-d_H-i-s') . '.' . $this->userlog->logext; |
||
390 | if (!$result = rename($log_file, $old_file)) { |
||
391 | $this->setErrors("ERROR renaming ({$log_file})"); |
||
392 | |||
393 | return false; |
||
394 | } |
||
395 | } |
||
396 | // force to create file if not exist |
||
397 | if (!$fileHandler->exists()) { |
||
398 | if (!$fileHandler->__construct($log_file, true)) { // create file and folder |
||
399 | // Errors Warning: mkdir() [function.mkdir]: Permission denied in file /class/file/folder.php line 529 |
||
400 | $this->setErrors("Cannot create folder/file ({$log_file})"); |
||
401 | |||
402 | return false; |
||
403 | } |
||
404 | $this->setErrors("File was not exist create file ({$log_file})"); |
||
405 | // update the new file in database |
||
406 | $statsObj = UserlogStats::getInstance(); |
||
407 | $statsObj->update('file', 0, 0, false, $log_file); // value = 0 to not auto increment |
||
408 | // update old file if exist |
||
409 | if (!empty($old_file)) { |
||
410 | $statsObj->update('file', 0, 0, false, $old_file); // value = 0 to not auto increment |
||
411 | } |
||
412 | $statsObj->updateAll('file', 100); // prob = 100 |
||
413 | $data = ''; |
||
414 | } else { |
||
415 | $data = "\n"; |
||
416 | } |
||
417 | $data .= json_encode($tolog, (PHP_VERSION > '5.4.0') ? JSON_UNESCAPED_UNICODE : 0); |
||
418 | if (false === $fileHandler->open('a')) { |
||
419 | $this->setErrors("Cannot open file ({$log_file})"); |
||
420 | |||
421 | return false; |
||
422 | } |
||
423 | if (false === $fileHandler->write($data)) { |
||
424 | $this->setErrors("Cannot write to file ({$log_file})"); |
||
425 | |||
426 | return false; |
||
427 | } |
||
428 | $fileHandler->close(); |
||
429 | |||
430 | return true; |
||
431 | } |
||
432 | |||
433 | /** |
||
434 | * @param array $log_files |
||
435 | * @param $headers |
||
436 | * @param string $csvNamePrefix |
||
437 | * @param string $delimiter |
||
438 | * |
||
439 | * @return bool|string |
||
440 | */ |
||
441 | public function exportFilesToCsv($log_files = [], $headers, $csvNamePrefix = 'list_', $delimiter = ';') |
||
442 | { |
||
443 | $log_files = $this->parseFiles($log_files); |
||
444 | if (0 == ($totalFiles = count($log_files))) { |
||
445 | $this->setErrors(_AM_USERLOG_FILE_SELECT_ONE); |
||
446 | |||
447 | return false; |
||
448 | } |
||
449 | list($logs, $totalLogs) = $this->getLogsFromFiles($log_files); |
||
450 | $logs = $this->arrayToDisplay($logs); |
||
451 | $csvNamePrefix = basename($csvNamePrefix); |
||
452 | if ($csvFile == $this->exportLogsToCsv($logs, $headers, $csvNamePrefix . 'from_file_total_' . $totalLogs, $delimiter)) { |
||
453 | return $csvFile; |
||
454 | } |
||
455 | |||
456 | return false; |
||
457 | } |
||
458 | |||
459 | /** |
||
460 | * @param $logs |
||
461 | * @param $headers |
||
462 | * @param string $csvNamePrefix |
||
463 | * @param string $delimiter |
||
464 | * |
||
465 | * @return bool|string |
||
466 | */ |
||
467 | public function exportLogsToCsv($logs, $headers, $csvNamePrefix = 'list_', $delimiter = ';') |
||
468 | { |
||
469 | $csvFile = $this->userlog->getConfig('logfilepath') . '/' . USERLOG_DIRNAME . '/export/csv/' . $csvNamePrefix . '_' . date('Y-m-d_H-i-s') . '.csv'; |
||
470 | // file create/open/write |
||
471 | /** @var \XoopsFileHandler $fileHandler */ |
||
472 | $fileHandler = XoopsFile::getHandler(); |
||
473 | $fileHandler->__construct($csvFile, false); |
||
474 | // force to create file if not exist |
||
475 | if (!$fileHandler->exists()) { |
||
476 | $fileHandler->__construct($csvFile, true); // create file and folder |
||
477 | $this->setErrors("File was not exist create file ({$csvFile})"); |
||
478 | } |
||
479 | if (false === $fileHandler->open('a')) { |
||
480 | $this->setErrors("Cannot open file ({$csvFile})"); |
||
481 | |||
482 | return false; |
||
483 | } |
||
484 | if (!fputcsv($fileHandler->handler, $headers, $delimiter)) { |
||
485 | return false; |
||
486 | } |
||
487 | foreach ($logs as $thisRow) { |
||
488 | if (!fputcsv($fileHandler->handler, $thisRow, $delimiter)) { |
||
489 | return false; |
||
490 | } |
||
491 | } |
||
492 | $fileHandler->close(); |
||
493 | |||
494 | return $csvFile; |
||
495 | } |
||
496 | |||
497 | /** |
||
498 | * @param array $log_files |
||
499 | * @param int $limit |
||
500 | * @param int $start |
||
501 | * @param null $options |
||
502 | * @param string $sort |
||
503 | * @param string $order |
||
504 | * |
||
505 | * @return array |
||
506 | */ |
||
507 | public function getLogsFromFiles( |
||
508 | $log_files = [], |
||
509 | $limit = 0, |
||
510 | $start = 0, |
||
511 | $options = null, |
||
512 | $sort = 'log_time', |
||
513 | $order = 'DESC' |
||
514 | ) { |
||
515 | $logs = []; |
||
516 | $logsStr = $this->readFiles($log_files); |
||
517 | // if no logs return empty array and total = 0 |
||
518 | if (empty($logsStr)) { |
||
519 | return [[], 0]; |
||
520 | } |
||
521 | foreach ($logsStr as $id => $log) { |
||
522 | $logArr = json_decode($log, true); |
||
523 | // check if data is correct in file before do anything more |
||
524 | if (!is_array($logArr) || !array_key_exists('log_id', $logArr)) { |
||
525 | continue; |
||
526 | } |
||
527 | foreach ($logArr as $option => $logvalue) { |
||
528 | // value array to string |
||
529 | $logs[$id][$option] = is_array($logvalue) ? ((count($logvalue) > 0) ? var_export($logvalue, true) : '') : $logvalue; |
||
530 | } |
||
531 | } |
||
532 | // START Criteria in array |
||
533 | foreach ($options as $key => $val) { |
||
534 | // if user input an empty variable unset it |
||
535 | if (empty($val)) { |
||
536 | continue; |
||
537 | } |
||
538 | // deal with greater than and lower than |
||
539 | $tt = substr($key, -2); |
||
540 | switch ($tt) { |
||
541 | case 'GT': |
||
542 | $op = substr($key, 0, -2); |
||
543 | break; |
||
544 | case 'LT': |
||
545 | $op = substr($key, 0, -2); |
||
546 | break; |
||
547 | default: |
||
548 | $op = $key; |
||
549 | break; |
||
550 | } |
||
551 | $val_arr = explode(',', $val); |
||
552 | // if type is text |
||
553 | if (!empty($val_arr[0]) && 0 == (int)$val_arr[0]) { |
||
554 | foreach ($logs as $id => $log) { |
||
555 | if (is_array($log[$op])) { |
||
556 | $log[$op] = json_encode($log[$op], (PHP_VERSION > '5.4.0') ? JSON_UNESCAPED_UNICODE : 0); |
||
557 | } |
||
558 | foreach ($val_arr as $qry) { |
||
559 | // if !QUERY eg: !logs.php,views.php |
||
560 | if (0 === strpos($qry, '!')) { |
||
561 | $flagStr = true; |
||
562 | View Code Duplication | if (false !== strpos($log[$op], substr($qry, 1))) { |
|
563 | $flagStr = false; // have that delete |
||
564 | break; // means AND |
||
565 | } |
||
566 | View Code Duplication | } else { |
|
567 | $flagStr = false; |
||
568 | if (false !== strpos($log[$op], $qry)) { |
||
569 | $flagStr = true; // have that dont delete |
||
570 | break; // means OR |
||
571 | } |
||
572 | } |
||
573 | } |
||
574 | if (!$flagStr) { |
||
575 | unset($logs[$id]); |
||
576 | } |
||
577 | } |
||
578 | } else { |
||
579 | // if there is one value - deal with =, > ,< |
||
580 | if (1 == count($val_arr)) { |
||
581 | $val_int = $val_arr[0]; |
||
582 | if ('log_time' === $op || 'last_login' === $op) { |
||
583 | $val_int = time() - $this->userlog->getSinceTime($val_int); |
||
584 | } |
||
585 | // query is one int $t (=, < , >) |
||
586 | foreach ($logs as $id => $log) { |
||
587 | switch ($tt) { |
||
588 | case 'GT': |
||
589 | if ($log[$op] <= $val_int) { |
||
590 | unset($logs[$id]); |
||
591 | } |
||
592 | break; |
||
593 | case 'LT': |
||
594 | if ($log[$op] >= $val_int) { |
||
595 | unset($logs[$id]); |
||
596 | } |
||
597 | break; |
||
598 | default: |
||
599 | if ($log[$op] != $val_int) { |
||
600 | unset($logs[$id]); |
||
601 | } |
||
602 | break; |
||
603 | } |
||
604 | } |
||
605 | } else { |
||
606 | // query is an array of int separate with comma. use OR ??? |
||
607 | foreach ($logs as $id => $log) { |
||
608 | if (!in_array($log[$op], $val_arr)) { |
||
609 | unset($logs[$id]); |
||
610 | } |
||
611 | } |
||
612 | } |
||
613 | } |
||
614 | } |
||
615 | // END Criteria in array |
||
616 | // if no logs return empty array and total = 0 |
||
617 | if (empty($logs)) { |
||
618 | return [[], 0]; |
||
619 | } |
||
620 | |||
621 | // sort order array. multisort is possible :D |
||
622 | if (!empty($sort)) { |
||
623 | // log_id is just the same as log_time |
||
624 | if ('log_id' === $sort) { |
||
625 | $sort = 'log_time'; |
||
626 | } |
||
627 | // $typeFlag = is_numeric($logs[0][$sort]) ? SORT_NUMERIC : SORT_STRING; |
||
0 ignored issues
–
show
Unused Code
Comprehensibility
introduced
by
55% of this comment could be valid code. Did you maybe forget this after debugging?
Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it. The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production. This check looks for comments that seem to be mostly valid code and reports them. ![]() |
|||
628 | // Obtain a list of columns |
||
629 | foreach ($logs as $key => $log) { |
||
630 | $col[$key] = $log[$sort]; |
||
631 | //$col2[$key] = $log[$sort2]; |
||
0 ignored issues
–
show
Unused Code
Comprehensibility
introduced
by
75% of this comment could be valid code. Did you maybe forget this after debugging?
Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it. The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production. This check looks for comments that seem to be mostly valid code and reports them. ![]() |
|||
632 | } |
||
633 | // Add $logs as the last parameter, to sort by the common key |
||
634 | array_multisort($col, ('ASC' === $order) ? SORT_ASC : SORT_DESC, $logs); |
||
635 | } |
||
636 | // get count |
||
637 | $total = count($logs); |
||
638 | // now slice the array with desired start and limit |
||
639 | if (!empty($limit)) { |
||
640 | $logs = array_slice($logs, $start, $limit); |
||
641 | } |
||
642 | |||
643 | return [$logs, $total]; |
||
644 | } |
||
645 | |||
646 | /** |
||
647 | * @param array $log_files |
||
648 | * |
||
649 | * @return array |
||
650 | */ |
||
651 | public function readFiles($log_files = []) |
||
652 | { |
||
653 | $log_files = $this->parseFiles($log_files); |
||
654 | if (0 == ($totalFiles = count($log_files))) { |
||
655 | return $this->readFile(); |
||
656 | } |
||
657 | $logs = []; |
||
658 | foreach ($log_files as $file) { |
||
659 | $logs = array_merge($logs, $this->readFile($file)); |
||
660 | } |
||
661 | |||
662 | return $logs; |
||
663 | } |
||
664 | |||
665 | /** |
||
666 | * @param array $log_files |
||
667 | * @param null $mergeFileName |
||
668 | * |
||
669 | * @return bool|string |
||
670 | */ |
||
671 | public function mergeFiles($log_files = [], $mergeFileName = null) |
||
672 | { |
||
673 | $log_files = $this->parseFiles($log_files); |
||
674 | if (0 == ($totalFiles = count($log_files))) { |
||
675 | $this->setErrors(_AM_USERLOG_FILE_SELECT_ONE); |
||
676 | |||
677 | return false; |
||
678 | } |
||
679 | $logs = []; |
||
0 ignored issues
–
show
$logs is not used, you could remove the assignment.
This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently. $myVar = 'Value';
$higher = false;
if (rand(1, 6) > 3) {
$higher = true;
} else {
$higher = false;
}
Both the ![]() |
|||
680 | $logsStr = $this->readFiles($log_files); |
||
681 | $data = implode("\n", $logsStr); |
||
682 | $mergeFile = $this->userlog->getConfig('logfilepath') . '/' . USERLOG_DIRNAME . '/'; |
||
683 | $mergeFileName = basename($mergeFileName, '.' . $this->userlog->logext); |
||
684 | if (empty($mergeFileName)) { |
||
685 | $mergeFile .= $this->userlog->getConfig('logfilename') . '_merge_' . count($log_files) . '_files_' . date('Y-m-d_H-i-s'); |
||
686 | } else { |
||
687 | $mergeFile .= $mergeFileName; |
||
688 | } |
||
689 | $mergeFile .= '.' . $this->userlog->logext; |
||
690 | |||
691 | // file create/open/write |
||
692 | $fileHandler = XoopsFile::getHandler(); |
||
693 | $fileHandler->__construct($mergeFile, false); //to see if file exist |
||
694 | if ($fileHandler->exists()) { |
||
695 | $this->setErrors("file ({$mergeFile}) is exist"); |
||
696 | |||
697 | return false; |
||
698 | } |
||
699 | $fileHandler->__construct($mergeFile, true); // create file and folder |
||
700 | if (false === $fileHandler->open('a')) { |
||
701 | $this->setErrors("Cannot open file ({$mergeFile})"); |
||
702 | |||
703 | return false; |
||
704 | } |
||
705 | if (false === $fileHandler->write($data)) { |
||
706 | $this->setErrors("Cannot write to file ({$mergeFile})"); |
||
707 | |||
708 | return false; |
||
709 | } |
||
710 | $fileHandler->close(); |
||
711 | |||
712 | return $mergeFile; |
||
713 | } |
||
714 | |||
715 | /** |
||
716 | * @param null $log_file |
||
717 | * |
||
718 | * @return array |
||
719 | */ |
||
720 | public function readFile($log_file = null) |
||
721 | { |
||
722 | if (!$log_file) { |
||
723 | $log_file = $this->userlog->getWorkingFile(); |
||
724 | } |
||
725 | // file open/read |
||
726 | $fileHandler = XoopsFile::getHandler(); |
||
727 | // not create file if not exist |
||
728 | $fileHandler->__construct($log_file, false); |
||
729 | if (!$fileHandler->exists()) { |
||
730 | $this->setErrors("Cannot open file ({$log_file})"); |
||
731 | |||
732 | return []; |
||
733 | } |
||
734 | |||
735 | if (false === ($data = $fileHandler->read())) { |
||
736 | $this->setErrors("Cannot read file ({$log_file})"); |
||
737 | |||
738 | return []; |
||
739 | } |
||
740 | $fileHandler->close(); |
||
741 | $logs = explode("\n", $data); |
||
742 | |||
743 | return $logs; |
||
744 | } |
||
745 | |||
746 | /** |
||
747 | * @param array $log_files |
||
748 | * |
||
749 | * @return int |
||
750 | */ |
||
751 | public function deleteFiles($log_files = []) |
||
752 | { |
||
753 | $log_files = $this->parseFiles($log_files); |
||
754 | if (0 == ($totalFiles = count($log_files))) { |
||
755 | $this->setErrors(_AM_USERLOG_FILE_SELECT_ONE); |
||
756 | |||
757 | return false; |
||
758 | } |
||
759 | $deletedFiles = 0; |
||
760 | // file open/read |
||
761 | $fileHandler = XoopsFile::getHandler(); |
||
762 | foreach ($log_files as $file) { |
||
763 | $fileHandler->__construct($file, false); |
||
764 | if (!$fileHandler->exists()) { |
||
765 | $this->setErrors("({$file}) is a folder or is not exist"); |
||
766 | continue; |
||
767 | } |
||
768 | if (false === ($ret = $fileHandler->delete())) { |
||
769 | $this->setErrors("Cannot delete ({$file})"); |
||
770 | continue; |
||
771 | } |
||
772 | ++$deletedFiles; |
||
773 | } |
||
774 | $fileHandler->close(); |
||
775 | |||
776 | return $deletedFiles; |
||
777 | } |
||
778 | |||
779 | /** |
||
780 | * @param null $log_file |
||
781 | * @param null $newFileName |
||
782 | * |
||
783 | * @return bool|string |
||
784 | */ |
||
785 | View Code Duplication | public function renameFile($log_file = null, $newFileName = null) |
|
786 | { |
||
787 | if (!is_string($log_file)) { |
||
788 | $this->setErrors(_AM_USERLOG_FILE_SELECT_ONE); |
||
789 | |||
790 | return false; |
||
791 | } |
||
792 | // check if file exist |
||
793 | $fileHandler = XoopsFile::getHandler(); |
||
794 | $fileHandler->__construct($log_file, false); |
||
795 | if (!$fileHandler->exists()) { |
||
796 | $this->setErrors("({$log_file}) is a folder or is not exist"); |
||
797 | |||
798 | return false; |
||
799 | } |
||
800 | |||
801 | $newFileName = basename($newFileName, '.' . $this->userlog->logext); |
||
802 | if (empty($newFileName)) { |
||
803 | $newFileName = $fileHandler->name() . '_rename_' . date('Y-m-d_H-i-s'); |
||
804 | } |
||
805 | $newFile = dirname($log_file) . '/' . $newFileName . '.' . $this->userlog->logext; |
||
806 | // check if new file exist => return false |
||
807 | $fileHandler->__construct($newFile, false); |
||
808 | if ($fileHandler->exists()) { |
||
809 | $this->setErrors("({$newFile}) is exist"); |
||
810 | |||
811 | return false; |
||
812 | } |
||
813 | if (!@rename($log_file, $newFile)) { |
||
814 | $this->setErrors("Cannot rename ({$log_file})"); |
||
815 | |||
816 | return false; |
||
817 | } |
||
818 | $fileHandler->close(); |
||
819 | |||
820 | return $newFile; |
||
821 | } |
||
822 | |||
823 | /** |
||
824 | * @param null $log_file |
||
825 | * @param null $newFileName |
||
826 | * |
||
827 | * @return bool|string |
||
828 | */ |
||
829 | View Code Duplication | public function copyFile($log_file = null, $newFileName = null) |
|
830 | { |
||
831 | if (!is_string($log_file)) { |
||
832 | $this->setErrors(_AM_USERLOG_FILE_SELECT_ONE); |
||
833 | |||
834 | return false; |
||
835 | } |
||
836 | // check if file exist |
||
837 | $fileHandler = XoopsFile::getHandler(); |
||
838 | $fileHandler->__construct($log_file, false); |
||
839 | if (!$fileHandler->exists()) { |
||
840 | $this->setErrors("({$log_file}) is a folder or is not exist"); |
||
841 | |||
842 | return false; |
||
843 | } |
||
844 | |||
845 | $newFileName = basename($newFileName, '.' . $this->userlog->logext); |
||
846 | if (empty($newFileName)) { |
||
847 | $newFileName = $fileHandler->name() . '_copy_' . date('Y-m-d_H-i-s'); |
||
848 | } |
||
849 | $newFile = dirname($log_file) . '/' . $newFileName . '.' . $this->userlog->logext; |
||
850 | // check if new file exist => return false |
||
851 | $fileHandler->__construct($newFile, false); |
||
852 | if ($fileHandler->exists()) { |
||
853 | $this->setErrors("({$newFile}) is exist"); |
||
854 | |||
855 | return false; |
||
856 | } |
||
857 | if (!@copy($log_file, $newFile)) { |
||
858 | $this->setErrors("Cannot copy ({$log_file})"); |
||
859 | |||
860 | return false; |
||
861 | } |
||
862 | $fileHandler->close(); |
||
863 | |||
864 | return $newFile; |
||
865 | } |
||
866 | |||
867 | /** |
||
868 | * @param array $folders |
||
869 | * |
||
870 | * @return array |
||
871 | */ |
||
872 | public function getFilesFromFolders($folders = []) |
||
873 | { |
||
874 | list($allFiles, $totalFiles) = $this->userlog->getAllLogFiles(); |
||
875 | if (empty($totalFiles)) { |
||
876 | return []; |
||
877 | } |
||
878 | $pathFiles = []; |
||
879 | $getAll = false; |
||
880 | if (in_array('all', $folders)) { |
||
881 | $getAll = true; |
||
882 | } |
||
883 | foreach ($allFiles as $path => $files) { |
||
884 | if ($getAll || in_array($path, $folders)) { |
||
885 | foreach ($files as $file) { |
||
886 | $pathFiles[] = $path . '/' . $file; |
||
887 | } |
||
888 | } |
||
889 | } |
||
890 | |||
891 | return $pathFiles; |
||
892 | } |
||
893 | |||
894 | /** |
||
895 | * @param array $log_files |
||
896 | * |
||
897 | * @return array |
||
898 | */ |
||
899 | public function parseFiles($log_files = []) |
||
900 | { |
||
901 | $pathFiles = $this->getFilesFromFolders($log_files); |
||
902 | $log_files = array_unique(array_merge($log_files, $pathFiles)); |
||
903 | // file open/read |
||
904 | $fileHandler = XoopsFile::getHandler(); |
||
905 | foreach ($log_files as $key => $file) { |
||
906 | $fileHandler->__construct($file, false); |
||
907 | if (!$fileHandler->exists()) { |
||
908 | $this->setErrors("({$file}) is a folder or is not exist"); |
||
909 | unset($log_files[$key]); |
||
910 | continue; |
||
911 | } |
||
912 | } |
||
913 | $fileHandler->close(); |
||
914 | |||
915 | return $log_files; |
||
916 | } |
||
917 | |||
918 | /** |
||
919 | * @param array $log_files |
||
920 | * @param null $zipFileName |
||
921 | * |
||
922 | * @return string |
||
923 | */ |
||
924 | public function zipFiles($log_files = [], $zipFileName = null) |
||
925 | { |
||
926 | $log_files = $this->parseFiles($log_files); |
||
927 | if (0 == ($totalFiles = count($log_files))) { |
||
928 | $this->setErrors('No file to zip'); |
||
929 | |||
930 | return false; |
||
931 | } |
||
932 | //this folder must be writeable by the server |
||
933 | $zipFolder = $this->userlog->getConfig('logfilepath') . '/' . USERLOG_DIRNAME . '/zip'; |
||
934 | $folderHandler = XoopsFile::getHandler('folder', $zipFolder, true);// create if not exist |
||
0 ignored issues
–
show
$folderHandler is not used, you could remove the assignment.
This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently. $myVar = 'Value';
$higher = false;
if (rand(1, 6) > 3) {
$higher = true;
} else {
$higher = false;
}
Both the ![]() |
|||
935 | $zipFileName = basename($zipFileName, '.zip'); |
||
936 | if (empty($zipFileName)) { |
||
937 | $zipFileName = $this->userlog->getConfig('logfilename') . '_zip_' . $totalFiles . '_files_' . date('Y-m-d_H-i-s') . '.zip'; |
||
938 | } else { |
||
939 | $zipFileName .= '.zip'; |
||
940 | } |
||
941 | $zipFile = $zipFolder . '/' . $zipFileName; |
||
942 | |||
943 | $zip = new ZipArchive(); |
||
944 | |||
945 | if (true !== $zip->open($zipFile, ZipArchive::CREATE)) { |
||
946 | $this->setErrors("Cannot open ({$zipFile})"); |
||
947 | |||
948 | return false; |
||
949 | } |
||
950 | foreach ($log_files as $file) { |
||
951 | if (!$zip->addFile($file, basename($file))) { |
||
952 | $this->setErrors("Cannot zip ({$file})"); |
||
953 | } |
||
954 | } |
||
955 | // if there are some files existed in zip file and/or some files overwritten |
||
956 | if ($totalFiles != $zip->numFiles) { |
||
957 | $this->setErrors("Number of files operated in zipped file: ({$zip->numFiles})"); |
||
958 | } |
||
959 | //$this->setErrors("Zip file name: ({$zip->filename})"); |
||
0 ignored issues
–
show
Unused Code
Comprehensibility
introduced
by
86% of this comment could be valid code. Did you maybe forget this after debugging?
Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it. The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production. This check looks for comments that seem to be mostly valid code and reports them. ![]() |
|||
960 | $zip->close(); |
||
961 | |||
962 | return $zipFile; |
||
963 | } |
||
964 | |||
965 | /** |
||
966 | * @param array $currentFile |
||
967 | * @param bool $multi |
||
968 | * @param int $size |
||
969 | * |
||
970 | * @return XoopsFormSelect |
||
971 | */ |
||
972 | public function buildFileSelectEle($currentFile = [], $multi = false, $size = 3) |
||
973 | { |
||
974 | // $modversion['config'][$i]['options'] = array(_AM_USERLOG_FILE_WORKING=>'0',_AM_USERLOG_STATS_FILEALL=>'all'); |
||
0 ignored issues
–
show
Unused Code
Comprehensibility
introduced
by
76% of this comment could be valid code. Did you maybe forget this after debugging?
Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it. The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production. This check looks for comments that seem to be mostly valid code and reports them. ![]() |
|||
975 | if (0 == count($currentFile) || '0' == $currentFile[0]) { |
||
976 | $currentFile = $this->userlog->getWorkingFile(); |
||
977 | } |
||
978 | $fileEl = new XoopsFormSelect(_AM_USERLOG_FILE, 'file', $currentFile, $size, $multi); |
||
979 | list($allFiles, $totalFiles) = $this->userlog->getAllLogFiles(); |
||
980 | if (empty($totalFiles)) { |
||
981 | return $fileEl; |
||
982 | } |
||
983 | $log_file_name = $this->userlog->getConfig('logfilename'); |
||
984 | $working_file = $log_file_name . '.' . $this->userlog->logext; |
||
985 | $fileEl->addOption('all', _AM_USERLOG_STATS_FILEALL); |
||
986 | foreach ($allFiles as $path => $files) { |
||
987 | $fileEl->addOption($path, '>' . $path); |
||
988 | foreach ($files as $file) { |
||
989 | $fileEl->addOption($path . '/' . $file, '-----' . $file . (($file == $working_file) ? '(' . _AM_USERLOG_FILE_WORKING . ')' : '')); |
||
990 | } |
||
991 | } |
||
992 | |||
993 | return $fileEl; |
||
994 | } |
||
995 | |||
996 | /** |
||
997 | * @return bool |
||
998 | */ |
||
999 | public function setItem() |
||
1000 | { |
||
1001 | // In very rare occasions like newbb the item_id is not in the URL $_REQUEST |
||
1002 | require_once __DIR__ . '/plugin/plugin.php'; |
||
1003 | require_once __DIR__ . '/plugin/Abstract.php'; |
||
1004 | if ($plugin = Userlog_Module_Plugin::getPlugin($this->userlog->getLogModule()->getVar('dirname'), USERLOG_DIRNAME, true)) { |
||
1005 | /* |
||
0 ignored issues
–
show
Unused Code
Comprehensibility
introduced
by
47% of this comment could be valid code. Did you maybe forget this after debugging?
Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it. The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production. This check looks for comments that seem to be mostly valid code and reports them. ![]() |
|||
1006 | // get all module scripts can accept an item_name to check if this script is exist |
||
1007 | $scripts = $plugin->item(); |
||
1008 | $ii = 0; |
||
1009 | $len_script = count($scripts); |
||
1010 | foreach ($scripts as $item_name=>$script_arr) { |
||
1011 | ++$ii; |
||
1012 | $script_arr = is_array($script_arr) ? $script_arr : array($script_arr); |
||
1013 | if(in_array($this->script(), $script_arr)) break; |
||
1014 | if($ii == $len_script) return false; |
||
1015 | } |
||
1016 | */ |
||
1017 | $item = $plugin->item($this->script()); |
||
1018 | if (empty($item['item_id'])) { |
||
1019 | return false; |
||
1020 | } |
||
1021 | $this->setVar('item_name', $item['item_name']); |
||
1022 | $this->setVar('item_id', $item['item_id']); |
||
1023 | |||
1024 | return true; |
||
1025 | } |
||
1026 | // if there is no plugin, use notifications |
||
1027 | $not_config = $this->userlog->getLogModule()->getInfo('notification'); |
||
1028 | if (!empty($not_config)) { |
||
1029 | foreach ($not_config['category'] as $category) { |
||
1030 | // if $item_id != 0 ---> return true |
||
0 ignored issues
–
show
Unused Code
Comprehensibility
introduced
by
40% of this comment could be valid code. Did you maybe forget this after debugging?
Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it. The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production. This check looks for comments that seem to be mostly valid code and reports them. ![]() |
|||
1031 | if (!empty($category['item_name']) |
||
1032 | && in_array($this->script(), is_array($category['subscribe_from']) ? $category['subscribe_from'] : [$category['subscribe_from']]) |
||
1033 | && $item_id = Request::getInt($category['item_name'], 0)) { |
||
1034 | $this->setVar('item_name', $category['item_name']); |
||
1035 | $this->setVar('item_id', $item_id); |
||
1036 | |||
1037 | return true; |
||
1038 | } |
||
1039 | } |
||
1040 | } |
||
1041 | |||
1042 | return false; |
||
1043 | } |
||
1044 | } |
||
1045 | |||
1046 | /** |
||
1047 | * Class UserlogLogHandler |
||
1048 | */ |
||
1049 | class UserlogLogHandler extends XoopsPersistableObjectHandler |
||
1050 | { |
||
1051 | public $userlog = null; |
||
1052 | |||
1053 | /** |
||
1054 | * @param null|XoopsDatabase $db |
||
1055 | */ |
||
1056 | public function __construct(XoopsDatabase $db) |
||
1057 | { |
||
1058 | $this->userlog = Userlog::getInstance(); |
||
1059 | parent::__construct($db, USERLOG_DIRNAME . '_log', 'UserlogLog', 'log_id', 'log_time'); |
||
1060 | } |
||
1061 | |||
1062 | /** |
||
1063 | * @param int $limit |
||
1064 | * @param int $start |
||
1065 | * @param null $otherCriteria |
||
1066 | * @param string $sort |
||
1067 | * @param string $order |
||
1068 | * @param null $fields |
||
1069 | * @param bool $asObject |
||
1070 | * @param bool $id_as_key |
||
1071 | * |
||
1072 | * @return mixed |
||
1073 | */ |
||
1074 | View Code Duplication | public function getLogs( |
|
1075 | $limit = 0, |
||
1076 | $start = 0, |
||
1077 | $otherCriteria = null, |
||
1078 | $sort = 'log_id', |
||
1079 | $order = 'DESC', |
||
1080 | $fields = null, |
||
1081 | $asObject = true, |
||
1082 | $id_as_key = true |
||
1083 | ) { |
||
1084 | $criteria = new CriteriaCompo(); |
||
1085 | if (!empty($otherCriteria)) { |
||
1086 | $criteria->add($otherCriteria); |
||
1087 | } |
||
1088 | $criteria->setLimit($limit); |
||
1089 | $criteria->setStart($start); |
||
1090 | $criteria->setSort($sort); |
||
1091 | $criteria->setOrder($order); |
||
1092 | $ret =& $this->getAll($criteria, $fields, $asObject, $id_as_key); |
||
1093 | |||
1094 | return $ret; |
||
1095 | } |
||
1096 | |||
1097 | /** |
||
1098 | * @param null $criteria |
||
1099 | * @param null $fields |
||
1100 | * @param bool $asObject |
||
1101 | * @param bool $id_as_key |
||
1102 | * |
||
1103 | * @return array |
||
1104 | */ |
||
1105 | public function getLogsCounts($criteria = null, $fields = null, $asObject = true, $id_as_key = true) |
||
1106 | { |
||
1107 | if (is_array($fields) && count($fields) > 0) { |
||
1108 | if (!in_array($this->keyName, $fields)) { |
||
1109 | $fields[] = $this->keyName; |
||
1110 | } |
||
1111 | $select = implode(',', $fields); |
||
1112 | } else { |
||
1113 | $select = '*'; |
||
1114 | } |
||
1115 | $limit = null; |
||
1116 | $start = null; |
||
1117 | $sql = "SELECT {$select}, COUNT(*) AS count FROM {$this->table}"; |
||
1118 | if (isset($criteria) && is_subclass_of($criteria, 'criteriaelement')) { |
||
1119 | $sql .= ' ' . $criteria->renderWhere(); |
||
1120 | if ($groupby = $criteria->getGroupby()) { |
||
1121 | $sql .= !strpos($groupby, 'GROUP BY') ? " GROUP BY {$groupby}" : $groupby; |
||
1122 | } |
||
1123 | if ($sort = $criteria->getSort()) { |
||
1124 | $sql .= " ORDER BY {$sort} " . $criteria->getOrder(); |
||
1125 | } |
||
1126 | $limit = $criteria->getLimit(); |
||
1127 | $start = $criteria->getStart(); |
||
1128 | } |
||
1129 | $result = $this->db->query($sql, $limit, $start); |
||
1130 | $ret = []; |
||
1131 | $retCount = []; |
||
1132 | if ($asObject) { |
||
1133 | while (false !== ($myrow = $this->db->fetchArray($result))) { |
||
1134 | View Code Duplication | if ($id_as_key) { |
|
1135 | $retCount[$myrow[$this->keyName]] = array_pop($myrow); |
||
1136 | } else { |
||
1137 | $retCount[] = array_pop($myrow); |
||
1138 | } |
||
1139 | $object = $this->create(false); |
||
1140 | $object->assignVars($myrow); |
||
1141 | if ($id_as_key) { |
||
1142 | $ret[$myrow[$this->keyName]] = $object; |
||
1143 | } else { |
||
1144 | $ret[] = $object; |
||
1145 | } |
||
1146 | unset($object); |
||
1147 | } |
||
1148 | } else { |
||
1149 | $object = $this->create(false); |
||
1150 | while (false !== ($myrow = $this->db->fetchArray($result))) { |
||
1151 | View Code Duplication | if ($id_as_key) { |
|
1152 | $retCount[$myrow[$this->keyName]] = array_pop($myrow); |
||
1153 | } else { |
||
1154 | $retCount[] = array_pop($myrow); |
||
1155 | } |
||
1156 | $object->assignVars($myrow); |
||
1157 | if ($id_as_key) { |
||
1158 | $ret[$myrow[$this->keyName]] = $object->getValues(array_keys($myrow)); |
||
1159 | } else { |
||
1160 | $ret[] = $object->getValues(array_keys($myrow)); |
||
1161 | } |
||
1162 | } |
||
1163 | unset($object); |
||
1164 | } |
||
1165 | |||
1166 | return [$ret, $retCount]; |
||
1167 | } |
||
1168 | |||
1169 | /** |
||
1170 | * @param null $otherCriteria |
||
1171 | * @param string $notNullFields |
||
1172 | * |
||
1173 | * @return int |
||
1174 | */ |
||
1175 | public function getLogsCount($otherCriteria = null, $notNullFields = '') |
||
1176 | { |
||
1177 | $criteria = new CriteriaCompo(); |
||
1178 | if (!empty($otherCriteria)) { |
||
1179 | $criteria->add($otherCriteria); |
||
1180 | } |
||
1181 | |||
1182 | return $this->getCount($criteria, $notNullFields); |
||
1183 | } |
||
1184 | |||
1185 | /** |
||
1186 | * Change Field in a table |
||
1187 | * |
||
1188 | * @access public |
||
1189 | * |
||
1190 | * @param string $field - name of the field eg: "my_field" |
||
1191 | * @param string $structure - structure of the field eg: "VARCHAR(50) NOT NULL default ''" |
||
1192 | * @param bool |
||
1193 | * |
||
1194 | * @return bool |
||
1195 | */ |
||
1196 | public function changeField($field = null, $structure = null) |
||
1197 | { |
||
1198 | $sql = "ALTER TABLE {$this->table} CHANGE {$field} {$field} {$structure}"; |
||
1199 | if (!$result = $this->db->queryF($sql)) { |
||
1200 | xoops_error($this->db->error() . '<br>' . $sql); |
||
1201 | |||
1202 | return false; |
||
1203 | } |
||
1204 | |||
1205 | return true; |
||
1206 | } |
||
1207 | |||
1208 | /** |
||
1209 | * Show Fields in a table - one field or all fields |
||
1210 | * |
||
1211 | * @access public |
||
1212 | * |
||
1213 | * @param string $field - name of the field eg: "my_field" or null for all fields |
||
1214 | * |
||
1215 | * @internal param array $ret [my_field] = Field Type Null Key Default Extra |
||
1216 | * |
||
1217 | * @return array|bool |
||
1218 | */ |
||
1219 | View Code Duplication | public function showFields($field = null) |
|
1220 | { |
||
1221 | $sql = "SHOW FIELDS FROM {$this->table}"; |
||
1222 | if (isset($field)) { |
||
1223 | $sql .= " LIKE '{$field}'"; |
||
1224 | } |
||
1225 | if (!$result = $this->db->queryF($sql)) { |
||
1226 | xoops_error($this->db->error() . '<br>' . $sql); |
||
1227 | |||
1228 | return false; |
||
1229 | } |
||
1230 | $ret = []; |
||
1231 | while ($myrow = $this->db->fetchArray($result)) { |
||
1232 | $ret[$myrow['Field']] = $myrow; |
||
1233 | } |
||
1234 | |||
1235 | return $ret; |
||
1236 | } |
||
1237 | |||
1238 | /** |
||
1239 | * Add Field in a table |
||
1240 | * |
||
1241 | * @access public |
||
1242 | * |
||
1243 | * @param string $field - name of the field eg: "my_field" |
||
1244 | * @param string $structure - structure of the field eg: "VARCHAR(50) NOT NULL default '' AFTER item_id" |
||
1245 | * @param bool |
||
1246 | * |
||
1247 | * @return bool |
||
1248 | */ |
||
1249 | View Code Duplication | public function addField($field = null, $structure = null) |
|
1250 | { |
||
1251 | if (empty($field) || empty($structure)) { |
||
1252 | return false; |
||
1253 | } |
||
1254 | if ($this->showFields($field)) { |
||
1255 | return false; |
||
1256 | } // field is exist |
||
1257 | $sql = "ALTER TABLE {$this->table} ADD {$field} {$structure}"; |
||
1258 | if (!$result = $this->db->queryF($sql)) { |
||
1259 | xoops_error($this->db->error() . '<br>' . $sql); |
||
1260 | |||
1261 | return false; |
||
1262 | } |
||
1263 | |||
1264 | return true; |
||
1265 | } |
||
1266 | |||
1267 | /** |
||
1268 | * Drop Field in a table |
||
1269 | * |
||
1270 | * @access public |
||
1271 | * |
||
1272 | * @param string $field - name of the field |
||
1273 | * @param bool |
||
1274 | * |
||
1275 | * @return bool |
||
1276 | */ |
||
1277 | View Code Duplication | public function dropField($field = null) |
|
1278 | { |
||
1279 | if (empty($field)) { |
||
1280 | return false; |
||
1281 | } |
||
1282 | if (!$this->showFields($field)) { |
||
1283 | return false; |
||
1284 | } // field is not exist |
||
1285 | $sql = "ALTER TABLE {$this->table} DROP {$field}"; |
||
1286 | if (!$result = $this->db->queryF($sql)) { |
||
1287 | xoops_error($this->db->error() . '<br>' . $sql); |
||
1288 | |||
1289 | return false; |
||
1290 | } |
||
1291 | |||
1292 | return true; |
||
1293 | } |
||
1294 | |||
1295 | /** |
||
1296 | * Show index in a table |
||
1297 | * |
||
1298 | * @access public |
||
1299 | * |
||
1300 | * @param string $index - name of the index (will be used in KEY_NAME) |
||
1301 | * @internal param array $ret = Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment Index_comment |
||
1302 | * |
||
1303 | * @return array|bool |
||
1304 | */ |
||
1305 | View Code Duplication | public function showIndex($index = null) |
|
1306 | { |
||
1307 | $sql = "SHOW INDEX FROM {$this->table}"; |
||
1308 | if (isset($index)) { |
||
1309 | $sql .= " WHERE KEY_NAME = '{$index}'"; |
||
1310 | } |
||
1311 | if (!$result = $this->db->queryF($sql)) { |
||
1312 | xoops_error($this->db->error() . '<br>' . $sql); |
||
1313 | |||
1314 | return false; |
||
1315 | } |
||
1316 | $ret = []; |
||
1317 | while ($myrow = $this->db->fetchArray($result)) { |
||
1318 | $ret[] = $myrow; |
||
1319 | } |
||
1320 | |||
1321 | return $ret; |
||
1322 | } |
||
1323 | |||
1324 | /** |
||
1325 | * Add Index to a table |
||
1326 | * |
||
1327 | * @access public |
||
1328 | * |
||
1329 | * @param string $index - name of the index |
||
1330 | * @param array $fields - array of table fields should be in the index |
||
1331 | * @param string $index_type - type of the index array("INDEX", "UNIQUE", "SPATIAL", "FULLTEXT") |
||
1332 | * @param bool |
||
1333 | * |
||
1334 | * @return bool |
||
1335 | */ |
||
1336 | View Code Duplication | public function addIndex($index = null, $fields = [], $index_type = 'INDEX') |
|
1337 | { |
||
1338 | if (empty($index) || empty($fields)) { |
||
1339 | return false; |
||
1340 | } |
||
1341 | if ($this->showIndex($index)) { |
||
1342 | return false; |
||
1343 | } // index is exist |
||
1344 | $index_type = strtoupper($index_type); |
||
1345 | if (!in_array($index_type, ['INDEX', 'UNIQUE', 'SPATIAL', 'FULLTEXT'])) { |
||
1346 | return false; |
||
1347 | } |
||
1348 | $fields = is_array($fields) ? implode(',', $fields) : $fields; |
||
1349 | $sql = "ALTER TABLE {$this->table} ADD {$index_type} {$index} ( {$fields} )"; |
||
1350 | if (!$result = $this->db->queryF($sql)) { |
||
1351 | xoops_error($this->db->error() . '<br>' . $sql); |
||
1352 | |||
1353 | return false; |
||
1354 | } |
||
1355 | |||
1356 | return true; |
||
1357 | } |
||
1358 | |||
1359 | /** |
||
1360 | * Drop index in a table |
||
1361 | * |
||
1362 | * @access public |
||
1363 | * |
||
1364 | * @param string $index - name of the index |
||
1365 | * @param bool |
||
1366 | * |
||
1367 | * @return bool |
||
1368 | */ |
||
1369 | View Code Duplication | public function dropIndex($index = null) |
|
1370 | { |
||
1371 | if (empty($index)) { |
||
1372 | return false; |
||
1373 | } |
||
1374 | if (!$this->showIndex($index)) { |
||
1375 | return false; |
||
1376 | } // index is not exist |
||
1377 | $sql = "ALTER TABLE {$this->table} DROP INDEX {$index}"; |
||
1378 | if (!$result = $this->db->queryF($sql)) { |
||
1379 | xoops_error($this->db->error() . '<br>' . $sql); |
||
1380 | |||
1381 | return false; |
||
1382 | } |
||
1383 | |||
1384 | return true; |
||
1385 | } |
||
1386 | |||
1387 | /** |
||
1388 | * Change Index = Drop index + Add Index |
||
1389 | * |
||
1390 | * @access public |
||
1391 | * |
||
1392 | * @param string $index - name of the index |
||
1393 | * @param array $fields - array of table fields should be in the index |
||
1394 | * @param string $index_type - type of the index array("INDEX", "UNIQUE", "SPATIAL", "FULLTEXT") |
||
1395 | * @param bool |
||
1396 | * |
||
1397 | * @return bool |
||
1398 | */ |
||
1399 | View Code Duplication | public function changeIndex($index = null, $fields = [], $index_type = 'INDEX') |
|
1400 | { |
||
1401 | if ($this->showIndex($index) && !$this->dropIndex($index)) { |
||
1402 | return false; |
||
1403 | } // if index is exist but cannot drop it |
||
1404 | |||
1405 | return $this->addIndex($index, $fields, $index_type); |
||
1406 | } |
||
1407 | |||
1408 | /** |
||
1409 | * Show if the object table or any other table is exist in database |
||
1410 | * |
||
1411 | * @access public |
||
1412 | * |
||
1413 | * @param string $table or $db->prefix("{$table}") eg: $db->prefix("bb_forums") or "bb_forums" will return same result |
||
1414 | * @internal param bool $found |
||
1415 | * |
||
1416 | * @return bool |
||
1417 | */ |
||
1418 | public function showTable($table = null) |
||
1419 | { |
||
1420 | if (empty($table)) { |
||
1421 | $table = $this->table; |
||
1422 | } // the table for this object |
||
1423 | // check if database prefix is not added yet and then add it!!! |
||
1424 | View Code Duplication | if (0 !== strpos($table, $this->db->prefix() . '_')) { |
|
1425 | $table = $this->db->prefix("{$table}"); |
||
1426 | } |
||
1427 | $result = $this->db->queryF("SHOW TABLES LIKE '{$table}'"); |
||
1428 | $found = $this->db->getRowsNum($result); |
||
1429 | |||
1430 | return empty($found) ? false : true; |
||
1431 | } |
||
1432 | |||
1433 | /** |
||
1434 | * Rename an old table to the current object table in database |
||
1435 | * |
||
1436 | * @access public |
||
1437 | * |
||
1438 | * @param string $oldTable or $db->prefix("{$oldTable}") eg: $db->prefix("bb_forums") or "bb_forums" will return same result |
||
1439 | * @param bool |
||
1440 | * |
||
1441 | * @return bool |
||
1442 | */ |
||
1443 | public function renameTable($oldTable) |
||
1444 | { |
||
1445 | if ($this->showTable() || !$this->showTable($oldTable)) { |
||
1446 | return false; |
||
1447 | } // table is current || oldTable is not exist |
||
1448 | // check if database prefix is not added yet and then add it!!! |
||
1449 | View Code Duplication | if (0 !== strpos($oldTable, $this->db->prefix() . '_')) { |
|
1450 | $oldTable = $this->db->prefix("{$oldTable}"); |
||
1451 | } |
||
1452 | if (!$result = $this->db->queryF("ALTER TABLE {$oldTable} RENAME {$this->table}")) { |
||
1453 | xoops_error($this->db->error() . '<br>' . $sql); |
||
1454 | |||
1455 | return false; |
||
1456 | } |
||
1457 | |||
1458 | return true; |
||
1459 | } |
||
1460 | } |
||
1461 |
Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.
The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.
This check looks for comments that seem to be mostly valid code and reports them.