Issues (304)

Security Analysis    not enabled

This project does not seem to handle request data directly as such no vulnerable execution paths were found.

  Cross-Site Scripting
Cross-Site Scripting enables an attacker to inject code into the response of a web-request that is viewed by other users. It can for example be used to bypass access controls, or even to take over other users' accounts.
  File Exposure
File Exposure allows an attacker to gain access to local files that he should not be able to access. These files can for example include database credentials, or other configuration files.
  File Manipulation
File Manipulation enables an attacker to write custom data to files. This potentially leads to injection of arbitrary code on the server.
  Object Injection
Object Injection enables an attacker to inject an object into PHP code, and can lead to arbitrary code execution, file exposure, or file manipulation attacks.
  Code Injection
Code Injection enables an attacker to execute arbitrary code on the server.
  Response Splitting
Response Splitting can be used to send arbitrary responses.
  File Inclusion
File Inclusion enables an attacker to inject custom files into PHP's file loading mechanism, either explicitly passed to include, or for example via PHP's auto-loading mechanism.
  Command Injection
Command Injection enables an attacker to inject a shell command that is execute with the privileges of the web-server. This can be used to expose sensitive data, or gain access of your server.
  SQL Injection
SQL Injection enables an attacker to execute arbitrary SQL code on your database server gaining access to user data, or manipulating user data.
  XPath Injection
XPath Injection enables an attacker to modify the parts of XML document that are read. If that XML document is for example used for authentication, this can lead to further vulnerabilities similar to SQL Injection.
  LDAP Injection
LDAP Injection enables an attacker to inject LDAP statements potentially granting permission to run unauthorized queries, or modify content inside the LDAP tree.
  Header Injection
  Other Vulnerability
This category comprises other attack vectors such as manipulating the PHP runtime, loading custom extensions, freezing the runtime, or similar.
  Regex Injection
Regex Injection enables an attacker to execute arbitrary code in your PHP process.
  XML Injection
XML Injection enables an attacker to read files on your local filesystem including configuration files, or can be abused to freeze your web-server process.
  Variable Injection
Variable Injection enables an attacker to overwrite program variables with custom data, and can lead to further vulnerabilities.
Unfortunately, the security analysis is currently not available for your project. If you are a non-commercial open-source project, please contact support to gain access.

class/setting.php (3 issues)

Upgrade to new PHP Analysis Engine

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
 *  userlog module
13
 *
14
 * @copyright       XOOPS Project (https://xoops.org)
15
 * @license         GNU GPL 2 (http://www.gnu.org/licenses/old-licenses/gpl-2.0.html)
16
 * @package         userlog class
17
 * @since           1
18
 * @author          irmtfan ([email protected])
19
 * @author          XOOPS Project <www.xoops.org> <www.xoops.ir>
20
 */
21
22
defined('XOOPS_ROOT_PATH') || exit('Restricted access.');
23
require_once __DIR__ . '/../include/common.php';
24
25
xoops_loadLanguage('admin', USERLOG_DIRNAME);
26
xoops_load('XoopsFormLoader');
27
28
/**
29
 * Class UserlogSetting
30
 */
31
class UserlogSetting extends XoopsObject
32
{
33
    /**
34
     * @var string
35
     */
36
    public $all_logby = ['uid' => _AM_USERLOG_UID, 'gid' => _AM_USERLOG_SET_GID, 'ip' => _AM_USERLOG_SET_IP];
37
38
    public $userlog = null;
39
40
    /**
41
     * constructor
42
     */
43
    public function __construct()
44
    {
45
        $this->userlog = Userlog::getInstance();
46
        $this->initVar('set_id', XOBJ_DTYPE_INT, null, false);
47
        $this->initVar('name', XOBJ_DTYPE_TXTBOX, null, false, 100);
48
        $this->initVar('logby', XOBJ_DTYPE_TXTBOX, null, true, 10);
49
        $this->initVar('unique_id', XOBJ_DTYPE_INT, null, false);
50
        $this->initVar('options', XOBJ_DTYPE_TXTAREA, '', false);
51
        $this->initVar('scope', XOBJ_DTYPE_TXTAREA, '', false);
52
    }
53
54
    /**
55
     * @param string $method
56
     * @param array  $args
57
     *
58
     * @return mixed
59
     */
60
    public function __call($method, $args)
61
    {
62
        $arg = isset($args[0]) ? $args[0] : null;
63
64
        return $this->getVar($method, $arg);
65
    }
66
67
    /**
68
     * @return UserlogSetting
69
     */
70
    public static function getInstance()
71
    {
72
        static $instance;
73
        if (null === $instance) {
74
            $instance = new static();
75
        }
76
77
        return $instance;
78
    }
79
80
    /**
81
     * @return mixed|string
82
     */
83
    public function unique_id()
84
    {
85
        if ('ip' === $this->getVar('logby')) {
86
            return long2ip($this->getVar('unique_id'));
87
        }
88
89
        return $this->getVar('unique_id');
90
    }
91
92
    /**
93
     * @param bool $force
94
     *
95
     * @return bool
96
     */
97
    public function storeSet($force = true)
98
    {
99
        if ($this->setDb(true)) {
100
            // use $this->getVar('unique_id') (int ip) instead of $this->unique_id() (string ip)
0 ignored issues
show
Unused Code Comprehensibility introduced by
46% 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.

Loading history...
101
            if ($this->setFile($this->logby(), $this->getVar('unique_id'), [$this->options(), $this->scope()])) {
102
                return true;
103
            }
104
        }
105
106
        return false;
107
    }
108
109
    /**
110
     * @return array|bool
111
     */
112
    public function getSet()
113
    {
114
        $options = '';
0 ignored issues
show
$options 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 $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
115
        // if uid setting exist in File
116
        $unique_uid = $this->userlog->getUser() ? $this->userlog->getUser()->getVar('uid') : 0;
117
        if ($options = $this->getFile('uid', $unique_uid)) {
118
            return $options;
119
        }
120
121
        // if gid setting exist in File
122
        $unique_gid = $this->userlog->getUser() ? $this->userlog->getUser()->getGroups() : [XOOPS_GROUP_ANONYMOUS];
123
        foreach ($unique_gid as $gid) {
124
            if ($options = $this->getFile('gid', $gid)) {
125
                return $options;
126
            }
127
        }
128
        // if ip setting exist in File
129
        $unique_ip = XoopsUserUtility::getIP(); // ip as int
130
        if ($options = $this->getFile('ip', $unique_ip)) {
131
            return $options;
132
        }
133
        // if all exist in File
134
        if ($options = $this->getFile('all', 0)) {
135
            return $options;
136
        }
137
        ///////////////////////////////////////////////////////////
138
        // check probability
139
        if (!$this->userlog->probCheck($this->userlog->getConfig('probset'))) {
140
            return false;
141
        }
142
        // database get All is better for performance???
143
        $logsetsObj = $this->userlog->getHandler('setting')->getAll();
144
        if (empty($logsetsObj)) {
145
            return false;
146
        } // if not set in db return false
147
        $uid_unique_uid = 'uid' . $unique_uid;
148
        foreach ($unique_gid as $key => $gid) {
149
            $gid_unique_gid[$key] = 'gid' . $gid;
150
        }
151
        $ip_unique_ip = 'ip' . $unique_ip;
152
        foreach ($logsetsObj as $setObj) {
153
            $sLogby     = $setObj->logby();
154
            $sUnique_id = $setObj->getVar('unique_id');
155
            $sLogbyId   = $sLogby . $sUnique_id;
156
            // if uid setting exist in db return it
157
            if ($sLogbyId == $uid_unique_uid
158
                || // if gid setting exist in db return it
159
                in_array($sLogbyId, $gid_unique_gid)
160
                || // if ip setting exist in db return it
161
                $sLogbyId == $ip_unique_ip
162
            ) {
163
                $sets = [$setObj->options(), $setObj->scope()];
164
                $this->setFile($sLogby, $sUnique_id, $sets); // build cache
165
166
                return $sets;
167
            }
168
            // if all exist in db
169
            if (0 == $sUnique_id) {
170
                $sets = [$setObj->options(), $setObj->scope()];
171
                $this->setFile('all', 0, $sets); // build cache
172
173
                return $sets;
174
            }
175
        }
176
177
        return false;
178
    }
179
180
    /**
181
     * @param bool $force
182
     *
183
     * @return mixed
184
     */
185
    public function setDb($force = true)
186
    {
187
        $ret = $this->userlog->getHandler('setting')->insert($this, $force);
188
        $this->unsetNew();
189
190
        return $ret;
191
    }
192
193
    public function getDb()
194
    {
195
    }
196
197
    /**
198
     * @param string $logby
199
     * @param        $unique_id
200
     * @param        $options
201
     *
202
     * @return bool
203
     */
204
    public function setFile($logby = 'uid', $unique_id, $options)
205
    {
206
        return $this->_createCacheFile($options, "setting_{$logby}_{$unique_id}");
207
    }
208
209
    /**
210
     * @param string $logby
211
     * @param        $unique_id
212
     *
213
     * @return bool|mixed
214
     */
215
    public function getFile($logby = 'uid', $unique_id)
216
    {
217
        return $this->_loadCacheFile("setting_{$logby}_{$unique_id}");
218
    }
219
220
    /**
221
     * @param string $logby
222
     * @param        $unique_id
223
     *
224
     * @return bool
225
     */
226
    public function deleteFile($logby = 'uid', $unique_id)
227
    {
228
        return $this->_deleteCacheFile("setting_{$logby}_{$unique_id}");
229
    }
230
231
    /**
232
     * @param        $data
233
     * @param null   $name
234
     * @param string $root_path
235
     *
236
     * @return bool
237
     */
238
    private function _createCacheFile($data, $name = null, $root_path = XOOPS_CACHE_PATH)
239
    {
240
        $name = $name ?: (string)time();
241
        $key  = USERLOG_DIRNAME . "_{$name}";
242
243
        //$cacheHandler = XoopsCache::config($key, array('path' => XOOPS_VAR_PATH . '/caches/xoops_cache/userlog'));
0 ignored issues
show
Unused Code Comprehensibility introduced by
52% 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.

Loading history...
244
        return XoopsCache::write($key, $data);
245
    }
246
247
    /**
248
     * @param null   $name
249
     * @param string $root_path
250
     *
251
     * @return bool|mixed
252
     */
253 View Code Duplication
    private function _loadCacheFile($name = null, $root_path = XOOPS_CACHE_PATH)
254
    {
255
        if (empty($name)) {
256
            return false;
257
        }
258
        $key = USERLOG_DIRNAME . "_{$name}";
259
260
        return XoopsCache::read($key);
261
    }
262
263
    /**
264
     * @param null   $name
265
     * @param string $root_path
266
     *
267
     * @return bool
268
     */
269 View Code Duplication
    private function _deleteCacheFile($name = null, $root_path = XOOPS_CACHE_PATH)
270
    {
271
        if (empty($name)) {
272
            return false;
273
        }
274
        $key = USERLOG_DIRNAME . "_{$name}";
275
276
        return XoopsCache::delete($key);
277
    }
278
279
    /**
280
     * @param null   $option
281
     * @param string $V
282
     *
283
     * @return array
284
     */
285
    public function getOptions($option = null, $V = 'value')
286
    {
287
        $V = strtolower($V);
288
289
        if ($this->userlog->getUser()) {
290
            $uid        = $this->userlog->getUser()->getVar('uid');
291
            $uname      = $this->userlog->getUser()->getVar('uname');
292
            $last_login = $this->userlog->getUser()->getVar('last_login');
293
            $admin      = $this->userlog->getUser()->isAdmin();
294
            $groups     = 'g' . implode('g', array_unique($this->userlog->getUser()->getGroups())); // g1g2
295
        } else {
296
            $uid        = 0;
297
            $uname      = '';
298
            $last_login = 0;
299
            $admin      = 0;
300
            $groups     = 'g' . XOOPS_GROUP_ANONYMOUS; // g3
301
        }
302
        $tempUserLog = explode('/', $_SERVER['PHP_SELF']);
303
        $options = [
304
            'log_id'         => [
305
                'type'  => 'int',
306
                'title' => _AM_USERLOG_LOG_ID,
307
                'value' => null // null for now
308
            ],
309
            'log_time'       => [
310
                'type'  => 'int',
311
                'title' => _AM_USERLOG_LOG_TIME,
312
                'value' => time()
313
            ],
314
            'uid'            => [
315
                'type'  => 'int',
316
                'title' => _AM_USERLOG_UID,
317
                'value' => $uid
318
            ],
319
            'uname'          => [
320
                'type'  => 'text',
321
                'title' => _AM_USERLOG_UNAME,
322
                'value' => $uname
323
            ],
324
            'admin'          => [
325
                'type'  => 'bool',
326
                'title' => _AM_USERLOG_ADMIN,
327
                'value' => $admin
328
            ],
329
            'groups'         => [
330
                'type'  => 'text',
331
                'title' => _AM_USERLOG_GROUPS,
332
                'value' => $groups
333
            ],
334
            'last_login'     => [
335
                'type'  => 'int',
336
                'title' => _AM_USERLOG_LAST_LOGIN,
337
                'value' => $last_login
338
            ],
339
            'user_ip'        => [
340
                'type'  => 'text',
341
                'title' => _AM_USERLOG_USER_IP,
342
                'value' => $_SERVER['REMOTE_ADDR']
343
            ],
344
            'user_agent'     => [
345
                'type'  => 'text',
346
                'title' => _AM_USERLOG_USER_AGENT,
347
                'value' => $_SERVER['HTTP_USER_AGENT']
348
            ],
349
            'url'            => [
350
                'type'  => 'text',
351
                'title' => _AM_USERLOG_URL,
352
                'value' => $_SERVER['REQUEST_URI']
353
            ],
354
            'script'         => [
355
                'type'  => 'text',
356
                'title' => _AM_USERLOG_SCRIPT,
357
                'value' => end($tempUserLog)
358
            ],
359
            'referer'        => [
360
                'type'  => 'text',
361
                'title' => _AM_USERLOG_REFERER,
362
                'value' => !empty($_SERVER['HTTP_REFERER']) ? $_SERVER['HTTP_REFERER'] : ''
363
            ],
364
            'pagetitle'      => [
365
                'type'  => 'text',
366
                'title' => _AM_USERLOG_PAGETITLE,
367
                'value' => isset($GLOBALS['xoopsTpl']) ? $GLOBALS['xoopsTpl']->get_template_vars('xoops_pagetitle') : ''
368
            ],
369
            'pageadmin'      => [
370
                'type'  => 'bool',
371
                'title' => _AM_USERLOG_PAGEADMIN,
372
                'value' => (isset($GLOBALS['xoopsOption']['pagetype'])
373
                            && 'admin' === $GLOBALS['xoopsOption']['pagetype']) ? 1 : 0
374
            ],
375
            'module'         => [
376
                'type'  => 'text',
377
                'title' => _AM_USERLOG_MODULE,
378
                'value' => $this->userlog->getLogModule()->getVar('dirname')
379
            ],
380
            'module_name'    => [
381
                'type'  => 'text',
382
                'title' => _AM_USERLOG_MODULE_NAME,
383
                'value' => $this->userlog->getLogModule()->getVar('name')
384
            ],
385
            'item_name'      => [
386
                'type'  => 'text',
387
                'title' => _AM_USERLOG_ITEM_NAME,
388
                'value' => null
389
            ],
390
            'item_id'        => [
391
                'type'  => 'int',
392
                'title' => _AM_USERLOG_ITEM_ID,
393
                'value' => null
394
            ],
395
            // user data input method
396
            'request_method' => [
397
                'type'  => 'text',
398
                'title' => _AM_USERLOG_REQUEST_METHOD,
399
                'value' => $_SERVER['REQUEST_METHOD']
400
            ],
401
            'zget'           => [
402
                'type'  => 'text',
403
                'title' => _AM_USERLOG_GET,
404
                'value' => $_GET
405
            ],
406
            'post'           => [
407
                'type'  => 'text',
408
                'title' => _AM_USERLOG_POST,
409
                'value' => $_POST
410
            ],
411
            'request'        => [
412
                'type'  => 'text',
413
                'title' => _AM_USERLOG_REQUEST,
414
                'value' => $_REQUEST
415
            ],
416
            'files'          => [
417
                'type'  => 'text',
418
                'title' => _AM_USERLOG_FILES,
419
                'value' => $_FILES
420
            ],
421
            'env'            => [
422
                'type'  => 'text',
423
                'title' => _AM_USERLOG_ENV,
424
                'value' => $_ENV
425
            ],
426
            'session'        => [
427
                'type'  => 'text',
428
                'title' => _AM_USERLOG_SESSION,
429
                'value' => $_SESSION
430
            ],
431
            'cookie'         => [
432
                'type'  => 'text',
433
                'title' => _AM_USERLOG_COOKIE,
434
                'value' => $_COOKIE
435
            ],
436
            'header'         => [
437
                'type'  => 'text',
438
                'title' => _AM_USERLOG_HEADER,
439
                'value' => headers_list()
440
            ],
441
            'logger'         => [
442
                'type'  => 'text',
443
                'title' => _AM_USERLOG_LOGGER,
444
                'value' => $GLOBALS['xoopsLogger']->errors
445
            ],
446
            // settings will not be logged
447
            'active'         => [
448
                'type'  => 'int',
449
                'title' => _AM_USERLOG_SET_ACTIVE,
450
                'value' => 1
451
            ],
452
            'inside'         => [
453
                'type'  => 'int',
454
                'title' => _AM_USERLOG_INSIDE,
455
                'value' => 1
456
            ],
457
            'outside'        => [
458
                'type'  => 'int',
459
                'title' => _AM_USERLOG_OUTSIDE,
460
                'value' => 1
461
            ],
462
            'unset_pass'     => [
463
                'type'  => 'int',
464
                'title' => _AM_USERLOG_UNSET_PASS,
465
                'value' => 1
466
            ],
467
            'store_file'     => [
468
                'type'  => 'int',
469
                'title' => _AM_USERLOG_STORE_FILE,
470
                'value' => 1
471
            ],
472
            'store_db'       => [
473
                'type'  => 'int',
474
                'title' => _AM_USERLOG_STORE_DB,
475
                'value' => 1
476
            ],
477
            'views'          => [
478
                'type'  => 'int',
479
                'title' => _AM_USERLOG_VIEWS,
480
                'value' => 1 // for item_name and item_id
481
            ]
482
        ];
483
        $ret     = $this->userlog->getFromKeys($options, $option);
484
        // patch Login/Register History
485
        if (isset($ret['post']['value'])) {
486
            $ret['post']['value'] = $this->userlog->patchLoginHistory($ret['post']['value'], $uid, !empty($ret['unset_pass']['value']));
487
        }
488
        if (empty($V)) {
489
            return $ret;
490
        }
491
        if ('key' === $V) {
492
            return array_keys($ret);
493
        }
494
        $ret2     = [];
495
        $emptyAll = 'value' === $V; // check if all values are empty
496
        foreach ($ret as $option => $val) {
497
            $ret2[$option] = $val[$V];
498
            // if there is a value || exceptions continue
499
            if (!$emptyAll
500
                || in_array($option, [
501
                    'log_id',
502
                    'log_time',
503
                    'active',
504
                    'inside',
505
                    'outside',
506
                    'unset_pass',
507
                    'store_file',
508
                    'store_db',
509
                    'views'
510
                ])
511
            ) {
512
                continue;
513
            }
514
            // check values
515
            if (!empty($val[$V])) {
516
                $emptyAll = false;
517
            }
518
        }
519
520
        return $emptyAll ? [] : $ret2;
521
    }
522
523
    /**
524
     * @param null $options
525
     *
526
     * @return array
527
     */
528
    public function logForm($options = null)
529
    {
530
        $form    = new XoopsThemeForm(_AM_USERLOG_LOGFORM, 'logs', 'logs.php', 'get');
531
        $headers = $this->getOptions('', 'title');
532
        unset($headers['active'], $headers['inside'], $headers['outside'], $headers['unset_pass'], $headers['store_db'], $headers['store_file'], $headers['views']);
533
        $el          = [];
534
        $query_types = ['=' => '', '>' => 'GT', '<' => 'LT'];
535
        foreach ($headers as $ele => $def) {
536
            switch ($ele) {
537
                case 'pageadmin':
538
                case 'admin':
539
                    $defEl    = '_AM_USERLOG_' . strtoupper($ele); // if constant is defined in translation - it is good for now
540
                    $el[$ele] = new XoopsFormRadio(constant($defEl), "options[{$ele}]", isset($options[$ele]) ? $options[$ele] : '');
541
                    $el[$ele]->addOption(1, _YES);
542
                    $el[$ele]->addOption(0, _NO);
543
                    $el[$ele]->addOption('', _ALL);
544
                    $el[$ele]->setDescription(constant($defEl . '_FORM'));
545
                    $form->addElement($el[$ele]);
546
                    break;
547
                default:
548
                    foreach ($query_types as $type) {
549
                        $defEl = '_AM_USERLOG_' . strtoupper($ele . $type); // if constant is defined in translation - it is good for now
550
                        if (defined($defEl . '_FORM')) {
551
                            $el[$ele . $type] = new XoopsFormText(constant($defEl), "options[{$ele}{$type}]", 10, 255, !empty($options[$ele . $type]) ? $options[$ele . $type] : null);
552
                            $defEle           = '_AM_USERLOG_' . strtoupper($ele);
553
                            $el[$ele . $type]->setDescription(sprintf(constant($defEl . '_FORM'), constant($defEle), constant($defEle)));
554
                            $form->addElement($el[$ele . $type]);
555
                        }
556
                    }
557
                    break;
558
            }
559
        }
560
        // http://stackoverflow.com/questions/8029532/how-to-prevent-submitting-the-html-forms-input-field-value-if-it-empty
561
        // http://stackoverflow.com/questions/2617480/how-to-get-all-elements-which-name-starts-with-some-string
562
        $el['log_id']->customValidationCode[] = "preventSubmitEmptyInput('options[');"; // check all input tags
563
564
        return [$form, $el, $headers];
565
    }
566
567
    /**
568
     * @return int
569
     */
570
    public function cleanCache()
571
    {
572
        $files = glob(XOOPS_VAR_PATH . '/caches/xoops_cache/*' . USERLOG_DIRNAME . '*.*');
573
        foreach ($files as $filename) {
574
            unlink($filename);
575
        }
576
577
        return count($files);
578
    }
579
}
580
581
/**
582
 * Class UserlogSettingHandler
583
 */
584
class UserlogSettingHandler extends XoopsPersistableObjectHandler
585
{
586
    public $userlog = null;
587
588
    /**
589
     * @param null|XoopsDatabase $db
590
     */
591
    public function __construct(XoopsDatabase $db)
592
    {
593
        $this->userlog = Userlog::getInstance();
594
        parent::__construct($db, USERLOG_DIRNAME . '_set', 'UserlogSetting', 'set_id', 'logby');
595
    }
596
597
    /**
598
     * @param int    $limit
599
     * @param int    $start
600
     * @param null   $otherCriteria
601
     * @param string $sort
602
     * @param string $order
603
     * @param null   $fields
604
     * @param bool   $asObject
605
     * @param bool   $id_as_key
606
     *
607
     * @return mixed
608
     */
609 View Code Duplication
    public function getSets(
610
        $limit = 0,
611
        $start = 0,
612
        $otherCriteria = null,
613
        $sort = 'set_id',
614
        $order = 'DESC',
615
        $fields = null,
616
        $asObject = true,
617
        $id_as_key = true
618
    ) {
619
        $criteria = new CriteriaCompo();
620
        if (!empty($otherCriteria)) {
621
            $criteria->add($otherCriteria);
622
        }
623
        $criteria->setLimit($limit);
624
        $criteria->setStart($start);
625
        $criteria->setSort($sort);
626
        $criteria->setOrder($order);
627
        $ret = $this->getAll($criteria, $fields, $asObject, $id_as_key);
628
629
        return $ret;
630
    }
631
}
632