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 |
||
0 ignored issues
–
show
|
|||
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 |
||
0 ignored issues
–
show
PSR1 recommends that each class must be in a namespace of at least one level to avoid collisions.
You can fix this by adding a namespace to your class: namespace YourVendor;
class YourClass { }
When choosing a vendor namespace, try to pick something that is not too generic to avoid conflicts with other libraries. ![]() |
|||
32 | { |
||
33 | /** |
||
34 | * @var string |
||
35 | */ |
||
36 | public $userlog = null; |
||
37 | |||
38 | public $store = 0; // store: 0,1->db 2->file 3->both |
||
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")); |
||
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!!! |
||
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" |
||
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; |
||
628 | // Obtain a list of columns |
||
629 | foreach ($logs as $key => $log) { |
||
630 | $col[$key] = $log[$sort]; |
||
631 | //$col2[$key] = $log[$sort2]; |
||
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 = []; |
||
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 |
||
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})"); |
||
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'); |
||
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 | /* |
||
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 |
||
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 |
||
0 ignored issues
–
show
PSR1 recommends that each class must be in a namespace of at least one level to avoid collisions.
You can fix this by adding a namespace to your class: namespace YourVendor;
class YourClass { }
When choosing a vendor namespace, try to pick something that is not too generic to avoid conflicts with other libraries. ![]() |
|||
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 |
The PSR-1: Basic Coding Standard recommends that a file should either introduce new symbols, that is classes, functions, constants or similar, or have side effects. Side effects are anything that executes logic, like for example printing output, changing ini settings or writing to a file.
The idea behind this recommendation is that merely auto-loading a class should not change the state of an application. It also promotes a cleaner style of programming and makes your code less prone to errors, because the logic is not spread out all over the place.
To learn more about the PSR-1, please see the PHP-FIG site on the PSR-1.