GitHub Access Token became invalid

It seems like the GitHub access token used for retrieving details about this repository from GitHub became invalid. This might prevent certain types of inspections from being run (in particular, everything related to pull requests).
Please ask an admin of your repository to re-new the access token on this website.
Completed
Push — 2.9 ( 961c43...c5dff8 )
by Thorsten
18:06
created

PMF_Faq::deleteCategoryRelations()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 16
Code Lines 7

Duplication

Lines 0
Ratio 0 %
Metric Value
dl 0
loc 16
rs 9.4285
cc 1
eloc 7
nc 1
nop 2
1
<?php
2
3
/**
4
 * The main FAQ class.
5
 *
6
 * PHP Version 5.5
7
 *
8
 * This Source Code Form is subject to the terms of the Mozilla Public License,
9
 * v. 2.0. If a copy of the MPL was not distributed with this file, You can
10
 * obtain one at http://mozilla.org/MPL/2.0/.
11
 *
12
 * @category  phpMyFAQ
13
 * @author    Thorsten Rinne <[email protected]>
14
 * @author    Matteo Scaramuccia <[email protected]>
15
 * @author    Georgi Korchev <[email protected]>
16
 * @author    Adrianna Musiol <[email protected]>
17
 * @author    Peter Caesar <[email protected]>
18
 * @copyright 2005-2016 phpMyFAQ Team
19
 * @license   http://www.mozilla.org/MPL/2.0/ Mozilla Public License Version 2.0
20
 * @link      http://www.phpmyfaq.de
21
 * @since     2005-12-20
22
 */
23
if (!defined('IS_VALID_PHPMYFAQ')) {
24
    exit();
25
}
26
27
/*
28
 * SQL constants definitions
29
 */
30
define('FAQ_SQL_ACTIVE_YES', 'yes');
31
define('FAQ_SQL_ACTIVE_NO',  'no');
32
33
/*
34
 * Query type definitions
35
 */
36
define('FAQ_QUERY_TYPE_DEFAULT',      'faq_default');
37
define('FAQ_QUERY_TYPE_APPROVAL',     'faq_approval');
38
define('FAQ_QUERY_TYPE_EXPORT_PDF',   'faq_export_pdf');
39
define('FAQ_QUERY_TYPE_EXPORT_XHTML', 'faq_export_xhtml');
40
define('FAQ_QUERY_TYPE_EXPORT_XML',   'faq_export_xml');
41
define('FAQ_QUERY_TYPE_RSS_LATEST',   'faq_rss_latest');
42
43
/*
44
 * Sorting type definitions
45
 */
46
define('FAQ_SORTING_TYPE_NONE', 0);
47
define('FAQ_SORTING_TYPE_CATID_FAQID', 1);
48
define('FAQ_SORTING_TYPE_FAQTITLE_FAQID', 2);
49
define('FAQ_SORTING_TYPE_DATE_FAQID', 3);
50
define('FAQ_SORTING_TYPE_FAQID', 4);
51
52
/**
53
 * The main FAQ class - 3K LOC of funny things for phpMyFAQ.
54
 *
55
 * @category  phpMyFAQ
56
 * @author    Thorsten Rinne <[email protected]>
57
 * @author    Matteo Scaramuccia <[email protected]>
58
 * @author    Georgi Korchev <[email protected]>
59
 * @author    Adrianna Musiol <[email protected]>
60
 * @author    Peter Caesar <[email protected]>
61
 * @copyright 2005-2016 phpMyFAQ Team
62
 * @license   http://www.mozilla.org/MPL/2.0/ Mozilla Public License Version 2.0
63
 * @link      http://www.phpmyfaq.de
64
 * @since     2005-12-20
65
 */
66
class PMF_Faq
67
{
68
    /**
69
     * @var PMF_Configuration
70
     */
71
    private $_config;
72
73
    /**
74
     * Language strings.
75
     *
76
     * @var string
77
     */
78
    private $pmf_lang;
79
80
    /**
81
     * Plural form support.
82
     *
83
     * @var PMF_Language_Plurals
84
     */
85
    private $plr;
86
87
    /**
88
     * The current FAQ record.
89
     *
90
     * @var array
91
     */
92
    public $faqRecord = [];
93
94
    /**
95
     * All current FAQ records in an array.
96
     *
97
     * @var array
98
     */
99
    public $faqRecords = [];
100
101
    /**
102
     * Users.
103
     *
104
     * @var int
105
     */
106
    private $user = -1;
107
108
    /**
109
     * Groups.
110
     *
111
     * @var array
112
     */
113
    private $groups = array(-1);
114
115
    /**
116
     * Flag for Group support.
117
     *
118
     * @var bool
119
     */
120
    private $groupSupport = false;
121
122
    /**
123
     * Constructor.
124
     *
125
     * @param PMF_Configuration $config
126
     *
127
     * @return PMF_Faq
128
     */
129
    public function __construct(PMF_Configuration $config)
130
    {
131
        global $PMF_LANG, $plr;
132
133
        $this->_config = $config;
134
        $this->pmf_lang = $PMF_LANG;
135
        $this->plr = $plr;
136
137
        if ($this->_config->get('security.permLevel') == 'medium') {
138
            $this->groupSupport = true;
139
        }
140
    }
141
142
    //
143
    //
144
    // PUBLIC METHODS
145
    //
146
    //
147
148
    /**
149
     * @param int $userId
150
     */
151
    public function setUser($userId = -1)
152
    {
153
        $this->user = $userId;
154
    }
155
156
    /**
157
     * @param array $groups
158
     */
159
    public function setGroups(Array $groups)
160
    {
161
        $this->groups = $groups;
162
    }
163
164
    /**
165
     * This function returns all not expired records from one category.
166
     *
167
     * @param int    $category_id Category ID
168
     * @param string $orderby     Order by
169
     * @param string $sortby      Sorty by
170
     *
171
     * @return array
172
     */
173
    public function getAllRecordPerCategory($category_id, $orderby = 'id', $sortby = 'ASC')
174
    {
175
        global $sids;
176
177
        $faqdata = [];
178
179
        if ($orderby == 'visits') {
180
            $currentTable = 'fv';
181
        } else {
182
            $currentTable = 'fd';
183
        }
184
185
        $now = date('YmdHis');
186
        $query = sprintf("
187
            SELECT
188
                fd.id AS id,
189
                fd.lang AS lang,
190
                fd.thema AS thema,
191
                fd.content AS record_content,
192
                fd.updated AS updated,
193
                fcr.category_id AS category_id,
194
                fv.visits AS visits,
195
                fd.created AS created
196
            FROM
197
                %sfaqdata AS fd
198
            LEFT JOIN
199
                %sfaqcategoryrelations AS fcr
200
            ON
201
                fd.id = fcr.record_id
202
            AND
203
                fd.lang = fcr.record_lang
204
            LEFT JOIN
205
                %sfaqvisits AS fv
206
            ON
207
                fd.id = fv.id
208
            AND
209
                fv.lang = fd.lang
210
            LEFT JOIN
211
                %sfaqdata_group AS fdg
212
            ON
213
                fd.id = fdg.record_id
214
            LEFT JOIN
215
                %sfaqdata_user AS fdu
216
            ON
217
                fd.id = fdu.record_id
218
            WHERE
219
                fd.date_start <= '%s'
220
            AND
221
                fd.date_end   >= '%s'
222
            AND
223
                fd.active = 'yes'
224
            AND
225
                fcr.category_id = %d
226
            AND
227
                fd.lang = '%s'
228
                %s
229
            ORDER BY
230
                %s.%s %s",
231
            PMF_Db::getTablePrefix(),
232
            PMF_Db::getTablePrefix(),
233
            PMF_Db::getTablePrefix(),
234
            PMF_Db::getTablePrefix(),
235
            PMF_Db::getTablePrefix(),
236
            $now,
237
            $now,
238
            $category_id,
239
            $this->_config->getLanguage()->getLanguage(),
240
            $this->queryPermission($this->groupSupport),
241
            $currentTable,
242
            $this->_config->getDb()->escape($orderby),
243
            $this->_config->getDb()->escape($sortby)
244
        );
245
246
        $result = $this->_config->getDb()->query($query);
247
        $num = $this->_config->getDb()->numRows($result);
248
249
        if ($num > 0) {
250
            $faqHelper = new PMF_Helper_Faq($this->_config);
251
            while (($row = $this->_config->getDb()->fetchObject($result))) {
252
                if (empty($row->visits)) {
253
                    $visits = 0;
254
                } else {
255
                    $visits = $row->visits;
256
                }
257
258
                $url = sprintf(
259
                    '%sindex.php?%saction=artikel&cat=%d&id=%d&artlang=%s',
260
                    $this->_config->getDefaultUrl(),
261
                    $sids,
262
                    $row->category_id,
263
                    $row->id,
264
                    $row->lang
265
                );
266
                $oLink = new PMF_Link($url, $this->_config);
267
                $oLink->itemTitle = $oLink->text = $oLink->tooltip = $row->thema;
268
269
                $faqdata[] = array(
270
                    'record_id' => $row->id,
271
                    'record_lang' => $row->lang,
272
                    'category_id' => $row->category_id,
273
                    'record_title' => $row->thema,
274
                    'record_preview' => $faqHelper->renderAnswerPreview($row->record_content, 25),
275
                    'record_link' => $oLink->toString(),
276
                    'record_updated' => $row->updated,
277
                    'visits' => $visits,
278
                    'record_created' => $row->created,
279
                );
280
            }
281
        } else {
282
            return $faqdata;
283
        }
284
285
        return $faqdata;
286
    }
287
288
    /**
289
     * This function returns all not expired records from one category.
290
     *
291
     * @param int    $categoryId Category ID
292
     * @param string $orderby    Order by
293
     * @param string $sortby     Sorty by
294
     *
295
     * @return string
296
     */
297
    public function showAllRecords($categoryId, $orderby = 'id', $sortby = 'ASC')
298
    {
299
        global $sids;
300
301
        $numPerPage = $this->_config->get('records.numberOfRecordsPerPage');
302
        $page = PMF_Filter::filterInput(INPUT_GET, 'seite', FILTER_VALIDATE_INT, 1);
303
        $output = '';
304
        $title = '';
305
306
        if ($orderby == 'visits') {
307
            $currentTable = 'fv';
308
        } else {
309
            $currentTable = 'fd';
310
        }
311
312
        // If random FAQs are activated, we don't need an order
313
        if (true === $this->_config->get('records.randomSort')) {
314
            $order = '';
315
        } else {
316
            $order = sprintf(
317
                'ORDER BY fd.sticky DESC, %s.%s %s',
318
                $currentTable,
319
                $this->_config->getDb()->escape($orderby),
320
                $this->_config->getDb()->escape($sortby)
321
            );
322
        }
323
324
        $now = date('YmdHis');
325
        $query = sprintf("
326
            SELECT
327
                fd.id AS id,
328
                fd.lang AS lang,
329
                fd.sticky AS sticky,
330
                fd.thema AS thema,
331
                fcr.category_id AS category_id,
332
                fv.visits AS visits
333
            FROM
334
                %sfaqdata AS fd
335
            LEFT JOIN
336
                %sfaqcategoryrelations AS fcr
337
            ON
338
                fd.id = fcr.record_id
339
            AND
340
                fd.lang = fcr.record_lang
341
            LEFT JOIN
342
                %sfaqvisits AS fv
343
            ON
344
                fd.id = fv.id
345
            AND
346
                fv.lang = fd.lang
347
            LEFT JOIN
348
                %sfaqdata_group AS fdg
349
            ON
350
                fd.id = fdg.record_id
351
            LEFT JOIN
352
                %sfaqdata_user AS fdu
353
            ON
354
                fd.id = fdu.record_id
355
            WHERE
356
                fd.date_start <= '%s'
357
            AND
358
                fd.date_end   >= '%s'
359
            AND
360
                fd.active = 'yes'
361
            AND
362
                fcr.category_id = %d
363
            AND
364
                fd.lang = '%s'
365
            %s
366
            %s",
367
            PMF_Db::getTablePrefix(),
368
            PMF_Db::getTablePrefix(),
369
            PMF_Db::getTablePrefix(),
370
            PMF_Db::getTablePrefix(),
371
            PMF_Db::getTablePrefix(),
372
            $now,
373
            $now,
374
            $categoryId,
375
            $this->_config->getLanguage()->getLanguage(),
376
            $this->queryPermission($this->groupSupport),
377
            $order
378
        );
379
380
        $result = $this->_config->getDb()->query($query);
381
        $num = $this->_config->getDb()->numRows($result);
382
        $pages = (int) ceil($num / $numPerPage);
383
384
        if ($page == 1) {
385
            $first = 0;
386
        } else {
387
            $first = $page * $numPerPage - $numPerPage;
388
        }
389
390
        if ($num > 0) {
391 View Code Duplication
            if ($pages > 1) {
392
                $output .= sprintf('<p><strong>%s %s %s</strong></p>',
393
                    $this->pmf_lang['msgPage'].$page,
394
                    $this->pmf_lang['msgVoteFrom'],
395
                    $pages.$this->pmf_lang['msgPages']);
396
            }
397
            $output .= '<ul class="phpmyfaq_ul">';
398
399
            $counter = 0;
400
            $displayedCounter = 0;
401
            $renderedItems = [];
402
            while (($row = $this->_config->getDb()->fetchObject($result)) && $displayedCounter < $numPerPage) {
403
                ++$counter;
404
                if ($counter <= $first) {
405
                    continue;
406
                }
407
                ++$displayedCounter;
408
409
                if (empty($row->visits)) {
410
                    $visits = 0;
411
                } else {
412
                    $visits = $row->visits;
413
                }
414
415
                $title = $row->thema;
416
                $url = sprintf(
417
                    '%s?%saction=artikel&amp;cat=%d&amp;id=%d&amp;artlang=%s',
418
                    PMF_Link::getSystemRelativeUri(),
419
                    $sids,
420
                    $row->category_id,
421
                    $row->id,
422
                    $row->lang
423
                );
424
425
                $oLink = new PMF_Link($url, $this->_config);
426
                $oLink->itemTitle = $oLink->text = $oLink->tooltip = $title;
427
428
                // If random FAQs are activated, we don't need sticky FAQs
429
                if (true === $this->_config->get('records.randomSort')) {
430
                    $row->sticky = 0;
431
                }
432
433
                $renderedItems[$row->id] = sprintf(
434
                    '<li%s>%s<span id="viewsPerRecord"><br /><small>(%s)</small></span></li>',
435
                    ($row->sticky == 1) ? ' class="sticky-faqs"' : '',
436
                    $oLink->toHtmlAnchor(),
437
                    $this->plr->GetMsg('plmsgViews', $visits)
438
                );
439
            }
440
441
            // If random FAQs are activated, shuffle the FAQs :-)
442
            if (true === $this->_config->get('records.randomSort')) {
443
                shuffle($renderedItems);
444
            }
445
446
            $output .= implode("\n", $renderedItems);
447
            $output .= '</ul><span class="totalFaqRecords hide">'.$num.'</span>';
448
        } else {
449
            return false;
450
        }
451
452
        if ($pages > 1) {
453
            // Set rewrite URL, if needed
454
            if ($this->_config->get('main.enableRewriteRules')) {
455
                $link = new PMF_Link(PMF_Link::getSystemRelativeUri('index.php'), $this->_config);
456
                $useRewrite = true;
457
                $rewriteUrl = sprintf(
458
                    '%scategory/%d/%%d/%s.html',
459
                    PMF_Link::getSystemRelativeUri('index.php'),
460
                    $categoryId,
461
                    $link->getSEOItemTitle($title)
462
                );
463
            } else {
464
                $useRewrite = false;
465
                $rewriteUrl = '';
466
            }
467
            $baseUrl = sprintf(
468
                '%s?%saction=show&amp;cat=%d&amp;seite=%d',
469
                PMF_Link::getSystemRelativeUri(),
470
                (empty($sids) ? '' : $sids),
471
                $categoryId,
472
                $page
473
            );
474
475
            $options = array(
476
                'baseUrl' => $baseUrl,
477
                'total' => $num,
478
                'perPage' => $this->_config->get('records.numberOfRecordsPerPage'),
479
                'useRewrite' => $useRewrite,
480
                'rewriteUrl' => $rewriteUrl,
481
                'pageParamName' => 'seite',
482
            );
483
484
            $pagination = new PMF_Pagination($this->_config, $options);
485
            $output    .= $pagination->render();
486
        }
487
488
        return $output;
489
    }
490
491
    /**
492
     * This function returns all not expired records from the given record ids.
493
     *
494
     * @param array  $record_ids Array of record ids
495
     * @param string $orderby    Order by
496
     * @param string $sortby     Sort by
497
     *
498
     * @return string
499
     */
500
    public function showAllRecordsByIds(Array $record_ids, $orderby = 'fd.id', $sortby = 'ASC')
501
    {
502
        global $sids;
503
504
        $records = implode(', ', $record_ids);
505
        $page = PMF_Filter::filterInput(INPUT_GET, 'seite', FILTER_VALIDATE_INT, 1);
506
        $tagging_id = PMF_Filter::filterInput(INPUT_GET, 'tagging_id', FILTER_VALIDATE_INT);
507
        $output = '';
508
509
        $now = date('YmdHis');
510
        $query = sprintf("
511
            SELECT
512
                fd.id AS id,
513
                fd.lang AS lang,
514
                fd.thema AS thema,
515
                fcr.category_id AS category_id,
516
                fv.visits AS visits
517
            FROM
518
                %sfaqdata AS fd
519
            LEFT JOIN
520
                %sfaqcategoryrelations AS fcr
521
            ON
522
                fd.id = fcr.record_id
523
            AND
524
                fd.lang = fcr.record_lang
525
            LEFT JOIN
526
                %sfaqvisits AS fv
527
            ON
528
                fd.id = fv.id
529
            AND
530
                fv.lang = fd.lang
531
            LEFT JOIN
532
                %sfaqdata_group AS fdg
533
            ON
534
                fd.id = fdg.record_id
535
            LEFT JOIN
536
                %sfaqdata_user AS fdu
537
            ON
538
                fd.id = fdu.record_id
539
            WHERE
540
                fd.date_start <= '%s'
541
            AND
542
                fd.date_end   >= '%s'
543
            AND
544
                fd.active = 'yes'
545
            AND
546
                fd.id IN (%s)
547
            AND
548
                fd.lang = '%s'
549
                %s
550
            ORDER BY
551
                %s %s",
552
            PMF_Db::getTablePrefix(),
553
            PMF_Db::getTablePrefix(),
554
            PMF_Db::getTablePrefix(),
555
            PMF_Db::getTablePrefix(),
556
            PMF_Db::getTablePrefix(),
557
            $now,
558
            $now,
559
            $records,
560
            $this->_config->getLanguage()->getLanguage(),
561
            $this->queryPermission($this->groupSupport),
562
            $this->_config->getDb()->escape($orderby),
563
            $this->_config->getDb()->escape($sortby));
564
565
        $result = $this->_config->getDb()->query($query);
566
567
        $num = $this->_config->getDb()->numRows($result);
568
        $pages = ceil($num / $this->_config->get('records.numberOfRecordsPerPage'));
569
570
        if ($page == 1) {
571
            $first = 0;
572
        } else {
573
            $first = ($page * $this->_config->get('records.numberOfRecordsPerPage')) - $this->_config->get('records.numberOfRecordsPerPage');
574
        }
575
576
        if ($num > 0) {
577 View Code Duplication
            if ($pages > 1) {
578
                $output .= sprintf('<p><strong>%s %s %s</strong></p>',
579
                    $this->pmf_lang['msgPage'].$page,
580
                    $this->pmf_lang['msgVoteFrom'],
581
                    $pages.$this->pmf_lang['msgPages']);
582
            }
583
            $output .= '<ul class="phpmyfaq_ul">';
584
            $counter = 0;
585
            $displayedCounter = 0;
586
587
            $lastFaqId = 0;
588
            while (($row = $this->_config->getDb()->fetchObject($result)) && $displayedCounter < $this->_config->get('records.numberOfRecordsPerPage')) {
589
                ++$counter;
590
                if ($counter <= $first) {
591
                    continue;
592
                }
593
                ++$displayedCounter;
594
595
                if ($lastFaqId == $row->id) {
596
                    continue; // Don't show multiple FAQs
597
                }
598
599
                if (empty($row->visits)) {
600
                    $visits = 0;
601
                } else {
602
                    $visits = $row->visits;
603
                }
604
605
                $title = $row->thema;
606
                $url = sprintf(
607
                    '%s?%saction=artikel&amp;cat=%d&amp;id=%d&amp;artlang=%s',
608
                    PMF_Link::getSystemRelativeUri(),
609
                    $sids,
610
                    $row->category_id,
611
                    $row->id,
612
                    $row->lang
613
                );
614
                $oLink = new PMF_Link($url, $this->_config);
615
                $oLink->itemTitle = $row->thema;
616
                $oLink->text = $title;
617
                $oLink->tooltip = $title;
618
                $listItem = sprintf(
619
                    '<li>%s<br /><small>(%s)</small></li>',
620
                    $oLink->toHtmlAnchor(),
621
                    $this->plr->GetMsg('plmsgViews', $visits)
622
                );
623
624
                $output .= $listItem;
625
626
                $lastFaqId = $row->id;
627
            }
628
            $output .= '</ul><span id="totFaqRecords" style="display: none;">'.$num.'</span>';
629
        } else {
630
            return false;
631
        }
632
633
        if ($num > $this->_config->get('records.numberOfRecordsPerPage')) {
634
            $output .= '<p class="text-center"><strong>';
635
            if (!isset($page)) {
636
                $page = 1;
637
            }
638
            $vor = $page - 1;
639
            $next = $page + 1;
640 View Code Duplication
            if ($vor != 0) {
641
                $url = $sids.'&amp;action=search&amp;tagging_id='.$tagging_id.'&amp;seite='.$vor;
642
                $oLink = new PMF_Link(PMF_Link::getSystemRelativeUri().'?'.$url, $this->_config);
643
                $oLink->itemTitle = 'tag';
644
                $oLink->text = $this->pmf_lang['msgPrevious'];
645
                $oLink->tooltip = $this->pmf_lang['msgPrevious'];
646
                $output          .= '[ '.$oLink->toHtmlAnchor().' ]';
647
            }
648
            $output .= ' ';
649 View Code Duplication
            if ($next <= $pages) {
650
                $url = $sids.'&amp;action=search&amp;tagging_id='.$tagging_id.'&amp;seite='.$next;
651
                $oLink = new PMF_Link(PMF_Link::getSystemRelativeUri().'?'.$url, $this->_config);
652
                $oLink->itemTitle = 'tag';
653
                $oLink->text = $this->pmf_lang['msgNext'];
654
                $oLink->tooltip = $this->pmf_lang['msgNext'];
655
                $output          .= '[ '.$oLink->toHtmlAnchor().' ]';
656
            }
657
            $output .= '</strong></p>';
658
        }
659
660
        return $output;
661
    }
662
663
    /**
664
     * Returns an array with all data from a FAQ record.
665
     *
666
     * @param int  $faqId         FAQ ID
667
     * @param int  $faqRevisionId Revision ID
668
     * @param bool $isAdmin       Must be true if it is called by an admin/author context
669
     */
670
    public function getRecord($faqId, $faqRevisionId = null, $isAdmin = false)
671
    {
672
        global $PMF_LANG;
673
674
        $currentLanguage = $this->_config->getLanguage()->getLanguage();
675
        $defaultLanguage = $this->_config->getDefaultLanguage();
676
677
        $result = $this->getRecordResult($faqId, $currentLanguage, $faqRevisionId, $isAdmin);
678
679
        if (0 === $this->_config->getDb()->numRows($result)) {
680
            $result = $this->getRecordResult($faqId, $defaultLanguage, $faqRevisionId, $isAdmin);
681
        }
682
683
        if ($row = $this->_config->getDb()->fetchObject($result)) {
684
            $question = nl2br($row->thema);
685
            $answer = $row->content;
686
            $active = ('yes' === $row->active);
687
            $expired = (date('YmdHis') > $row->date_end);
688
689
            if (!$isAdmin) {
690
                if (!$active) {
691
                    $answer = $this->pmf_lang['err_inactiveArticle'];
692
                }
693
                if ($expired) {
694
                    $answer = $this->pmf_lang['err_expiredArticle'];
695
                }
696
            }
697
698
            $this->faqRecord = [
699
                'id' => $row->id,
700
                'lang' => $row->lang,
701
                'solution_id' => $row->solution_id,
702
                'revision_id' => $row->revision_id,
703
                'active' => $row->active,
704
                'sticky' => $row->sticky,
705
                'keywords' => $row->keywords,
706
                'title' => $question,
707
                'content' => $answer,
708
                'author' => $row->author,
709
                'email' => $row->email,
710
                'comment' => $row->comment,
711
                'date' => PMF_Date::createIsoDate($row->updated),
712
                'dateStart' => $row->date_start,
713
                'dateEnd' => $row->date_end,
714
                'linkState' => $row->links_state,
715
                'linkCheckDate' => $row->links_check_date,
716
                'created' => $row->created,
717
            ];
718
        } else {
719
            $this->faqRecord = [
720
                'id' => $faqId,
721
                'lang' => $currentLanguage,
722
                'solution_id' => 42,
723
                'revision_id' => $faqRevisionId,
724
                'active' => 'no',
725
                'sticky' => 0,
726
                'keywords' => '',
727
                'title' => '',
728
                'content' => $PMF_LANG['msgAccessDenied'],
729
                'author' => '',
730
                'email' => '',
731
                'comment' => '',
732
                'date' => PMF_Date::createIsoDate(date('YmdHis')),
733
                'dateStart' => '',
734
                'dateEnd' => '',
735
                'linkState' => '',
736
                'linkCheckDate' => '',
737
                'created' => date('c'),
738
            ];
739
        }
740
    }
741
742
    /**
743
     * Executes a query to retrieve a single FAQ.
744
     *
745
     * @param int    $faqId
746
     * @param string $faqLanguage
747
     * @param int    $faqRevisionId
748
     * @param bool   $isAdmin
749
     *
750
     * @return mixed
751
     */
752
    public function getRecordResult($faqId, $faqLanguage, $faqRevisionId = null, $isAdmin = false)
753
    {
754
        $query = sprintf(
755
            "SELECT
756
                 id, lang, solution_id, revision_id, active, sticky, keywords,
757
                 thema, content, author, email, comment, updated, links_state,
758
                 links_check_date, date_start, date_end, created
759
            FROM
760
                %s%s fd
761
            LEFT JOIN
762
                %sfaqdata_group fdg
763
            ON
764
                fd.id = fdg.record_id
765
            LEFT JOIN
766
                %sfaqdata_user fdu
767
            ON
768
                fd.id = fdu.record_id
769
            WHERE
770
                fd.id = %d
771
            %s
772
            AND
773
                fd.lang = '%s'
774
                %s",
775
            PMF_Db::getTablePrefix(),
776
            isset($faqRevisionId) ? 'faqdata_revisions' : 'faqdata',
777
            PMF_Db::getTablePrefix(),
778
            PMF_Db::getTablePrefix(),
779
            $faqId,
780
            isset($faqRevisionId) ? 'AND revision_id = '.$faqRevisionId : '',
781
            $faqLanguage,
782
            ($isAdmin) ? 'AND 1=1' : $this->queryPermission($this->groupSupport)
783
        );
784
785
        return $this->_config->getDb()->query($query);
786
    }
787
788
    public function getRecordsByIds(Array $faqIds)
789
    {
790
        $faqRecords = [];
791
792
        $query = sprintf(
793
            "SELECT
794
                 fd.id AS id,
795
                 fd.lang AS lang,
796
                 fd.thema AS question,
797
                 fd.content AS answer,
798
                 fd.updated AS updated,
799
                 fd.created AS created,
800
                 fcr.category_id AS category_id,
801
                 fv.visits AS visits
802
            FROM
803
                %sfaqdata fd
804
            LEFT JOIN
805
                %sfaqcategoryrelations fcr
806
            ON
807
                fd.id = fcr.record_id
808
            AND
809
                fd.lang = fcr.record_lang
810
            LEFT JOIN
811
                %sfaqdata_group fdg
812
            ON
813
                fd.id = fdg.record_id
814
            LEFT JOIN
815
                %sfaqvisits AS fv
816
            ON
817
                fd.id = fv.id
818
            AND
819
                fv.lang = fd.lang
820
            LEFT JOIN
821
                %sfaqdata_user fdu
822
            ON
823
                fd.id = fdu.record_id
824
            WHERE
825
                fd.id IN (%s)
826
            AND
827
                fd.lang = '%s'
828
                %s",
829
            PMF_Db::getTablePrefix(),
830
            PMF_Db::getTablePrefix(),
831
            PMF_Db::getTablePrefix(),
832
            PMF_Db::getTablePrefix(),
833
            PMF_Db::getTablePrefix(),
834
            implode(',', $faqIds),
835
            $this->_config->getLanguage()->getLanguage(),
836
            $this->queryPermission($this->groupSupport)
837
        );
838
839
        $result = $this->_config->getDb()->query($query);
840
841
        $faqHelper = new PMF_Helper_Faq($this->_config);
842
        while ($row = $this->_config->getDb()->fetchObject($result)) {
843
            if (empty($row->visits)) {
844
                $visits = 0;
845
            } else {
846
                $visits = $row->visits;
847
            }
848
849
            $url = sprintf(
850
                '%sindex.php?action=artikel&cat=%d&id=%d&artlang=%s',
851
                $this->_config->getDefaultUrl(),
852
                $row->category_id,
853
                $row->id,
854
                $row->lang
855
            );
856
            $oLink = new PMF_Link($url, $this->_config);
857
            $oLink->itemTitle = $oLink->text = $oLink->tooltip = $row->question;
858
859
            $faqRecords[] = [
860
                'record_id' => (int)$row->id,
861
                'record_lang' => $row->lang,
862
                'category_id' => (int)$row->category_id,
863
                'record_title' => $row->question,
864
                'record_preview' => $faqHelper->renderAnswerPreview($row->answer, 25),
865
                'record_link' => $oLink->toString(),
866
                'record_updated' => PMF_Date::createIsoDate($row->updated).':00',
867
                'visits' => (int)$visits,
868
                'record_created' => $row->created
869
            ];
870
        }
871
872
        return $faqRecords;
873
    }
874
875
    /**
876
     * Adds a new record.
877
     *
878
     * @param array $data      Array of FAQ data
879
     * @param bool  $newRecord Do not create a new ID if false
880
     *
881
     * @return int
882
     */
883
    public function addRecord(Array $data, $newRecord = true)
884
    {
885
        if ($newRecord) {
886
            $recordId = $this->_config->getDb()->nextId(PMF_Db::getTablePrefix().'faqdata', 'id');
887
        } else {
888
            $recordId = $data['id'];
889
        }
890
891
        // Add new entry
892
        $query = sprintf(
893
            "INSERT INTO
894
                %sfaqdata
895
            VALUES
896
                (%d, '%s', %d, %d, '%s', %d, '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', %d, '%s', '%s', '%s')",
897
            PMF_Db::getTablePrefix(),
898
            $recordId,
899
            $data['lang'],
900
            $this->getSolutionId(),
901
            0,
902
            $data['active'],
903
            $data['sticky'],
904
            $this->_config->getDb()->escape($data['keywords']),
905
            $this->_config->getDb()->escape($data['thema']),
906
            $this->_config->getDb()->escape($data['content']),
907
            $this->_config->getDb()->escape($data['author']),
908
            $data['email'],
909
            $data['comment'],
910
            $data['date'],
911
            $data['linkState'],
912
            $data['linkDateCheck'],
913
            $data['dateStart'],
914
            $data['dateEnd'],
915
            date('Y-m-d H:i:s')
916
        );
917
918
        $this->_config->getDb()->query($query);
919
920
        return $recordId;
921
    }
922
923
    /**
924
     * Updates a record.
925
     *
926
     * @param array $data Array of FAQ data
927
     *
928
     * @return bool
929
     */
930
    public function updateRecord(Array $data)
931
    {
932
        // Update entry
933
        $query = sprintf("
934
            UPDATE
935
                %sfaqdata
936
            SET
937
                revision_id = %d,
938
                active = '%s',
939
                sticky = %d,
940
                keywords = '%s',
941
                thema = '%s',
942
                content = '%s',
943
                author = '%s',
944
                email = '%s',
945
                comment = '%s',
946
                updated = '%s',
947
                links_state = '%s',
948
                links_check_date = %d,
949
                date_start = '%s',
950
                date_end = '%s'
951
            WHERE
952
                id = %d
953
            AND
954
                lang = '%s'",
955
            PMF_Db::getTablePrefix(),
956
            $data['revision_id'],
957
            $data['active'],
958
            $data['sticky'],
959
            $this->_config->getDb()->escape($data['keywords']),
960
            $this->_config->getDb()->escape($data['thema']),
961
            $this->_config->getDb()->escape($data['content']),
962
            $this->_config->getDb()->escape($data['author']),
963
            $data['email'],
964
            $data['comment'],
965
            $data['date'],
966
            $data['linkState'],
967
            $data['linkDateCheck'],
968
            $data['dateStart'],
969
            $data['dateEnd'],
970
            $data['id'],
971
            $data['lang']);
972
973
        $this->_config->getDb()->query($query);
974
975
        return true;
976
    }
977
978
    /**
979
     * Deletes a record and all the dependencies.
980
     *
981
     * @param int    $recordId   Record id
982
     * @param string $recordLang Record language
983
     *
984
     * @return bool
985
     */
986
    public function deleteRecord($recordId, $recordLang)
987
    {
988
        $solutionId = $this->getSolutionIdFromId($recordId, $recordLang);
989
990
        $queries = array(
991
            sprintf(
992
                "DELETE FROM %sfaqchanges WHERE beitrag = %d AND lang = '%s'",
993
                PMF_Db::getTablePrefix(),
994
                $recordId,
995
                $recordLang
996
            ),
997
            sprintf(
998
                "DELETE FROM %sfaqcategoryrelations WHERE record_id = %d AND record_lang = '%s'",
999
                PMF_Db::getTablePrefix(),
1000
                $recordId,
1001
                $recordLang
1002
            ),
1003
            sprintf(
1004
                "DELETE FROM %sfaqdata WHERE id = %d AND lang = '%s'",
1005
                PMF_Db::getTablePrefix(),
1006
                $recordId,
1007
                $recordLang
1008
            ),
1009
            sprintf(
1010
                "DELETE FROM %sfaqdata_revisions WHERE id = %d AND lang = '%s'",
1011
                PMF_Db::getTablePrefix(),
1012
                $recordId,
1013
                $recordLang
1014
            ),
1015
            sprintf(
1016
                "DELETE FROM %sfaqvisits WHERE id = %d AND lang = '%s'",
1017
                PMF_Db::getTablePrefix(),
1018
                $recordId,
1019
                $recordLang
1020
            ),
1021
            sprintf(
1022
                'DELETE FROM %sfaqdata_user WHERE record_id = %d',
1023
                PMF_Db::getTablePrefix(),
1024
                $recordId,
1025
                $recordLang
1026
            ),
1027
            sprintf(
1028
                'DELETE FROM %sfaqdata_group WHERE record_id = %d',
1029
                PMF_Db::getTablePrefix(),
1030
                $recordId,
1031
                $recordLang
1032
            ),
1033
            sprintf(
1034
                'DELETE FROM %sfaqdata_tags WHERE record_id = %d',
1035
                PMF_Db::getTablePrefix(),
1036
                $recordId
1037
            ),
1038
            sprintf(
1039
                'DELETE FROM %sfaqdata_tags WHERE %sfaqdata_tags.record_id NOT IN (SELECT %sfaqdata.id FROM %sfaqdata)',
1040
                PMF_Db::getTablePrefix(),
1041
                PMF_Db::getTablePrefix(),
1042
                PMF_Db::getTablePrefix(),
1043
                PMF_Db::getTablePrefix()
1044
            ),
1045
            sprintf(
1046
                'DELETE FROM %sfaqcomments WHERE id = %d',
1047
                PMF_Db::getTablePrefix(),
1048
                $recordId
1049
            ),
1050
            sprintf(
1051
                'DELETE FROM %sfaqvoting WHERE artikel = %d',
1052
                PMF_Db::getTablePrefix(),
1053
                $recordId
1054
            ),
1055
        );
1056
1057
        foreach ($queries as $query) {
1058
            $this->_config->getDb()->query($query);
1059
        }
1060
1061
        // Delete possible attachments
1062
        $attId = PMF_Attachment_Factory::fetchByRecordId($this->_config, $recordId);
1063
        $attachment = PMF_Attachment_Factory::create($attId);
1064
        $attachment->delete();
1065
1066
        // Delete possible Elasticsearch documents
1067
        if ($this->_config->get('search.enableElasticsearch')) {
1068
            $esInstance = new PMF_Instance_Elasticsearch($this->_config);
1069
            $esInstance->delete($solutionId);
1070
        }
1071
1072
        return true;
1073
    }
1074
1075
    /**
1076
     * Checks if a record is already translated.
1077
     *
1078
     * @param int    $record_id   Record id
1079
     * @param string $record_lang Record language
1080
     *
1081
     * @return bool
1082
     */
1083
    public function isAlreadyTranslated($record_id, $record_lang)
1084
    {
1085
        $query = sprintf("
1086
            SELECT
1087
                id, lang
1088
            FROM
1089
                %sfaqdata
1090
            WHERE
1091
                id = %d
1092
            AND
1093
                lang = '%s'",
1094
            PMF_Db::getTablePrefix(),
1095
            $record_id,
1096
            $record_lang);
1097
1098
        $result = $this->_config->getDb()->query($query);
1099
1100
        if ($this->_config->getDb()->numRows($result)) {
1101
            return true;
1102
        }
1103
1104
        return false;
1105
    }
1106
1107
    /**
1108
     * Checks, if comments are disabled for the FAQ record.
1109
     *
1110
     * @param int    $record_id   Id of FAQ or news entry
1111
     * @param string $record_lang Language
1112
     * @param string $record_type Type of comment: faq or news
1113
     *
1114
     * @return bool true, if comments are disabled
1115
     */
1116
    public function commentDisabled($record_id, $record_lang, $record_type = 'faq')
1117
    {
1118
        if ('news' == $record_type) {
1119
            $table = 'faqnews';
1120
        } else {
1121
            $table = 'faqdata';
1122
        }
1123
1124
        $query = sprintf("
1125
            SELECT
1126
                comment
1127
            FROM
1128
                %s%s
1129
            WHERE
1130
                id = %d
1131
            AND
1132
                lang = '%s'",
1133
            PMF_Db::getTablePrefix(),
1134
            $table,
1135
            $record_id,
1136
            $record_lang);
1137
1138
        $result = $this->_config->getDb()->query($query);
1139
1140
        if ($row = $this->_config->getDb()->fetchObject($result)) {
1141
            return ($row->comment === 'y') ? false : true;
1142
        } else {
1143
            return true;
1144
        }
1145
    }
1146
1147
    /**
1148
     * Adds new category relations to a record.
1149
     *
1150
     * @param array  $categories Array of categories
1151
     * @param int    $record_id  Record id
1152
     * @param string $language   Language
1153
     *
1154
     * @return int
1155
     */
1156
    public function addCategoryRelations(Array $categories, $record_id, $language)
1157
    {
1158
        if (!is_array($categories)) {
1159
            return false;
1160
        }
1161
1162
        foreach ($categories as $_category) {
1163
            $this->_config->getDb()->query(sprintf(
1164
                "INSERT INTO
1165
                    %sfaqcategoryrelations
1166
                VALUES
1167
                    (%d, '%s', %d, '%s')",
1168
                PMF_Db::getTablePrefix(),
1169
                $_category,
1170
                $language,
1171
                $record_id,
1172
                $language));
1173
        }
1174
1175
        return true;
1176
    }
1177
1178
    /**
1179
     * Adds new category relation to a record.
1180
     *
1181
     * @param mixed  $category  Category or array of categories
1182
     * @param int    $record_id Record id
1183
     * @param string $language  Language
1184
     *
1185
     * @return bool
1186
     */
1187
    public function addCategoryRelation($category, $record_id, $language)
1188
    {
1189
        // Just a fallback when (wrong case) $category is an array
1190
        if (is_array($category)) {
1191
            $this->addCategoryRelations($category, $record_id, $language);
1192
        }
1193
        $categories[] = $category;
1194
1195
        return $this->addCategoryRelations($categories, $record_id, $language);
1196
    }
1197
1198
    /**
1199
     * Deletes category relations to a record.
1200
     *
1201
     * @param int    $record_id   Record id
1202
     * @param string $record_lang Language
1203
     *
1204
     * @return bool
1205
     */
1206
    public function deleteCategoryRelations($record_id, $record_lang)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in 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...
1207
    {
1208
        $query = sprintf("
1209
            DELETE FROM
1210
                %sfaqcategoryrelations
1211
            WHERE
1212
                record_id = %d
1213
            AND
1214
                record_lang = '%s'",
1215
            PMF_Db::getTablePrefix(),
1216
            $record_id,
1217
            $record_lang);
1218
        $this->_config->getDb()->query($query);
1219
1220
        return true;
1221
    }
1222
1223
    /**
1224
     * Returns an array with all data from a FAQ record.
1225
     *
1226
     * @param int $solutionId Solution ID
1227
     */
1228
    public function getRecordBySolutionId($solutionId)
1229
    {
1230
        $query = sprintf(
1231
            'SELECT
1232
                *
1233
            FROM
1234
                %sfaqdata fd
1235
            LEFT JOIN
1236
                %sfaqdata_group fdg
1237
            ON
1238
                fd.id = fdg.record_id
1239
            LEFT JOIN
1240
                %sfaqdata_user fdu
1241
            ON
1242
                fd.id = fdu.record_id
1243
            WHERE
1244
                fd.solution_id = %d
1245
                %s',
1246
            PMF_Db::getTablePrefix(),
1247
            PMF_Db::getTablePrefix(),
1248
            PMF_Db::getTablePrefix(),
1249
            $solutionId,
1250
            $this->queryPermission($this->groupSupport)
1251
        );
1252
1253
        $result = $this->_config->getDb()->query($query);
1254
1255
        if ($row = $this->_config->getDb()->fetchObject($result)) {
1256
            $question = nl2br($row->thema);
1257
            $content = $row->content;
1258
            $active = ('yes' == $row->active);
1259
            $expired = (date('YmdHis') > $row->date_end);
1260
1261
            if (!$active) {
1262
                $content = $this->pmf_lang['err_inactiveArticle'];
1263
            }
1264
            if ($expired) {
1265
                $content = $this->pmf_lang['err_expiredArticle'];
1266
            }
1267
1268
            $this->faqRecord = array(
1269
                'id' => $row->id,
1270
                'lang' => $row->lang,
1271
                'solution_id' => $row->solution_id,
1272
                'revision_id' => $row->revision_id,
1273
                'active' => $row->active,
1274
                'sticky' => $row->sticky,
1275
                'keywords' => $row->keywords,
1276
                'title' => $question,
1277
                'content' => $content,
1278
                'author' => $row->author,
1279
                'email' => $row->email,
1280
                'comment' => $row->comment,
1281
                'date' => PMF_Date::createIsoDate($row->updated),
1282
                'dateStart' => $row->date_start,
1283
                'dateEnd' => $row->date_end,
1284
                'linkState' => $row->links_state,
1285
                'linkCheckDate' => $row->links_check_date,
1286
            );
1287
        }
1288
    }
1289
1290
    /**
1291
     * Gets the record ID from a given solution ID.
1292
     *
1293
     * @param int $solutionId Solution ID
1294
     *
1295
     * @return array
1296
     */
1297
    public function getIdFromSolutionId($solutionId)
1298
    {
1299
        $query = sprintf('
1300
            SELECT
1301
                id, lang, content
1302
            FROM
1303
                %sfaqdata
1304
            WHERE
1305
                solution_id = %d',
1306
            PMF_Db::getTablePrefix(),
1307
            $solutionId
1308
        );
1309
1310
        $result = $this->_config->getDb()->query($query);
1311
1312
        if ($row = $this->_config->getDb()->fetchObject($result)) {
1313
            return [
1314
                'id' => $row->id,
1315
                'lang' => $row->lang,
1316
                'content' => $row->content
1317
            ];
1318
        }
1319
1320
        return [];
1321
    }
1322
1323
    /**
1324
     * Returns the solution ID from a given ID and language
1325
     *
1326
     * @param integer $faqId
1327
     * @param string $faqLang
1328
     *
1329
     * @return int
1330
     */
1331
    public function getSolutionIdFromId($faqId, $faqLang)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in 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...
1332
    {
1333
        $query = sprintf("
1334
            SELECT
1335
                solution_id
1336
            FROM
1337
                %sfaqdata
1338
            WHERE
1339
                id = %d
1340
                AND
1341
                lang = '%s'",
1342
            PMF_Db::getTablePrefix(),
1343
            (int) $faqId,
1344
            $this->_config->getDb()->escape($faqLang)
1345
        );
1346
1347
        $result = $this->_config->getDb()->query($query);
1348
1349
        if ($row = $this->_config->getDb()->fetchObject($result)) {
1350
            return $row->solution_id;
1351
        }
1352
1353
        return $this->getSolutionId();
1354
    }
1355
1356
    /**
1357
     * Gets the latest solution id for a FAQ record.
1358
     *
1359
     * @return int
1360
     */
1361
    public function getSolutionId()
1362
    {
1363
        $latestId = 0;
1364
1365
        $query = sprintf('
1366
            SELECT
1367
                MAX(solution_id) AS solution_id
1368
            FROM
1369
                %sfaqdata',
1370
            PMF_Db::getTablePrefix()
1371
        );
1372
1373
        $result = $this->_config->getDb()->query($query);
1374
1375
        if ($result && $row = $this->_config->getDb()->fetchObject($result)) {
1376
            $latestId = $row->solution_id;
1377
        }
1378
1379
        if ($latestId < PMF_SOLUTION_ID_START_VALUE) {
1380
            $nextSolutionId = PMF_SOLUTION_ID_START_VALUE;
1381
        } else {
1382
            $nextSolutionId = $latestId + PMF_SOLUTION_ID_INCREMENT_VALUE;
1383
        }
1384
1385
        return $nextSolutionId;
1386
    }
1387
1388
    /**
1389
     * Returns an array with all data from all FAQ records.
1390
     *
1391
     * @param int    $sortType  Sorting type
1392
     * @param array  $condition Condition
1393
     * @param string $sortOrder Sorting order
1394
     */
1395
    public function getAllRecords($sortType = FAQ_SORTING_TYPE_CATID_FAQID, Array $condition = null, $sortOrder = 'ASC')
1396
    {
1397
        $where = '';
1398
        if (!is_null($condition)) {
1399
            $num = count($condition);
1400
            $where = 'WHERE ';
1401
            foreach ($condition as $field => $data) {
1402
                --$num;
1403
                $where .= $field;
1404
                if (is_array($data)) {
1405
                    $where .= ' IN (';
1406
                    $separator = '';
1407
                    foreach ($data as $value) {
1408
                        $where .= $separator."'".$this->_config->getDb()->escape($value)."'";
1409
                        $separator = ', ';
1410
                    }
1411
                    $where .= ')';
1412
                } else {
1413
                    $where .= " = '".$this->_config->getDb()->escape($data)."'";
1414
                }
1415
                if ($num > 0) {
1416
                    $where .= ' AND ';
1417
                }
1418
            }
1419
        }
1420
1421
        switch ($sortType) {
1422
1423
            case FAQ_SORTING_TYPE_CATID_FAQID:
1424
                $orderBy = sprintf('
1425
            ORDER BY
1426
                fcr.category_id,
1427
                fd.id %s',
1428
                    $sortOrder);
1429
                break;
1430
1431
            case FAQ_SORTING_TYPE_FAQID:
1432
                $orderBy = sprintf('
1433
            ORDER BY
1434
                fd.id %s',
1435
                    $sortOrder);
1436
                break;
1437
1438
            case FAQ_SORTING_TYPE_FAQTITLE_FAQID:
1439
                $orderBy = sprintf('
1440
            ORDER BY
1441
                fcr.category_id,
1442
                fd.thema %s',
1443
                    $sortOrder);
1444
                break;
1445
1446
            case FAQ_SORTING_TYPE_DATE_FAQID:
1447
                $orderBy = sprintf('
1448
            ORDER BY
1449
                fcr.category_id,
1450
                fd.updated %s',
1451
                    $sortOrder);
1452
                break;
1453
1454
            default:
1455
                $orderBy = '';
1456
                break;
1457
        }
1458
1459
        $query = sprintf('
1460
            SELECT
1461
                fd.id AS id,
1462
                fd.lang AS lang,
1463
                fcr.category_id AS category_id,
1464
                fd.solution_id AS solution_id,
1465
                fd.revision_id AS revision_id,
1466
                fd.active AS active,
1467
                fd.sticky AS sticky,
1468
                fd.keywords AS keywords,
1469
                fd.thema AS thema,
1470
                fd.content AS content,
1471
                fd.author AS author,
1472
                fd.email AS email,
1473
                fd.comment AS comment,
1474
                fd.updated AS updated,
1475
                fd.links_state AS links_state,
1476
                fd.links_check_date AS links_check_date,
1477
                fd.date_start AS date_start,
1478
                fd.date_end AS date_end,
1479
                fd.sticky AS sticky,
1480
                fd.created AS created
1481
            FROM
1482
                %sfaqdata fd
1483
            LEFT JOIN
1484
                %sfaqcategoryrelations fcr
1485
            ON
1486
                fd.id = fcr.record_id
1487
            AND
1488
                fd.lang = fcr.record_lang
1489
            %s
1490
            %s',
1491
            PMF_Db::getTablePrefix(),
1492
            PMF_Db::getTablePrefix(),
1493
            $where,
1494
            $orderBy
1495
        );
1496
1497
        $result = $this->_config->getDb()->query($query);
1498
1499
        while ($row = $this->_config->getDb()->fetchObject($result)) {
1500
            $content = $row->content;
1501
            $active = ('yes' == $row->active);
1502
            $expired = (date('YmdHis') > $row->date_end);
1503
1504
            if (!$active) {
1505
                $content = $this->pmf_lang['err_inactiveArticle'];
1506
            }
1507
            if ($expired) {
1508
                $content = $this->pmf_lang['err_expiredArticle'];
1509
            }
1510
1511
            $this->faqRecords[] = [
1512
                'id' => $row->id,
1513
                'category_id' => $row->category_id,
1514
                'lang' => $row->lang,
1515
                'solution_id' => $row->solution_id,
1516
                'revision_id' => $row->revision_id,
1517
                'active' => $row->active,
1518
                'sticky' => $row->sticky,
1519
                'keywords' => $row->keywords,
1520
                'title' => $row->thema,
1521
                'content' => $content,
1522
                'author' => $row->author,
1523
                'email' => $row->email,
1524
                'comment' => $row->comment,
1525
                'updated' => PMF_Date::createIsoDate($row->updated, 'Y-m-d H:i:s'),
1526
                'dateStart' => $row->date_start,
1527
                'dateEnd' => $row->date_end,
1528
                'created' => $row->created,
1529
            ];
1530
        }
1531
    }
1532
1533
    /**
1534
     * Returns the FAQ record title from the ID and language.
1535
     *
1536
     * @param int $id Record id
1537
     *
1538
     * @return string
1539
     */
1540
    public function getRecordTitle($id)
1541
    {
1542
        if (isset($this->faqRecord['id']) && ($this->faqRecord['id'] == $id)) {
1543
            return $this->faqRecord['title'];
1544
        }
1545
1546
        $query = sprintf(
1547
            "SELECT
1548
                thema
1549
            FROM
1550
                %sfaqdata
1551
            WHERE
1552
                id = %d AND lang = '%s'",
1553
            PMF_Db::getTablePrefix(),
1554
            $id,
1555
            $this->_config->getLanguage()->getLanguage()
1556
            );
1557
        $result = $this->_config->getDb()->query($query);
1558
1559
        if ($this->_config->getDb()->numRows($result) > 0) {
1560
            while ($row = $this->_config->getDb()->fetchObject($result)) {
1561
                $output = $row->thema;
1562
            }
1563
        } else {
1564
            $output = $this->pmf_lang['no_cats'];
1565
        }
1566
1567
        return $output;
1568
    }
1569
1570
    /**
1571
     * Gets all revisions from a given record ID.
1572
     *
1573
     * @param int    $recordId   Record id
1574
     * @param string $recordLang Record language
1575
     *
1576
     * @return array
1577
     */
1578
    public function getRevisionIds($recordId, $recordLang)
1579
    {
1580
        $revisionData = [];
1581
1582
        $query = sprintf("
1583
            SELECT
1584
                revision_id, updated, author
1585
            FROM
1586
                %sfaqdata_revisions
1587
            WHERE
1588
                id = %d
1589
            AND
1590
                lang = '%s'
1591
            ORDER BY
1592
                revision_id",
1593
            PMF_Db::getTablePrefix(),
1594
            $recordId,
1595
            $recordLang
1596
        );
1597
1598
        $result = $this->_config->getDb()->query($query);
1599
1600
        if ($this->_config->getDb()->numRows($result) > 0) {
1601
            while ($row = $this->_config->getDb()->fetchObject($result)) {
1602
                $revisionData[] = [
1603
                    'revision_id' => $row->revision_id,
1604
                    'updated' => $row->updated,
1605
                    'author' => $row->author,
1606
                ];
1607
            }
1608
        }
1609
1610
        return $revisionData;
1611
    }
1612
1613
    /**
1614
     * Adds a new revision from a given record ID.
1615
     *
1616
     * @param int    $record_id   Record id
1617
     * @param string $record_lang Record language
1618
     *
1619
     * @return array
1620
     */
1621
    public function addNewRevision($record_id, $record_lang)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in 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...
1622
    {
1623
        $query = sprintf("
1624
            INSERT INTO
1625
                %sfaqdata_revisions
1626
            SELECT * FROM
1627
                %sfaqdata
1628
            WHERE
1629
                id = %d
1630
            AND
1631
                lang = '%s'",
1632
            PMF_Db::getTablePrefix(),
1633
            PMF_Db::getTablePrefix(),
1634
            $record_id,
1635
            $record_lang);
1636
        $this->_config->getDb()->query($query);
1637
1638
        return true;
1639
    }
1640
1641
    /**
1642
     * Returns the keywords of a FAQ record from the ID and language.
1643
     *
1644
     * @param int $id record id
1645
     *
1646
     * @return string
1647
     */
1648
    public function getRecordKeywords($id)
1649
    {
1650
        if (isset($this->faqRecord['id']) && ($this->faqRecord['id'] == $id)) {
1651
            return $this->faqRecord['keywords'];
1652
        }
1653
1654
        $query = sprintf(
1655
            "SELECT
1656
                keywords
1657
            FROM
1658
                %sfaqdata
1659
            WHERE id = %d AND lang = '%s'",
1660
            PMF_Db::getTablePrefix(),
1661
            $id,
1662
            $this->_config->getLanguage()->getLanguage());
1663
1664
        $result = $this->_config->getDb()->query($query);
1665
1666
        if ($this->_config->getDb()->numRows($result) > 0) {
1667
            $row = $this->_config->getDb()->fetchObject($result);
1668
1669
            return PMF_String::htmlspecialchars($row->keywords, ENT_QUOTES, 'utf-8');
1670
        } else {
1671
            return '';
1672
        }
1673
    }
1674
1675
    /**
1676
     * Returns a answer preview of the FAQ record.
1677
     *
1678
     * @param int $recordId  FAQ record ID
1679
     * @param int $wordCount Number of words, default: 12
1680
     *
1681
     * @return string
1682
     */
1683
    public function getRecordPreview($recordId, $wordCount = 12)
1684
    {
1685
        $answerPreview = '';
1686
1687
        if (isset($this->faqRecord['id']) && ($this->faqRecord['id'] == $recordId)) {
1688
            $answerPreview = $this->faqRecord['content'];
1689
        }
1690
1691
        $query = sprintf("
1692
            SELECT
1693
                content as answer
1694
            FROM
1695
                %sfaqdata
1696
            WHERE 
1697
                id = %d 
1698
            AND 
1699
                lang = '%s'",
1700
            PMF_Db::getTablePrefix(),
1701
            $recordId,
1702
            $this->_config->getLanguage()->getLanguage());
1703
1704
        $result = $this->_config->getDb()->query($query);
1705
1706
        if ($this->_config->getDb()->numRows($result) > 0) {
1707
            $row = $this->_config->getDb()->fetchObject($result);
1708
            $answerPreview = strip_tags($row->answer);
1709
        } else {
1710
            $answerPreview = $this->_config->get('main.metaDescription');
1711
        }
1712
1713
        return PMF_Utils::makeShorterText($answerPreview, $wordCount);
1714
    }
1715
1716
    /**
1717
     * Returns the number of activated and not expired records, optionally
1718
     * not limited to the current language.
1719
     *
1720
     * @param string $language Language
1721
     *
1722
     * @return int
1723
     */
1724
    public function getNumberOfRecords($language = null)
1725
    {
1726
        $now = date('YmdHis');
1727
1728
        $query = sprintf("
1729
            SELECT
1730
                id
1731
            FROM
1732
                %sfaqdata
1733
            WHERE
1734
                active = 'yes'
1735
            %s
1736
            AND
1737
                date_start <= '%s'
1738
            AND
1739
                date_end   >= '%s'",
1740
            PMF_Db::getTablePrefix(),
1741
            null == $language ? '' : "AND lang = '".$language."'",
1742
            $now,
1743
            $now);
1744
1745
        $num = $this->_config->getDb()->numRows($this->_config->getDb()->query($query));
1746
1747
        if ($num > 0) {
1748
            return $num;
1749
        } else {
1750
            return 0;
1751
        }
1752
    }
1753
1754
    /**
1755
     * This function generates a list with the most voted or most visited records.
1756
     *
1757
     * @param string $type Type definition visits/voted
1758
     *
1759
     * @since  2009-11-03
1760
     *
1761
     * @author Max Köhler <[email protected]>
1762
     *
1763
     * @return array
1764
     */
1765
    public function getTopTen($type = 'visits')
1766
    {
1767
        if ('visits' == $type) {
1768
            $result = $this->getTopTenData(PMF_NUMBER_RECORDS_TOPTEN, 0, $this->_config->getLanguage()->getLanguage());
1769
        } else {
1770
            $result = $this->getTopVotedData(PMF_NUMBER_RECORDS_TOPTEN, $this->_config->getLanguage()->getLanguage());
1771
        }
1772
        $output = [];
1773
1774
        if (count($result) > 0) {
1775
            foreach ($result as $row) {
1776
                if ('visits' == $type) {
1777
                    $output['title'][] = PMF_Utils::makeShorterText($row['question'], 8);
1778
                    $output['preview'][] = $row['question'];
1779
                    $output['url'][] = $row['url'];
1780
                    $output['visits'][] = $this->plr->GetMsg('plmsgViews', $row['visits']);
1781
                } else {
1782
                    $output['title'][] = PMF_Utils::makeShorterText($row['question'], 8);
1783
                    $output['preview'][] = $row['question'];
1784
                    $output['url'][] = $row['url'];
1785
                    $output['voted'][] = sprintf(
1786
                        '%s %s 5 - %s',
1787
                        round($row['avg'], 2),
1788
                        $this->pmf_lang['msgVoteFrom'],
1789
                        $this->plr->GetMsg('plmsgVotes', $row['user'])
1790
                    );
1791
                }
1792
            }
1793
        } else {
1794
            $output['error'] = $this->pmf_lang['err_noTopTen'];
1795
        }
1796
1797
        return $output;
1798
    }
1799
1800
    /**
1801
     * This function generates the list with the latest published records.
1802
     *
1803
     * @return array
1804
     */
1805
    public function getLatest()
1806
    {
1807
        $date = new PMF_Date($this->_config);
1808
        $result = $this->getLatestData(PMF_NUMBER_RECORDS_LATEST, $this->_config->getLanguage()->getLanguage());
1809
        $output = [];
1810
1811
        if (count($result) > 0) {
1812
            foreach ($result as $row) {
1813
                $output['url'][] = $row['url'];
1814
                $output['title'][] = PMF_Utils::makeShorterText($row['question'], 8);
1815
                $output['preview'][] = $row['question'];
1816
                $output['date'][] = $date->format(PMF_Date::createIsoDate($row['date']));
1817
            }
1818
        } else {
1819
            $output['error'] = $this->pmf_lang['err_noArticles'];
1820
        }
1821
1822
        return $output;
1823
    }
1824
1825
    /**
1826
     * Deletes a question for the table faqquestions.
1827
     *
1828
     * @param int $questionId
1829
     *
1830
     * @return bool
1831
     */
1832
    public function deleteQuestion($questionId)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in 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...
1833
    {
1834
        $delete = sprintf("
1835
            DELETE FROM
1836
                %sfaqquestions
1837
            WHERE
1838
                id = %d
1839
            AND
1840
                lang = '%s'",
1841
            PMF_Db::getTablePrefix(),
1842
            $questionId,
1843
            $this->_config->getLanguage()->getLanguage()
1844
        );
1845
1846
        $this->_config->getDb()->query($delete);
1847
1848
        return true;
1849
    }
1850
1851
     /**
1852
      * Returns the visibility of a question.
1853
      *
1854
      * @param   int $questionId
1855
      *
1856
      * @return  string
1857
      */
1858
     public function getVisibilityOfQuestion($questionId)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in 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...
1859
     {
1860
         $query = sprintf("
1861
            SELECT
1862
                is_visible
1863
            FROM
1864
                %sfaqquestions
1865
            WHERE
1866
                id = %d
1867
            AND
1868
                lang = '%s'",
1869
            PMF_Db::getTablePrefix(),
1870
            $questionId,
1871
            $this->_config->getLanguage()->getLanguage()
1872
        );
1873
1874
         $result = $this->_config->getDb()->query($query);
1875
         if ($this->_config->getDb()->numRows($result) > 0) {
1876
             $row = $this->_config->getDb()->fetchObject($result);
1877
1878
             return $row->is_visible;
1879
         }
1880
1881
         return;
1882
     }
1883
1884
    /**
1885
     * Sets the visibility of a question.
1886
     *
1887
     * @param int    $questionId
1888
     * @param string $isVisible
1889
     *
1890
     * @return bool
1891
     */
1892
    public function setVisibilityOfQuestion($questionId, $isVisible)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in 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...
1893
    {
1894
        $query = sprintf("
1895
            UPDATE
1896
                %sfaqquestions
1897
            SET
1898
                is_visible = '%s'
1899
            WHERE
1900
                id = %d
1901
            AND
1902
                lang = '%s'",
1903
            PMF_Db::getTablePrefix(),
1904
            $isVisible,
1905
            $questionId,
1906
            $this->_config->getLanguage()->getLanguage()
1907
        );
1908
1909
        $this->_config->getDb()->query($query);
1910
1911
        return true;
1912
    }
1913
1914
    /**
1915
     * This function generates a data-set with the most voted FAQs.
1916
     *  
1917
     * @param int    $count    Number of records
1918
     * @param string $language Language
1919
     *
1920
     * @return array
1921
     */
1922
    public function getTopVotedData($count = PMF_NUMBER_RECORDS_TOPTEN, $language = null)
1923
    {
1924
        global $sids;
1925
1926
        $topten = $data = [];
1927
1928
        $now = date('YmdHis');
1929
        $query =
1930
'            SELECT
1931
                fd.id AS id,
1932
                fd.lang AS lang,
1933
                fd.thema AS thema,
1934
                fd.updated AS updated,
1935
                fcr.category_id AS category_id,
1936
                (fv.vote/fv.usr) AS avg,
1937
                fv.usr AS user
1938
            FROM
1939
                '.PMF_Db::getTablePrefix().'faqvoting fv,
1940
                '.PMF_Db::getTablePrefix().'faqdata fd
1941
            LEFT JOIN
1942
                '.PMF_Db::getTablePrefix().'faqcategoryrelations fcr
1943
            ON
1944
                fd.id = fcr.record_id
1945
            AND
1946
                fd.lang = fcr.record_lang
1947
            LEFT JOIN
1948
                '.PMF_Db::getTablePrefix().'faqdata_group AS fdg
1949
            ON
1950
                fd.id = fdg.record_id
1951
            LEFT JOIN
1952
                '.PMF_Db::getTablePrefix().'faqdata_user AS fdu
1953
            ON
1954
                fd.id = fdu.record_id
1955
            WHERE
1956
                    fd.date_start <= \''.$now.'\'
1957
                AND fd.date_end   >= \''.$now.'\'
1958
                AND fd.id = fv.artikel
1959
                AND fd.active = \'yes\'';
1960
1961 View Code Duplication
        if (isset($categoryId) && is_numeric($categoryId) && ($categoryId != 0)) {
0 ignored issues
show
Bug introduced by
The variable $categoryId seems to never exist, and therefore isset should always return false. Did you maybe rename this variable?

This check looks for calls to isset(...) or empty() on variables that are yet undefined. These calls will always produce the same result and can be removed.

This is most likely caused by the renaming of a variable or the removal of a function/method parameter.

Loading history...
1962
            $query .= '
1963
            AND
1964
                fcr.category_id = \''.$categoryId.'\'';
1965
        }
1966
        if (isset($language) && PMF_Language::isASupportedLanguage($language)) {
1967
            $query .= '
1968
            AND
1969
                fd.lang = \''.$language.'\'';
1970
        }
1971
        $query .= '
1972
                '.$this->queryPermission($this->groupSupport).'
1973
            ORDER BY
1974
                avg DESC';
1975
1976
        $result = $this->_config->getDb()->query($query);
1977
1978
        $i = 1;
1979
        $oldId = 0;
1980
        while (($row = $this->_config->getDb()->fetchObject($result)) && $i <= $count) {
1981
            if ($oldId != $row->id) {
1982
                $data['avg'] = $row->avg;
1983
                $data['question'] = $row->thema;
1984
                $data['date'] = $row->updated;
1985
                $data['user'] = $row->user;
1986
1987
                $title = $row->thema;
1988
                $url = sprintf(
1989
                    '%s?%saction=artikel&amp;cat=%d&amp;id=%d&amp;artlang=%s',
1990
                    PMF_Link::getSystemRelativeUri(),
1991
                    $sids,
1992
                    $row->category_id,
1993
                    $row->id,
1994
                    $row->lang
1995
                );
1996
                $oLink = new PMF_Link($url, $this->_config);
1997
                $oLink->itemTitle = $row->thema;
1998
                $oLink->tooltip = $title;
1999
                $data['url'] = $oLink->toString();
2000
2001
                $topten[] = $data;
2002
                ++$i;
2003
            }
2004
            $oldId = $row->id;
2005
        }
2006
2007
        return $topten;
2008
    }
2009
2010
    /**
2011
     * This function generates the Top Ten data with the mosted viewed records.
2012
     *
2013
     * @param int    $count      Number of records
2014
     * @param int    $categoryId Category ID
2015
     * @param string $language   Language
2016
     *
2017
     * @return array
2018
     */
2019
    public function getTopTenData($count = PMF_NUMBER_RECORDS_TOPTEN, $categoryId = 0, $language = null)
2020
    {
2021
        global $sids;
2022
2023
        $now = date('YmdHis');
2024
        $query =
2025
'            SELECT
2026
                fd.id AS id,
2027
                fd.lang AS lang,
2028
                fd.thema AS thema,
2029
                fd.updated AS updated,
2030
                fcr.category_id AS category_id,
2031
                fv.visits AS visits,
2032
                fv.last_visit AS last_visit,
2033
                fdg.group_id AS group_id,
2034
                fdu.user_id AS user_id
2035
            FROM
2036
                '.PMF_Db::getTablePrefix().'faqvisits fv,
2037
                '.PMF_Db::getTablePrefix().'faqdata fd
2038
            LEFT JOIN
2039
                '.PMF_Db::getTablePrefix().'faqcategoryrelations fcr
2040
            ON
2041
                fd.id = fcr.record_id
2042
            AND
2043
                fd.lang = fcr.record_lang
2044
            LEFT JOIN
2045
                '.PMF_Db::getTablePrefix().'faqdata_group AS fdg
2046
            ON
2047
                fd.id = fdg.record_id
2048
            LEFT JOIN
2049
                '.PMF_Db::getTablePrefix().'faqdata_user AS fdu
2050
            ON
2051
                fd.id = fdu.record_id
2052
            WHERE
2053
                    fd.date_start <= \''.$now.'\'
2054
                AND fd.date_end   >= \''.$now.'\'
2055
                AND fd.id = fv.id
2056
                AND fd.lang = fv.lang
2057
                AND fd.active = \'yes\'';
2058
2059 View Code Duplication
        if (isset($categoryId) && is_numeric($categoryId) && ($categoryId != 0)) {
2060
            $query .= '
2061
            AND
2062
                fcr.category_id = \''.$categoryId.'\'';
2063
        }
2064
        if (isset($language) && PMF_Language::isASupportedLanguage($language)) {
2065
            $query .= '
2066
            AND
2067
                fd.lang = \''.$language.'\'';
2068
        }
2069
        $query .= '
2070
                '.$this->queryPermission($this->groupSupport).'
2071
2072
            GROUP BY
2073
                fd.id,fd.lang,fcr.category_id,fv.visits,fv.last_visit,fdg.group_id,fdu.user_id
2074
            ORDER BY
2075
                fv.visits DESC';
2076
2077
        $result = $this->_config->getDb()->query($query, 0, $count);
2078
        $topten = [];
2079
        $data = [];
2080
2081 View Code Duplication
        while ($row = $this->_config->getDb()->fetchObject($result)) {
0 ignored issues
show
Duplication introduced by
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...
2082
            if ($this->groupSupport) {
2083
                if (!in_array($row->user_id, array(-1, $this->user)) || !in_array($row->group_id, $this->groups)) {
2084
                    continue;
2085
                }
2086
            } else {
2087
                if (!in_array($row->user_id, array(-1, $this->user))) {
2088
                    continue;
2089
                }
2090
            }
2091
2092
            $data['visits'] = $row->visits;
2093
            $data['question'] = $row->thema;
2094
            $data['date'] = $row->updated;
2095
            $data['last_visit'] = $row->last_visit;
2096
2097
            $title = $row->thema;
2098
            $url = sprintf(
2099
                '%sindex.php?%saction=artikel&cat=%d&id=%d&artlang=%s',
2100
                $this->_config->getDefaultUrl(),
2101
                $sids,
2102
                $row->category_id,
2103
                $row->id,
2104
                $row->lang
2105
            );
2106
            $oLink = new PMF_Link($url, $this->_config);
2107
            $oLink->itemTitle = $row->thema;
2108
            $oLink->tooltip = $title;
2109
            $data['url'] = $oLink->toString();
2110
2111
            $topten[] = $data;
2112
        }
2113
2114
        return $topten;
2115
    }
2116
2117
    /**
2118
     * This function generates an array with a specified number of most recent
2119
     * published records.
2120
     *
2121
     * @param int    $count    Number of records
2122
     * @param string $language Language
2123
     *
2124
     * @return array
2125
     */
2126
    public function getLatestData($count = PMF_NUMBER_RECORDS_LATEST, $language = null)
2127
    {
2128
        global $sids;
2129
2130
        $now = date('YmdHis');
2131
        $query =
2132
'            SELECT
2133
                fd.id AS id,
2134
                fd.lang AS lang,
2135
                fcr.category_id AS category_id,
2136
                fd.thema AS thema,
2137
                fd.content AS content,
2138
                fd.updated AS updated,
2139
                fv.visits AS visits,
2140
                fdg.group_id AS group_id,
2141
                fdu.user_id AS user_id
2142
            FROM
2143
                '.PMF_Db::getTablePrefix().'faqvisits fv,
2144
                '.PMF_Db::getTablePrefix().'faqdata fd
2145
            LEFT JOIN
2146
                '.PMF_Db::getTablePrefix().'faqcategoryrelations fcr
2147
            ON
2148
                fd.id = fcr.record_id
2149
            AND
2150
                fd.lang = fcr.record_lang
2151
            LEFT JOIN
2152
                '.PMF_Db::getTablePrefix().'faqdata_group AS fdg
2153
            ON
2154
                fd.id = fdg.record_id
2155
            LEFT JOIN
2156
                '.PMF_Db::getTablePrefix().'faqdata_user AS fdu
2157
            ON
2158
                fd.id = fdu.record_id
2159
            WHERE
2160
                    fd.date_start <= \''.$now.'\'
2161
                AND fd.date_end   >= \''.$now.'\'
2162
                AND fd.id = fv.id
2163
                AND fd.lang = fv.lang
2164
                AND fd.active = \'yes\'';
2165
2166
        if (isset($language) && PMF_Language::isASupportedLanguage($language)) {
2167
            $query .= '
2168
            AND
2169
                fd.lang = \''.$language.'\'';
2170
        }
2171
        $query .= '
2172
                '.$this->queryPermission($this->groupSupport).'
2173
            GROUP BY
2174
                fd.id,fd.lang,fcr.category_id,fv.visits,fdg.group_id,fdu.user_id
2175
            ORDER BY
2176
                fd.updated DESC';
2177
2178
        $result = $this->_config->getDb()->query($query, 0, $count);
2179
        $latest = [];
2180
        $data = [];
2181
2182 View Code Duplication
        while (($row = $this->_config->getDb()->fetchObject($result))) {
0 ignored issues
show
Duplication introduced by
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...
2183
            if ($this->groupSupport) {
2184
                if (!in_array($row->user_id, array(-1, $this->user)) || !in_array($row->group_id, $this->groups)) {
2185
                    continue;
2186
                }
2187
            } else {
2188
                if (!in_array($row->user_id, array(-1, $this->user))) {
2189
                    continue;
2190
                }
2191
            }
2192
2193
            $data['date'] = $row->updated;
2194
            $data['question'] = $row->thema;
2195
            $data['answer'] = $row->content;
2196
            $data['visits'] = $row->visits;
2197
2198
            $title = $row->thema;
2199
            $url = sprintf(
2200
                '%sindex.php?%saction=artikel&cat=%d&id=%d&artlang=%s',
2201
                $this->_config->getDefaultUrl(),
2202
                $sids,
2203
                $row->category_id,
2204
                $row->id,
2205
                $row->lang
2206
            );
2207
            $oLink = new PMF_Link($url, $this->_config);
2208
            $oLink->itemTitle = $row->thema;
2209
            $oLink->tooltip = $title;
2210
            $data['url'] = $oLink->toString();
2211
2212
            $latest[] = $data;
2213
        }
2214
2215
        return $latest;
2216
    }
2217
2218
    /**
2219
     * Reload locking for user votings.
2220
     *
2221
     * @param int    $id FAQ record id
2222
     * @param string $ip IP
2223
     *
2224
     * @return bool
2225
     */
2226
    public function votingCheck($id, $ip)
2227
    {
2228
        $check = $_SERVER['REQUEST_TIME'] - 300;
2229
        $query = sprintf(
2230
            "SELECT
2231
                id
2232
            FROM
2233
                %sfaqvoting
2234
            WHERE
2235
                artikel = %d AND (ip = '%s' AND datum > '%s')",
2236
            PMF_Db::getTablePrefix(),
2237
            $id,
2238
            $ip,
2239
            $check);
2240
        if ($this->_config->getDb()->numRows($this->_config->getDb()->query($query))) {
2241
            return false;
2242
        }
2243
2244
        return true;
2245
    }
2246
2247
    /**
2248
     * Returns the number of users from the table faqvotings.
2249
     *
2250
     * @param int $record_id
2251
     *
2252
     * @return int
2253
     *
2254
     * @since   2006-06-18
2255
     *
2256
     * @author  Thorsten Rinne <[email protected]>
2257
     */
2258 View Code Duplication
    public function getNumberOfVotings($record_id)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in 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...
2259
    {
2260
        $query = sprintf(
2261
            'SELECT
2262
                usr
2263
            FROM
2264
                %sfaqvoting
2265
            WHERE
2266
                artikel = %d',
2267
            PMF_Db::getTablePrefix(),
2268
            $record_id);
2269
        if ($result = $this->_config->getDb()->query($query)) {
2270
            if ($row = $this->_config->getDb()->fetchObject($result)) {
2271
                return $row->usr;
2272
            }
2273
        }
2274
2275
        return 0;
2276
    }
2277
2278
    /**
2279
     * Adds a new voting record.
2280
     *
2281
     * @param array $votingData
2282
     *
2283
     * @return bool
2284
     *
2285
     * @since    2006-06-18
2286
     *
2287
     * @author   Thorsten Rinne <[email protected]>
2288
     */
2289
    public function addVoting($votingData)
2290
    {
2291
        if (!is_array($votingData)) {
2292
            return false;
2293
        }
2294
2295
        $query = sprintf(
2296
            "INSERT INTO
2297
                %sfaqvoting
2298
            VALUES
2299
                (%d, %d, %d, 1, %d, '%s')",
2300
            PMF_Db::getTablePrefix(),
2301
            $this->_config->getDb()->nextId(PMF_Db::getTablePrefix().'faqvoting', 'id'),
2302
            $votingData['record_id'],
2303
            $votingData['vote'],
2304
            $_SERVER['REQUEST_TIME'],
2305
            $votingData['user_ip']);
2306
        $this->_config->getDb()->query($query);
2307
2308
        return true;
2309
    }
2310
2311
    /**
2312
     * Adds a new question.
2313
     *
2314
     * @param array $questionData
2315
     *
2316
     * @return bool
2317
     */
2318
    public function addQuestion(Array $questionData)
2319
    {
2320
        $query = sprintf("
2321
            INSERT INTO
2322
                %sfaqquestions
2323
            VALUES
2324
                (%d, '%s', '%s', '%s', %d, '%s', '%s', '%s', %d)",
2325
            PMF_Db::getTablePrefix(),
2326
            $this->_config->getDb()->nextId(PMF_Db::getTablePrefix().'faqquestions', 'id'),
2327
            $this->_config->getLanguage()->getLanguage(),
2328
            $this->_config->getDb()->escape($questionData['username']),
2329
            $this->_config->getDb()->escape($questionData['email']),
2330
            $questionData['category_id'],
2331
            $this->_config->getDb()->escape($questionData['question']),
2332
            date('YmdHis'),
2333
            $questionData['is_visible'],
2334
            0
2335
        );
2336
        $this->_config->getDb()->query($query);
2337
2338
        return true;
2339
    }
2340
2341
    /**
2342
     * Returns a new question.
2343
     *
2344
     * @param int $questionId
2345
     *
2346
     * @return array
2347
     *
2348
     * @since    2006-11-11
2349
     *
2350
     * @author   Thorsten Rinne <[email protected]>
2351
     */
2352
    public function getQuestion($questionId)
2353
    {
2354
        $question = [
2355
            'id' => 0,
2356
            'lang' => '',
2357
            'username' => '',
2358
            'email' => '',
2359
            'category_id' => '',
2360
            'question' => '',
2361
            'created' => '',
2362
            'is_visible' => '',
2363
        ];
2364
2365
        if (!is_int($questionId)) {
2366
            return $question;
2367
        }
2368
2369
        $question = [];
2370
2371
        $query = sprintf("
2372
            SELECT
2373
                 id, lang, username, email, category_id, question, created, is_visible
2374
            FROM
2375
                %sfaqquestions
2376
            WHERE
2377
                id = %d
2378
            AND
2379
                lang = '%s'",
2380
            PMF_Db::getTablePrefix(),
2381
            $questionId,
2382
            $this->_config->getLanguage()->getLanguage()
2383
        );
2384
2385 View Code Duplication
        if ($result = $this->_config->getDb()->query($query)) {
2386
            if ($row = $this->_config->getDb()->fetchObject($result)) {
2387
                $question = array(
2388
                    'id' => $row->id,
2389
                    'lang' => $row->lang,
2390
                    'username' => $row->username,
2391
                    'email' => $row->email,
2392
                    'category_id' => $row->category_id,
2393
                    'question' => $row->question,
2394
                    'created' => $row->created,
2395
                    'is_visible' => $row->is_visible, );
2396
            }
2397
        }
2398
2399
        return $question;
2400
    }
2401
2402
     /**
2403
      * Returns all open questions.
2404
      *
2405
      * @param  $all boolean If true, then return visible and unvisble questions; otherwise only visible ones
2406
      *
2407
      * @return array
2408
      */
2409
     public function getAllOpenQuestions($all = true)
2410
     {
2411
         $questions = [];
2412
2413
         $query = sprintf("
2414
            SELECT
2415
                id, lang, username, email, category_id, question, created, answer_id, is_visible
2416
            FROM
2417
                %sfaqquestions
2418
            WHERE
2419
                lang = '%s'
2420
                %s
2421
            ORDER BY 
2422
                created ASC",
2423
            PMF_Db::getTablePrefix(),
2424
            $this->_config->getLanguage()->getLanguage(),
2425
            ($all == false ? " AND is_visible = 'Y'" : '')
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...
2426
        );
2427
2428 View Code Duplication
         if ($result = $this->_config->getDb()->query($query)) {
2429
             while ($row = $this->_config->getDb()->fetchObject($result)) {
2430
                 $questions[] = array(
2431
                    'id' => $row->id,
2432
                    'lang' => $row->lang,
2433
                    'username' => $row->username,
2434
                    'email' => $row->email,
2435
                    'category_id' => $row->category_id,
2436
                    'question' => $row->question,
2437
                    'created' => $row->created,
2438
                    'answer_id' => $row->answer_id,
2439
                    'is_visible' => $row->is_visible,
2440
                );
2441
             }
2442
         }
2443
2444
         return $questions;
2445
     }
2446
2447
    /**
2448
     * Updates an existing voting record.
2449
     *
2450
     * @param array $votingData
2451
     *
2452
     * @return bool
2453
     *
2454
     * @since    2006-06-18
2455
     *
2456
     * @author   Thorsten Rinne <[email protected]>
2457
     */
2458
    public function updateVoting($votingData)
2459
    {
2460
        if (!is_array($votingData)) {
2461
            return false;
2462
        }
2463
2464
        $query = sprintf(
2465
            "UPDATE
2466
                %sfaqvoting
2467
            SET
2468
                vote    = vote + %d,
2469
                usr     = usr + 1,
2470
                datum   = %d,
2471
                ip      = '%s'
2472
            WHERE
2473
                artikel = %d",
2474
            PMF_Db::getTablePrefix(),
2475
            $votingData['vote'],
2476
            $_SERVER['REQUEST_TIME'],
2477
            $votingData['user_ip'],
2478
            $votingData['record_id']);
2479
        $this->_config->getDb()->query($query);
2480
2481
        return true;
2482
    }
2483
2484
    /**
2485
     * Adds a new changelog entry in the table faqchanges.
2486
     *
2487
     * @param int    $id
2488
     * @param int    $userId
2489
     * @param string $text
2490
     * @param string $lang
2491
     * @param int    $revision_id
2492
     *
2493
     * @return bool
2494
     *
2495
     * @since   2006-08-18
2496
     *
2497
     * @author  Thorsten Rinne <[email protected]>
2498
     * @author  Matteo Scaramuccia <[email protected]>
2499
     */
2500
    public function createChangeEntry($id, $userId, $text, $lang, $revision_id = 0)
2501
    {
2502
        if (!is_numeric($id)
2503
            && !is_numeric($userId)
2504
            && !is_string($text)
2505
            && !is_string($lang)
2506
            ) {
2507
            return false;
2508
        }
2509
2510
        $query = sprintf(
2511
            "INSERT INTO
2512
                %sfaqchanges
2513
            (id, beitrag, lang, revision_id, usr, datum, what)
2514
                VALUES
2515
            (%d, %d, '%s', %d, %d, %d, '%s')",
2516
            PMF_Db::getTablePrefix(),
2517
            $this->_config->getDb()->nextId(PMF_Db::getTablePrefix().'faqchanges', 'id'),
2518
            $id,
2519
            $lang,
2520
            $revision_id,
2521
            $userId,
2522
            $_SERVER['REQUEST_TIME'],
2523
            $text);
2524
2525
        $this->_config->getDb()->query($query);
2526
2527
        return true;
2528
    }
2529
2530
    /**
2531
     * Returns the changelog of a FAQ record.
2532
     *
2533
     * @param int $record_id
2534
     *
2535
     * @return array
2536
     *
2537
     * @since   2007-03-03
2538
     *
2539
     * @author  Thorsten Rinne <[email protected]>
2540
     */
2541 View Code Duplication
    public function getChangeEntries($record_id)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in 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...
2542
    {
2543
        $entries = [];
2544
2545
        $query = sprintf('
2546
            SELECT
2547
                DISTINCT revision_id, usr, datum, what
2548
            FROM
2549
                %sfaqchanges
2550
            WHERE
2551
                beitrag = %d
2552
            ORDER BY id DESC',
2553
            PMF_Db::getTablePrefix(),
2554
            $record_id
2555
            );
2556
2557
        if ($result = $this->_config->getDb()->query($query)) {
2558
            while ($row = $this->_config->getDb()->fetchObject($result)) {
2559
                $entries[] = array(
2560
                    'revision_id' => $row->revision_id,
2561
                    'user' => $row->usr,
2562
                    'date' => $row->datum,
2563
                    'changelog' => $row->what, );
2564
            }
2565
        }
2566
2567
        return $entries;
2568
    }
2569
2570
    /**
2571
     * Retrieve faq records according to the constraints provided.
2572
     *
2573
     * @param string $QueryType
2574
     * @param int    $nCatid
2575
     * @param bool   $bDownwards
2576
     * @param string $lang
2577
     * @param string $date
2578
     *
2579
     * @return array
2580
     */
2581
    public function get($QueryType = FAQ_QUERY_TYPE_DEFAULT, $nCatid = 0, $bDownwards = true, $lang = '', $date = '')
2582
    {
2583
        $faqs = [];
2584
2585
        $result = $this->_config->getDb()->query($this->_getSQLQuery($QueryType, $nCatid, $bDownwards, $lang, $date));
2586
2587
        if ($this->_config->getDb()->numRows($result) > 0) {
2588
            $i = 0;
2589
            while ($row = $this->_config->getDb()->fetchObject($result)) {
2590
                $faq = [];
2591
                $faq['id'] = $row->id;
2592
                $faq['solution_id'] = $row->solution_id;
2593
                $faq['revision_id'] = $row->revision_id;
2594
                $faq['lang'] = $row->lang;
2595
                $faq['category_id'] = $row->category_id;
2596
                $faq['active'] = $row->active;
2597
                $faq['sticky'] = $row->sticky;
2598
                $faq['keywords'] = $row->keywords;
2599
                $faq['topic'] = $row->thema;
2600
                $faq['content'] = $row->content;
2601
                $faq['author_name'] = $row->author;
2602
                $faq['author_email'] = $row->email;
2603
                $faq['comment_enable'] = $row->comment;
2604
                $faq['lastmodified'] = $row->updated;
2605
                $faq['hits'] = $row->visits;
2606
                $faq['hits_last'] = $row->last_visit;
2607
                $faqs[$i] = $faq;
2608
                ++$i;
2609
            }
2610
        }
2611
2612
        return $faqs;
2613
    }
2614
2615
    /**
2616
     * Build a logic sequence, for a WHERE statement, of those category IDs
2617
     * children of the provided category ID, if any.
2618
     *
2619
     * @param   $nCatid
2620
     * @param   $logicOp
2621
     * @param   $oCat
2622
     *
2623
     * @return string
2624
     *
2625
     * @since   2005-11-02
2626
     *
2627
     * @author  Matteo Scaramuccia <[email protected]>
2628
     */
2629
    public function _getCatidWhereSequence($nCatid, $logicOp = 'OR', $oCat = null)
2630
    {
2631
        $sqlWherefilter = '';
2632
2633
        if (!isset($oCat)) {
2634
            $oCat = new PMF_Category($this->_config);
2635
        }
2636
        $aChildren = array_values($oCat->getChildren($nCatid));
2637
2638
        foreach ($aChildren as $catid) {
2639
            $sqlWherefilter .= ' '.$logicOp.' fcr.category_id = '.$catid;
2640
            $sqlWherefilter .= $this->_getCatidWhereSequence($catid, 'OR', $oCat);
2641
        }
2642
2643
        return $sqlWherefilter;
2644
    }
2645
2646
    /**
2647
     * Build the SQL query for retrieving faq records according to the constraints provided.
2648
     *
2649
     * @param   $QueryType
2650
     * @param   $nCatid
2651
     * @param   $bDownwards
2652
     * @param   $lang
2653
     * @param   $date
2654
     * @param   $faqid
2655
     *
2656
     * @return array
2657
     *
2658
     * @since   2005-11-02
2659
     *
2660
     * @author  Matteo Scaramuccia <[email protected]>
2661
     */
2662
    private function _getSQLQuery($QueryType, $nCatid, $bDownwards, $lang, $date, $faqid = 0)
2663
    {
2664
        $now = date('YmdHis');
2665
        $query = sprintf("
2666
            SELECT
2667
                fd.id AS id,
2668
                fd.solution_id AS solution_id,
2669
                fd.revision_id AS revision_id,
2670
                fd.lang AS lang,
2671
                fcr.category_id AS category_id,
2672
                fd.active AS active,
2673
                fd.sticky AS sticky,
2674
                fd.keywords AS keywords,
2675
                fd.thema AS thema,
2676
                fd.content AS content,
2677
                fd.author AS author,
2678
                fd.email AS email,
2679
                fd.comment AS comment,
2680
                fd.updated AS updated,
2681
                fv.visits AS visits,
2682
                fv.last_visit AS last_visit
2683
            FROM
2684
                %sfaqdata fd,
2685
                %sfaqvisits fv,
2686
                %sfaqcategoryrelations fcr
2687
            WHERE
2688
                fd.id = fcr.record_id
2689
            AND
2690
                fd.lang = fcr.record_lang
2691
            AND
2692
                fd.date_start <= '%s'
2693
            AND
2694
                fd.date_end   >= '%s'
2695
            AND ",
2696
            PMF_Db::getTablePrefix(),
2697
            PMF_Db::getTablePrefix(),
2698
            PMF_Db::getTablePrefix(),
2699
            $now,
2700
            $now);
2701
        // faqvisits data selection
2702
        if (!empty($faqid)) {
2703
            // Select ONLY the faq with the provided $faqid
2704
            $query .= "fd.id = '".$faqid."' AND ";
2705
        }
2706
        $query .= 'fd.id = fv.id
2707
            AND
2708
                fd.lang = fv.lang';
2709
        $needAndOp = true;
2710
        if ((!empty($nCatid)) && is_int($nCatid) && $nCatid > 0) {
2711
            if ($needAndOp) {
2712
                $query .= ' AND';
2713
            }
2714
            $query .= ' (fcr.category_id = '.$nCatid;
2715
            if ($bDownwards) {
2716
                $query .= $this->_getCatidWhereSequence($nCatid, 'OR');
2717
            }
2718
            $query .= ')';
2719
            $needAndOp = true;
2720
        }
2721 View Code Duplication
        if ((!empty($date)) && PMF_Utils::isLikeOnPMFDate($date)) {
2722
            if ($needAndOp) {
2723
                $query .= ' AND';
2724
            }
2725
            $query .= " fd.updated LIKE '".$date."'";
2726
            $needAndOp = true;
2727
        }
2728 View Code Duplication
        if ((!empty($lang)) && PMF_Utils::isLanguage($lang)) {
2729
            if ($needAndOp) {
2730
                $query .= ' AND';
2731
            }
2732
            $query .= " fd.lang = '".$lang."'";
2733
            $needAndOp = true;
2734
        }
2735
        switch ($QueryType) {
2736
            case FAQ_QUERY_TYPE_APPROVAL:
2737
                if ($needAndOp) {
2738
                    $query .= ' AND';
2739
                }
2740
                $query .= " fd.active = '".FAQ_SQL_ACTIVE_NO."'";
2741
                $needAndOp = true;
2742
                break;
2743
            case FAQ_QUERY_TYPE_EXPORT_PDF:
2744
            case FAQ_QUERY_TYPE_EXPORT_XHTML:
2745 View Code Duplication
            case FAQ_QUERY_TYPE_EXPORT_XML:
2746
                if ($needAndOp) {
2747
                    $query .= ' AND';
2748
                }
2749
                $query .= " fd.active = '".FAQ_SQL_ACTIVE_YES."'";
2750
                $needAndOp = true;
2751
                break;
2752 View Code Duplication
            default:
2753
                if ($needAndOp) {
2754
                    $query .= ' AND';
2755
                }
2756
                $query .= " fd.active = '".FAQ_SQL_ACTIVE_YES."'";
2757
                $needAndOp = true;
2758
                break;
2759
        }
2760
        // Sort criteria
2761
        switch ($QueryType) {
2762
            case FAQ_QUERY_TYPE_EXPORT_PDF:
2763
            case FAQ_QUERY_TYPE_EXPORT_XHTML:
2764
            case FAQ_QUERY_TYPE_EXPORT_XML:
2765
                $query .= "\nORDER BY fcr.category_id, fd.id";
2766
                break;
2767
            case FAQ_QUERY_TYPE_RSS_LATEST:
2768
                $query .= "\nORDER BY fd.updated DESC";
2769
                break;
2770
            default:
2771
                // Normal ordering
2772
                $query .= "\nORDER BY fcr.category_id, fd.id";
2773
                break;
2774
        }
2775
2776
        return $query;
2777
    }
2778
2779
    /**
2780
     * Adds the record permissions for users and groups.
2781
     *
2782
     * @param string $mode     'group' or 'user'
2783
     * @param int    $recordId ID of the current record
2784
     * @param array  $ids      Array of group or user IDs
2785
     *
2786
     * @return bool
2787
     */
2788
    public function addPermission($mode, $recordId, $ids)
2789
    {
2790
        if ('user' !== $mode && 'group' !== $mode) {
2791
            return false;
2792
        }
2793
2794
        foreach ($ids as $id) {
2795
            $query = sprintf('
2796
            INSERT INTO
2797
                %sfaqdata_%s
2798
            (record_id, %s_id)
2799
                VALUES
2800
            (%d, %d)',
2801
                PMF_Db::getTablePrefix(),
2802
                $mode,
2803
                $mode,
2804
                $recordId,
2805
                $id
2806
            );
2807
2808
            $this->_config->getDb()->query($query);
2809
        }
2810
2811
        return true;
2812
    }
2813
2814
    /**
2815
     * Deletes the record permissions for users and groups.
2816
     *
2817
     * @param string $mode      'group' or 'user'
2818
     * @param int    $record_id ID of the current record
2819
     *
2820
     * @return bool
2821
     *
2822
     * @author  Thorsten Rinne <[email protected]>
2823
     */
2824 View Code Duplication
    public function deletePermission($mode, $record_id)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in 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...
2825
    {
2826
        if (!($mode == 'user' || $mode == 'group')) {
2827
            return false;
2828
        }
2829
        if (!is_int($record_id)) {
2830
            return false;
2831
        }
2832
2833
        $query = sprintf('
2834
            DELETE FROM
2835
                %sfaqdata_%s
2836
            WHERE
2837
                record_id = %d',
2838
            PMF_Db::getTablePrefix(),
2839
            $mode,
2840
            $record_id);
2841
        $this->_config->getDb()->query($query);
2842
2843
        return true;
2844
    }
2845
2846
    /**
2847
     * Returns the record permissions for users and groups.
2848
     *
2849
     * @param string $mode     'group' or 'user'
2850
     * @param int    $recordId
2851
     *
2852
     * @return array
2853
     *
2854
     * @author  Thorsten Rinne <[email protected]>
2855
     */
2856
    public function getPermission($mode, $recordId)
2857
    {
2858
        $permissions = [];
2859
2860
        if (!($mode == 'user' || $mode == 'group')) {
2861
            return false;
2862
        }
2863
2864
        $query = sprintf('
2865
            SELECT
2866
                %s_id AS permission
2867
            FROM
2868
                %sfaqdata_%s
2869
            WHERE
2870
                record_id = %d',
2871
            $mode,
2872
            PMF_Db::getTablePrefix(),
2873
            $mode,
2874
            (int) $recordId);
2875
2876
        $result = $this->_config->getDb()->query($query);
2877
2878
        if ($this->_config->getDb()->numRows($result) > 0) {
2879
            while (($row = $this->_config->getDb()->fetchObject($result))) {
2880
                $permissions[] = (int) $row->permission;
2881
            }
2882
        }
2883
2884
        return $permissions;
2885
    }
2886
2887
    /**
2888
     * Returns all records of one category.
2889
     *
2890
     * @param int $category
2891
     *
2892
     * @return string
2893
     *
2894
     * @since   2007-04-04
2895
     *
2896
     * @author  Georgi Korchev <[email protected]>
2897
     */
2898
    public function showAllRecordsWoPaging($category)
2899
    {
2900
        global $sids;
2901
2902
        $now = date('YmdHis');
2903
        $query = '
2904
            SELECT
2905
                fd.id AS id,
2906
                fd.lang AS lang,
2907
                fd.thema AS thema,
2908
                fcr.category_id AS category_id,
2909
                fv.visits AS visits
2910
            FROM
2911
                '.PMF_Db::getTablePrefix().'faqdata fd
2912
            LEFT JOIN
2913
                '.PMF_Db::getTablePrefix().'faqcategoryrelations fcr
2914
            ON
2915
                fd.id = fcr.record_id
2916
            AND
2917
                fd.lang = fcr.record_lang
2918
            LEFT JOIN
2919
                '.PMF_Db::getTablePrefix().'faqvisits fv
2920
            ON
2921
                fd.id = fv.id
2922
            AND
2923
                fv.lang = fd.lang
2924
            LEFT JOIN
2925
                '.PMF_Db::getTablePrefix().'faqdata_group fdg
2926
            ON
2927
                fd.id = fdg.record_id
2928
            LEFT JOIN
2929
                '.PMF_Db::getTablePrefix().'faqdata_user fdu
2930
            ON
2931
                fd.id = fdu.record_id
2932
            WHERE
2933
                fd.date_start <= \''.$now.'\'
2934
            AND
2935
                fd.date_end   >= \''.$now.'\'
2936
            AND
2937
                fd.active = \'yes\'
2938
            AND
2939
                fcr.category_id = '.$category.'
2940
            AND
2941
                fd.lang = \''.$this->_config->getLanguage()->getLanguage().'\'
2942
            GROUP BY
2943
                fd.id,fd.lang,fcr.category_id,fv.visits
2944
            ORDER BY
2945
                fd.id';
2946
2947
        $result = $this->_config->getDb()->query($query);
2948
2949
        $output = '<ul class="phpmyfaq_ul">';
2950
2951
        while (($row = $this->_config->getDb()->fetchObject($result))) {
2952
            $title = $row->thema;
2953
            $url = sprintf(
2954
                '%s?%saction=artikel&amp;cat=%d&amp;id=%d&amp;artlang=%s',
2955
                PMF_Link::getSystemRelativeUri(),
2956
                $sids,
2957
                $row->category_id,
2958
                $row->id,
2959
                $row->lang
2960
            );
2961
2962
            $oLink = new PMF_Link($url, $this->_config);
2963
            $oLink->itemTitle = $row->thema;
2964
            $oLink->text = $title;
2965
            $oLink->tooltip = $title;
2966
            $listItem = sprintf('<li>%s</li>', $oLink->toHtmlAnchor(), $this->pmf_lang['msgViews']);
2967
            $listItem = '<li>'.$oLink->toHtmlAnchor().'</li>';
2968
2969
            $output .= $listItem;
2970
        }
2971
2972
        $output .= '</ul>';
2973
2974
        return $output;
2975
    }
2976
2977
    /**
2978
     * Prints the open questions as a XHTML table.
2979
     *
2980
     * @return string
2981
     *
2982
     * @since   2002-09-17
2983
     *
2984
     * @author  Thorsten Rinne <[email protected]>
2985
     */
2986
    public function printOpenQuestions()
2987
    {
2988
        global $sids, $category;
2989
2990
        $date = new PMF_Date($this->_config);
2991
        $mail = new PMF_Mail($this->_config);
2992
2993
        $query = sprintf("
2994
            SELECT
2995
                COUNT(id) AS num
2996
            FROM
2997
                %sfaqquestions
2998
            WHERE
2999
                lang = '%s'
3000
            AND
3001
                is_visible != 'Y'",
3002
            PMF_Db::getTablePrefix(),
3003
            $this->_config->getLanguage()->getLanguage()
3004
        );
3005
3006
        $result = $this->_config->getDb()->query($query);
3007
        $row = $this->_config->getDb()->fetchObject($result);
3008
        $numOfInvisibles = $row->num;
3009
3010
        if ($numOfInvisibles > 0) {
3011
            $extraout = sprintf(
3012
                '<tr><td colspan="3"><small>%s %s</small></td></tr>',
3013
                $this->pmf_lang['msgQuestionsWaiting'],
3014
                $numOfInvisibles
3015
            );
3016
        } else {
3017
            $extraout = '';
3018
        }
3019
3020
        $query = sprintf("
3021
            SELECT
3022
                *
3023
            FROM
3024
                %sfaqquestions
3025
            WHERE
3026
                lang = '%s'
3027
            AND
3028
                is_visible = 'Y'
3029
            ORDER BY
3030
                created ASC",
3031
            PMF_Db::getTablePrefix(),
3032
            $this->_config->getLanguage()->getLanguage()
3033
        );
3034
3035
        $result = $this->_config->getDb()->query($query);
3036
        $output = '';
3037
3038
        if ($result && $this->_config->getDb()->numRows($result) > 0) {
3039
            while ($row = $this->_config->getDb()->fetchObject($result)) {
3040
                $output .= '<tr class="openquestions">';
3041
                $output .= sprintf(
3042
                    '<td><small>%s</small><br /><a href="mailto:%s">%s</a></td>',
3043
                    $date->format(PMF_Date::createIsoDate($row->created)),
3044
                    $mail->safeEmail($row->email),
3045
                    $row->username
3046
                );
3047
                $output .= sprintf(
3048
                    '<td><strong>%s:</strong><br />%s</td>',
3049
                    isset($category->categoryName[$row->category_id]['name']) ? $category->categoryName[$row->category_id]['name'] : '',
3050
                    strip_tags($row->question)
3051
                );
3052
                if ($this->_config->get('records.enableCloseQuestion') && $row->answer_id) {
3053
                    $output .= sprintf(
3054
                        '<td><a id="PMF_openQuestionAnswered" href="?%saction=artikel&amp;cat=%d&amp;id=%d">%s</a></td>',
3055
                        $sids,
3056
                        $row->category_id,
3057
                        $row->answer_id,
3058
                        $this->pmf_lang['msg2answerFAQ']
3059
                    );
3060
                } else {
3061
                    $output .= sprintf(
3062
                        '<td><a class="btn btn-primary" href="?%saction=add&amp;question=%d&amp;cat=%d">%s</a></td>',
3063
                        $sids,
3064
                        $row->id,
3065
                        $row->category_id,
3066
                        $this->pmf_lang['msg2answer']
3067
                    );
3068
                }
3069
                $output .= '</tr>';
3070
            }
3071
        } else {
3072
            $output = sprintf(
3073
                '<tr><td colspan="3">%s</td></tr>',
3074
                $this->pmf_lang['msgNoQuestionsAvailable']
3075
            );
3076
        }
3077
3078
        return $output.$extraout;
3079
    }
3080
3081
    /**
3082
     * Set or unset a faq item flag.
3083
     *
3084
     * @param int    $id   Record id
3085
     * @param string $lang language code which is valid with Language::isASupportedLanguage
3086
     * @param bool   $flag weither or not the record is set to sticky
3087
     * @param string $type type of the flag to set, use the column name
3088
     *
3089
     * @return bool
3090
     */
3091
    public function updateRecordFlag($id, $lang, $flag, $type)
3092
    {
3093
        $retval = false;
3094
3095
        switch ($type) {
3096
            case 'sticky':
3097
                $flag = ($flag === 'checked' ? 1 : 0);
3098
                break;
3099
3100
            case 'active':
3101
                $flag = ($flag === 'checked' ? "'yes'" : "'no'");
3102
                break;
3103
3104
            default:
3105
                // This is because we would run into unknown db column
3106
                $flag = null;
3107
                break;
3108
        }
3109
3110
        if (null !== $flag) {
3111
            $update = sprintf("
3112
                UPDATE 
3113
                    %sfaqdata 
3114
                SET 
3115
                    %s = %s 
3116
                WHERE 
3117
                    id = %d 
3118
                AND 
3119
                    lang = '%s'",
3120
                PMF_Db::getTablePrefix(),
3121
                $type,
3122
                $flag,
3123
                $id,
3124
                $lang
3125
            );
3126
3127
            $retval = (bool) $this->_config->getDb()->query($update);
3128
        }
3129
3130
        return $retval;
3131
    }
3132
3133
    /**
3134
     * Returns the sticky records with URL and Title.
3135
     *
3136
     * @return array
3137
     */
3138
    private function getStickyRecordsData()
3139
    {
3140
        global $sids;
3141
3142
        $now = date('YmdHis');
3143
        $query = sprintf("
3144
            SELECT
3145
                fd.id AS id,
3146
                fd.lang AS lang,
3147
                fd.thema AS thema,
3148
                fcr.category_id AS category_id
3149
            FROM
3150
                %sfaqdata fd
3151
            LEFT JOIN
3152
                %sfaqcategoryrelations fcr
3153
            ON
3154
                fd.id = fcr.record_id
3155
            AND
3156
                fd.lang = fcr.record_lang
3157
            LEFT JOIN
3158
                %sfaqdata_group AS fdg
3159
            ON
3160
                fd.id = fdg.record_id
3161
            LEFT JOIN
3162
                %sfaqdata_user AS fdu
3163
            ON
3164
                fd.id = fdu.record_id
3165
            WHERE
3166
                fd.lang = '%s'
3167
            AND 
3168
                fd.date_start <= '%s'
3169
            AND 
3170
                fd.date_end   >= '%s'
3171
            AND 
3172
                fd.active = 'yes'
3173
            AND 
3174
                fd.sticky = 1
3175
            %s",
3176
            PMF_Db::getTablePrefix(),
3177
            PMF_Db::getTablePrefix(),
3178
            PMF_Db::getTablePrefix(),
3179
            PMF_Db::getTablePrefix(),
3180
            $this->_config->getLanguage()->getLanguage(),
3181
            $now,
3182
            $now,
3183
            $this->queryPermission($this->groupSupport)
3184
        );
3185
3186
        $result = $this->_config->getDb()->query($query);
3187
        $sticky = [];
3188
        $data = [];
3189
3190
        $oldId = 0;
3191
        while (($row = $this->_config->getDb()->fetchObject($result))) {
3192
            if ($oldId != $row->id) {
3193
                $data['thema'] = $row->thema;
3194
3195
                $title = $row->thema;
3196
                $url = sprintf(
3197
                    '%s?%saction=artikel&amp;cat=%d&amp;id=%d&amp;artlang=%s',
3198
                    PMF_Link::getSystemRelativeUri(),
3199
                    $sids,
3200
                    $row->category_id,
3201
                    $row->id,
3202
                    $row->lang
3203
                );
3204
                $oLink = new PMF_Link($url, $this->_config);
3205
                $oLink->itemTitle = $row->thema;
3206
                $oLink->tooltip = $title;
3207
                $data['url'] = $oLink->toString();
3208
3209
                $sticky[] = $data;
3210
            }
3211
            $oldId = $row->id;
3212
        }
3213
3214
        return $sticky;
3215
    }
3216
3217
    /**
3218
     * Prepares and returns the sticky records for the frontend.
3219
     *
3220
     * @return array
3221
     */
3222
    public function getStickyRecords()
3223
    {
3224
        $result = $this->getStickyRecordsData();
3225
        $output = [];
3226
3227
        if (count($result) > 0) {
3228
            foreach ($result as $row) {
3229
                $output[] = array(
3230
                    'title' => PMF_Utils::makeShorterText($row['thema'], 8),
3231
                    'preview' => $row['thema'],
3232
                    'url' => $row['url'],
3233
                );
3234
            }
3235
        } else {
3236
            $output['error'] = sprintf('<li>%s</li>', $this->pmf_lang['err_noTopTen']);
3237
        }
3238
        if (!isset($output['error'])) {
3239
            $html = '';
3240
            foreach ($output as $entry) {
3241
                $html .= sprintf(
3242
                    '<li><a class="sticky-faqs" data-toggle="tooltip" data-placement="top" title="%s" href="%s">%s</a></li>',
3243
                    $entry['preview'],
3244
                    $entry['url'],
3245
                    $entry['title']
3246
                );
3247
            }
3248
            $output['html'] = $html;
3249
        }
3250
3251
        return $output;
3252
    }
3253
3254
    /**
3255
     * Updates field answer_id in faqquestion.
3256
     *
3257
     * @param int $openQuestionId
3258
     * @param int $faqId
3259
     * @param int $categoryId
3260
     *
3261
     * @return bool
3262
     */
3263 View Code Duplication
    public function updateQuestionAnswer($openQuestionId, $faqId, $categoryId)
3264
    {
3265
        $query = sprintf(
3266
            'UPDATE %sfaqquestions SET answer_id = %d, category_id= %d WHERE id= %d',
3267
            PMF_Db::getTablePrefix(),
3268
            $faqId,
3269
            $categoryId,
3270
            $openQuestionId
3271
        );
3272
3273
        return $this->_config->getDb()->query($query);
3274
    }
3275
3276
    /**
3277
     * Returns a part of a query to check permissions.
3278
     *
3279
     * @param bool $hasGroupSupport
3280
     *
3281
     * @return string
3282
     */
3283
    protected function queryPermission($hasGroupSupport = false)
3284
    {
3285
        if ($hasGroupSupport) {
3286
            if (-1 === $this->user) {
3287
                return sprintf(
3288
                    'AND fdg.group_id IN (%s)',
3289
                    implode(', ', $this->groups),
3290
                    $this->user,
3291
                    implode(', ', $this->groups));
3292 View Code Duplication
            } else {
3293
                return sprintf(
3294
                    'AND ( fdg.group_id IN (%s) OR (fdu.user_id = %d OR fdg.group_id IN (%s)) )',
3295
                    implode(', ', $this->groups),
3296
                    $this->user,
3297
                    implode(', ', $this->groups)
3298
                );
3299
            }
3300
        } else {
3301
            if (-1 !== $this->user) {
3302
                return sprintf(
3303
                    'AND ( fdu.user_id = %d OR fdu.user_id = -1 )',
3304
                    $this->user
3305
                );
3306
            } else {
3307
                return sprintf(
3308
                    'AND fdu.user_id = -1',
3309
                    $this->user
3310
                );
3311
            }
3312
        }
3313
    }
3314
}
3315