FaqHandler::getFaqsCount()   F
last analyzed

Complexity

Conditions 15
Paths 288

Size

Total Lines 60
Code Lines 32

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 32
c 1
b 0
f 0
dl 0
loc 60
rs 3.9833
cc 15
nc 288
nop 3

How to fix   Long Method    Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php declare(strict_types=1);
2
3
namespace XoopsModules\Smartfaq;
4
5
/**
6
 * Module: SmartFAQ
7
 * Author: The SmartFactory <www.smartfactory.ca>
8
 * Licence: GNU
9
 */
10
11
use XoopsModules\Smartfaq;
12
13
//require_once XOOPS_ROOT_PATH . '/modules/smartfaq/class/category.php';
14
15
/**
16
 * Q&A handler class.
17
 * This class is responsible for providing data access mechanisms to the data source
18
 * of Q&A class objects.
19
 *
20
 * @author  marcan <[email protected]>
21
 */
22
class FaqHandler extends \XoopsObjectHandler
23
{
24
    protected $helper;
25
26
    /**
27
     * @param \XoopsDatabase|null                $db
28
     * @param \XoopsModules\Smartfaq\Helper|null $helper
29
     */
30
    public function __construct(\XoopsDatabase $db = null, \XoopsModules\Smartfaq\Helper $helper = null)
31
    {
32
        /** @var \XoopsModules\Smartfaq\Helper $this ->helper */
33
        if (null === $helper) {
34
            $this->helper = \XoopsModules\Smartfaq\Helper::getInstance();
0 ignored issues
show
Bug introduced by
The property helper does not seem to exist on XoopsModules\Smartfaq\Helper.
Loading history...
35
        } else {
36
            $this->helper = $helper;
37
        }
38
39
        if (null === $db) {
40
            $db = \XoopsDatabaseFactory::getDatabaseConnection();
41
        }
42
43
        $smartfaqIsAdmin = $this->helper->isUserAdmin();
0 ignored issues
show
Unused Code introduced by
The assignment to $smartfaqIsAdmin is dead and can be removed.
Loading history...
44
        parent::__construct($db, 'smartfaq_faq', Faq::class, 'faqid', 'faqid');
0 ignored issues
show
Unused Code introduced by
The call to XoopsObjectHandler::__construct() has too many arguments starting with 'smartfaq_faq'. ( Ignorable by Annotation )

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

44
        parent::/** @scrutinizer ignore-call */ 
45
                __construct($db, 'smartfaq_faq', Faq::class, 'faqid', 'faqid');

This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress. Please note the @ignore annotation hint above.

Loading history...
45
    }
46
47
    /**
48
     * @param bool $isNew
49
     * @return Smartfaq\Faq
50
     */
51
    public function create($isNew = true)
52
    {
53
        $faq = new Smartfaq\Faq();
54
        if ($isNew) {
55
            $faq->setDefaultPermissions();
56
            $faq->setNew();
57
        }
58
59
        return $faq;
60
    }
61
62
    /**
63
     * retrieve an FAQ
64
     *
65
     * @param int $id faqid of the user
66
     * @return mixed reference to the {@link Smartfaq\Faq} object, FALSE if failed
67
     */
68
    public function get($id)
69
    {
70
        if ((int)$id > 0) {
71
            $sql = 'SELECT * FROM ' . $this->db->prefix('smartfaq_faq') . ' WHERE faqid=' . $id;
72
            if (!$result = $this->db->query($sql)) {
73
                return false;
74
            }
75
76
            $numrows = $this->db->getRowsNum($result);
77
            if (1 == $numrows) {
78
                $faq = new Smartfaq\Faq();
79
                $faq->assignVars($this->db->fetchArray($result));
80
81
                return $faq;
82
            }
83
        }
84
85
        return false;
86
    }
87
88
    /**
89
     * insert a new faq in the database
90
     *
91
     * @param \XoopsObject $object reference to the {@link Smartfaq\Faq} object
92
     * @param bool         $force
93
     * @return bool        FALSE if failed, TRUE if already present and unchanged or successful
94
     */
95
    public function insert(\XoopsObject $object, $force = false)
96
    {
97
        if ('xoopsmodules\smartfaq\faq' !== \mb_strtolower(\get_class($object))) {
98
            return false;
99
        }
100
101
        if (!$object->isDirty()) {
102
            return true;
103
        }
104
105
        if (!$object->cleanVars()) {
106
            return false;
107
        }
108
109
        foreach ($object->cleanVars as $k => $v) {
110
            ${$k} = $v;
111
        }
112
113
        if ($object->isNew()) {
114
            $sql = \sprintf(
115
                'INSERT INTO `%s` (faqid, categoryid, question, howdoi, diduno, uid, datesub, status, counter, weight, html, smiley, xcodes, cancomment, comments, notifypub, modulelink, contextpage, exacturl, partialview) VALUES (NULL, %u, %s, %s, %s, %u, %u, %u, %u, %u, %u, %u, %u, %u, %u, %u, %s, %s, %u, %u)',
116
                $this->db->prefix('smartfaq_faq'),
117
                $categoryid,
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $categoryid seems to be never defined.
Loading history...
118
                $this->db->quoteString($question),
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $question seems to be never defined.
Loading history...
119
                $this->db->quoteString($howdoi),
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $howdoi seems to be never defined.
Loading history...
120
                $this->db->quoteString($diduno),
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $diduno seems to be never defined.
Loading history...
121
                $uid,
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $uid seems to be never defined.
Loading history...
122
                \time(),
123
                $status,
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $status seems to be never defined.
Loading history...
124
                $counter,
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $counter seems to be never defined.
Loading history...
125
                $weight,
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $weight seems to be never defined.
Loading history...
126
                $html,
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $html seems to be never defined.
Loading history...
127
                $smiley,
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $smiley seems to be never defined.
Loading history...
128
                $xcodes,
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $xcodes seems to be never defined.
Loading history...
129
                $cancomment,
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $cancomment seems to be never defined.
Loading history...
130
                $comments,
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $comments seems to be never defined.
Loading history...
131
                $notifypub,
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $notifypub seems to be never defined.
Loading history...
132
                $this->db->quoteString($modulelink),
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $modulelink seems to be never defined.
Loading history...
133
                $this->db->quoteString($contextpage),
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $contextpage seems to be never defined.
Loading history...
134
                $exacturl,
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $exacturl seems to be never defined.
Loading history...
135
                $partialview
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $partialview seems to be never defined.
Loading history...
136
            );
137
        } else {
138
            $sql = \sprintf(
139
                'UPDATE `%s` SET categoryid = %u, question = %s, howdoi = %s, diduno = %s, uid = %u, datesub = %u, status = %u, counter = %u, weight = %u, html = %u, smiley = %u, xcodes = %u, cancomment = %u, comments = %u, notifypub = %u, modulelink = %s, contextpage = %s, exacturl = %u, partialview = %u  WHERE faqid = %u',
140
                $this->db->prefix('smartfaq_faq'),
141
                $categoryid,
142
                $this->db->quoteString($question),
143
                $this->db->quoteString($howdoi),
144
                $this->db->quoteString($diduno),
145
                $uid,
146
                $datesub,
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $datesub seems to be never defined.
Loading history...
147
                $status,
148
                $counter,
149
                $weight,
150
                $html,
151
                $smiley,
152
                $xcodes,
153
                $cancomment,
154
                $comments,
155
                $notifypub,
156
                $this->db->quoteString($modulelink),
157
                $this->db->quoteString($contextpage),
158
                $exacturl,
159
                $partialview,
160
                $objectid
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $objectid does not exist. Did you maybe mean $object?
Loading history...
161
            );
162
        }
163
        if ($force) {
164
            $result = $this->db->queryF($sql);
165
        } else {
166
            $result = $this->db->query($sql);
167
        }
168
169
        if (!$result) {
170
            $object->setErrors('Could not store data in the database.<br >' . $this->db->error() . ' (' . $this->db->errno() . ')<br >' . $sql);
171
172
            $logger = \XoopsLogger::getInstance();
173
            $logger->handleError(\E_USER_WARNING, $sql, __FILE__, __LINE__);
174
            $logger->addExtra('Token Validation', 'No valid token found in request/session');
175
176
            /** @var Smartfaq\Helper $helper */
177
            $helper = Smartfaq\Helper::getInstance();
178
            $helper->addLog($this->db->error());
179
180
            /** @var \XoopsObject $object */
181
            //            $object->setError($this->db->error());
182
183
            \trigger_error('Class ' . $object . ' could not be saved ' . __FILE__ . ' at line ' . __LINE__, \E_USER_WARNING);
0 ignored issues
show
Bug introduced by
Are you sure $object of type XoopsObject can be used in concatenation? Consider adding a __toString()-method. ( Ignorable by Annotation )

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

183
            \trigger_error('Class ' . /** @scrutinizer ignore-type */ $object . ' could not be saved ' . __FILE__ . ' at line ' . __LINE__, \E_USER_WARNING);
Loading history...
184
185
            return false;
186
        }
187
188
        if ($object->isNew()) {
189
            $object->assignVar('faqid', $this->db->getInsertId());
190
        }
191
192
        // Saving permissions
193
        Smartfaq\Utility::saveItemPermissions($object->getGroups_read(), $object->faqid());
0 ignored issues
show
Bug introduced by
The method getGroups_read() does not exist on XoopsObject. It seems like you code against a sub-type of XoopsObject such as XoopsModules\Smartfaq\Faq or XoopsModules\Smartfaq\Category. ( Ignorable by Annotation )

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

193
        Smartfaq\Utility::saveItemPermissions($object->/** @scrutinizer ignore-call */ getGroups_read(), $object->faqid());
Loading history...
Bug introduced by
The method faqid() does not exist on XoopsObject. It seems like you code against a sub-type of XoopsObject such as XoopsModules\Smartfaq\Faq or XoopsModules\Smartfaq\Answer. ( Ignorable by Annotation )

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

193
        Smartfaq\Utility::saveItemPermissions($object->getGroups_read(), $object->/** @scrutinizer ignore-call */ faqid());
Loading history...
194
195
        return true;
196
    }
197
198
    /**
199
     * delete an FAQ from the database
200
     *
201
     * @param \XoopsObject $object reference to the FAQ to delete
202
     * @param bool         $force
203
     * @return bool        FALSE if failed.
204
     */
205
    public function delete(\XoopsObject $object, $force = false)
206
    {
207
        $smartModule = Smartfaq\Utility::getModuleInfo();
208
        $module_id   = $smartModule->getVar('mid');
209
210
        //        if ('XoopsModules\Smartfaq\Faq' !== \mb_strtolower(get_class($object))) {
211
        if (Faq::class !== \get_class($object)) {
212
            return false;
213
        }
214
215
        // Deleting the answers
216
        $answerHandler = new Smartfaq\AnswerHandler($this->db);
217
        if (!$answerHandler->deleteFaqAnswers($object)) {
218
            // error msg...
219
            echo 'error while deleteing an answer';
220
        }
221
222
        $sql = \sprintf('DELETE FROM `%s` WHERE faqid = %u', $this->db->prefix('smartfaq_faq'), $object->getVar('faqid'));
0 ignored issues
show
Bug introduced by
It seems like $object->getVar('faqid') can also be of type array and array; however, parameter $values of sprintf() does only seem to accept double|integer|string, maybe add an additional type check? ( Ignorable by Annotation )

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

222
        $sql = \sprintf('DELETE FROM `%s` WHERE faqid = %u', $this->db->prefix('smartfaq_faq'), /** @scrutinizer ignore-type */ $object->getVar('faqid'));
Loading history...
223
224
        if ($force) {
225
            $result = $this->db->queryF($sql);
226
        } else {
227
            $result = $this->db->query($sql);
228
        }
229
        if (!$result) {
230
            return false;
231
        }
232
233
        \xoops_groupperm_deletebymoditem($module_id, 'item_read', $object->faqid());
234
235
        return true;
236
    }
237
238
    /**
239
     * retrieve FAQs from the database
240
     *
241
     * @param \CriteriaElement|null $criteria  {@link CriteriaElement} conditions to be met
242
     * @param bool                  $id_as_key use the faqid as key for the array?
243
     * @param string                $notNullFields
244
     * @return false|array  array of <a href='psi_element://Smartfaq\Faq'>Smartfaq\Faq</a> objects
245
     */
246
    public function getObjects(\CriteriaElement $criteria = null, $id_as_key = false, $notNullFields = '')
247
    {
248
        $ret   = [];
249
        $limit = $start = 0;
250
        $sql   = 'SELECT * FROM ' . $this->db->prefix('smartfaq_faq');
251
252
        if (($criteria instanceof \CriteriaCompo) || ($criteria instanceof \Criteria)) {
253
            $whereClause = $criteria->renderWhere();
254
255
            if ('WHERE ()' !== $whereClause) {
256
                $sql .= ' ' . $criteria->renderWhere();
257
                if (!empty($notNullFields)) {
258
                    $sql .= $this->NotNullFieldClause($notNullFields, true);
259
                }
260
            } elseif (!empty($notNullFields)) {
261
                $sql .= ' WHERE ' . $this->NotNullFieldClause($notNullFields);
262
            }
263
            if ('' != $criteria->getSort()) {
264
                $sql .= ' ORDER BY ' . $criteria->getSort() . ' ' . $criteria->getOrder();
265
            }
266
            $limit = $criteria->getLimit();
267
            $start = $criteria->getStart();
268
        } elseif (!empty($notNullFields)) {
269
            $sql .= $sql .= ' WHERE ' . $this->NotNullFieldClause($notNullFields);
270
        }
271
272
        //echo "<br>" . $sql . "<br>";
273
        $result = $this->db->query($sql, $limit, $start);
274
        if (!$result) {
275
            return false;
276
        }
277
278
        if (0 == $GLOBALS['xoopsDB']->getRowsNum($result)) {
279
            $temp = false;
280
281
            return $temp;
282
        }
283
284
        while (false !== ($myrow = $this->db->fetchArray($result))) {
285
            $faq = new Smartfaq\Faq();
286
            $faq->assignVars($myrow);
287
288
            if ($id_as_key) {
289
                $ret[$myrow['faqid']] = &$faq;
290
            } else {
291
                $ret[] = &$faq;
292
            }
293
            unset($faq);
294
        }
295
296
        return $ret;
297
    }
298
299
    /**
300
     * @param \CriteriaElement|null $criteria
301
     * @param bool   $id_as_key
302
     * @param string $notNullFields
303
     * @return array|bool
304
     */
305
    public function getObjectsAdminSide(\CriteriaElement $criteria = null, $id_as_key = false, $notNullFields = '')
306
    {
307
        $ret   = [];
308
        $limit = $start = 0;
309
        $sql   = 'SELECT
310
                            faq.faqid AS faqid,
311
                            faq.categoryid AS categoryid,
312
                            faq.question AS question,
313
                            faq.howdoi AS howdoi,
314
                            faq.diduno AS diduno,
315
                            faq.uid AS uid,
316
                            faq.datesub AS datesub,
317
                            faq.status AS status,
318
                            faq.counter AS counter,
319
                            faq.weight AS weight,
320
                            faq.html AS html,
321
                            faq.smiley AS smiley,
322
                            faq.image AS image,
323
                            faq.linebreak AS linebreak,
324
                            faq.xcodes AS xcodes,
325
                            faq.cancomment AS cancomment,
326
                            faq.comments AS comments,
327
                            faq.notifypub AS notifypub,
328
                            faq.modulelink AS modulelink,
329
                            faq.contextpage AS contextpage,
330
                            faq.exacturl AS exacturl
331
                FROM ' . $this->db->prefix('smartfaq_faq') . ' AS faq INNER JOIN ' . $this->db->prefix('smartfaq_categories') . ' AS category ON faq.categoryid = category.categoryid ';
332
333
        if (($criteria instanceof \CriteriaCompo) || ($criteria instanceof \Criteria)) {
334
            $whereClause = $criteria->renderWhere();
335
336
            if ('WHERE ()' !== $whereClause) {
337
                $sql .= ' ' . $criteria->renderWhere();
338
                if (!empty($notNullFields)) {
339
                    $sql .= $this->NotNullFieldClause($notNullFields, true);
340
                }
341
            } elseif (!empty($notNullFields)) {
342
                $sql .= ' WHERE ' . $this->NotNullFieldClause($notNullFields);
343
            }
344
            if ('' != $criteria->getSort()) {
345
                $sql .= ' ORDER BY ' . $criteria->getSort() . ' ' . $criteria->getOrder();
346
            }
347
            $limit = $criteria->getLimit();
348
            $start = $criteria->getStart();
349
        } elseif (!empty($notNullFields)) {
350
            $sql .= $sql .= ' WHERE ' . $this->NotNullFieldClause($notNullFields);
351
        }
352
353
        //echo "<br>" . $sql . "<br>";
354
        $result = $this->db->query($sql, $limit, $start);
355
        if (!$result) {
356
            return false;
357
        }
358
359
        if (0 == $GLOBALS['xoopsDB']->getRowsNum($result)) {
360
            return false;
361
        }
362
363
        while (false !== ($myrow = $this->db->fetchArray($result))) {
364
            $faq = new Smartfaq\Faq();
365
            $faq->assignVars($myrow);
366
367
            if ($id_as_key) {
368
                $ret[$myrow['faqid']] = &$faq;
369
            } else {
370
                $ret[] = &$faq;
371
            }
372
            unset($faq);
373
        }
374
375
        return $ret;
376
        /*while (false !== ($myrow = $this->db->fetchArray($result))) {
377
            $faq = new Smartfaq\Faq($myrow['faqid']);
378
379
            if (!$id_as_key) {
380
                $ret[] =& $faq;
381
            } else {
382
                $ret[$myrow['faqid']] =& $faq;
383
            }
384
            unset($faq);
385
        }
386
387
        return $ret;*/
388
    }
389
390
    /**
391
     * count FAQs matching a condition
392
     *
393
     * @param object $criteria {@link CriteriaElement} to match
394
     * @param string $notNullFields
395
     * @return int    count of FAQs
396
     */
397
    public function getCount($criteria = null, $notNullFields = '')
398
    {
399
        $sql = 'SELECT COUNT(*) FROM ' . $this->db->prefix('smartfaq_faq');
400
        if (($criteria instanceof \CriteriaCompo) || ($criteria instanceof \Criteria)) {
401
            $whereClause = $criteria->renderWhere();
402
            if ('WHERE ()' !== $whereClause) {
403
                $sql .= ' ' . $criteria->renderWhere();
404
                if (!empty($notNullFields)) {
405
                    $sql .= $this->NotNullFieldClause($notNullFields, true);
406
                }
407
            } elseif (!empty($notNullFields)) {
408
                $sql .= ' WHERE ' . $this->NotNullFieldClause($notNullFields);
409
            }
410
        } elseif (!empty($notNullFields)) {
411
            $sql .= ' WHERE ' . $this->NotNullFieldClause($notNullFields);
412
        }
413
414
        //echo "<br>" . $sql . "<br>";
415
        $result = $this->db->query($sql);
416
        if (!$result) {
417
            return 0;
418
        }
419
        [$count] = $this->db->fetchRow($result);
420
421
        return $count;
422
    }
423
424
    /**
425
     * @param int          $categoryid
426
     * @param string|array $status
427
     * @param string       $notNullFields
428
     * @return int
429
     */
430
    public function getFaqsCount($categoryid = -1, $status = '', $notNullFields = '')
431
    {
432
        global $xoopsUser;
433
434
        //  if ( ($categoryid = -1) && (empty($status) || ($status == -1)) ) {
435
        //return $this->getCount();
436
        //}
437
438
        $criteriaCategory = null;
439
        $userIsAdmin      = Smartfaq\Utility::userIsAdmin();
440
        // Categories for which user has access
441
        if (!$userIsAdmin) {
442
            /** @var Smartfaq\PermissionHandler $smartPermHandler */
443
            $smartPermHandler = Smartfaq\Helper::getInstance()->getHandler('Permission');
444
445
            $categoriesGranted = $smartPermHandler->getPermissions('category');
446
            $grantedCategories = new \Criteria('categoryid', '(' . \implode(',', $categoriesGranted) . ')', 'IN');
447
448
            $faqsGranted = $smartPermHandler->getPermissions('item');
449
            $grantedFaq  = new \CriteriaCompo();
450
            $grantedFaq->add(new \Criteria('faqid', '(' . \implode(',', $faqsGranted) . ')', 'IN'), 'OR');
451
            // If user is anonymous, check if the FAQ allow partialview
452
            if (!\is_object($xoopsUser)) {
453
                $grantedFaq->add(new \Criteria('partialview', '1'), 'OR');
454
            }
455
        }
456
457
        if (isset($categoryid) && (-1 != $categoryid)) {
458
            $criteriaCategory = new \Criteria('categoryid', $categoryid);
459
        }
460
461
        $criteriaStatus = new \CriteriaCompo();
462
        if (!empty($status) && \is_array($status)) {
463
            foreach ($status as $v) {
464
                $criteriaStatus->add(new \Criteria('status', $v), 'OR');
465
            }
466
        } elseif (!empty($status) && (-1 != $status)) {
467
            $criteriaStatus->add(new \Criteria('status', $status), 'OR');
468
        }
469
470
        $criteriaPermissions = new \CriteriaCompo();
471
        if (!$userIsAdmin) {
472
            $criteriaPermissions->add($grantedCategories, 'AND');
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $grantedCategories does not seem to be defined for all execution paths leading up to this point.
Loading history...
473
            $criteriaPermissions->add($grantedFaq, 'AND');
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $grantedFaq does not seem to be defined for all execution paths leading up to this point.
Loading history...
474
        }
475
476
        $criteria = new \CriteriaCompo();
477
        if (null !== $criteriaCategory) {
478
            $criteria->add($criteriaCategory);
479
        }
480
481
        if (null !== $criteriaPermissions && (!$userIsAdmin)) {
482
            $criteria->add($criteriaPermissions);
483
        }
484
485
        if (null !== $criteriaStatus) {
486
            $criteria->add($criteriaStatus);
487
        }
488
489
        return $this->getCount($criteria, $notNullFields);
490
    }
491
492
    /**
493
     * @return array
494
     */
495
    public function getFaqsCountByStatus()
496
    {
497
        $sql    = 'SELECT status, COUNT(*) FROM ' . $this->db->prefix('smartfaq_faq') . ' GROUP BY status';
498
        $result = $this->db->query($sql);
499
        if (!$result) {
500
            return [];
501
        }
502
        $ret = [];
503
        while ([$status, $count] = $this->db->fetchRow($result)) {
504
            $ret[$status] = $count;
505
        }
506
507
        return $ret;
508
    }
509
510
    /**
511
     * @param int    $limit
512
     * @param int    $start
513
     * @param int    $categoryid
514
     * @param string $sort
515
     * @param string $order
516
     * @param bool   $asobject
517
     * @return array
518
     */
519
    public function getAllPublished(
520
        $limit = 0,
521
        $start = 0,
522
        $categoryid = -1,
523
        $sort = 'datesub',
524
        $order = 'DESC',
525
        $asobject = true
526
    ) {
527
        return $this->getFaqs($limit, $start, [Constants::SF_STATUS_PUBLISHED, Constants::SF_STATUS_NEW_ANSWER], $categoryid, $sort, $order, null, $asobject, null);
528
    }
529
530
    /**
531
     * @param int          $limit
532
     * @param int          $start
533
     * @param string|array $status
534
     * @param int|array    $categoryid
535
     * @param string       $sort
536
     * @param string       $order
537
     * @param string       $notNullFields
538
     * @param bool         $asobject
539
     * @param null         $otherCriteria
0 ignored issues
show
Documentation Bug introduced by
Are you sure the doc-type for parameter $otherCriteria is correct as it would always require null to be passed?
Loading history...
540
     * @return array
541
     */
542
    public function getFaqs(
543
        $limit = 0,
544
        $start = 0,
545
        $status = '',
546
        $categoryid = -1,
547
        $sort = 'datesub',
548
        $order = 'DESC',
549
        $notNullFields = '',
550
        $asobject = true,
0 ignored issues
show
Unused Code introduced by
The parameter $asobject is not used and could be removed. ( Ignorable by Annotation )

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

550
        /** @scrutinizer ignore-unused */ $asobject = true,

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

Loading history...
551
        $otherCriteria = null
552
    ) {
553
        global $xoopsUser;
554
        //        require_once XOOPS_ROOT_PATH . '/modules/smartfaq/include/functions.php';
555
556
        //if ( ($categoryid == -1) && (empty($status) || ($status == -1)) && ($limit == 0) && ($start ==0) ) {
557
        //  return $this->getObjects();
558
        //}
559
        $ret              = [];
0 ignored issues
show
Unused Code introduced by
The assignment to $ret is dead and can be removed.
Loading history...
560
        $userIsAdmin      = Smartfaq\Utility::userIsAdmin();
561
        $criteriaCategory = null;
562
        // Categories for which user has access
563
        if (!$userIsAdmin) {
564
            /** @var Smartfaq\PermissionHandler $smartPermHandler */
565
            $smartPermHandler = Smartfaq\Helper::getInstance()->getHandler('Permission');
566
567
            $categoriesGranted = $smartPermHandler->getPermissions('category');
568
            $grantedCategories = new \Criteria('categoryid', '(' . \implode(',', $categoriesGranted) . ')', 'IN');
569
570
            $faqsGranted = $smartPermHandler->getPermissions('item');
571
            $grantedFaq  = new \CriteriaCompo();
572
            $grantedFaq->add(new \Criteria('faqid', '(' . \implode(',', $faqsGranted) . ')', 'IN'), 'OR');
573
            // If user is anonymous, check if the FAQ allow partialview
574
            if (!\is_object($xoopsUser)) {
575
                $grantedFaq->add(new \Criteria('partialview', '1'), 'OR');
576
            }
577
        }
578
579
        if (isset($categoryid) && (-1 != $categoryid)) {
580
            if (\is_array($categoryid)) {
581
                $criteriaCategory = new \Criteria('categoryid', '(' . \implode(',', $categoryid) . ')', 'IN');
582
            } else {
583
                $criteriaCategory = new \Criteria('categoryid', (int)$categoryid);
584
            }
585
        }
586
587
        if (!empty($status) && \is_array($status)) {
588
            $criteriaStatus = new \CriteriaCompo();
589
            foreach ($status as $v) {
590
                $criteriaStatus->add(new \Criteria('status', $v), 'OR');
591
            }
592
        } elseif (!empty($status) && (-1 != $status)) {
593
            $criteriaStatus = new \CriteriaCompo();
594
            $criteriaStatus->add(new \Criteria('status', $status), 'OR');
595
        }
596
597
        $criteriaPermissions = new \CriteriaCompo();
598
        if (!$userIsAdmin) {
599
            $criteriaPermissions->add($grantedCategories, 'AND');
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $grantedCategories does not seem to be defined for all execution paths leading up to this point.
Loading history...
600
            $criteriaPermissions->add($grantedFaq, 'AND');
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $grantedFaq does not seem to be defined for all execution paths leading up to this point.
Loading history...
601
        }
602
603
        $criteria = new \CriteriaCompo();
604
        if (null !== $criteriaCategory) {
605
            $criteria->add($criteriaCategory);
606
        }
607
608
        if (null !== $criteriaPermissions && (!$userIsAdmin)) {
609
            $criteria->add($criteriaPermissions);
610
        }
611
612
        if (null !== $criteriaStatus) {
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $criteriaStatus does not seem to be defined for all execution paths leading up to this point.
Loading history...
613
            $criteria->add($criteriaStatus);
614
        }
615
616
        if (!empty($otherCriteria)) {
617
            $criteria->add($otherCriteria);
618
        }
619
620
        $criteria->setLimit($limit);
621
        $criteria->setStart($start);
622
        $criteria->setSort($sort);
623
        $criteria->setOrder($order);
624
        $ret = $this->getObjects($criteria, false, $notNullFields);
625
626
        return $ret;
0 ignored issues
show
Bug Best Practice introduced by
The expression return $ret could also return false which is incompatible with the documented return type array. Did you maybe forget to handle an error condition?

If the returned type also contains false, it is an indicator that maybe an error condition leading to the specific return statement remains unhandled.

Loading history...
627
    }
628
629
    /**
630
     * @param int          $limit
631
     * @param int          $start
632
     * @param string|array $status
633
     * @param int          $categoryid
634
     * @param string       $sort
635
     * @param string       $order
636
     * @param bool         $asobject
637
     * @param null         $otherCriteria
0 ignored issues
show
Documentation Bug introduced by
Are you sure the doc-type for parameter $otherCriteria is correct as it would always require null to be passed?
Loading history...
638
     * @return array|bool
639
     */
640
    public function getFaqsAdminSide(
641
        $limit = 0,
642
        $start = 0,
643
        $status = '',
644
        $categoryid = -1,
645
        $sort = 'datesub',
646
        $order = 'DESC',
647
        $asobject = true,
0 ignored issues
show
Unused Code introduced by
The parameter $asobject is not used and could be removed. ( Ignorable by Annotation )

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

647
        /** @scrutinizer ignore-unused */ $asobject = true,

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

Loading history...
648
        $otherCriteria = null
649
    ) {
650
        //        require_once XOOPS_ROOT_PATH . '/modules/smartfaq/include/functions.php';
651
652
        //        $smartModule = Smartfaq\Utility::getModuleInfo();
653
654
        $ret              = [];
0 ignored issues
show
Unused Code introduced by
The assignment to $ret is dead and can be removed.
Loading history...
655
        $criteriaCategory = $criteriaStatus = null;
656
657
        if (isset($categoryid) && (-1 != $categoryid)) {
658
            $criteriaCategory = new \Criteria('faq.categoryid', $categoryid);
659
        }
660
661
        if (!empty($status) && \is_array($status)) {
662
            $criteriaStatus = new \CriteriaCompo();
663
            foreach ($status as $v) {
664
                $criteriaStatus->add(new \Criteria('faq.status', $v), 'OR');
665
            }
666
        } elseif (!empty($status) && (-1 != $status)) {
667
            $criteriaStatus = new \CriteriaCompo();
668
            $criteriaStatus->add(new \Criteria('faq.status', $status), 'OR');
669
        }
670
671
        $criteria = new \CriteriaCompo();
672
        if (null !== $criteriaCategory) {
673
            $criteria->add($criteriaCategory);
674
        }
675
676
        if (null !== $criteriaStatus) {
677
            $criteria->add($criteriaStatus);
678
        }
679
680
        if (!empty($otherCriteria)) {
681
            $criteria->add($otherCriteria);
682
        }
683
684
        $criteria->setLimit($limit);
685
        $criteria->setStart($start);
686
        $criteria->setSort($sort);
687
        $criteria->setOrder($order);
688
        $ret = $this->getObjectsAdminSide($criteria, false);
689
690
        return $ret;
691
    }
692
693
    /**
694
     * @param string $field
695
     * @param string $status
696
     * @param int    $category
697
     * @return bool|mixed
698
     */
699
    public function getRandomFaq($field = '', $status = '', $category = -1)
0 ignored issues
show
Unused Code introduced by
The parameter $category is not used and could be removed. ( Ignorable by Annotation )

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

699
    public function getRandomFaq($field = '', $status = '', /** @scrutinizer ignore-unused */ $category = -1)

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

Loading history...
700
    {
701
        $ret = false;
702
703
        $notNullFields = $field;
704
705
        // Getting the number of published FAQ
706
        $totalFaqs = $this->getFaqsCount(-1, $status, $notNullFields);
707
708
        if ($totalFaqs > 0) {
709
            --$totalFaqs;
710
            $entrynumber = \random_int(0, $totalFaqs);
711
            $faq         = $this->getFaqs(1, $entrynumber, $status, -1, 'datesub', 'DESC', $notNullFields);
712
            if ($faq) {
713
                $ret = &$faq[0];
714
            }
715
        }
716
717
        return $ret;
718
    }
719
720
    /**
721
     * @param int $limit
722
     * @return array|bool
723
     */
724
    public function getContextualFaqs($limit = 0)
725
    {
726
        $ret = false;
727
728
        $otherCriteria = new \CriteriaCompo();
729
        $otherCriteria->add(new \Criteria('modulelink', 'None', '<>'));
730
731
        $faqsObj = $this->getFaqs(0, 0, [Constants::SF_STATUS_PUBLISHED, Constants::SF_STATUS_NEW_ANSWER], -1, 'datesub', 'DESC', '', true, $otherCriteria);
732
733
        $totalfaqs  = \is_array($faqsObj) ? \count($faqsObj) : 0;
0 ignored issues
show
Unused Code introduced by
The assignment to $totalfaqs is dead and can be removed.
Loading history...
introduced by
The condition is_array($faqsObj) is always true.
Loading history...
734
        $randomFaqs = [];
735
        if ($faqsObj) {
736
            foreach ($faqsObj as $i => $iValue) {
737
                $display = false;
738
739
                $http        = (false === mb_strpos(XOOPS_URL, 'https://')) ? 'https://' : 'https://';
740
                $phpself     = $_SERVER['SCRIPT_NAME'];
741
                $httphost    = $_SERVER['HTTP_HOST'];
742
                $querystring = $_SERVER['QUERY_STRING'];
743
                if ('' != $querystring) {
744
                    $querystring = '?' . $querystring;
745
                }
746
                $currenturl     = $http . $httphost . $phpself . $querystring;
747
                $fullcontexturl = XOOPS_URL . '/' . $iValue->contextpage();
748
                switch ($iValue->modulelink()) {
749
                    case '':
750
                    case 'None':
751
                        $display = false;
752
                        break;
753
                    case 'All':
754
                        $display = true;
755
                        break;
756
                    case 'url':
757
                        if ($iValue->exacturl()) {
758
                            $display = ($currenturl == $fullcontexturl);
759
                        } else {
760
                            $display = (false === mb_strpos($currenturl, $fullcontexturl));
761
                        }
762
                        break;
763
                    default:
764
                        if (false === mb_strpos($currenturl, XOOPS_URL . '/modules/')) {
765
                            $display = false;
766
                        } elseif (false === mb_strpos($currenturl, $iValue->modulelink())) {
767
                                $display = false;
768
                            } else {
769
                                $display = true;
770
                        }
771
                        break;
772
                }
773
                if ($display) {
774
                    $randomFaqs[] = &$iValue;
775
                }
776
            }
777
        }
778
779
        if (\count($randomFaqs) > $limit) {
780
            $rand_keys = \array_rand($randomFaqs, $limit);
781
            foreach ($rand_keys as $jValue) {
782
                $ret[] = &$randomFaqs[$jValue];
783
            }
784
        } else {
785
            $ret = &$randomFaqs;
786
        }
787
788
        return $ret;
789
    }
790
791
    /**
792
     * @param array $status
793
     * @return array
794
     */
795
    public function getLastPublishedByCat($status = [Constants::SF_STATUS_PUBLISHED, Constants::SF_STATUS_NEW_ANSWER])
796
    {
797
        $ret       = [];
798
        $faqclause = '';
799
        if (!Smartfaq\Utility::userIsAdmin()) {
800
            /** @var Smartfaq\PermissionHandler $smartPermHandler */
801
            $smartPermHandler = Smartfaq\Helper::getInstance()->getHandler('Permission');
802
            $items            = $smartPermHandler->getPermissions('item');
803
            $faqclause        = ' AND faqid IN (' . \implode(',', $items) . ')';
804
        }
805
806
        $sql  = "CREATE TEMPORARY TABLE tmp (categoryid INT(8) UNSIGNED NOT NULL,datesub INT(11) DEFAULT '0' NOT NULL);";
807
        $sql2 = ' LOCK TABLES ' . $this->db->prefix('smartfaq_faq') . ' READ;';
808
        $sql3 = ' INSERT INTO tmp SELECT categoryid, MAX(datesub) FROM ' . $this->db->prefix('smartfaq_faq') . ' WHERE status IN (' . \implode(',', $status) . ") $faqclause GROUP BY categoryid;";
809
        $sql4 = ' SELECT ' . $this->db->prefix('smartfaq_faq') . '.categoryid, faqid, question, uid, ' . $this->db->prefix('smartfaq_faq') . '.datesub FROM ' . $this->db->prefix('smartfaq_faq') . ', tmp
810
                              WHERE ' . $this->db->prefix('smartfaq_faq') . '.categoryid=tmp.categoryid AND ' . $this->db->prefix('smartfaq_faq') . '.datesub=tmp.datesub;';
811
        /*
812
        //Old implementation
813
        $sql = "SELECT categoryid, faqid, question, uid, MAX(datesub) AS datesub FROM ".$this->db->prefix("smartfaq_faq")."
814
               WHERE status IN (". implode(',', $status).")";
815
        $sql .= " GROUP BY categoryid";
816
        */
817
        $this->db->queryF($sql);
818
        $this->db->queryF($sql2);
819
        $this->db->queryF($sql3);
820
        $result = $this->db->query($sql4);
821
        $error  = $this->db->error();
822
        $this->db->queryF('UNLOCK TABLES;');
823
        $this->db->queryF('DROP TABLE tmp;');
824
        if (!$result) {
825
            \trigger_error('Error in getLastPublishedByCat SQL: ' . $error);
826
827
            return $ret;
828
        }
829
        while (false !== ($row = $this->db->fetchArray($result))) {
830
            $faq = new Smartfaq\Faq();
831
            $faq->assignVars($row);
832
            $ret[$row['categoryid']] = &$faq;
833
            unset($faq);
834
        }
835
836
        return $ret;
837
    }
838
839
    /**
840
     * delete FAQs matching a set of conditions
841
     *
842
     * @param object $criteria {@link CriteriaElement}
843
     * @return bool   FALSE if deletion failed
844
     */
845
    public function deleteAll($criteria = null)
846
    {
847
        $sql = 'DELETE FROM ' . $this->db->prefix('smartfaq_faq');
848
        if (($criteria instanceof \CriteriaCompo) || ($criteria instanceof \Criteria)) {
849
            $sql .= ' ' . $criteria->renderWhere();
850
        }
851
        if (!$this->db->query($sql)) {
852
            return false;
853
            // TODO : Also delete the permissions related to each FAQ
854
        }
855
856
        return true;
857
    }
858
859
    /**
860
     * Change a value for FAQ with a certain criteria
861
     *
862
     * @param string $fieldname  Name of the field
863
     * @param string $fieldvalue Value to write
864
     * @param object $criteria   {@link CriteriaElement}
865
     *
866
     * @return bool
867
     **/
868
    public function updateAll($fieldname, $fieldvalue, $criteria = null)
869
    {
870
        $set_clause = \is_numeric($fieldvalue) ? $fieldname . ' = ' . $fieldvalue : $fieldname . ' = ' . $this->db->quoteString($fieldvalue);
871
        $sql        = 'UPDATE ' . $this->db->prefix('smartfaq_faq') . ' SET ' . $set_clause;
872
        if (($criteria instanceof \CriteriaCompo) || ($criteria instanceof \Criteria)) {
873
            $sql .= ' ' . $criteria->renderWhere();
874
        }
875
        if (!$this->db->queryF($sql)) {
876
            return false;
877
        }
878
879
        return true;
880
    }
881
882
    /**
883
     * @param $faqid
884
     * @return bool
885
     */
886
    public function updateCounter($faqid)
887
    {
888
        $sql = 'UPDATE ' . $this->db->prefix('smartfaq_faq') . ' SET counter=counter+1 WHERE faqid = ' . $faqid;
889
        if ($this->db->queryF($sql)) {
890
            return true;
891
        }
892
893
        return false;
894
    }
895
896
    /**
897
     * @param string|array $notNullFields
898
     * @param bool         $withAnd
899
     * @return string
900
     */
901
    public function NotNullFieldClause($notNullFields = '', $withAnd = false)
902
    {
903
        $ret = '';
904
        if ($withAnd) {
905
            $ret .= ' AND ';
906
        }
907
        if (!empty($notNullFields) && \is_array($notNullFields)) {
908
            foreach ($notNullFields as $v) {
909
                $ret .= " ($v IS NOT NULL AND $v <> ' ' )";
910
            }
911
        } elseif (!empty($notNullFields)) {
912
            $ret .= " ($notNullFields IS NOT NULL AND $notNullFields <> ' ' )";
913
        }
914
915
        return $ret;
916
    }
917
918
    /**
919
     * @param array  $queryarray
920
     * @param string $andor
921
     * @param int    $limit
922
     * @param int    $offset
923
     * @param int    $userid
924
     * @return array
925
     */
926
    public function getFaqsFromSearch($queryarray = [], $andor = 'AND', $limit = 0, $offset = 0, $userid = 0)
927
    {
928
        global $xoopsUser;
929
930
        $ret              = [];
931
        $criteriaKeywords = null;
932
933
        $userIsAdmin = Smartfaq\Utility::userIsAdmin();
934
935
        if (0 != $userid) {
936
            $criteriaUser = new \CriteriaCompo();
937
            $criteriaUser->add(new \Criteria('faq.uid', $userid), 'OR');
938
            $criteriaUser->add(new \Criteria('answer.uid', $userid), 'OR');
939
        }
940
941
        if (!empty($queryarray)) {
942
            $criteriaKeywords = new \CriteriaCompo();
943
            foreach ($queryarray as $iValue) {
944
                $criteriaKeyword = new \CriteriaCompo();
945
                $criteriaKeyword->add(new \Criteria('faq.question', '%' . $iValue . '%', 'LIKE'), 'OR');
946
                $criteriaKeyword->add(new \Criteria('answer.answer', '%' . $iValue . '%', 'LIKE'), 'OR');
947
                $criteriaKeywords->add($criteriaKeyword, $andor);
948
                unset($criteriaKeyword);
949
            }
950
        }
951
952
        // Categories for which user has access
953
        if (!$userIsAdmin) {
954
            /** @var Smartfaq\PermissionHandler $smartPermHandler */
955
            $smartPermHandler = Smartfaq\Helper::getInstance()->getHandler('Permission');
956
957
            $categoriesGranted = $smartPermHandler->getPermissions('category');
958
            $faqsGranted       = $smartPermHandler->getPermissions('item');
959
            if (empty($categoriesGranted)) {
960
                return $ret;
961
            }
962
            if (empty($faqsGranted)) {
963
                return $ret;
964
            }
965
            $grantedCategories = new \Criteria('faq.categoryid', '(' . \implode(',', $categoriesGranted) . ')', 'IN');
966
            $grantedFaq        = new \CriteriaCompo();
967
            $grantedFaq->add(new \Criteria('faq.faqid', '(' . \implode(',', $faqsGranted) . ')', 'IN'), 'OR');
968
            // If user is anonymous, check if the FAQ allow partialview
969
            if (!\is_object($xoopsUser)) {
970
                $grantedFaq->add(new \Criteria('partialview', '1'), 'OR');
971
            }
972
        }
973
974
        $criteriaPermissions = new \CriteriaCompo();
975
        if (!$userIsAdmin) {
976
            $criteriaPermissions->add($grantedCategories, 'AND');
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $grantedCategories does not seem to be defined for all execution paths leading up to this point.
Loading history...
977
            $criteriaPermissions->add($grantedFaq, 'AND');
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $grantedFaq does not seem to be defined for all execution paths leading up to this point.
Loading history...
978
        }
979
980
        $criteriaAnswersStatus = new \CriteriaCompo();
981
        $criteriaAnswersStatus->add(new \Criteria('answer.status', Constants::SF_AN_STATUS_APPROVED));
982
983
        $criteriaFasStatus = new \CriteriaCompo();
984
        $criteriaFasStatus->add(new \Criteria('faq.status', Constants::SF_STATUS_OPENED), 'OR');
985
        $criteriaFasStatus->add(new \Criteria('faq.status', Constants::SF_STATUS_PUBLISHED), 'OR');
986
987
        $criteria = new \CriteriaCompo();
988
        if (null !== $criteriaUser) {
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $criteriaUser does not seem to be defined for all execution paths leading up to this point.
Loading history...
989
            $criteria->add($criteriaUser, 'AND');
990
        }
991
992
        if (null !== $criteriaKeywords) {
993
            $criteria->add($criteriaKeywords, 'AND');
994
        }
995
996
        if (null !== $criteriaPermissions && (!$userIsAdmin)) {
997
            $criteria->add($criteriaPermissions);
998
        }
999
1000
        if (null !== $criteriaAnswersStatus) {
1001
            $criteria->add($criteriaAnswersStatus, 'AND');
1002
        }
1003
1004
        if (null !== $criteriaFasStatus) {
1005
            $criteria->add($criteriaFasStatus, 'AND');
1006
        }
1007
1008
        $criteria->setLimit($limit);
1009
        $criteria->setStart($offset);
1010
        $criteria->setSort('faq.datesub');
1011
        $criteria->setOrder('DESC');
1012
1013
        $sql = 'SELECT faq.faqid, faq.question, faq.datesub, faq.uid FROM ' . $this->db->prefix('smartfaq_faq') . ' AS faq INNER JOIN ' . $this->db->prefix('smartfaq_answers') . ' AS answer ON faq.faqid = answer.faqid';
1014
1015
        if (($criteria instanceof \CriteriaCompo) || ($criteria instanceof \Criteria)) {
0 ignored issues
show
introduced by
$criteria is always a sub-type of CriteriaCompo.
Loading history...
1016
            $whereClause = $criteria->renderWhere();
1017
1018
            if ('WHERE ()' !== $whereClause) {
1019
                $sql .= ' ' . $criteria->renderWhere();
1020
                if ('' != $criteria->getSort()) {
1021
                    $sql .= ' ORDER BY ' . $criteria->getSort() . ' ' . $criteria->getOrder();
1022
                }
1023
                $limit = $criteria->getLimit();
1024
                $start = $criteria->getStart();
1025
            }
1026
        }
1027
1028
        //echo "<br>" . $sql . "<br>";
1029
1030
        $result = $this->db->query($sql, $limit, $start);
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $start does not seem to be defined for all execution paths leading up to this point.
Loading history...
1031
        if (!$result) {
1032
            \trigger_error('Query did not work in smartfaq', \E_USER_WARNING);
1033
1034
            return $ret;
1035
        }
1036
1037
        if (0 == $GLOBALS['xoopsDB']->getRowsNum($result)) {
1038
            return $ret;
1039
        }
1040
1041
        while (false !== ($myrow = $this->db->fetchArray($result))) {
1042
            $faq = new Smartfaq\Faq();
1043
            $faq->assignVars($myrow);
1044
            $ret[] = &$faq;
1045
            unset($faq);
1046
        }
1047
1048
        return $ret;
1049
    }
1050
1051
    /**
1052
     * @param int    $cat_id
1053
     * @param        $status
1054
     * @return array
1055
     */
1056
    public function getCountsByCat($cat_id, $status)
1057
    {
1058
        global $xoopsUser;
1059
        $ret = [];
1060
        $sql = 'SELECT categoryid, COUNT(*) AS count FROM ' . $this->db->prefix('smartfaq_faq');
1061
        if ((int)$cat_id > 0) {
1062
            $sql .= ' WHERE categoryid = ' . (int)$cat_id;
1063
            $sql .= ' AND status IN (' . \implode(',', $status) . ')';
1064
        } else {
1065
            $sql .= ' WHERE status IN (' . \implode(',', $status) . ')';
1066
            if (!Smartfaq\Utility::userIsAdmin()) {
1067
                /** @var Smartfaq\PermissionHandler $smartPermHandler */
1068
                $smartPermHandler = Smartfaq\Helper::getInstance()->getHandler('Permission');
1069
                $items            = $smartPermHandler->getPermissions('item');
1070
                if (\is_object($xoopsUser)) {
1071
                    $sql .= ' AND faqid IN (' . \implode(',', $items) . ')';
1072
                } else {
1073
                    $sql .= ' AND (faqid IN (' . \implode(',', $items) . ') OR partialview = 1)';
1074
                }
1075
            }
1076
        }
1077
        $sql .= ' GROUP BY categoryid';
1078
1079
        //echo "<br>" . $sql . "<br>";
1080
1081
        $result = $this->db->query($sql);
1082
        if (!$result) {
1083
            return $ret;
1084
        }
1085
        while (false !== ($row = $this->db->fetchArray($result))) {
1086
            $ret[$row['categoryid']] = (int)$row['count'];
1087
        }
1088
1089
        return $ret;
1090
    }
1091
}
1092