Completed
Branch master (c92e39)
by Michael
02:32
created

class/faq.php (39 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
/**
4
 * Module: SmartFAQ
5
 * Author: The SmartFactory <www.smartfactory.ca>
6
 * Licence: GNU
7
 */
8
9
// defined('XOOPS_ROOT_PATH') || exit('XOOPS root path not defined');
10
11
require_once XOOPS_ROOT_PATH . '/modules/smartfaq/class/category.php';
12
13
// FAQ status
14
define('_SF_STATUS_NOTSET', -1);
15
define('_SF_STATUS_ALL', 0);
16
define('_SF_STATUS_ASKED', 1);
17
define('_SF_STATUS_OPENED', 2);
18
define('_SF_STATUS_ANSWERED', 3);
19
define('_SF_STATUS_SUBMITTED', 4);
20
define('_SF_STATUS_PUBLISHED', 5);
21
define('_SF_STATUS_NEW_ANSWER', 6);
22
define('_SF_STATUS_OFFLINE', 7);
23
define('_SF_STATUS_REJECTED_QUESTION', 8);
24
define('_SF_STATUS_REJECTED_SMARTFAQ', 9);
25
26
// Notification Events
27
define('_SF_NOT_CATEGORY_CREATED', 1);
28
define('_SF_NOT_FAQ_SUBMITTED', 2);
29
define('_SF_NOT_FAQ_PUBLISHED', 3);
30
define('_SF_NOT_FAQ_REJECTED', 4);
31
define('_SF_NOT_QUESTION_SUBMITTED', 5);
32
define('_SF_NOT_QUESTION_PUBLISHED', 6);
33
define('_SF_NOT_NEW_ANSWER_PROPOSED', 7);
34
define('_SF_NOT_NEW_ANSWER_PUBLISHED', 8);
35
36
/**
37
 * Class sfFaq
38
 */
39
class sfFaq extends XoopsObject
40
{
41
42
    /**
43
     * @var sfCategory
44
     * @access private
45
     */
46
    private $category = null;
47
48
    /**
49
     * @var sfAnswer
50
     * @access private
51
     */
52
    private $answer = null;
53
54
    /**
55
     * @var array
56
     * @access private
57
     */
58
    private $_notifications = null;
59
    // TODO : Create a seperated class for notifications
60
61
    /**
62
     * @var array
63
     * @access private
64
     */
65
    private $groups_read = null;
66
67
    /**
68
     * @var object
69
     * @access private
70
     */
71
    // Is this still usefull??
72
    private $_smartModule = null;
73
    private $_smartModuleConfig;
74
75
    /**
76
     * constructor
77
     * @param null $id
78
     */
79
    public function __construct($id = null)
80
    {
81
        $this->db = XoopsDatabaseFactory::getDatabaseConnection();
82
        $this->initVar('faqid', XOBJ_DTYPE_INT, -1, false);
83
        $this->initVar('categoryid', XOBJ_DTYPE_INT, 0, false);
84
        $this->initVar('question', XOBJ_DTYPE_TXTBOX, null, true, 100000);
85
        $this->initVar('howdoi', XOBJ_DTYPE_TXTBOX, null, false, 255);
86
        $this->initVar('diduno', XOBJ_DTYPE_TXTBOX, null, false, 255);
87
        $this->initVar('uid', XOBJ_DTYPE_INT, 0, false);
88
        $this->initVar('datesub', XOBJ_DTYPE_INT, null, false);
89
        $this->initVar('status', XOBJ_DTYPE_INT, -1, false);
90
        $this->initVar('counter', XOBJ_DTYPE_INT, 0, false);
91
        $this->initVar('weight', XOBJ_DTYPE_INT, 0, false);
92
        $this->initVar('html', XOBJ_DTYPE_INT, 1, false);
93
        $this->initVar('smiley', XOBJ_DTYPE_INT, 1, false);
94
        $this->initVar('image', XOBJ_DTYPE_INT, 1, false);
95
        $this->initVar('linebreak', XOBJ_DTYPE_INT, 1, false);
96
        $this->initVar('xcodes', XOBJ_DTYPE_INT, 1, false);
97
        $this->initVar('cancomment', XOBJ_DTYPE_INT, 1, false);
98
        $this->initVar('comments', XOBJ_DTYPE_INT, 0, false);
99
        $this->initVar('notifypub', XOBJ_DTYPE_INT, 1, false);
100
        $this->initVar('modulelink', XOBJ_DTYPE_TXTBOX, 'None', false, 50);
101
        $this->initVar('contextpage', XOBJ_DTYPE_TXTBOX, null, false, 255);
102
        $this->initVar('exacturl', XOBJ_DTYPE_INT, 0, false);
103
        $this->initVar('partialview', XOBJ_DTYPE_INT, 0, false);
104
105
        if (isset($id)) {
106
            $faqHandler = new sfFaqHandler($this->db);
107
            $faq        = &$faqHandler->get($id);
108
            foreach ($faq->vars as $k => $v) {
109
                $this->assignVar($k, $v['value']);
110
            }
111
            $this->assignOtherProperties();
112
        }
113
    }
114
115
    public function assignOtherProperties()
116
    {
117
        $smartModule = sf_getModuleInfo();
118
        $module_id   = $smartModule->getVar('mid');
119
120
        $gpermHandler = xoops_getHandler('groupperm');
121
122
        $this->category    = new sfCategory($this->getVar('categoryid'));
123
        $this->groups_read = $gpermHandler->getGroupIds('item_read', $this->faqid(), $module_id);
124
    }
125
126
    /**
127
     * @return bool
128
     */
129 View Code Duplication
    public function checkPermission()
130
    {
131
        include_once XOOPS_ROOT_PATH . '/modules/smartfaq/include/functions.php';
132
133
        $userIsAdmin = sf_userIsAdmin();
134
        if ($userIsAdmin) {
135
            return true;
136
        }
137
138
        $smartPermHandler = xoops_getModuleHandler('permission', 'smartfaq');
139
140
        $faqsGranted = $smartPermHandler->getPermissions('item');
141
        if (in_array($this->categoryid(), $faqsGranted)) {
142
            $ret = true;
143
        }
144
145
        return $ret;
146
    }
147
148
    /**
149
     * @return array
150
     */
151
    public function getGroups_read()
152
    {
153
        if (count($this->groups_read) < 1) {
154
            $this->assignOtherProperties();
155
        }
156
157
        return $this->groups_read;
158
    }
159
160
    /**
161
     * @param array $groups_read
162
     */
163
    public function setGroups_read($groups_read = array('0'))
164
    {
165
        $this->groups_read = $groups_read;
166
    }
167
168
    /**
169
     * @return mixed
170
     */
171
    public function faqid()
172
    {
173
        return $this->getVar('faqid');
174
    }
175
176
    /**
177
     * @return mixed
178
     */
179
    public function categoryid()
180
    {
181
        return $this->getVar('categoryid');
182
    }
183
184
    /**
185
     * @return sfCategory
186
     */
187
    public function category()
188
    {
189
        return $this->category;
190
    }
191
192
    /**
193
     * @param  int    $maxLength
194
     * @param  string $format
195
     * @return mixed|string
196
     */
197
    public function question($maxLength = 0, $format = 'S')
198
    {
199
        $ret = $this->getVar('question', $format);
200
        if (($format === 's') || ($format === 'S') || ($format === 'show')) {
201
            $myts = MyTextSanitizer:: getInstance();
202
            $ret  = $myts->displayTarea($ret);
203
        }
204 View Code Duplication
        if ($maxLength != 0) {
205
            if (!XOOPS_USE_MULTIBYTES) {
206
                if (strlen($ret) >= $maxLength) {
207
                    $ret = substr($ret, 0, $maxLength - 1) . '...';
208
                }
209
            }
210
        }
211
212
        return $ret;
213
    }
214
215
    /**
216
     * @param  string $format
217
     * @return mixed
218
     */
219 View Code Duplication
    public function howdoi($format = 'S')
220
    {
221
        $ret = $this->getVar('howdoi', $format);
222
        if (($format === 's') || ($format === 'S') || ($format === 'show')) {
223
            $myts = MyTextSanitizer:: getInstance();
224
            $ret  = $myts->displayTarea($ret);
225
        }
226
227
        return $ret;
228
    }
229
230
    /**
231
     * @param  string $format
232
     * @return mixed
233
     */
234 View Code Duplication
    public function diduno($format = 'S')
235
    {
236
        $ret = $this->getVar('diduno', $format);
237
        if (($format === 's') || ($format === 'S') || ($format === 'show')) {
238
            $myts = MyTextSanitizer:: getInstance();
239
            $ret  = $myts->displayTarea($ret);
240
        }
241
242
        return $ret;
243
    }
244
245
    /**
246
     * @return mixed
247
     */
248
    public function uid()
249
    {
250
        return $this->getVar('uid');
251
    }
252
253
    /**
254
     * @param  string $dateFormat
255
     * @param  string $format
256
     * @return string
257
     */
258 View Code Duplication
    public function datesub($dateFormat = 'none', $format = 'S')
259
    {
260
        if ($dateFormat === 'none') {
261
            $smartConfig = sf_getModuleConfig();
262
            $dateFormat  = $smartConfig['dateformat'];
263
        }
264
265
        return formatTimestamp($this->getVar('datesub', $format), $dateFormat);
266
    }
267
268
    /**
269
     * @return mixed
270
     */
271
    public function status()
272
    {
273
        return $this->getVar('status');
274
    }
275
276
    /**
277
     * @return mixed
278
     */
279
    public function counter()
280
    {
281
        return $this->getVar('counter');
282
    }
283
284
    /**
285
     * @return mixed
286
     */
287
    public function weight()
288
    {
289
        return $this->getVar('weight');
290
    }
291
292
    /**
293
     * @return mixed
294
     */
295
    public function html()
296
    {
297
        return $this->getVar('html');
298
    }
299
300
    /**
301
     * @return mixed
302
     */
303
    public function smiley()
304
    {
305
        return $this->getVar('smiley');
306
    }
307
308
    /**
309
     * @return mixed
310
     */
311
    public function xcodes()
312
    {
313
        return $this->getVar('xcodes');
314
    }
315
316
    /**
317
     * @return mixed
318
     */
319
    public function cancomment()
320
    {
321
        return $this->getVar('cancomment');
322
    }
323
324
    /**
325
     * @return mixed
326
     */
327
    public function comments()
328
    {
329
        return $this->getVar('comments');
330
    }
331
332
    /**
333
     * @return mixed
334
     */
335
    public function notifypub()
336
    {
337
        return $this->getVar('notifypub');
338
    }
339
340
    /**
341
     * @param  string $format
342
     * @return mixed
343
     */
344
    public function modulelink($format = 'S')
345
    {
346
        return $this->getVar('modulelink', $format);
347
    }
348
349
    /**
350
     * @param  string $format
351
     * @return mixed
352
     */
353
    public function contextpage($format = 'S')
354
    {
355
        return $this->getVar('contextpage', $format);
356
    }
357
358
    /**
359
     * @return mixed
360
     */
361
    public function exacturl()
362
    {
363
        return $this->getVar('exacturl');
364
    }
365
366
    /**
367
     * @return mixed
368
     */
369
    public function partialview()
370
    {
371
        return $this->getVar('partialview');
372
    }
373
374
    /**
375
     * @param  int $realName
376
     * @return string
377
     */
378
    public function posterName($realName = -1)
379
    {
380
        if ($realName == -1) {
381
            $smartConfig = sf_getModuleConfig();
382
            $realName    = $smartConfig['userealname'];
383
        }
384
385
        return sf_getLinkedUnameFromId($this->uid(), $realName);
386
    }
387
388
    /**
389
     * @return mixed|object|sfAnswer
390
     */
391
    public function answer()
392
    {
393
        $answerHandler = new sfAnswerHandler($this->db);
394
        switch ($this->status()) {
395
            case _SF_STATUS_SUBMITTED:
396
                $theAnswers = $answerHandler->getAllAnswers($this->faqid(), _SF_AN_STATUS_APPROVED, 1, 0);
397
                //echo "test";
398
                //exit;
399
                $this->answer = &$theAnswers[0];
400
                break;
401
402
            case _SF_STATUS_ANSWERED:
403
                $theAnswers = $answerHandler->getAllAnswers($this->faqid(), _SF_AN_STATUS_PROPOSED, 1, 0);
404
                //echo "test";
405
                //exit;
406
                $this->answer = &$theAnswers[0];
407
                break;
408
409
            case _SF_STATUS_PUBLISHED:
410
            case _SF_STATUS_NEW_ANSWER:
411
            case _SF_STATUS_OFFLINE:
412
                $this->answer = $answerHandler->getOfficialAnswer($this->faqid());
413
                break;
414
415
            case _SF_STATUS_ASKED:
416
                $this->answer = $answerHandler->create();
417
                break;
418
            case _SF_STATUS_OPENED:
419
                $this->answer = $answerHandler->create();
420
                break;
421
        }
422
423
        if ($this->answer) {
424
            $this->answer->setVar('dohtml', $this->getVar('html'));
425
            $this->answer->setVar('doxcode', $this->getVar('xcodes'));
426
            $this->answer->setVar('dosmiley', $this->getVar('smiley'));
427
            $this->answer->setVar('doimage', $this->getVar('image'));
428
            $this->answer->setVar('dobr', $this->getVar('linebreak'));
429
        }
430
431
        return $this->answer;
432
    }
433
434
    /**
435
     * @return array
436
     */
437
    public function getAllAnswers()
438
    {
439
        $answerHandler = new sfAnswerHandler($this->db);
440
441
        return $answerHandler->getAllAnswers($this->faqid());
442
    }
443
444
    /**
445
     * @return bool
446
     */
447
    public function updateCounter()
448
    {
449
        $faqHandler = new sfFaqHandler($this->db);
450
451
        return $faqHandler->updateCounter($this->faqid());
452
    }
453
454
    /**
455
     * @param  bool $force
456
     * @return bool
457
     */
458
    public function store($force = true)
459
    {
460
        $faqHandler = new sfFaqHandler($this->db);
461
462
        return $faqHandler->insert($this, $force);
463
    }
464
465
    /**
466
     * @return mixed
467
     */
468
    public function getCategoryName()
469
    {
470
        if (!isset($this->category)) {
471
            $this->category = new sfCategory($this->getVar('categoryid'));
472
        }
473
474
        return $this->category->name();
475
    }
476
477
    /**
478
     * @param array $notifications
479
     */
480
    public function sendNotifications($notifications = array())
481
    {
482
        $smartModule = sf_getModuleInfo();
483
484
        $myts                = MyTextSanitizer:: getInstance();
485
        $notificationHandler = xoops_getHandler('notification');
486
        //$categoryObj = $this->category();
487
488
        $tags                  = array();
489
        $tags['MODULE_NAME']   = $myts->displayTarea($smartModule->getVar('name'));
490
        $tags['FAQ_NAME']      = $this->question();
491
        $tags['CATEGORY_NAME'] = $this->getCategoryName();
492
        $tags['CATEGORY_URL']  = XOOPS_URL . '/modules/' . $smartModule->getVar('dirname') . '/category.php?categoryid=' . $this->categoryid();
493
        $tags['FAQ_QUESTION']  = $this->question();
494
        $answerObj             = $this->answer();
495
        if (is_object($answerObj)) {
496
            // TODO : Not sure about the 'formpreview' ...
497
            $tags['FAQ_ANSWER'] = $answerObj->answer('formpreview');
498
        }
499
        $tags['DATESUB'] = $this->datesub();
500
501
        foreach ($notifications as $notification) {
502
            switch ($notification) {
503 View Code Duplication
                case _SF_NOT_FAQ_PUBLISHED:
504
                    $tags['FAQ_URL'] = XOOPS_URL . '/modules/' . $smartModule->getVar('dirname') . '/faq.php?faqid=' . $this->faqid();
505
506
                    $notificationHandler->triggerEvent('global_faq', 0, 'published', $tags);
507
                    $notificationHandler->triggerEvent('category_faq', $this->categoryid(), 'published', $tags);
508
                    $notificationHandler->triggerEvent('faq', $this->faqid(), 'approved', $tags);
509
                    break;
510
511 View Code Duplication
                case _SF_NOT_FAQ_SUBMITTED:
512
                    $tags['WAITINGFILES_URL'] = XOOPS_URL . '/modules/' . $smartModule->getVar('dirname') . '/admin/faq.php?faqid=' . $this->faqid();
513
                    $notificationHandler->triggerEvent('global_faq', 0, 'submitted', $tags);
514
                    $notificationHandler->triggerEvent('category_faq', $this->categoryid(), 'submitted', $tags);
515
                    break;
516
517 View Code Duplication
                case _SF_NOT_QUESTION_PUBLISHED:
518
                    $tags['FAQ_URL'] = XOOPS_URL . '/modules/' . $smartModule->getVar('dirname') . '/answer.php?faqid=' . $this->faqid();
519
                    $notificationHandler->triggerEvent('global_question', 0, 'published', $tags);
520
                    $notificationHandler->triggerEvent('category_question', $this->categoryid(), 'published', $tags);
521
                    $notificationHandler->triggerEvent('question', $this->faqid(), 'approved', $tags);
522
                    break;
523
524 View Code Duplication
                case _SF_NOT_QUESTION_SUBMITTED:
525
                    $tags['WAITINGFILES_URL'] = XOOPS_URL . '/modules/' . $smartModule->getVar('dirname') . '/admin/question.php?op=mod&faqid=' . $this->faqid();
526
                    $notificationHandler->triggerEvent('global_question', 0, 'submitted', $tags);
527
                    $notificationHandler->triggerEvent('category_question', $this->categoryid(), 'submitted', $tags);
528
                    break;
529
530
                case _SF_NOT_FAQ_REJECTED:
531
                    $notificationHandler->triggerEvent('faq', $this->faqid(), 'rejected', $tags);
532
                    break;
533
534 View Code Duplication
                case _SF_NOT_NEW_ANSWER_PROPOSED:
535
                    $tags['WAITINGFILES_URL'] = XOOPS_URL . '/modules/' . $smartModule->getVar('dirname') . '/admin/answer.php?op=mod&faqid=' . $this->faqid();
536
                    $notificationHandler->triggerEvent('global_faq', 0, 'answer_proposed', $tags);
537
                    $notificationHandler->triggerEvent('category_faq', $this->categoryid(), 'answer_proposed', $tags);
538
                    break;
539
540
                case _SF_NOT_NEW_ANSWER_PUBLISHED:
541
                    $notificationHandler->triggerEvent('global_faq', 0, 'answer_published', $tags);
542
                    $notificationHandler->triggerEvent('category_faq', $this->categoryid(), 'answer_published', $tags);
543
                    break;
544
545
                // TODO : I commented out this one because I'm not sure. The $this->faqid() should probably be the
546
                // answerid not the faqid....
547
                /*
548
                case _SF_NOT_ANSWER_APPROVED:
549
                $notificationHandler->triggerEvent('faq', $this->faqid(), 'answer_approved', $tags);
550
                break;
551
                */
552
553
                // TODO : I commented out this one because I'm not sure. The $this->faqid() should probably be the
554
                // answerid not the faqid....
555
                /*
556
                case _SF_NOT_ANSWER_REJECTED:
557
                $notificationHandler->triggerEvent('faq', $this->faqid(), 'answer_approved', $tags);
558
                break;
559
                */
560
561
                case -1:
562
                default:
563
                    break;
564
            }
565
        }
566
    }
567
568 View Code Duplication
    public function setDefaultPermissions()
569
    {
570
        $memberHandler = xoops_getHandler('member');
571
        $groups        = $memberHandler->getGroupList();
572
573
        $j         = 0;
574
        $group_ids = array();
575
        foreach (array_keys($groups) as $i) {
576
            $group_ids[$j] = $i;
577
            ++$j;
578
        }
579
        $this->groups_read = $group_ids;
580
    }
581
582
    /**
583
     * @param $group_ids
584
     */
585 View Code Duplication
    public function setPermissions($group_ids)
586
    {
587
        if (!isset($group_ids)) {
588
            $memberHandler = xoops_getHandler('member');
589
            $groups        = $memberHandler->getGroupList();
590
591
            $j         = 0;
592
            $group_ids = array();
593
            foreach (array_keys($groups) as $i) {
594
                $group_ids[$j] = $i;
595
                ++$j;
596
            }
597
        }
598
    }
599
600
    /**
601
     * @return bool
602
     */
603
    public function notLoaded()
604
    {
605
        return ($this->getVar('faqid') == -1);
606
    }
607
608
    /**
609
     * @param  null  $answerObj
610
     * @param  array $users
611
     * @return string
612
     */
613
    public function getWhoAndWhen($answerObj = null, $users = array())
614
    {
615
        $smartModuleConfig = sf_getModuleConfig();
616
617
        $requester   = sf_getLinkedUnameFromId($this->uid(), $smartModuleConfig['userealname'], $users);
618
        $requestdate = $this->datesub();
619
620
        if (($this->status() == _SF_STATUS_PUBLISHED) || $this->status() == _SF_STATUS_NEW_ANSWER) {
621
            if ($answerObj == null) {
622
                $answerObj = $this->answer();
623
            }
624
            $submitdate = $answerObj->datesub();
625
            if ($this->uid() == $answerObj->uid()) {
626
                $result = sprintf(_MD_SF_REQUESTEDANDANSWERED, $requester, $submitdate);
627
            } else {
628
                $submitter = sf_getLinkedUnameFromId($answerObj->uid(), $smartModuleConfig['userealname'], $users);
629
                $result    = sprintf(_MD_SF_REQUESTEDBYANDANSWEREDBY, $requester, $submitter, $submitdate);
630
            }
631
        } else {
632
            $result = sprintf(_MD_SF_REQUESTEDBY, $requester, $requestdate);
633
        }
634
635
        return $result;
636
    }
637
638
    /**
639
     * @return string
640
     */
641
    public function getComeFrom()
642
    {
643
        global $xoopsConfig;
644
        $text = _MD_SF_QUESTIONCOMEFROM;
645
        if (($this->status() == _SF_STATUS_PUBLISHED) || $this->status() == _SF_STATUS_NEW_ANSWER) {
646
            $text = _MD_SF_FAQCOMEFROM;
647
        }
648
649
        return $text
650
               . $xoopsConfig['sitename']
651
               . ' : <a href='
652
               . XOOPS_URL
653
               . '/modules/smartfaq/faq.php?faqid='
654
               . $this->faqid()
655
               . '>'
656
               . XOOPS_URL
657
               . '/modules/smartfaq/faq.php?faqid='
658
               . $this->faqid()
659
               . '</a>';
660
    }
661
662
    /**
663
     * @param  array $faq
664
     * @param  null  $category
665
     * @param  bool  $linkInQuestion
666
     * @return array
667
     */
668
    public function toArray($faq = array(), $category = null, $linkInQuestion = true)
669
    {
670
        global $xoopsModuleConfig;
671
        $lastfaqsize = (int)$xoopsModuleConfig['lastfaqsize'];
672
673
        $faq['id']         = $this->faqid();
674
        $faq['categoryid'] = $this->categoryid();
675
        $faq['question']   = $this->question();
676
        $page              = ($this->status() == _SF_STATUS_OPENED) ? 'answer.php' : 'faq.php';
677
678
        $faq['questionlink'] = "<a href='$page?faqid=" . $this->faqid() . "'>" . $this->question($lastfaqsize) . '</a>';
679
        if ($linkInQuestion) {
680
            $faq['fullquestionlink'] = "<a href='$page?faqid=" . $this->faqid() . "'>" . $this->question() . '</a>';
681
        } else {
682
            $faq['fullquestionlink'] = $this->question();
683
        }
684
        $faq['faqid']      = $this->faqid();
685
        $faq['counter']    = $this->counter();
686
        $faq['cancomment'] = $this->cancomment();
687
        $faq['comments']   = $this->comments();
688
        $faq['datesub']    = $this->datesub();
689
        if (isset($category)) {
690
            if (is_object($category) && strtolower(get_class($category)) === 'sfcategory') {
691
                $categoryObj = $category;
692
            } elseif (is_array($category)) {
693
                $categoryObj = $category[$this->categoryid()];
694
            }
695
            $faq['categoryname'] = $categoryObj->getVar('name');
696
            $faq['categorylink'] = "<a href='" . XOOPS_URL . '/modules/smartfaq/category.php?categoryid=' . $this->categoryid() . "'>" . $categoryObj->getVar('name') . '</a>';
697
        }
698
699
        return $faq;
700
    }
701
}
702
703
/**
704
 * Q&A handler class.
705
 * This class is responsible for providing data access mechanisms to the data source
706
 * of Q&A class objects.
707
 *
708
 * @author  marcan <[email protected]>
709
 * @package SmartFAQ
710
 */
711
class sfFaqHandler extends XoopsObjectHandler
712
{
713
    /**
714
     * @param  bool $isNew
715
     * @return sfFaq
716
     */
717
    public function & create($isNew = true)
718
    {
719
        $faq = new sfFaq();
720
        if ($isNew) {
721
            $faq->setDefaultPermissions();
722
            $faq->setNew();
723
        }
724
725
        return $faq;
726
    }
727
728
    /**
729
     * retrieve an FAQ
730
     *
731
     * @param  int $id faqid of the user
732
     * @return mixed reference to the {@link sfFaq} object, FALSE if failed
733
     */
734 View Code Duplication
    public function & get($id)
735
    {
736
        if ((int)$id > 0) {
737
            $sql = 'SELECT * FROM ' . $this->db->prefix('smartfaq_faq') . ' WHERE faqid=' . $id;
738
            if (!$result = $this->db->query($sql)) {
739
                return false;
740
            }
741
742
            $numrows = $this->db->getRowsNum($result);
743
            if ($numrows == 1) {
744
                $faq = new sfFaq();
745
                $faq->assignVars($this->db->fetchArray($result));
746
747
                return $faq;
748
            }
749
        }
750
751
        return false;
752
    }
753
754
    /**
755
     * insert a new faq in the database
756
     *
757
     * @param  XoopsObject $faq reference to the {@link sfFaq} object
758
     * @param  bool        $force
759
     * @return bool        FALSE if failed, TRUE if already present and unchanged or successful
760
     */
761
    public function insert(XoopsObject $faq, $force = false)
762
    {
763
        if (strtolower(get_class($faq)) !== 'sffaq') {
764
            return false;
765
        }
766
767
        if (!$faq->isDirty()) {
768
            return true;
769
        }
770
771
        if (!$faq->cleanVars()) {
772
            return false;
773
        }
774
775
        foreach ($faq->cleanVars as $k => $v) {
776
            ${$k} = $v;
777
        }
778
779
        if ($faq->isNew()) {
780
            $sql = sprintf('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)',
781
                           $this->db->prefix('smartfaq_faq'), $categoryid, $this->db->quoteString($question), $this->db->quoteString($howdoi), $this->db->quoteString($diduno), $uid, time(), $status,
0 ignored issues
show
The variable $categoryid does not exist. Did you forget to declare it?

This check marks access to variables or properties that have not been declared yet. While PHP has no explicit notion of declaring a variable, accessing it before a value is assigned to it is most likely a bug.

Loading history...
The variable $question does not exist. Did you forget to declare it?

This check marks access to variables or properties that have not been declared yet. While PHP has no explicit notion of declaring a variable, accessing it before a value is assigned to it is most likely a bug.

Loading history...
The variable $howdoi does not exist. Did you forget to declare it?

This check marks access to variables or properties that have not been declared yet. While PHP has no explicit notion of declaring a variable, accessing it before a value is assigned to it is most likely a bug.

Loading history...
The variable $diduno does not exist. Did you forget to declare it?

This check marks access to variables or properties that have not been declared yet. While PHP has no explicit notion of declaring a variable, accessing it before a value is assigned to it is most likely a bug.

Loading history...
The variable $uid does not exist. Did you forget to declare it?

This check marks access to variables or properties that have not been declared yet. While PHP has no explicit notion of declaring a variable, accessing it before a value is assigned to it is most likely a bug.

Loading history...
The variable $status does not exist. Did you forget to declare it?

This check marks access to variables or properties that have not been declared yet. While PHP has no explicit notion of declaring a variable, accessing it before a value is assigned to it is most likely a bug.

Loading history...
782
                           $counter, $weight, $html, $smiley, $xcodes, $cancomment, $comments, $notifypub, $this->db->quoteString($modulelink), $this->db->quoteString($contextpage), $exacturl,
0 ignored issues
show
The variable $counter does not exist. Did you forget to declare it?

This check marks access to variables or properties that have not been declared yet. While PHP has no explicit notion of declaring a variable, accessing it before a value is assigned to it is most likely a bug.

Loading history...
The variable $weight does not exist. Did you forget to declare it?

This check marks access to variables or properties that have not been declared yet. While PHP has no explicit notion of declaring a variable, accessing it before a value is assigned to it is most likely a bug.

Loading history...
The variable $html does not exist. Did you forget to declare it?

This check marks access to variables or properties that have not been declared yet. While PHP has no explicit notion of declaring a variable, accessing it before a value is assigned to it is most likely a bug.

Loading history...
The variable $smiley does not exist. Did you forget to declare it?

This check marks access to variables or properties that have not been declared yet. While PHP has no explicit notion of declaring a variable, accessing it before a value is assigned to it is most likely a bug.

Loading history...
The variable $xcodes does not exist. Did you forget to declare it?

This check marks access to variables or properties that have not been declared yet. While PHP has no explicit notion of declaring a variable, accessing it before a value is assigned to it is most likely a bug.

Loading history...
The variable $cancomment does not exist. Did you forget to declare it?

This check marks access to variables or properties that have not been declared yet. While PHP has no explicit notion of declaring a variable, accessing it before a value is assigned to it is most likely a bug.

Loading history...
The variable $comments does not exist. Did you forget to declare it?

This check marks access to variables or properties that have not been declared yet. While PHP has no explicit notion of declaring a variable, accessing it before a value is assigned to it is most likely a bug.

Loading history...
The variable $notifypub does not exist. Did you forget to declare it?

This check marks access to variables or properties that have not been declared yet. While PHP has no explicit notion of declaring a variable, accessing it before a value is assigned to it is most likely a bug.

Loading history...
The variable $modulelink does not exist. Did you forget to declare it?

This check marks access to variables or properties that have not been declared yet. While PHP has no explicit notion of declaring a variable, accessing it before a value is assigned to it is most likely a bug.

Loading history...
The variable $contextpage does not exist. Did you forget to declare it?

This check marks access to variables or properties that have not been declared yet. While PHP has no explicit notion of declaring a variable, accessing it before a value is assigned to it is most likely a bug.

Loading history...
The variable $exacturl does not exist. Did you forget to declare it?

This check marks access to variables or properties that have not been declared yet. While PHP has no explicit notion of declaring a variable, accessing it before a value is assigned to it is most likely a bug.

Loading history...
783
                           $partialview);
0 ignored issues
show
The variable $partialview does not exist. Did you forget to declare it?

This check marks access to variables or properties that have not been declared yet. While PHP has no explicit notion of declaring a variable, accessing it before a value is assigned to it is most likely a bug.

Loading history...
784
        } else {
785
            $sql = sprintf('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',
786
                           $this->db->prefix('smartfaq_faq'), $categoryid, $this->db->quoteString($question), $this->db->quoteString($howdoi), $this->db->quoteString($diduno), $uid, $datesub, $status,
0 ignored issues
show
The variable $datesub does not exist. Did you forget to declare it?

This check marks access to variables or properties that have not been declared yet. While PHP has no explicit notion of declaring a variable, accessing it before a value is assigned to it is most likely a bug.

Loading history...
787
                           $counter, $weight, $html, $smiley, $xcodes, $cancomment, $comments, $notifypub, $this->db->quoteString($modulelink), $this->db->quoteString($contextpage), $exacturl,
788
                           $partialview, $faqid);
0 ignored issues
show
The variable $faqid does not exist. Did you forget to declare it?

This check marks access to variables or properties that have not been declared yet. While PHP has no explicit notion of declaring a variable, accessing it before a value is assigned to it is most likely a bug.

Loading history...
789
        }
790 View Code Duplication
        if (false != $force) {
0 ignored issues
show
Coding Style Best Practice introduced by
It seems like you are loosely comparing two booleans. Considering using the strict comparison !== instead.

When comparing two booleans, it is generally considered safer to use the strict comparison operator.

Loading history...
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
791
            $result = $this->db->queryF($sql);
792
        } else {
793
            $result = $this->db->query($sql);
794
        }
795
796
        if (!$result) {
797
            return false;
798
        }
799
        if ($faq->isNew()) {
800
            $faq->assignVar('faqid', $this->db->getInsertId());
801
        }
802
803
        // Saving permissions
804
        sf_saveItemPermissions($faq->getGroups_read(), $faq->faqid());
805
806
        return true;
807
    }
808
809
    /**
810
     * delete an FAQ from the database
811
     *
812
     * @param  XoopsObject $faq reference to the FAQ to delete
813
     * @param  bool        $force
814
     * @return bool        FALSE if failed.
815
     */
816
    public function delete(XoopsObject $faq, $force = false)
817
    {
818
        $smartModule = sf_getModuleInfo();
819
        $module_id   = $smartModule->getVar('mid');
820
821
        if (strtolower(get_class($faq)) !== 'sffaq') {
822
            return false;
823
        }
824
825
        // Deleting the answers
826
        $answerHandler = new sfAnswerHandler($this->db);
827
        if (!$answerHandler->deleteFaqAnswers($faq)) {
828
            // error msg...
829
            echo 'error while deleteing an answer';
830
        }
831
832
        $sql = sprintf('DELETE FROM %s WHERE faqid = %u', $this->db->prefix('smartfaq_faq'), $faq->getVar('faqid'));
833
834 View Code Duplication
        if (false != $force) {
0 ignored issues
show
Coding Style Best Practice introduced by
It seems like you are loosely comparing two booleans. Considering using the strict comparison !== instead.

When comparing two booleans, it is generally considered safer to use the strict comparison operator.

Loading history...
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
835
            $result = $this->db->queryF($sql);
836
        } else {
837
            $result = $this->db->query($sql);
838
        }
839
        if (!$result) {
840
            return false;
841
        }
842
843
        xoops_groupperm_deletebymoditem($module_id, 'item_read', $faq->faqid());
844
845
        return true;
846
    }
847
848
    /**
849
     * retrieve FAQs from the database
850
     *
851
     * @param  object $criteria  {@link CriteriaElement} conditions to be met
852
     * @param  bool   $id_as_key use the faqid as key for the array?
853
     * @param  string $notNullFields
854
     * @return false|array  array of <a href='psi_element://sfFaq'>sfFaq</a> objects
855
     */
856
    public function &getObjects($criteria = null, $id_as_key = false, $notNullFields = '')
857
    {
858
        $ret   = array();
859
        $limit = $start = 0;
860
        $sql   = 'SELECT * FROM ' . $this->db->prefix('smartfaq_faq');
861
862 View Code Duplication
        if (isset($criteria) && is_subclass_of($criteria, 'criteriaelement')) {
863
            $whereClause = $criteria->renderWhere();
864
865
            if ($whereClause !== 'WHERE ()') {
866
                $sql .= ' ' . $criteria->renderWhere();
867
                if (!empty($notNullFields)) {
868
                    $sql .= $this->NotNullFieldClause($notNullFields, true);
869
                }
870
            } elseif (!empty($notNullFields)) {
871
                $sql .= ' WHERE ' . $this->NotNullFieldClause($notNullFields);
872
            }
873
            if ($criteria->getSort() != '') {
874
                $sql .= ' ORDER BY ' . $criteria->getSort() . ' ' . $criteria->getOrder();
875
            }
876
            $limit = $criteria->getLimit();
877
            $start = $criteria->getStart();
878
        } elseif (!empty($notNullFields)) {
879
            $sql .= $sql .= ' WHERE ' . $this->NotNullFieldClause($notNullFields);
880
        }
881
882
        //echo "<br>" . $sql . "<br>";
0 ignored issues
show
Unused Code Comprehensibility introduced by
42% 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...
883
        $result = $this->db->query($sql, $limit, $start);
884
        if (!$result) {
885
            return false;
886
        }
887
888
        if (count($result) == 0) {
889
            return false;
890
        }
891
892 View Code Duplication
        while ($myrow = $this->db->fetchArray($result)) {
893
            $faq = new sfFaq();
894
            $faq->assignVars($myrow);
895
896
            if (!$id_as_key) {
897
                $ret[] = &$faq;
898
            } else {
899
                $ret[$myrow['faqid']] = &$faq;
900
            }
901
            unset($faq);
902
        }
903
904
        return $ret;
905
    }
906
907
    /**
908
     * @param  null   $criteria
909
     * @param  bool   $id_as_key
910
     * @param  string $notNullFields
911
     * @return array|bool
912
     */
913
    public function &getObjectsAdminSide($criteria = null, $id_as_key = false, $notNullFields = '')
914
    {
915
        $ret   = array();
916
        $limit = $start = 0;
917
        $sql   = 'SELECT
918
                            faq.faqid AS faqid,
919
                            faq.categoryid AS categoryid,
920
                            faq.question AS question,
921
                            faq.howdoi AS howdoi,
922
                            faq.diduno AS diduno,
923
                            faq.uid AS uid,
924
                            faq.datesub AS datesub,
925
                            faq.status AS status,
926
                            faq.counter AS counter,
927
                            faq.weight AS weight,
928
                            faq.html AS html,
929
                            faq.smiley AS smiley,
930
                            faq.image AS image,
931
                            faq.linebreak AS linebreak,
932
                            faq.xcodes AS xcodes,
933
                            faq.cancomment AS cancomment,
934
                            faq.comments AS comments,
935
                            faq.notifypub AS notifypub,
936
                            faq.modulelink AS modulelink,
937
                            faq.contextpage AS contextpage,
938
                            faq.exacturl AS exacturl
939
                FROM ' . $this->db->prefix('smartfaq_faq') . ' AS faq INNER JOIN ' . $this->db->prefix('smartfaq_categories') . ' AS category ON faq.categoryid = category.categoryid ';
940
941 View Code Duplication
        if (isset($criteria) && is_subclass_of($criteria, 'criteriaelement')) {
0 ignored issues
show
Due to PHP Bug #53727, is_subclass_of returns inconsistent results on some PHP versions for interfaces; you could instead use ReflectionClass::implementsInterface.
Loading history...
942
            $whereClause = $criteria->renderWhere();
943
944
            if ($whereClause !== 'WHERE ()') {
945
                $sql .= ' ' . $criteria->renderWhere();
946
                if (!empty($notNullFields)) {
947
                    $sql .= $this->NotNullFieldClause($notNullFields, true);
948
                }
949
            } elseif (!empty($notNullFields)) {
950
                $sql .= ' WHERE ' . $this->NotNullFieldClause($notNullFields);
951
            }
952
            if ($criteria->getSort() != '') {
953
                $sql .= ' ORDER BY ' . $criteria->getSort() . ' ' . $criteria->getOrder();
954
            }
955
            $limit = $criteria->getLimit();
956
            $start = $criteria->getStart();
957
        } elseif (!empty($notNullFields)) {
958
            $sql .= $sql .= ' WHERE ' . $this->NotNullFieldClause($notNullFields);
959
        }
960
961
        //echo "<br>" . $sql . "<br>";
0 ignored issues
show
Unused Code Comprehensibility introduced by
42% 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...
962
        $result = $this->db->query($sql, $limit, $start);
963
        if (!$result) {
964
            return false;
965
        }
966
967
        if (count($result) == 0) {
968
            return false;
969
        }
970
971 View Code Duplication
        while ($myrow = $this->db->fetchArray($result)) {
972
            $faq = new sfFaq();
973
            $faq->assignVars($myrow);
974
975
            if (!$id_as_key) {
976
                $ret[] = &$faq;
977
            } else {
978
                $ret[$myrow['faqid']] = &$faq;
979
            }
980
            unset($faq);
981
        }
982
983
        return $ret;
984
985
        /*while ($myrow = $this->db->fetchArray($result)) {
986
            $faq = new sfFaq($myrow['faqid']);
987
988
            if (!$id_as_key) {
989
                $ret[] =& $faq;
990
            } else {
991
                $ret[$myrow['faqid']] =& $faq;
992
            }
993
            unset($faq);
994
        }
995
996
        return $ret;*/
997
    }
998
999
    /**
1000
     * count FAQs matching a condition
1001
     *
1002
     * @param  object $criteria {@link CriteriaElement} to match
1003
     * @param  string $notNullFields
1004
     * @return int    count of FAQs
1005
     */
1006
    public function getCount($criteria = null, $notNullFields = '')
1007
    {
1008
        $sql = 'SELECT COUNT(*) FROM ' . $this->db->prefix('smartfaq_faq');
1009
        if (isset($criteria) && is_subclass_of($criteria, 'criteriaelement')) {
0 ignored issues
show
Due to PHP Bug #53727, is_subclass_of returns inconsistent results on some PHP versions for interfaces; you could instead use ReflectionClass::implementsInterface.
Loading history...
1010
            $whereClause = $criteria->renderWhere();
1011
            if ($whereClause !== 'WHERE ()') {
1012
                $sql .= ' ' . $criteria->renderWhere();
1013
                if (!empty($notNullFields)) {
1014
                    $sql .= $this->NotNullFieldClause($notNullFields, true);
1015
                }
1016
            } elseif (!empty($notNullFields)) {
1017
                $sql .= ' WHERE ' . $this->NotNullFieldClause($notNullFields);
1018
            }
1019
        } elseif (!empty($notNullFields)) {
1020
            $sql .= ' WHERE ' . $this->NotNullFieldClause($notNullFields);
1021
        }
1022
1023
        //echo "<br>" . $sql . "<br>";
0 ignored issues
show
Unused Code Comprehensibility introduced by
42% 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...
1024
        $result = $this->db->query($sql);
1025
        if (!$result) {
1026
            return 0;
1027
        }
1028
        list($count) = $this->db->fetchRow($result);
1029
1030
        return $count;
1031
    }
1032
1033
    /**
1034
     * @param  int    $categoryid
1035
     * @param  string $status
1036
     * @param  string $notNullFields
1037
     * @return int
1038
     */
1039
    public function getFaqsCount($categoryid = -1, $status = '', $notNullFields = '')
1040
    {
1041
        global $xoopsUser;
0 ignored issues
show
Compatibility Best Practice introduced by
Use of global functionality is not recommended; it makes your code harder to test, and less reusable.

Instead of relying on global state, we recommend one of these alternatives:

1. Pass all data via parameters

function myFunction($a, $b) {
    // Do something
}

2. Create a class that maintains your state

class MyClass {
    private $a;
    private $b;

    public function __construct($a, $b) {
        $this->a = $a;
        $this->b = $b;
    }

    public function myFunction() {
        // Do something
    }
}
Loading history...
1042
1043
        //  if ( ($categoryid = -1) && (empty($status) || ($status == -1)) ) {
1044
        //return $this->getCount();
1045
        //}
1046
1047
        $userIsAdmin = sf_userIsAdmin();
1048
        // Categories for which user has access
1049 View Code Duplication
        if (!$userIsAdmin) {
1050
            $smartPermHandler = xoops_getModuleHandler('permission', 'smartfaq');
1051
1052
            $categoriesGranted = $smartPermHandler->getPermissions('category');
1053
            $grantedCategories = new Criteria('categoryid', '(' . implode(',', $categoriesGranted) . ')', 'IN');
1054
1055
            $faqsGranted = $smartPermHandler->getPermissions('item');
1056
            $grantedFaq  = new CriteriaCompo();
1057
            $grantedFaq->add(new Criteria('faqid', '(' . implode(',', $faqsGranted) . ')', 'IN'), 'OR');
1058
            // If user is anonymous, check if the FAQ allow partialview
1059
            if (!is_object($xoopsUser)) {
1060
                $grantedFaq->add(new Criteria('partialview', '1'), 'OR');
1061
            }
1062
        }
1063
1064
        if (isset($categoryid) && ($categoryid != -1)) {
1065
            $criteriaCategory = new criteria('categoryid', $categoryid);
1066
        }
1067
1068
        $criteriaStatus = new CriteriaCompo();
1069
        if (!empty($status) && is_array($status)) {
1070
            foreach ($status as $v) {
1071
                $criteriaStatus->add(new Criteria('status', $v), 'OR');
1072
            }
1073
        } elseif (!empty($status) && ($status != -1)) {
1074
            $criteriaStatus->add(new Criteria('status', $status), 'OR');
1075
        }
1076
1077
        $criteriaPermissions = new CriteriaCompo();
1078
        if (!$userIsAdmin) {
1079
            $criteriaPermissions->add($grantedCategories, 'AND');
1080
            $criteriaPermissions->add($grantedFaq, 'AND');
1081
        }
1082
1083
        $criteria = new CriteriaCompo();
1084
        if (!empty($criteriaCategory)) {
1085
            $criteria->add($criteriaCategory);
1086
        }
1087
1088
        if (!empty($criteriaPermissions) && (!$userIsAdmin)) {
1089
            $criteria->add($criteriaPermissions);
1090
        }
1091
1092
        if (!empty($criteriaStatus)) {
1093
            $criteria->add($criteriaStatus);
1094
        }
1095
1096
        return $this->getCount($criteria, $notNullFields);
1097
    }
1098
1099
    /**
1100
     * @return array
1101
     */
1102
    public function getFaqsCountByStatus()
1103
    {
1104
        $sql    = 'SELECT status, COUNT(*) FROM ' . $this->db->prefix('smartfaq_faq') . ' GROUP BY status';
1105
        $result = $this->db->query($sql);
1106
        if (!$result) {
1107
            return array();
1108
        }
1109
        $ret = array();
1110
        while (list($status, $count) = $this->db->fetchRow($result)) {
1111
            $ret[$status] = $count;
1112
        }
1113
1114
        return $ret;
1115
    }
1116
1117
    /**
1118
     * @param  int    $limit
1119
     * @param  int    $start
1120
     * @param  int    $categoryid
1121
     * @param  string $sort
1122
     * @param  string $order
1123
     * @param  bool   $asobject
1124
     * @return array
1125
     */
1126
    public function getAllPublished(
1127
        $limit = 0,
1128
        $start = 0,
1129
        $categoryid = -1,
1130
        $sort = 'datesub',
1131
        $order = 'DESC',
1132
        $asobject = true
1133
    ) {
1134
        return $this->getFaqs($limit, $start, array(_SF_STATUS_PUBLISHED, _SF_STATUS_NEW_ANSWER), $categoryid, $sort, $order, null, $asobject, null);
1135
    }
1136
1137
    /**
1138
     * @param  int    $limit
1139
     * @param  int    $start
1140
     * @param  string $status
1141
     * @param  int    $categoryid
1142
     * @param  string $sort
1143
     * @param  string $order
1144
     * @param  string $notNullFields
1145
     * @param  bool   $asobject
1146
     * @param  null   $otherCriteria
1147
     * @return array
1148
     */
1149
    public function getFaqs(
1150
        $limit = 0,
1151
        $start = 0,
1152
        $status = '',
1153
        $categoryid = -1,
1154
        $sort = 'datesub',
1155
        $order = 'DESC',
1156
        $notNullFields = '',
1157
        $asobject = true,
1158
        $otherCriteria = null
1159
    ) {
1160
        global $xoopsUser;
0 ignored issues
show
Compatibility Best Practice introduced by
Use of global functionality is not recommended; it makes your code harder to test, and less reusable.

Instead of relying on global state, we recommend one of these alternatives:

1. Pass all data via parameters

function myFunction($a, $b) {
    // Do something
}

2. Create a class that maintains your state

class MyClass {
    private $a;
    private $b;

    public function __construct($a, $b) {
        $this->a = $a;
        $this->b = $b;
    }

    public function myFunction() {
        // Do something
    }
}
Loading history...
1161
        include_once XOOPS_ROOT_PATH . '/modules/smartfaq/include/functions.php';
1162
1163
        //if ( ($categoryid == -1) && (empty($status) || ($status == -1)) && ($limit == 0) && ($start ==0) ) {
1164
        //  return $this->getObjects();
1165
        //}
1166
        $ret         = array();
1167
        $userIsAdmin = sf_userIsAdmin();
1168
        // Categories for which user has access
1169 View Code Duplication
        if (!$userIsAdmin) {
1170
            $smartPermHandler = xoops_getModuleHandler('permission', 'smartfaq');
1171
1172
            $categoriesGranted = $smartPermHandler->getPermissions('category');
1173
            $grantedCategories = new Criteria('categoryid', '(' . implode(',', $categoriesGranted) . ')', 'IN');
1174
1175
            $faqsGranted = $smartPermHandler->getPermissions('item');
1176
            $grantedFaq  = new CriteriaCompo();
1177
            $grantedFaq->add(new Criteria('faqid', '(' . implode(',', $faqsGranted) . ')', 'IN'), 'OR');
1178
            // If user is anonymous, check if the FAQ allow partialview
1179
            if (!is_object($xoopsUser)) {
1180
                $grantedFaq->add(new Criteria('partialview', '1'), 'OR');
1181
            }
1182
        }
1183
1184
        if (isset($categoryid) && ($categoryid != -1)) {
1185
            if (is_array($categoryid)) {
1186
                $criteriaCategory = new Criteria('categoryid', '(' . implode(',', $categoryid) . ')', 'IN');
1187
            } else {
1188
                $criteriaCategory = new Criteria('categoryid', (int)$categoryid);
1189
            }
1190
        }
1191
1192 View Code Duplication
        if (!empty($status) && is_array($status)) {
1193
            $criteriaStatus = new CriteriaCompo();
1194
            foreach ($status as $v) {
1195
                $criteriaStatus->add(new Criteria('status', $v), 'OR');
1196
            }
1197
        } elseif (!empty($status) && ($status != -1)) {
1198
            $criteriaStatus = new CriteriaCompo();
1199
            $criteriaStatus->add(new Criteria('status', $status), 'OR');
1200
        }
1201
1202
        $criteriaPermissions = new CriteriaCompo();
1203
        if (!$userIsAdmin) {
1204
            $criteriaPermissions->add($grantedCategories, 'AND');
1205
            $criteriaPermissions->add($grantedFaq, 'AND');
1206
        }
1207
1208
        $criteria = new CriteriaCompo();
1209
        if (!empty($criteriaCategory)) {
1210
            $criteria->add($criteriaCategory);
1211
        }
1212
1213
        if (!empty($criteriaPermissions) && (!$userIsAdmin)) {
1214
            $criteria->add($criteriaPermissions);
1215
        }
1216
1217
        if (!empty($criteriaStatus)) {
1218
            $criteria->add($criteriaStatus);
1219
        }
1220
1221
        if (!empty($otherCriteria)) {
1222
            $criteria->add($otherCriteria);
1223
        }
1224
1225
        $criteria->setLimit($limit);
1226
        $criteria->setStart($start);
1227
        $criteria->setSort($sort);
1228
        $criteria->setOrder($order);
1229
        $ret = &$this->getObjects($criteria, false, $notNullFields);
1230
1231
        return $ret;
1232
    }
1233
1234
    /**
1235
     * @param  int    $limit
1236
     * @param  int    $start
1237
     * @param  string $status
1238
     * @param  int    $categoryid
1239
     * @param  string $sort
1240
     * @param  string $order
1241
     * @param  bool   $asobject
1242
     * @param  null   $otherCriteria
1243
     * @return array|bool
1244
     */
1245
    public function getFaqsAdminSide(
1246
        $limit = 0,
1247
        $start = 0,
1248
        $status = '',
1249
        $categoryid = -1,
1250
        $sort = 'datesub',
1251
        $order = 'DESC',
1252
        $asobject = true,
1253
        $otherCriteria = null
1254
    ) {
1255
        include_once XOOPS_ROOT_PATH . '/modules/smartfaq/include/functions.php';
1256
1257
        $smartModule = sf_getModuleInfo();
1258
1259
        $ret = array();
1260
1261
        if (isset($categoryid) && ($categoryid != -1)) {
1262
            $criteriaCategory = new criteria('faq.categoryid', $categoryid);
1263
        }
1264
1265 View Code Duplication
        if (!empty($status) && is_array($status)) {
1266
            $criteriaStatus = new CriteriaCompo();
1267
            foreach ($status as $v) {
1268
                $criteriaStatus->add(new Criteria('faq.status', $v), 'OR');
1269
            }
1270
        } elseif (!empty($status) && ($status != -1)) {
1271
            $criteriaStatus = new CriteriaCompo();
1272
            $criteriaStatus->add(new Criteria('faq.status', $status), 'OR');
1273
        }
1274
1275
        $criteria = new CriteriaCompo();
1276
        if (!empty($criteriaCategory)) {
1277
            $criteria->add($criteriaCategory);
1278
        }
1279
1280
        if (!empty($criteriaStatus)) {
1281
            $criteria->add($criteriaStatus);
1282
        }
1283
1284
        if (!empty($otherCriteria)) {
1285
            $criteria->add($otherCriteria);
1286
        }
1287
1288
        $criteria->setLimit($limit);
1289
        $criteria->setStart($start);
1290
        $criteria->setSort($sort);
1291
        $criteria->setOrder($order);
1292
        $ret = &$this->getObjectsAdminSide($criteria, false);
1293
1294
        return $ret;
1295
    }
1296
1297
    /**
1298
     * @param  string $field
1299
     * @param  string $status
1300
     * @param  int    $category
1301
     * @return bool|mixed
1302
     */
1303
    public function getRandomFaq($field = '', $status = '', $category = -1)
1304
    {
1305
        $ret = false;
1306
1307
        $notNullFields = $field;
1308
1309
        // Getting the number of published FAQ
1310
        $totalFaqs = $this->getFaqsCount(-1, $status, $notNullFields);
1311
1312
        if ($totalFaqs > 0) {
1313
            --$totalFaqs;
1314
            mt_srand((double)microtime() * 1000000);
1315
            $entrynumber = mt_rand(0, $totalFaqs);
1316
            $faq         = $this->getFaqs(1, $entrynumber, $status, -1, 'datesub', 'DESC', $notNullFields);
1317
            if ($faq) {
1318
                $ret = &$faq[0];
1319
            }
1320
        }
1321
1322
        return $ret;
1323
    }
1324
1325
    /**
1326
     * @param  int $limit
1327
     * @return array|bool
1328
     */
1329
    public function getContextualFaqs($limit = 0)
1330
    {
1331
        $ret = false;
1332
1333
        $otherCriteria = new CriteriaCompo();
1334
        $otherCriteria->add(new Criteria('modulelink', 'None', '<>'));
1335
1336
        $faqsObj = $this->getFaqs(0, 0, array(_SF_STATUS_PUBLISHED, _SF_STATUS_NEW_ANSWER), -1, 'datesub', 'DESC', '', true, $otherCriteria);
1337
1338
        $totalfaqs  = count($faqsObj);
1339
        $randomFaqs = array();
1340
        if ($faqsObj) {
1341
            for ($i = 0; $i < $totalfaqs; ++$i) {
1342
                $display = false;
1343
1344
                $http        = (strpos(XOOPS_URL, 'https://') === false) ? 'http://' : 'https://';
1345
                $phpself     = $_SERVER['PHP_SELF'];
1346
                $httphost    = $_SERVER['HTTP_HOST'];
1347
                $querystring = $_SERVER['QUERY_STRING'];
1348
                if ($querystring != '') {
1349
                    $querystring = '?' . $querystring;
1350
                }
1351
                $currenturl     = $http . $httphost . $phpself . $querystring;
1352
                $fullcontexturl = XOOPS_URL . '/' . $faqsObj[$i]->contextpage();
1353
                switch ($faqsObj[$i]->modulelink()) {
1354
                    case '':
1355
                        $display = false;
1356
                        break;
1357
                    case 'None':
1358
                        $display = false;
1359
                        break;
1360
                    case 'All':
1361
                        $display = true;
1362
                        break;
1363
                    case 'url':
1364
                        if ($faqsObj[$i]->exacturl()) {
1365
                            $display = ($currenturl == $fullcontexturl);
1366
                        } else {
1367
                            $display = (strpos($currenturl, $fullcontexturl) === false);
1368
                        }
1369
                        break;
1370
                    default:
1371
                        if (strpos($currenturl, XOOPS_URL . '/modules/') === false) {
1372
                            $display = false;
1373
                        } else {
1374
                            if (strpos($currenturl, $faqsObj[$i]->modulelink()) === false) {
1375
                                $display = false;
1376
                            } else {
1377
                                $display = true;
1378
                            }
1379
                        }
1380
                        break;
1381
                }
1382
                if ($display) {
1383
                    $randomFaqs[] = &$faqsObj[$i];
1384
                }
1385
            }
1386
        }
1387
1388
        if (count($randomFaqs) > $limit) {
1389
            mt_srand((float)microtime() * 10000000);
1390
            $rand_keys = array_rand($randomFaqs, $limit);
1391
            for ($j = 0, $jMax = count($rand_keys); $j < $jMax; ++$j) {
1392
                $ret[] = &$randomFaqs[$rand_keys[$j]];
1393
            }
1394
        } else {
1395
            $ret = &$randomFaqs;
1396
        }
1397
1398
        return $ret;
1399
    }
1400
1401
    /**
1402
     * @param  array $status
1403
     * @return array
1404
     */
1405
    public function getLastPublishedByCat($status = array(_SF_STATUS_PUBLISHED, _SF_STATUS_NEW_ANSWER))
1406
    {
1407
        $ret       = array();
1408
        $faqclause = '';
1409
        if (!sf_userIsAdmin()) {
1410
            $smartPermHandler = xoops_getModuleHandler('permission', 'smartfaq');
1411
            $items            = $smartPermHandler->getPermissions('item');
1412
            $faqclause        = ' AND faqid IN (' . implode(',', $items) . ')';
1413
        }
1414
1415
        $sql  = "CREATE TEMPORARY TABLE tmp (categoryid INT(8) UNSIGNED NOT NULL,datesub INT(11) DEFAULT '0' NOT NULL);";
1416
        $sql2 = ' LOCK TABLES ' . $this->db->prefix('smartfaq_faq') . ' READ;';
1417
        $sql3 = ' INSERT INTO tmp SELECT categoryid, MAX(datesub) FROM ' . $this->db->prefix('smartfaq_faq') . ' WHERE status IN (' . implode(',', $status) . ") $faqclause GROUP BY categoryid;";
1418
        $sql4 = ' SELECT ' . $this->db->prefix('smartfaq_faq') . '.categoryid, faqid, question, uid, ' . $this->db->prefix('smartfaq_faq') . '.datesub FROM ' . $this->db->prefix('smartfaq_faq') . ', tmp
1419
                              WHERE ' . $this->db->prefix('smartfaq_faq') . '.categoryid=tmp.categoryid AND ' . $this->db->prefix('smartfaq_faq') . '.datesub=tmp.datesub;';
1420
        /*
1421
        //Old implementation
1422
        $sql = "SELECT categoryid, faqid, question, uid, MAX(datesub) AS datesub FROM ".$this->db->prefix("smartfaq_faq")."
1423
               WHERE status IN (". implode(',', $status).")";
1424
        $sql .= " GROUP BY categoryid";
1425
        */
1426
        $this->db->queryF($sql);
1427
        $this->db->queryF($sql2);
1428
        $this->db->queryF($sql3);
1429
        $result = $this->db->query($sql4);
1430
        $error  = $this->db->error();
1431
        $this->db->queryF('UNLOCK TABLES;');
1432
        $this->db->queryF('DROP TABLE tmp;');
1433
        if (!$result) {
1434
            trigger_error('Error in getLastPublishedByCat SQL: ' . $error);
1435
1436
            return $ret;
1437
        }
1438 View Code Duplication
        while ($row = $this->db->fetchArray($result)) {
1439
            $faq = new sfFaq();
1440
            $faq->assignVars($row);
1441
            $ret[$row['categoryid']] = &$faq;
1442
            unset($faq);
1443
        }
1444
1445
        return $ret;
1446
    }
1447
1448
    /**
1449
     * delete FAQs matching a set of conditions
1450
     *
1451
     * @param  object $criteria {@link CriteriaElement}
0 ignored issues
show
Should the type for parameter $criteria not be object|null?

This check looks for @param annotations where the type inferred by our type inference engine differs from the declared type.

It makes a suggestion as to what type it considers more descriptive.

Most often this is a case of a parameter that can be null in addition to its declared types.

Loading history...
1452
     * @return bool   FALSE if deletion failed
1453
     */
1454 View Code Duplication
    public function deleteAll($criteria = null)
1455
    {
1456
        $sql = 'DELETE FROM ' . $this->db->prefix('smartfaq_faq');
1457
        if (isset($criteria) && is_subclass_of($criteria, 'criteriaelement')) {
0 ignored issues
show
Due to PHP Bug #53727, is_subclass_of returns inconsistent results on some PHP versions for interfaces; you could instead use ReflectionClass::implementsInterface.
Loading history...
1458
            $sql .= ' ' . $criteria->renderWhere();
1459
        }
1460
        if (!$this->db->query($sql)) {
1461
            return false;
1462
            // TODO : Also delete the permissions related to each FAQ
1463
        }
1464
1465
        return true;
1466
    }
1467
1468
    /**
1469
     * Change a value for FAQ with a certain criteria
1470
     *
1471
     * @param string $fieldname  Name of the field
1472
     * @param string $fieldvalue Value to write
1473
     * @param object $criteria   {@link CriteriaElement}
0 ignored issues
show
Should the type for parameter $criteria not be object|null?

This check looks for @param annotations where the type inferred by our type inference engine differs from the declared type.

It makes a suggestion as to what type it considers more descriptive.

Most often this is a case of a parameter that can be null in addition to its declared types.

Loading history...
1474
     *
1475
     * @return bool
1476
     **/
1477 View Code Duplication
    public function updateAll($fieldname, $fieldvalue, $criteria = null)
1478
    {
1479
        $set_clause = is_numeric($fieldvalue) ? $fieldname . ' = ' . $fieldvalue : $fieldname . ' = ' . $this->db->quoteString($fieldvalue);
1480
        $sql        = 'UPDATE ' . $this->db->prefix('smartfaq_faq') . ' SET ' . $set_clause;
1481
        if (isset($criteria) && is_subclass_of($criteria, 'criteriaelement')) {
0 ignored issues
show
Due to PHP Bug #53727, is_subclass_of returns inconsistent results on some PHP versions for interfaces; you could instead use ReflectionClass::implementsInterface.
Loading history...
1482
            $sql .= ' ' . $criteria->renderWhere();
1483
        }
1484
        if (!$this->db->queryF($sql)) {
1485
            return false;
1486
        }
1487
1488
        return true;
1489
    }
1490
1491
    /**
1492
     * @param $faqid
1493
     * @return bool
1494
     */
1495
    public function updateCounter($faqid)
1496
    {
1497
        $sql = 'UPDATE ' . $this->db->prefix('smartfaq_faq') . ' SET counter=counter+1 WHERE faqid = ' . $faqid;
1498
        if ($this->db->queryF($sql)) {
1499
            return true;
1500
        } else {
1501
            return false;
1502
        }
1503
    }
1504
1505
    /**
1506
     * @param  string $notNullFields
1507
     * @param  bool   $withAnd
1508
     * @return string
1509
     */
1510
    public function NotNullFieldClause($notNullFields = '', $withAnd = false)
1511
    {
1512
        $ret = '';
1513
        if ($withAnd) {
1514
            $ret .= ' AND ';
1515
        }
1516
        if (!empty($notNullFields) && is_array($notNullFields)) {
1517
            foreach ($notNullFields as $v) {
1518
                $ret .= " ($v IS NOT NULL AND $v <> ' ' )";
1519
            }
1520
        } elseif (!empty($notNullFields)) {
1521
            $ret .= " ($notNullFields IS NOT NULL AND $notNullFields <> ' ' )";
1522
        }
1523
1524
        return $ret;
1525
    }
1526
1527
    /**
1528
     * @param  array  $queryarray
1529
     * @param  string $andor
1530
     * @param  int    $limit
1531
     * @param  int    $offset
1532
     * @param  int    $userid
1533
     * @return array
1534
     */
1535
    public function getFaqsFromSearch($queryarray = array(), $andor = 'AND', $limit = 0, $offset = 0, $userid = 0)
1536
    {
1537
        global $xoopsUser;
0 ignored issues
show
Compatibility Best Practice introduced by
Use of global functionality is not recommended; it makes your code harder to test, and less reusable.

Instead of relying on global state, we recommend one of these alternatives:

1. Pass all data via parameters

function myFunction($a, $b) {
    // Do something
}

2. Create a class that maintains your state

class MyClass {
    private $a;
    private $b;

    public function __construct($a, $b) {
        $this->a = $a;
        $this->b = $b;
    }

    public function myFunction() {
        // Do something
    }
}
Loading history...
1538
1539
        $ret = array();
1540
1541
        $userIsAdmin = sf_userIsAdmin();
1542
1543
        if ($userid != 0) {
1544
            $criteriaUser = new CriteriaCompo();
1545
            $criteriaUser->add(new Criteria('faq.uid', $userid), 'OR');
1546
            $criteriaUser->add(new Criteria('answer.uid', $userid), 'OR');
1547
        }
1548
1549
        if ($queryarray) {
1550
            $criteriaKeywords = new CriteriaCompo();
1551
            for ($i = 0, $iMax = count($queryarray); $i < $iMax; ++$i) {
1552
                $criteriaKeyword = new CriteriaCompo();
1553
                $criteriaKeyword->add(new Criteria('faq.question', '%' . $queryarray[$i] . '%', 'LIKE'), 'OR');
1554
                $criteriaKeyword->add(new Criteria('answer.answer', '%' . $queryarray[$i] . '%', 'LIKE'), 'OR');
1555
                $criteriaKeywords->add($criteriaKeyword, $andor);
1556
                unset($criteriaKeyword);
1557
            }
1558
        }
1559
1560
        // Categories for which user has access
1561
        if (!$userIsAdmin) {
1562
            $smartPermHandler = xoops_getModuleHandler('permission', 'smartfaq');
1563
1564
            $categoriesGranted = $smartPermHandler->getPermissions('category');
1565
            $faqsGranted       = $smartPermHandler->getPermissions('item');
1566
            if (!$categoriesGranted) {
1567
                return $ret;
1568
            }
1569
            if (!$faqsGranted) {
1570
                return $ret;
1571
            }
1572
            $grantedCategories = new Criteria('faq.categoryid', '(' . implode(',', $categoriesGranted) . ')', 'IN');
1573
            $grantedFaq        = new CriteriaCompo();
1574
            $grantedFaq->add(new Criteria('faq.faqid', '(' . implode(',', $faqsGranted) . ')', 'IN'), 'OR');
1575
            // If user is anonymous, check if the FAQ allow partialview
1576
            if (!is_object($xoopsUser)) {
1577
                $grantedFaq->add(new Criteria('partialview', '1'), 'OR');
1578
            }
1579
        }
1580
1581
        $criteriaPermissions = new CriteriaCompo();
1582
        if (!$userIsAdmin) {
1583
            $criteriaPermissions->add($grantedCategories, 'AND');
1584
            $criteriaPermissions->add($grantedFaq, 'AND');
1585
        }
1586
1587
        $criteriaAnswersStatus = new CriteriaCompo();
1588
        $criteriaAnswersStatus->add(new Criteria('answer.status', _SF_AN_STATUS_APPROVED));
1589
1590
        $criteriaFasStatus = new CriteriaCompo();
1591
        $criteriaFasStatus->add(new Criteria('faq.status', _SF_STATUS_OPENED), 'OR');
1592
        $criteriaFasStatus->add(new Criteria('faq.status', _SF_STATUS_PUBLISHED), 'OR');
1593
1594
        $criteria = new CriteriaCompo();
1595
        if (!empty($criteriaUser)) {
1596
            $criteria->add($criteriaUser, 'AND');
1597
        }
1598
1599
        if (!empty($criteriaKeywords)) {
1600
            $criteria->add($criteriaKeywords, 'AND');
1601
        }
1602
1603
        if (!empty($criteriaPermissions) && (!$userIsAdmin)) {
1604
            $criteria->add($criteriaPermissions);
1605
        }
1606
1607
        if (!empty($criteriaAnswersStatus)) {
1608
            $criteria->add($criteriaAnswersStatus, 'AND');
1609
        }
1610
1611
        if (!empty($criteriaFasStatus)) {
1612
            $criteria->add($criteriaFasStatus, 'AND');
1613
        }
1614
1615
        $criteria->setLimit($limit);
1616
        $criteria->setStart($offset);
1617
        $criteria->setSort('faq.datesub');
1618
        $criteria->setOrder('DESC');
1619
1620
        $sql = 'SELECT faq.faqid, faq.question, faq.datesub, faq.uid FROM '
1621
               . $this->db->prefix('smartfaq_faq')
1622
               . ' AS faq INNER JOIN '
1623
               . $this->db->prefix('smartfaq_answers')
1624
               . ' AS answer ON faq.faqid = answer.faqid';
1625
1626
        if (isset($criteria) && is_subclass_of($criteria, 'criteriaelement')) {
0 ignored issues
show
Due to PHP Bug #53727, is_subclass_of returns inconsistent results on some PHP versions for interfaces; you could instead use ReflectionClass::implementsInterface.
Loading history...
1627
            $whereClause = $criteria->renderWhere();
1628
1629 View Code Duplication
            if ($whereClause !== 'WHERE ()') {
1630
                $sql .= ' ' . $criteria->renderWhere();
1631
                if ($criteria->getSort() != '') {
1632
                    $sql .= ' ORDER BY ' . $criteria->getSort() . ' ' . $criteria->getOrder();
1633
                }
1634
                $limit = $criteria->getLimit();
1635
                $start = $criteria->getStart();
1636
            }
1637
        }
1638
1639
        //echo "<br>" . $sql . "<br>";
0 ignored issues
show
Unused Code Comprehensibility introduced by
42% 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...
1640
1641
        $result = $this->db->query($sql, $limit, $start);
1642
        if (!$result) {
1643
            trigger_error('Query did not work in smartfaq', E_USER_WARNING);
1644
1645
            return $ret;
1646
        }
1647
1648
        if (count($result) == 0) {
1649
            return $ret;
1650
        }
1651
1652
        while ($myrow = $this->db->fetchArray($result)) {
1653
            $faq = new sfFaq();
1654
            $faq->assignVars($myrow);
1655
            $ret[] = &$faq;
1656
            unset($faq);
1657
        }
1658
1659
        return $ret;
1660
    }
1661
1662
    /**
1663
     * @param  int   $cat_id
1664
     * @param        $status
1665
     * @return array
1666
     */
1667
    public function getCountsByCat($cat_id = 0, $status)
1668
    {
1669
        global $xoopsUser;
0 ignored issues
show
Compatibility Best Practice introduced by
Use of global functionality is not recommended; it makes your code harder to test, and less reusable.

Instead of relying on global state, we recommend one of these alternatives:

1. Pass all data via parameters

function myFunction($a, $b) {
    // Do something
}

2. Create a class that maintains your state

class MyClass {
    private $a;
    private $b;

    public function __construct($a, $b) {
        $this->a = $a;
        $this->b = $b;
    }

    public function myFunction() {
        // Do something
    }
}
Loading history...
1670
        $ret = array();
1671
        $sql = 'SELECT categoryid, COUNT(*) AS count FROM ' . $this->db->prefix('smartfaq_faq');
1672
        if ((int)$cat_id > 0) {
1673
            $sql .= ' WHERE categoryid = ' . (int)$cat_id;
1674
            $sql .= ' AND status IN (' . implode(',', $status) . ')';
1675
        } else {
1676
            $sql .= ' WHERE status IN (' . implode(',', $status) . ')';
1677
            if (!sf_userIsAdmin()) {
1678
                $smartPermHandler = xoops_getModuleHandler('permission', 'smartfaq');
1679
                $items            = $smartPermHandler->getPermissions('item');
1680
                if (is_object($xoopsUser)) {
1681
                    $sql .= ' AND faqid IN (' . implode(',', $items) . ')';
1682
                } else {
1683
                    $sql .= ' AND (faqid IN (' . implode(',', $items) . ') OR partialview = 1)';
1684
                }
1685
            }
1686
        }
1687
        $sql .= ' GROUP BY categoryid';
1688
1689
        //echo "<br>" . $sql . "<br>";
1690
1691
        $result = $this->db->query($sql);
1692
        if (!$result) {
1693
            return $ret;
1694
        }
1695
        while ($row = $this->db->fetchArray($result)) {
1696
            $ret[$row['categoryid']] = (int)$row['count'];
1697
        }
1698
1699
        return $ret;
1700
    }
1701
}
1702