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 ( 50844f...6464fc )
by Thorsten
24:55 queued 11:16
created

PMF_Faq::getLatestData()   D

Complexity

Conditions 9
Paths 14

Size

Total Lines 95
Code Lines 47

Duplication

Lines 36
Ratio 37.89 %

Importance

Changes 1
Bugs 1 Features 0
Metric Value
cc 9
eloc 47
c 1
b 1
f 0
nc 14
nop 2
dl 36
loc 95
rs 4.9931

How to fix   Long Method   

Long Method

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

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

Commonly applied refactorings include:

1
<?php
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
                'notes' => $row->notes,
717
                'created' => $row->created,
718
            ];
719
        } else {
720
            $this->faqRecord = [
721
                'id' => $faqId,
722
                'lang' => $currentLanguage,
723
                'solution_id' => 42,
724
                'revision_id' => $faqRevisionId,
725
                'active' => 'no',
726
                'sticky' => 0,
727
                'keywords' => '',
728
                'title' => '',
729
                'content' => $PMF_LANG['msgAccessDenied'],
730
                'author' => '',
731
                'email' => '',
732
                'comment' => '',
733
                'date' => PMF_Date::createIsoDate(date('YmdHis')),
734
                'dateStart' => '',
735
                'dateEnd' => '',
736
                'linkState' => '',
737
                'linkCheckDate' => '',
738
                'notes' => '',
739
                'created' => date('c'),
740
            ];
741
        }
742
    }
743
744
    /**
745
     * Executes a query to retrieve a single FAQ.
746
     *
747
     * @param int    $faqId
748
     * @param string $faqLanguage
749
     * @param int    $faqRevisionId
750
     * @param bool   $isAdmin
751
     *
752
     * @return mixed
753
     */
754
    public function getRecordResult($faqId, $faqLanguage, $faqRevisionId = null, $isAdmin = false)
755
    {
756
        $query = sprintf(
757
            "SELECT
758
                 id, lang, solution_id, revision_id, active, sticky, keywords,
759
                 thema, content, author, email, comment, updated, links_state,
760
                 links_check_date, date_start, date_end, created, notes
761
            FROM
762
                %s%s fd
763
            LEFT JOIN
764
                %sfaqdata_group fdg
765
            ON
766
                fd.id = fdg.record_id
767
            LEFT JOIN
768
                %sfaqdata_user fdu
769
            ON
770
                fd.id = fdu.record_id
771
            WHERE
772
                fd.id = %d
773
            %s
774
            AND
775
                fd.lang = '%s'
776
                %s",
777
            PMF_Db::getTablePrefix(),
778
            isset($faqRevisionId) ? 'faqdata_revisions' : 'faqdata',
779
            PMF_Db::getTablePrefix(),
780
            PMF_Db::getTablePrefix(),
781
            $faqId,
782
            isset($faqRevisionId) ? 'AND revision_id = '.$faqRevisionId : '',
783
            $faqLanguage,
784
            ($isAdmin) ? 'AND 1=1' : $this->queryPermission($this->groupSupport)
785
        );
786
787
        return $this->_config->getDb()->query($query);
788
    }
789
790
    /**
791
     * Return records from given IDs
792
     *
793
     * @param array $faqIds
794
     *
795
     * @return array
796
     */
797
    public function getRecordsByIds(Array $faqIds)
798
    {
799
        $faqRecords = [];
800
801
        $query = sprintf(
802
            "SELECT
803
                 fd.id AS id,
804
                 fd.lang AS lang,
805
                 fd.thema AS question,
806
                 fd.content AS answer,
807
                 fd.updated AS updated,
808
                 fd.created AS created,
809
                 fcr.category_id AS category_id,
810
                 fv.visits AS visits
811
            FROM
812
                %sfaqdata fd
813
            LEFT JOIN
814
                %sfaqcategoryrelations fcr
815
            ON
816
                fd.id = fcr.record_id
817
            AND
818
                fd.lang = fcr.record_lang
819
            LEFT JOIN
820
                %sfaqdata_group fdg
821
            ON
822
                fd.id = fdg.record_id
823
            LEFT JOIN
824
                %sfaqvisits AS fv
825
            ON
826
                fd.id = fv.id
827
            AND
828
                fv.lang = fd.lang
829
            LEFT JOIN
830
                %sfaqdata_user fdu
831
            ON
832
                fd.id = fdu.record_id
833
            WHERE
834
                fd.id IN (%s)
835
            AND
836
                fd.lang = '%s'
837
                %s",
838
            PMF_Db::getTablePrefix(),
839
            PMF_Db::getTablePrefix(),
840
            PMF_Db::getTablePrefix(),
841
            PMF_Db::getTablePrefix(),
842
            PMF_Db::getTablePrefix(),
843
            implode(',', $faqIds),
844
            $this->_config->getLanguage()->getLanguage(),
845
            $this->queryPermission($this->groupSupport)
846
        );
847
848
        $result = $this->_config->getDb()->query($query);
849
850
        $faqHelper = new PMF_Helper_Faq($this->_config);
851
        while ($row = $this->_config->getDb()->fetchObject($result)) {
852
            if (empty($row->visits)) {
853
                $visits = 0;
854
            } else {
855
                $visits = $row->visits;
856
            }
857
858
            $url = sprintf(
859
                '%sindex.php?action=artikel&cat=%d&id=%d&artlang=%s',
860
                $this->_config->getDefaultUrl(),
861
                $row->category_id,
862
                $row->id,
863
                $row->lang
864
            );
865
            $oLink = new PMF_Link($url, $this->_config);
866
            $oLink->itemTitle = $oLink->text = $oLink->tooltip = $row->question;
867
868
            $faqRecords[] = [
869
                'record_id' => (int)$row->id,
870
                'record_lang' => $row->lang,
871
                'category_id' => (int)$row->category_id,
872
                'record_title' => $row->question,
873
                'record_preview' => $faqHelper->renderAnswerPreview($row->answer, 25),
874
                'record_link' => $oLink->toString(),
875
                'record_updated' => PMF_Date::createIsoDate($row->updated).':00',
876
                'visits' => (int)$visits,
877
                'record_created' => $row->created
878
            ];
879
        }
880
881
        return $faqRecords;
882
    }
883
884
    /**
885
     * Adds a new record.
886
     *
887
     * @param array $data      Array of FAQ data
888
     * @param bool  $newRecord Do not create a new ID if false
889
     *
890
     * @return int
891
     */
892
    public function addRecord(Array $data, $newRecord = true)
893
    {
894
        if ($newRecord) {
895
            $recordId = $this->_config->getDb()->nextId(PMF_Db::getTablePrefix().'faqdata', 'id');
896
        } else {
897
            $recordId = $data['id'];
898
        }
899
900
        // Add new entry
901
        $query = sprintf("
902
            INSERT INTO
903
                %sfaqdata
904
            VALUES
905
                (%d, '%s', %d, %d, '%s', %d, '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', %d, '%s', '%s', '%s', '%s')",
906
            PMF_Db::getTablePrefix(),
907
            $recordId,
908
            $data['lang'],
909
            $this->getSolutionId(),
910
            0,
911
            $data['active'],
912
            $data['sticky'],
913
            $this->_config->getDb()->escape($data['keywords']),
914
            $this->_config->getDb()->escape($data['thema']),
915
            $this->_config->getDb()->escape($data['content']),
916
            $this->_config->getDb()->escape($data['author']),
917
            $data['email'],
918
            $data['comment'],
919
            $data['date'],
920
            $data['linkState'],
921
            $data['linkDateCheck'],
922
            $data['dateStart'],
923
            $data['dateEnd'],
924
            date('Y-m-d H:i:s'),
925
            $data['notes']
926
        );
927
928
        $this->_config->getDb()->query($query);
929
930
        return $recordId;
931
    }
932
933
    /**
934
     * Updates a record.
935
     *
936
     * @param array $data Array of FAQ data
937
     *
938
     * @return bool
939
     */
940
    public function updateRecord(Array $data)
941
    {
942
        // Update entry
943
        $query = sprintf("
944
            UPDATE
945
                %sfaqdata
946
            SET
947
                revision_id = %d,
948
                active = '%s',
949
                sticky = %d,
950
                keywords = '%s',
951
                thema = '%s',
952
                content = '%s',
953
                author = '%s',
954
                email = '%s',
955
                comment = '%s',
956
                updated = '%s',
957
                links_state = '%s',
958
                links_check_date = %d,
959
                date_start = '%s',
960
                date_end = '%s',
961
                notes = '%s'
962
            WHERE
963
                id = %d
964
            AND
965
                lang = '%s'",
966
            PMF_Db::getTablePrefix(),
967
            $data['revision_id'],
968
            $data['active'],
969
            $data['sticky'],
970
            $this->_config->getDb()->escape($data['keywords']),
971
            $this->_config->getDb()->escape($data['thema']),
972
            $this->_config->getDb()->escape($data['content']),
973
            $this->_config->getDb()->escape($data['author']),
974
            $data['email'],
975
            $data['comment'],
976
            $data['date'],
977
            $data['linkState'],
978
            $data['linkDateCheck'],
979
            $data['dateStart'],
980
            $data['dateEnd'],
981
            $data['notes'],
982
            $data['id'],
983
            $data['lang']
984
        );
985
986
        $this->_config->getDb()->query($query);
987
988
        return true;
989
    }
990
991
    /**
992
     * Deletes a record and all the dependencies.
993
     *
994
     * @param int    $recordId   Record id
995
     * @param string $recordLang Record language
996
     *
997
     * @return bool
998
     */
999
    public function deleteRecord($recordId, $recordLang)
1000
    {
1001
        $solutionId = $this->getSolutionIdFromId($recordId, $recordLang);
1002
1003
        $queries = array(
1004
            sprintf(
1005
                "DELETE FROM %sfaqchanges WHERE beitrag = %d AND lang = '%s'",
1006
                PMF_Db::getTablePrefix(),
1007
                $recordId,
1008
                $recordLang
1009
            ),
1010
            sprintf(
1011
                "DELETE FROM %sfaqcategoryrelations WHERE record_id = %d AND record_lang = '%s'",
1012
                PMF_Db::getTablePrefix(),
1013
                $recordId,
1014
                $recordLang
1015
            ),
1016
            sprintf(
1017
                "DELETE FROM %sfaqdata WHERE id = %d AND lang = '%s'",
1018
                PMF_Db::getTablePrefix(),
1019
                $recordId,
1020
                $recordLang
1021
            ),
1022
            sprintf(
1023
                "DELETE FROM %sfaqdata_revisions WHERE id = %d AND lang = '%s'",
1024
                PMF_Db::getTablePrefix(),
1025
                $recordId,
1026
                $recordLang
1027
            ),
1028
            sprintf(
1029
                "DELETE FROM %sfaqvisits WHERE id = %d AND lang = '%s'",
1030
                PMF_Db::getTablePrefix(),
1031
                $recordId,
1032
                $recordLang
1033
            ),
1034
            sprintf(
1035
                'DELETE FROM %sfaqdata_user WHERE record_id = %d',
1036
                PMF_Db::getTablePrefix(),
1037
                $recordId,
1038
                $recordLang
1039
            ),
1040
            sprintf(
1041
                'DELETE FROM %sfaqdata_group WHERE record_id = %d',
1042
                PMF_Db::getTablePrefix(),
1043
                $recordId,
1044
                $recordLang
1045
            ),
1046
            sprintf(
1047
                'DELETE FROM %sfaqdata_tags WHERE record_id = %d',
1048
                PMF_Db::getTablePrefix(),
1049
                $recordId
1050
            ),
1051
            sprintf(
1052
                'DELETE FROM %sfaqdata_tags WHERE %sfaqdata_tags.record_id NOT IN (SELECT %sfaqdata.id FROM %sfaqdata)',
1053
                PMF_Db::getTablePrefix(),
1054
                PMF_Db::getTablePrefix(),
1055
                PMF_Db::getTablePrefix(),
1056
                PMF_Db::getTablePrefix()
1057
            ),
1058
            sprintf(
1059
                'DELETE FROM %sfaqcomments WHERE id = %d',
1060
                PMF_Db::getTablePrefix(),
1061
                $recordId
1062
            ),
1063
            sprintf(
1064
                'DELETE FROM %sfaqvoting WHERE artikel = %d',
1065
                PMF_Db::getTablePrefix(),
1066
                $recordId
1067
            ),
1068
        );
1069
1070
        foreach ($queries as $query) {
1071
            $this->_config->getDb()->query($query);
1072
        }
1073
1074
        // Delete possible attachments
1075
        $attId = PMF_Attachment_Factory::fetchByRecordId($this->_config, $recordId);
1076
        $attachment = PMF_Attachment_Factory::create($attId);
1077
        $attachment->delete();
1078
1079
        // Delete possible Elasticsearch documents
1080
        if ($this->_config->get('search.enableElasticsearch')) {
1081
            $esInstance = new PMF_Instance_Elasticsearch($this->_config);
1082
            $esInstance->delete($solutionId);
1083
        }
1084
1085
        return true;
1086
    }
1087
1088
    /**
1089
     * Checks if a record is already translated.
1090
     *
1091
     * @param int    $record_id   Record id
1092
     * @param string $record_lang Record language
1093
     *
1094
     * @return bool
1095
     */
1096
    public function isAlreadyTranslated($record_id, $record_lang)
1097
    {
1098
        $query = sprintf("
1099
            SELECT
1100
                id, lang
1101
            FROM
1102
                %sfaqdata
1103
            WHERE
1104
                id = %d
1105
            AND
1106
                lang = '%s'",
1107
            PMF_Db::getTablePrefix(),
1108
            $record_id,
1109
            $record_lang);
1110
1111
        $result = $this->_config->getDb()->query($query);
1112
1113
        if ($this->_config->getDb()->numRows($result)) {
1114
            return true;
1115
        }
1116
1117
        return false;
1118
    }
1119
1120
    /**
1121
     * Checks, if comments are disabled for the FAQ record.
1122
     *
1123
     * @param int    $record_id   Id of FAQ or news entry
1124
     * @param string $record_lang Language
1125
     * @param string $record_type Type of comment: faq or news
1126
     *
1127
     * @return bool true, if comments are disabled
1128
     */
1129
    public function commentDisabled($record_id, $record_lang, $record_type = 'faq')
1130
    {
1131
        if ('news' == $record_type) {
1132
            $table = 'faqnews';
1133
        } else {
1134
            $table = 'faqdata';
1135
        }
1136
1137
        $query = sprintf("
1138
            SELECT
1139
                comment
1140
            FROM
1141
                %s%s
1142
            WHERE
1143
                id = %d
1144
            AND
1145
                lang = '%s'",
1146
            PMF_Db::getTablePrefix(),
1147
            $table,
1148
            $record_id,
1149
            $record_lang
1150
        );
1151
1152
        $result = $this->_config->getDb()->query($query);
1153
1154
        if ($row = $this->_config->getDb()->fetchObject($result)) {
1155
            return ($row->comment === 'y') ? false : true;
1156
        } else {
1157
            return true;
1158
        }
1159
    }
1160
1161
    /**
1162
     * Adds new category relations to a record.
1163
     *
1164
     * @param array  $categories Array of categories
1165
     * @param int    $record_id  Record id
1166
     * @param string $language   Language
1167
     *
1168
     * @return int
1169
     */
1170
    public function addCategoryRelations(Array $categories, $record_id, $language)
1171
    {
1172
        if (!is_array($categories)) {
1173
            return false;
1174
        }
1175
1176
        foreach ($categories as $_category) {
1177
            $this->_config->getDb()->query(sprintf(
1178
                "INSERT INTO
1179
                    %sfaqcategoryrelations
1180
                VALUES
1181
                    (%d, '%s', %d, '%s')",
1182
                PMF_Db::getTablePrefix(),
1183
                $_category,
1184
                $language,
1185
                $record_id,
1186
                $language));
1187
        }
1188
1189
        return true;
1190
    }
1191
1192
    /**
1193
     * Adds new category relation to a record.
1194
     *
1195
     * @param mixed  $category  Category or array of categories
1196
     * @param int    $record_id Record id
1197
     * @param string $language  Language
1198
     *
1199
     * @return bool
1200
     */
1201
    public function addCategoryRelation($category, $record_id, $language)
1202
    {
1203
        // Just a fallback when (wrong case) $category is an array
1204
        if (is_array($category)) {
1205
            $this->addCategoryRelations($category, $record_id, $language);
1206
        }
1207
        $categories[] = $category;
1208
1209
        return $this->addCategoryRelations($categories, $record_id, $language);
1210
    }
1211
1212
    /**
1213
     * Deletes category relations to a record.
1214
     *
1215
     * @param int    $record_id   Record id
1216
     * @param string $record_lang Language
1217
     *
1218
     * @return bool
1219
     */
1220
    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...
1221
    {
1222
        $query = sprintf("
1223
            DELETE FROM
1224
                %sfaqcategoryrelations
1225
            WHERE
1226
                record_id = %d
1227
            AND
1228
                record_lang = '%s'",
1229
            PMF_Db::getTablePrefix(),
1230
            $record_id,
1231
            $record_lang);
1232
        $this->_config->getDb()->query($query);
1233
1234
        return true;
1235
    }
1236
1237
    /**
1238
     * Returns an array with all data from a FAQ record.
1239
     *
1240
     * @param int $solutionId Solution ID
1241
     */
1242
    public function getRecordBySolutionId($solutionId)
1243
    {
1244
        $query = sprintf(
1245
            'SELECT
1246
                *
1247
            FROM
1248
                %sfaqdata fd
1249
            LEFT JOIN
1250
                %sfaqdata_group fdg
1251
            ON
1252
                fd.id = fdg.record_id
1253
            LEFT JOIN
1254
                %sfaqdata_user fdu
1255
            ON
1256
                fd.id = fdu.record_id
1257
            WHERE
1258
                fd.solution_id = %d
1259
                %s',
1260
            PMF_Db::getTablePrefix(),
1261
            PMF_Db::getTablePrefix(),
1262
            PMF_Db::getTablePrefix(),
1263
            $solutionId,
1264
            $this->queryPermission($this->groupSupport)
1265
        );
1266
1267
        $result = $this->_config->getDb()->query($query);
1268
1269
        if ($row = $this->_config->getDb()->fetchObject($result)) {
1270
            $question = nl2br($row->thema);
1271
            $content = $row->content;
1272
            $active = ('yes' == $row->active);
1273
            $expired = (date('YmdHis') > $row->date_end);
1274
1275
            if (!$active) {
1276
                $content = $this->pmf_lang['err_inactiveArticle'];
1277
            }
1278
            if ($expired) {
1279
                $content = $this->pmf_lang['err_expiredArticle'];
1280
            }
1281
1282
            $this->faqRecord = array(
1283
                'id' => $row->id,
1284
                'lang' => $row->lang,
1285
                'solution_id' => $row->solution_id,
1286
                'revision_id' => $row->revision_id,
1287
                'active' => $row->active,
1288
                'sticky' => $row->sticky,
1289
                'keywords' => $row->keywords,
1290
                'title' => $question,
1291
                'content' => $content,
1292
                'author' => $row->author,
1293
                'email' => $row->email,
1294
                'comment' => $row->comment,
1295
                'date' => PMF_Date::createIsoDate($row->updated),
1296
                'dateStart' => $row->date_start,
1297
                'dateEnd' => $row->date_end,
1298
                'linkState' => $row->links_state,
1299
                'linkCheckDate' => $row->links_check_date,
1300
                'notes' => $row->notes
1301
            );
1302
        }
1303
    }
1304
1305
    /**
1306
     * Gets the record ID from a given solution ID.
1307
     *
1308
     * @param int $solutionId Solution ID
1309
     *
1310
     * @return array
1311
     */
1312
    public function getIdFromSolutionId($solutionId)
1313
    {
1314
        $query = sprintf('
1315
            SELECT
1316
                id, lang, content
1317
            FROM
1318
                %sfaqdata
1319
            WHERE
1320
                solution_id = %d',
1321
            PMF_Db::getTablePrefix(),
1322
            $solutionId
1323
        );
1324
1325
        $result = $this->_config->getDb()->query($query);
1326
1327
        if ($row = $this->_config->getDb()->fetchObject($result)) {
1328
            return [
1329
                'id' => $row->id,
1330
                'lang' => $row->lang,
1331
                'content' => $row->content
1332
            ];
1333
        }
1334
1335
        return [];
1336
    }
1337
1338
    /**
1339
     * Returns the solution ID from a given ID and language
1340
     *
1341
     * @param integer $faqId
1342
     * @param string $faqLang
1343
     *
1344
     * @return int
1345
     */
1346
    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...
1347
    {
1348
        $query = sprintf("
1349
            SELECT
1350
                solution_id
1351
            FROM
1352
                %sfaqdata
1353
            WHERE
1354
                id = %d
1355
                AND
1356
                lang = '%s'",
1357
            PMF_Db::getTablePrefix(),
1358
            (int) $faqId,
1359
            $this->_config->getDb()->escape($faqLang)
1360
        );
1361
1362
        $result = $this->_config->getDb()->query($query);
1363
1364
        if ($row = $this->_config->getDb()->fetchObject($result)) {
1365
            return $row->solution_id;
1366
        }
1367
1368
        return $this->getSolutionId();
1369
    }
1370
1371
    /**
1372
     * Gets the latest solution id for a FAQ record.
1373
     *
1374
     * @return int
1375
     */
1376
    public function getSolutionId()
1377
    {
1378
        $latestId = 0;
1379
1380
        $query = sprintf('
1381
            SELECT
1382
                MAX(solution_id) AS solution_id
1383
            FROM
1384
                %sfaqdata',
1385
            PMF_Db::getTablePrefix()
1386
        );
1387
1388
        $result = $this->_config->getDb()->query($query);
1389
1390
        if ($result && $row = $this->_config->getDb()->fetchObject($result)) {
1391
            $latestId = $row->solution_id;
1392
        }
1393
1394
        if ($latestId < PMF_SOLUTION_ID_START_VALUE) {
1395
            $nextSolutionId = PMF_SOLUTION_ID_START_VALUE;
1396
        } else {
1397
            $nextSolutionId = $latestId + PMF_SOLUTION_ID_INCREMENT_VALUE;
1398
        }
1399
1400
        return $nextSolutionId;
1401
    }
1402
1403
    /**
1404
     * Returns an array with all data from all FAQ records.
1405
     *
1406
     * @param int    $sortType  Sorting type
1407
     * @param array  $condition Condition
1408
     * @param string $sortOrder Sorting order
1409
     */
1410
    public function getAllRecords($sortType = FAQ_SORTING_TYPE_CATID_FAQID, Array $condition = null, $sortOrder = 'ASC')
1411
    {
1412
        $where = '';
1413
        if (!is_null($condition)) {
1414
            $num = count($condition);
1415
            $where = 'WHERE ';
1416
            foreach ($condition as $field => $data) {
1417
                --$num;
1418
                $where .= $field;
1419
                if (is_array($data)) {
1420
                    $where .= ' IN (';
1421
                    $separator = '';
1422
                    foreach ($data as $value) {
1423
                        $where .= $separator."'".$this->_config->getDb()->escape($value)."'";
1424
                        $separator = ', ';
1425
                    }
1426
                    $where .= ')';
1427
                } else {
1428
                    $where .= " = '".$this->_config->getDb()->escape($data)."'";
1429
                }
1430
                if ($num > 0) {
1431
                    $where .= ' AND ';
1432
                }
1433
            }
1434
        }
1435
1436
        switch ($sortType) {
1437
1438
            case FAQ_SORTING_TYPE_CATID_FAQID:
1439
                $orderBy = sprintf('
1440
            ORDER BY
1441
                fcr.category_id,
1442
                fd.id %s',
1443
                    $sortOrder);
1444
                break;
1445
1446
            case FAQ_SORTING_TYPE_FAQID:
1447
                $orderBy = sprintf('
1448
            ORDER BY
1449
                fd.id %s',
1450
                    $sortOrder);
1451
                break;
1452
1453
            case FAQ_SORTING_TYPE_FAQTITLE_FAQID:
1454
                $orderBy = sprintf('
1455
            ORDER BY
1456
                fcr.category_id,
1457
                fd.thema %s',
1458
                    $sortOrder);
1459
                break;
1460
1461
            case FAQ_SORTING_TYPE_DATE_FAQID:
1462
                $orderBy = sprintf('
1463
            ORDER BY
1464
                fcr.category_id,
1465
                fd.updated %s',
1466
                    $sortOrder);
1467
                break;
1468
1469
            default:
1470
                $orderBy = '';
1471
                break;
1472
        }
1473
1474
        $query = sprintf('
1475
            SELECT
1476
                fd.id AS id,
1477
                fd.lang AS lang,
1478
                fcr.category_id AS category_id,
1479
                fd.solution_id AS solution_id,
1480
                fd.revision_id AS revision_id,
1481
                fd.active AS active,
1482
                fd.sticky AS sticky,
1483
                fd.keywords AS keywords,
1484
                fd.thema AS thema,
1485
                fd.content AS content,
1486
                fd.author AS author,
1487
                fd.email AS email,
1488
                fd.comment AS comment,
1489
                fd.updated AS updated,
1490
                fd.links_state AS links_state,
1491
                fd.links_check_date AS links_check_date,
1492
                fd.date_start AS date_start,
1493
                fd.date_end AS date_end,
1494
                fd.sticky AS sticky,
1495
                fd.created AS created,
1496
                fd.notes AS notes
1497
            FROM
1498
                %sfaqdata fd
1499
            LEFT JOIN
1500
                %sfaqcategoryrelations fcr
1501
            ON
1502
                fd.id = fcr.record_id
1503
            AND
1504
                fd.lang = fcr.record_lang
1505
            %s
1506
            %s',
1507
            PMF_Db::getTablePrefix(),
1508
            PMF_Db::getTablePrefix(),
1509
            $where,
1510
            $orderBy
1511
        );
1512
1513
        $result = $this->_config->getDb()->query($query);
1514
1515
        while ($row = $this->_config->getDb()->fetchObject($result)) {
1516
            $content = $row->content;
1517
            $active = ('yes' == $row->active);
1518
            $expired = (date('YmdHis') > $row->date_end);
1519
1520
            if (!$active) {
1521
                $content = $this->pmf_lang['err_inactiveArticle'];
1522
            }
1523
            if ($expired) {
1524
                $content = $this->pmf_lang['err_expiredArticle'];
1525
            }
1526
1527
            $this->faqRecords[] = [
1528
                'id' => $row->id,
1529
                'category_id' => $row->category_id,
1530
                'lang' => $row->lang,
1531
                'solution_id' => $row->solution_id,
1532
                'revision_id' => $row->revision_id,
1533
                'active' => $row->active,
1534
                'sticky' => $row->sticky,
1535
                'keywords' => $row->keywords,
1536
                'title' => $row->thema,
1537
                'content' => $content,
1538
                'author' => $row->author,
1539
                'email' => $row->email,
1540
                'comment' => $row->comment,
1541
                'updated' => PMF_Date::createIsoDate($row->updated, 'Y-m-d H:i:s'),
1542
                'dateStart' => $row->date_start,
1543
                'dateEnd' => $row->date_end,
1544
                'created' => $row->created,
1545
                'notes' => $row->notes
1546
            ];
1547
        }
1548
    }
1549
1550
    /**
1551
     * Returns the FAQ record title from the ID and language.
1552
     *
1553
     * @param int $id Record id
1554
     *
1555
     * @return string
1556
     */
1557
    public function getRecordTitle($id)
1558
    {
1559
        if (isset($this->faqRecord['id']) && ($this->faqRecord['id'] == $id)) {
1560
            return $this->faqRecord['title'];
1561
        }
1562
1563
        $question = '';
1564
1565
        $query = sprintf(
1566
            "SELECT
1567
                thema AS question
1568
            FROM
1569
                %sfaqdata
1570
            WHERE
1571
                id = %d AND lang = '%s'",
1572
            PMF_Db::getTablePrefix(),
1573
            $id,
1574
            $this->_config->getLanguage()->getLanguage()
1575
            );
1576
        $result = $this->_config->getDb()->query($query);
1577
1578 View Code Duplication
        if ($this->_config->getDb()->numRows($result) > 0) {
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...
1579
            while ($row = $this->_config->getDb()->fetchObject($result)) {
1580
                $question = $row->question;
1581
            }
1582
        } else {
1583
            $question = $this->pmf_lang['no_cats'];
1584
        }
1585
1586
        return $question;
1587
    }
1588
1589
    /**
1590
     * Gets all revisions from a given record ID.
1591
     *
1592
     * @param int    $recordId   Record id
1593
     * @param string $recordLang Record language
1594
     *
1595
     * @return array
1596
     */
1597
    public function getRevisionIds($recordId, $recordLang)
1598
    {
1599
        $revisionData = [];
1600
1601
        $query = sprintf("
1602
            SELECT
1603
                revision_id, updated, author
1604
            FROM
1605
                %sfaqdata_revisions
1606
            WHERE
1607
                id = %d
1608
            AND
1609
                lang = '%s'
1610
            ORDER BY
1611
                revision_id",
1612
            PMF_Db::getTablePrefix(),
1613
            $recordId,
1614
            $recordLang
1615
        );
1616
1617
        $result = $this->_config->getDb()->query($query);
1618
1619
        if ($this->_config->getDb()->numRows($result) > 0) {
1620
            while ($row = $this->_config->getDb()->fetchObject($result)) {
1621
                $revisionData[] = [
1622
                    'revision_id' => $row->revision_id,
1623
                    'updated' => $row->updated,
1624
                    'author' => $row->author,
1625
                ];
1626
            }
1627
        }
1628
1629
        return $revisionData;
1630
    }
1631
1632
    /**
1633
     * Adds a new revision from a given record ID.
1634
     *
1635
     * @param int    $record_id   Record id
1636
     * @param string $record_lang Record language
1637
     *
1638
     * @return array
1639
     */
1640
    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...
1641
    {
1642
        $query = sprintf("
1643
            INSERT INTO
1644
                %sfaqdata_revisions
1645
            SELECT * FROM
1646
                %sfaqdata
1647
            WHERE
1648
                id = %d
1649
            AND
1650
                lang = '%s'",
1651
            PMF_Db::getTablePrefix(),
1652
            PMF_Db::getTablePrefix(),
1653
            $record_id,
1654
            $record_lang);
1655
        $this->_config->getDb()->query($query);
1656
1657
        return true;
1658
    }
1659
1660
    /**
1661
     * Returns the keywords of a FAQ record from the ID and language.
1662
     *
1663
     * @param int $id record id
1664
     *
1665
     * @return string
1666
     */
1667
    public function getRecordKeywords($id)
1668
    {
1669
        if (isset($this->faqRecord['id']) && ($this->faqRecord['id'] == $id)) {
1670
            return $this->faqRecord['keywords'];
1671
        }
1672
1673
        $query = sprintf(
1674
            "SELECT
1675
                keywords
1676
            FROM
1677
                %sfaqdata
1678
            WHERE id = %d AND lang = '%s'",
1679
            PMF_Db::getTablePrefix(),
1680
            $id,
1681
            $this->_config->getLanguage()->getLanguage());
1682
1683
        $result = $this->_config->getDb()->query($query);
1684
1685
        if ($this->_config->getDb()->numRows($result) > 0) {
1686
            $row = $this->_config->getDb()->fetchObject($result);
1687
1688
            return PMF_String::htmlspecialchars($row->keywords, ENT_QUOTES, 'utf-8');
1689
        } else {
1690
            return '';
1691
        }
1692
    }
1693
1694
    /**
1695
     * Returns a answer preview of the FAQ record.
1696
     *
1697
     * @param int $recordId  FAQ record ID
1698
     * @param int $wordCount Number of words, default: 12
1699
     *
1700
     * @return string
1701
     */
1702
    public function getRecordPreview($recordId, $wordCount = 12)
1703
    {
1704
        $answerPreview = '';
1705
1706
        if (isset($this->faqRecord['id']) && ($this->faqRecord['id'] == $recordId)) {
1707
            $answerPreview = $this->faqRecord['content'];
1708
        }
1709
1710
        $query = sprintf("
1711
            SELECT
1712
                content as answer
1713
            FROM
1714
                %sfaqdata
1715
            WHERE 
1716
                id = %d 
1717
            AND 
1718
                lang = '%s'",
1719
            PMF_Db::getTablePrefix(),
1720
            $recordId,
1721
            $this->_config->getLanguage()->getLanguage());
1722
1723
        $result = $this->_config->getDb()->query($query);
1724
1725 View Code Duplication
        if ($this->_config->getDb()->numRows($result) > 0) {
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...
1726
            $row = $this->_config->getDb()->fetchObject($result);
1727
            $answerPreview = strip_tags($row->answer);
1728
        } else {
1729
            $answerPreview = $this->_config->get('main.metaDescription');
1730
        }
1731
1732
        return PMF_Utils::makeShorterText($answerPreview, $wordCount);
1733
    }
1734
1735
    /**
1736
     * Returns the number of activated and not expired records, optionally
1737
     * not limited to the current language.
1738
     *
1739
     * @param string $language Language
1740
     *
1741
     * @return int
1742
     */
1743
    public function getNumberOfRecords($language = null)
1744
    {
1745
        $now = date('YmdHis');
1746
1747
        $query = sprintf("
1748
            SELECT
1749
                id
1750
            FROM
1751
                %sfaqdata
1752
            WHERE
1753
                active = 'yes'
1754
            %s
1755
            AND
1756
                date_start <= '%s'
1757
            AND
1758
                date_end >= '%s'",
1759
            PMF_Db::getTablePrefix(),
1760
            null == $language ? '' : "AND lang = '".$language."'",
1761
            $now,
1762
            $now
1763
        );
1764
1765
        $num = $this->_config->getDb()->numRows($this->_config->getDb()->query($query));
1766
1767
        if ($num > 0) {
1768
            return $num;
1769
        } else {
1770
            return 0;
1771
        }
1772
    }
1773
1774
    /**
1775
     * This function generates a list with the most voted or most visited records.
1776
     *
1777
     * @param string $type Type definition visits/voted
1778
     *
1779
     * @since  2009-11-03
1780
     *
1781
     * @author Max Köhler <[email protected]>
1782
     *
1783
     * @return array
1784
     */
1785
    public function getTopTen($type = 'visits')
1786
    {
1787
        if ('visits' == $type) {
1788
            $result = $this->getTopTenData(PMF_NUMBER_RECORDS_TOPTEN, 0, $this->_config->getLanguage()->getLanguage());
1789
        } else {
1790
            $result = $this->getTopVotedData(PMF_NUMBER_RECORDS_TOPTEN, $this->_config->getLanguage()->getLanguage());
1791
        }
1792
        $output = [];
1793
1794
        if (count($result) > 0) {
1795
            foreach ($result as $row) {
1796
                if ('visits' == $type) {
1797
                    $output['title'][] = PMF_Utils::makeShorterText($row['question'], 8);
1798
                    $output['preview'][] = $row['question'];
1799
                    $output['url'][] = $row['url'];
1800
                    $output['visits'][] = $this->plr->GetMsg('plmsgViews', $row['visits']);
1801
                } else {
1802
                    $output['title'][] = PMF_Utils::makeShorterText($row['question'], 8);
1803
                    $output['preview'][] = $row['question'];
1804
                    $output['url'][] = $row['url'];
1805
                    $output['voted'][] = sprintf(
1806
                        '%s %s 5 - %s',
1807
                        round($row['avg'], 2),
1808
                        $this->pmf_lang['msgVoteFrom'],
1809
                        $this->plr->GetMsg('plmsgVotes', $row['user'])
1810
                    );
1811
                }
1812
            }
1813
        } else {
1814
            $output['error'] = $this->pmf_lang['err_noTopTen'];
1815
        }
1816
1817
        return $output;
1818
    }
1819
1820
    /**
1821
     * This function generates the list with the latest published records.
1822
     *
1823
     * @return array
1824
     */
1825
    public function getLatest()
1826
    {
1827
        $date = new PMF_Date($this->_config);
1828
        $result = $this->getLatestData(PMF_NUMBER_RECORDS_LATEST, $this->_config->getLanguage()->getLanguage());
1829
        $output = [];
1830
1831
        if (count($result) > 0) {
1832
            foreach ($result as $row) {
1833
                $output['url'][] = $row['url'];
1834
                $output['title'][] = PMF_Utils::makeShorterText($row['question'], 8);
1835
                $output['preview'][] = $row['question'];
1836
                $output['date'][] = $date->format(PMF_Date::createIsoDate($row['date']));
1837
            }
1838
        } else {
1839
            $output['error'] = $this->pmf_lang['err_noArticles'];
1840
        }
1841
1842
        return $output;
1843
    }
1844
1845
    /**
1846
     * Deletes a question for the table faqquestions.
1847
     *
1848
     * @param int $questionId
1849
     *
1850
     * @return bool
1851
     */
1852
    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...
1853
    {
1854
        $delete = sprintf("
1855
            DELETE FROM
1856
                %sfaqquestions
1857
            WHERE
1858
                id = %d
1859
            AND
1860
                lang = '%s'",
1861
            PMF_Db::getTablePrefix(),
1862
            $questionId,
1863
            $this->_config->getLanguage()->getLanguage()
1864
        );
1865
1866
        $this->_config->getDb()->query($delete);
1867
1868
        return true;
1869
    }
1870
1871
     /**
1872
      * Returns the visibility of a question.
1873
      *
1874
      * @param   int $questionId
1875
      *
1876
      * @return  string
1877
      */
1878
     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...
1879
     {
1880
         $query = sprintf("
1881
            SELECT
1882
                is_visible
1883
            FROM
1884
                %sfaqquestions
1885
            WHERE
1886
                id = %d
1887
            AND
1888
                lang = '%s'",
1889
            PMF_Db::getTablePrefix(),
1890
            $questionId,
1891
            $this->_config->getLanguage()->getLanguage()
1892
        );
1893
1894
         $result = $this->_config->getDb()->query($query);
1895
         if ($this->_config->getDb()->numRows($result) > 0) {
1896
             $row = $this->_config->getDb()->fetchObject($result);
1897
1898
             return $row->is_visible;
1899
         }
1900
1901
         return;
1902
     }
1903
1904
    /**
1905
     * Sets the visibility of a question.
1906
     *
1907
     * @param int    $questionId
1908
     * @param string $isVisible
1909
     *
1910
     * @return bool
1911
     */
1912
    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...
1913
    {
1914
        $query = sprintf("
1915
            UPDATE
1916
                %sfaqquestions
1917
            SET
1918
                is_visible = '%s'
1919
            WHERE
1920
                id = %d
1921
            AND
1922
                lang = '%s'",
1923
            PMF_Db::getTablePrefix(),
1924
            $isVisible,
1925
            $questionId,
1926
            $this->_config->getLanguage()->getLanguage()
1927
        );
1928
1929
        $this->_config->getDb()->query($query);
1930
1931
        return true;
1932
    }
1933
1934
    /**
1935
     * This function generates a data-set with the most voted FAQs.
1936
     *  
1937
     * @param int    $count    Number of records
1938
     * @param string $language Language
1939
     *
1940
     * @return array
1941
     */
1942
    public function getTopVotedData($count = PMF_NUMBER_RECORDS_TOPTEN, $language = null)
1943
    {
1944
        global $sids;
1945
1946
        $topten = $data = [];
1947
1948
        $now = date('YmdHis');
1949
        $query =
1950
'            SELECT
1951
                fd.id AS id,
1952
                fd.lang AS lang,
1953
                fd.thema AS thema,
1954
                fd.updated AS updated,
1955
                fcr.category_id AS category_id,
1956
                (fv.vote/fv.usr) AS avg,
1957
                fv.usr AS user
1958
            FROM
1959
                '.PMF_Db::getTablePrefix().'faqvoting fv,
1960
                '.PMF_Db::getTablePrefix().'faqdata fd
1961
            LEFT JOIN
1962
                '.PMF_Db::getTablePrefix().'faqcategoryrelations fcr
1963
            ON
1964
                fd.id = fcr.record_id
1965
            AND
1966
                fd.lang = fcr.record_lang
1967
            LEFT JOIN
1968
                '.PMF_Db::getTablePrefix().'faqdata_group AS fdg
1969
            ON
1970
                fd.id = fdg.record_id
1971
            LEFT JOIN
1972
                '.PMF_Db::getTablePrefix().'faqdata_user AS fdu
1973
            ON
1974
                fd.id = fdu.record_id
1975
            WHERE
1976
                    fd.date_start <= \''.$now.'\'
1977
                AND fd.date_end   >= \''.$now.'\'
1978
                AND fd.id = fv.artikel
1979
                AND fd.active = \'yes\'';
1980
1981 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...
1982
            $query .= '
1983
            AND
1984
                fcr.category_id = \''.$categoryId.'\'';
1985
        }
1986
        if (isset($language) && PMF_Language::isASupportedLanguage($language)) {
1987
            $query .= '
1988
            AND
1989
                fd.lang = \''.$language.'\'';
1990
        }
1991
        $query .= '
1992
                '.$this->queryPermission($this->groupSupport).'
1993
            ORDER BY
1994
                avg DESC';
1995
1996
        $result = $this->_config->getDb()->query($query);
1997
1998
        $i = 1;
1999
        $oldId = 0;
2000
        while (($row = $this->_config->getDb()->fetchObject($result)) && $i <= $count) {
2001
            if ($oldId != $row->id) {
2002
                $data['avg'] = $row->avg;
2003
                $data['question'] = $row->thema;
2004
                $data['date'] = $row->updated;
2005
                $data['user'] = $row->user;
2006
2007
                $title = $row->thema;
2008
                $url = sprintf(
2009
                    '%s?%saction=artikel&amp;cat=%d&amp;id=%d&amp;artlang=%s',
2010
                    PMF_Link::getSystemRelativeUri(),
2011
                    $sids,
2012
                    $row->category_id,
2013
                    $row->id,
2014
                    $row->lang
2015
                );
2016
                $oLink = new PMF_Link($url, $this->_config);
2017
                $oLink->itemTitle = $row->thema;
2018
                $oLink->tooltip = $title;
2019
                $data['url'] = $oLink->toString();
2020
2021
                $topten[] = $data;
2022
                ++$i;
2023
            }
2024
            $oldId = $row->id;
2025
        }
2026
2027
        return $topten;
2028
    }
2029
2030
    /**
2031
     * This function generates the Top Ten data with the mosted viewed records.
2032
     *
2033
     * @param int    $count      Number of records
2034
     * @param int    $categoryId Category ID
2035
     * @param string $language   Language
2036
     *
2037
     * @return array
2038
     */
2039
    public function getTopTenData($count = PMF_NUMBER_RECORDS_TOPTEN, $categoryId = 0, $language = null)
2040
    {
2041
        global $sids;
2042
2043
        $now = date('YmdHis');
2044
        $query =
2045
'            SELECT
2046
                fd.id AS id,
2047
                fd.lang AS lang,
2048
                fd.thema AS question,
2049
                fd.updated AS updated,
2050
                fcr.category_id AS category_id,
2051
                fv.visits AS visits,
2052
                fv.last_visit AS last_visit,
2053
                fdg.group_id AS group_id,
2054
                fdu.user_id AS user_id
2055
            FROM
2056
                '.PMF_Db::getTablePrefix().'faqvisits fv,
2057
                '.PMF_Db::getTablePrefix().'faqdata fd
2058
            LEFT JOIN
2059
                '.PMF_Db::getTablePrefix().'faqcategoryrelations fcr
2060
            ON
2061
                fd.id = fcr.record_id
2062
            AND
2063
                fd.lang = fcr.record_lang
2064
            LEFT JOIN
2065
                '.PMF_Db::getTablePrefix().'faqdata_group AS fdg
2066
            ON
2067
                fd.id = fdg.record_id
2068
            LEFT JOIN
2069
                '.PMF_Db::getTablePrefix().'faqdata_user AS fdu
2070
            ON
2071
                fd.id = fdu.record_id
2072
            WHERE
2073
                    fd.date_start <= \''.$now.'\'
2074
                AND fd.date_end   >= \''.$now.'\'
2075
                AND fd.id = fv.id
2076
                AND fd.lang = fv.lang
2077
                AND fd.active = \'yes\'';
2078
2079 View Code Duplication
        if (isset($categoryId) && is_numeric($categoryId) && ($categoryId != 0)) {
2080
            $query .= '
2081
            AND
2082
                fcr.category_id = \''.$categoryId.'\'';
2083
        }
2084
        if (isset($language) && PMF_Language::isASupportedLanguage($language)) {
2085
            $query .= '
2086
            AND
2087
                fd.lang = \''.$language.'\'';
2088
        }
2089
        $query .= '
2090
                '.$this->queryPermission($this->groupSupport).'
2091
2092
            GROUP BY
2093
                fd.id,fd.lang,fcr.category_id,fv.visits,fv.last_visit,fdg.group_id,fdu.user_id
2094
            ORDER BY
2095
                fv.visits DESC';
2096
2097
        $result = $this->_config->getDb()->query($query);
2098
        $topten = [];
2099
        $data = [];
2100
2101 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...
2102
            if ($this->groupSupport) {
2103
                if (!in_array($row->user_id, array(-1, $this->user)) || !in_array($row->group_id, $this->groups)) {
2104
                    continue;
2105
                }
2106
            } else {
2107
                if (!in_array($row->user_id, array(-1, $this->user))) {
2108
                    continue;
2109
                }
2110
            }
2111
2112
            $data['visits'] = $row->visits;
2113
            $data['question'] = $row->question;
2114
            $data['date'] = $row->updated;
2115
            $data['last_visit'] = $row->last_visit;
2116
2117
            $title = $row->question;
2118
            $url = sprintf(
2119
                '%sindex.php?%saction=artikel&cat=%d&id=%d&artlang=%s',
2120
                $this->_config->getDefaultUrl(),
2121
                $sids,
2122
                $row->category_id,
2123
                $row->id,
2124
                $row->lang
2125
            );
2126
            $oLink = new PMF_Link($url, $this->_config);
2127
            $oLink->itemTitle = $row->question;
2128
            $oLink->tooltip = $title;
2129
            $data['url'] = $oLink->toString();
2130
2131
            $topten[$row->id] = $data;
2132
2133
            if (count($topten) === $count) {
2134
                break;
2135
            }
2136
        }
2137
2138
        return $topten;
2139
    }
2140
2141
    /**
2142
     * This function generates an array with a specified number of most recent
2143
     * published records.
2144
     *
2145
     * @param int    $count    Number of records
2146
     * @param string $language Language
2147
     *
2148
     * @return array
2149
     */
2150
    public function getLatestData($count = PMF_NUMBER_RECORDS_LATEST, $language = null)
2151
    {
2152
        global $sids;
2153
2154
        $now = date('YmdHis');
2155
        $query =
2156
'            SELECT
2157
                fd.id AS id,
2158
                fd.lang AS lang,
2159
                fcr.category_id AS category_id,
2160
                fd.thema AS question,
2161
                fd.content AS content,
2162
                fd.updated AS updated,
2163
                fv.visits AS visits,
2164
                fdg.group_id AS group_id,
2165
                fdu.user_id AS user_id
2166
            FROM
2167
                '.PMF_Db::getTablePrefix().'faqvisits fv,
2168
                '.PMF_Db::getTablePrefix().'faqdata fd
2169
            LEFT JOIN
2170
                '.PMF_Db::getTablePrefix().'faqcategoryrelations fcr
2171
            ON
2172
                fd.id = fcr.record_id
2173
            AND
2174
                fd.lang = fcr.record_lang
2175
            LEFT JOIN
2176
                '.PMF_Db::getTablePrefix().'faqdata_group AS fdg
2177
            ON
2178
                fd.id = fdg.record_id
2179
            LEFT JOIN
2180
                '.PMF_Db::getTablePrefix().'faqdata_user AS fdu
2181
            ON
2182
                fd.id = fdu.record_id
2183
            WHERE
2184
                    fd.date_start <= \''.$now.'\'
2185
                AND fd.date_end   >= \''.$now.'\'
2186
                AND fd.id = fv.id
2187
                AND fd.lang = fv.lang
2188
                AND fd.active = \'yes\'';
2189
2190
        if (isset($language) && PMF_Language::isASupportedLanguage($language)) {
2191
            $query .= '
2192
            AND
2193
                fd.lang = \''.$language.'\'';
2194
        }
2195
        $query .= '
2196
                '.$this->queryPermission($this->groupSupport).'
2197
            GROUP BY
2198
                fd.id,fd.lang,fcr.category_id,fv.visits,fdg.group_id,fdu.user_id
2199
            ORDER BY
2200
                fd.updated DESC';
2201
2202
        $result = $this->_config->getDb()->query($query);
2203
        $latest = [];
2204
        $data = [];
2205
2206 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...
2207
            if ($this->groupSupport) {
2208
                if (!in_array($row->user_id, array(-1, $this->user)) || !in_array($row->group_id, $this->groups)) {
2209
                    continue;
2210
                }
2211
            } else {
2212
                if (!in_array($row->user_id, array(-1, $this->user))) {
2213
                    continue;
2214
                }
2215
            }
2216
2217
            $data['date'] = $row->updated;
2218
            $data['question'] = $row->question;
2219
            $data['answer'] = $row->content;
2220
            $data['visits'] = $row->visits;
2221
2222
            $title = $row->question;
2223
            $url = sprintf(
2224
                '%sindex.php?%saction=artikel&cat=%d&id=%d&artlang=%s',
2225
                $this->_config->getDefaultUrl(),
2226
                $sids,
2227
                $row->category_id,
2228
                $row->id,
2229
                $row->lang
2230
            );
2231
            $oLink = new PMF_Link($url, $this->_config);
2232
            $oLink->itemTitle = $row->question;
2233
            $oLink->tooltip = $title;
2234
            $data['url'] = $oLink->toString();
2235
2236
            $latest[$row->id] = $data;
2237
2238
            if (count($latest) === $count) {
2239
                break;
2240
            }
2241
        }
2242
2243
        return $latest;
2244
    }
2245
2246
    /**
2247
     * Reload locking for user votings.
2248
     *
2249
     * @param int    $id FAQ record id
2250
     * @param string $ip IP
2251
     *
2252
     * @return bool
2253
     */
2254
    public function votingCheck($id, $ip)
2255
    {
2256
        $check = $_SERVER['REQUEST_TIME'] - 300;
2257
        $query = sprintf(
2258
            "SELECT
2259
                id
2260
            FROM
2261
                %sfaqvoting
2262
            WHERE
2263
                artikel = %d AND (ip = '%s' AND datum > '%s')",
2264
            PMF_Db::getTablePrefix(),
2265
            $id,
2266
            $ip,
2267
            $check);
2268
        if ($this->_config->getDb()->numRows($this->_config->getDb()->query($query))) {
2269
            return false;
2270
        }
2271
2272
        return true;
2273
    }
2274
2275
    /**
2276
     * Returns the number of users from the table faqvotings.
2277
     *
2278
     * @param integer $record_id
2279
     *
2280
     * @return integer
2281
     */
2282 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...
2283
    {
2284
        $query = sprintf(
2285
            'SELECT
2286
                usr
2287
            FROM
2288
                %sfaqvoting
2289
            WHERE
2290
                artikel = %d',
2291
            PMF_Db::getTablePrefix(),
2292
            $record_id);
2293
        if ($result = $this->_config->getDb()->query($query)) {
2294
            if ($row = $this->_config->getDb()->fetchObject($result)) {
2295
                return $row->usr;
2296
            }
2297
        }
2298
2299
        return 0;
2300
    }
2301
2302
    /**
2303
     * Adds a new voting record.
2304
     *
2305
     * @param array $votingData
2306
     *
2307
     * @return bool
2308
     */
2309
    public function addVoting($votingData)
2310
    {
2311
        if (!is_array($votingData)) {
2312
            return false;
2313
        }
2314
2315
        $query = sprintf(
2316
            "INSERT INTO
2317
                %sfaqvoting
2318
            VALUES
2319
                (%d, %d, %d, 1, %d, '%s')",
2320
            PMF_Db::getTablePrefix(),
2321
            $this->_config->getDb()->nextId(PMF_Db::getTablePrefix().'faqvoting', 'id'),
2322
            $votingData['record_id'],
2323
            $votingData['vote'],
2324
            $_SERVER['REQUEST_TIME'],
2325
            $votingData['user_ip']);
2326
        $this->_config->getDb()->query($query);
2327
2328
        return true;
2329
    }
2330
2331
    /**
2332
     * Adds a new question.
2333
     *
2334
     * @param array $questionData
2335
     *
2336
     * @return bool
2337
     */
2338
    public function addQuestion(Array $questionData)
2339
    {
2340
        $query = sprintf("
2341
            INSERT INTO
2342
                %sfaqquestions
2343
            VALUES
2344
                (%d, '%s', '%s', '%s', %d, '%s', '%s', '%s', %d)",
2345
            PMF_Db::getTablePrefix(),
2346
            $this->_config->getDb()->nextId(PMF_Db::getTablePrefix().'faqquestions', 'id'),
2347
            $this->_config->getLanguage()->getLanguage(),
2348
            $this->_config->getDb()->escape($questionData['username']),
2349
            $this->_config->getDb()->escape($questionData['email']),
2350
            $questionData['category_id'],
2351
            $this->_config->getDb()->escape($questionData['question']),
2352
            date('YmdHis'),
2353
            $questionData['is_visible'],
2354
            0
2355
        );
2356
        $this->_config->getDb()->query($query);
2357
2358
        return true;
2359
    }
2360
2361
    /**
2362
     * Returns a new question.
2363
     *
2364
     * @param int $questionId
2365
     *
2366
     * @return array
2367
     */
2368
    public function getQuestion($questionId)
2369
    {
2370
        $question = [
2371
            'id' => 0,
2372
            'lang' => '',
2373
            'username' => '',
2374
            'email' => '',
2375
            'category_id' => '',
2376
            'question' => '',
2377
            'created' => '',
2378
            'is_visible' => '',
2379
        ];
2380
2381
        if (!is_int($questionId)) {
2382
            return $question;
2383
        }
2384
2385
        $question = [];
2386
2387
        $query = sprintf("
2388
            SELECT
2389
                 id, lang, username, email, category_id, question, created, is_visible
2390
            FROM
2391
                %sfaqquestions
2392
            WHERE
2393
                id = %d
2394
            AND
2395
                lang = '%s'",
2396
            PMF_Db::getTablePrefix(),
2397
            $questionId,
2398
            $this->_config->getLanguage()->getLanguage()
2399
        );
2400
2401 View Code Duplication
        if ($result = $this->_config->getDb()->query($query)) {
2402
            if ($row = $this->_config->getDb()->fetchObject($result)) {
2403
                $question = array(
2404
                    'id' => $row->id,
2405
                    'lang' => $row->lang,
2406
                    'username' => $row->username,
2407
                    'email' => $row->email,
2408
                    'category_id' => $row->category_id,
2409
                    'question' => $row->question,
2410
                    'created' => $row->created,
2411
                    'is_visible' => $row->is_visible, );
2412
            }
2413
        }
2414
2415
        return $question;
2416
    }
2417
2418
     /**
2419
      * Returns all open questions.
2420
      *
2421
      * @param  $all boolean If true, then return visible and unvisble questions; otherwise only visible ones
2422
      *
2423
      * @return array
2424
      */
2425
     public function getAllOpenQuestions($all = true)
2426
     {
2427
         $questions = [];
2428
2429
         $query = sprintf("
2430
            SELECT
2431
                id, lang, username, email, category_id, question, created, answer_id, is_visible
2432
            FROM
2433
                %sfaqquestions
2434
            WHERE
2435
                lang = '%s'
2436
                %s
2437
            ORDER BY 
2438
                created ASC",
2439
            PMF_Db::getTablePrefix(),
2440
            $this->_config->getLanguage()->getLanguage(),
2441
            ($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...
2442
        );
2443
2444 View Code Duplication
         if ($result = $this->_config->getDb()->query($query)) {
2445
             while ($row = $this->_config->getDb()->fetchObject($result)) {
2446
                 $questions[] = array(
2447
                    'id' => $row->id,
2448
                    'lang' => $row->lang,
2449
                    'username' => $row->username,
2450
                    'email' => $row->email,
2451
                    'category_id' => $row->category_id,
2452
                    'question' => $row->question,
2453
                    'created' => $row->created,
2454
                    'answer_id' => $row->answer_id,
2455
                    'is_visible' => $row->is_visible,
2456
                );
2457
             }
2458
         }
2459
2460
         return $questions;
2461
     }
2462
2463
    /**
2464
     * Updates an existing voting record.
2465
     *
2466
     * @param array $votingData
2467
     *
2468
     * @return bool
2469
     */
2470
    public function updateVoting($votingData)
2471
    {
2472
        if (!is_array($votingData)) {
2473
            return false;
2474
        }
2475
2476
        $query = sprintf(
2477
            "UPDATE
2478
                %sfaqvoting
2479
            SET
2480
                vote    = vote + %d,
2481
                usr     = usr + 1,
2482
                datum   = %d,
2483
                ip      = '%s'
2484
            WHERE
2485
                artikel = %d",
2486
            PMF_Db::getTablePrefix(),
2487
            $votingData['vote'],
2488
            $_SERVER['REQUEST_TIME'],
2489
            $votingData['user_ip'],
2490
            $votingData['record_id']);
2491
        $this->_config->getDb()->query($query);
2492
2493
        return true;
2494
    }
2495
2496
    /**
2497
     * Adds a new changelog entry in the table faqchanges.
2498
     *
2499
     * @param int    $id
2500
     * @param int    $userId
2501
     * @param string $text
2502
     * @param string $lang
2503
     * @param int    $revision_id
2504
     *
2505
     * @return bool
2506
     */
2507
    public function createChangeEntry($id, $userId, $text, $lang, $revision_id = 0)
2508
    {
2509
        if (!is_numeric($id)
2510
            && !is_numeric($userId)
2511
            && !is_string($text)
2512
            && !is_string($lang)
2513
            ) {
2514
            return false;
2515
        }
2516
2517
        $query = sprintf(
2518
            "INSERT INTO
2519
                %sfaqchanges
2520
            (id, beitrag, lang, revision_id, usr, datum, what)
2521
                VALUES
2522
            (%d, %d, '%s', %d, %d, %d, '%s')",
2523
            PMF_Db::getTablePrefix(),
2524
            $this->_config->getDb()->nextId(PMF_Db::getTablePrefix().'faqchanges', 'id'),
2525
            $id,
2526
            $lang,
2527
            $revision_id,
2528
            $userId,
2529
            $_SERVER['REQUEST_TIME'],
2530
            $text);
2531
2532
        $this->_config->getDb()->query($query);
2533
2534
        return true;
2535
    }
2536
2537
    /**
2538
     * Returns the changelog of a FAQ record.
2539
     *
2540
     * @param int $record_id
2541
     *
2542
     * @return array
2543
     */
2544 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...
2545
    {
2546
        $entries = [];
2547
2548
        $query = sprintf('
2549
            SELECT
2550
                DISTINCT revision_id, usr, datum, what
2551
            FROM
2552
                %sfaqchanges
2553
            WHERE
2554
                beitrag = %d
2555
            ORDER BY id DESC',
2556
            PMF_Db::getTablePrefix(),
2557
            $record_id
2558
            );
2559
2560
        if ($result = $this->_config->getDb()->query($query)) {
2561
            while ($row = $this->_config->getDb()->fetchObject($result)) {
2562
                $entries[] = array(
2563
                    'revision_id' => $row->revision_id,
2564
                    'user' => $row->usr,
2565
                    'date' => $row->datum,
2566
                    'changelog' => $row->what, );
2567
            }
2568
        }
2569
2570
        return $entries;
2571
    }
2572
2573
    /**
2574
     * Retrieve faq records according to the constraints provided.
2575
     *
2576
     * @param string $queryType
2577
     * @param int    $nCatid
2578
     * @param bool   $bDownwards
2579
     * @param string $lang
2580
     * @param string $date
2581
     *
2582
     * @return array
2583
     */
2584
    public function get($queryType = FAQ_QUERY_TYPE_DEFAULT, $nCatid = 0, $bDownwards = true, $lang = '', $date = '')
2585
    {
2586
        $faqs = [];
2587
2588
        $result = $this->_config->getDb()->query($this->_getSQLQuery($queryType, $nCatid, $bDownwards, $lang, $date));
2589
2590
        if ($this->_config->getDb()->numRows($result) > 0) {
2591
            $i = 0;
2592
            while ($row = $this->_config->getDb()->fetchObject($result)) {
2593
                $faq = [];
2594
                $faq['id'] = $row->id;
2595
                $faq['solution_id'] = $row->solution_id;
2596
                $faq['revision_id'] = $row->revision_id;
2597
                $faq['lang'] = $row->lang;
2598
                $faq['category_id'] = $row->category_id;
2599
                $faq['active'] = $row->active;
2600
                $faq['sticky'] = $row->sticky;
2601
                $faq['keywords'] = $row->keywords;
2602
                $faq['topic'] = $row->thema;
2603
                $faq['content'] = $row->content;
2604
                $faq['author_name'] = $row->author;
2605
                $faq['author_email'] = $row->email;
2606
                $faq['comment_enable'] = $row->comment;
2607
                $faq['lastmodified'] = $row->updated;
2608
                $faq['hits'] = $row->visits;
2609
                $faq['hits_last'] = $row->last_visit;
2610
                $faq['notes'] = $row->notes;
2611
                $faqs[$i] = $faq;
2612
                ++$i;
2613
            }
2614
        }
2615
2616
        return $faqs;
2617
    }
2618
2619
    /**
2620
     * Build a logic sequence, for a WHERE statement, of those category IDs
2621
     * children of the provided category ID, if any.
2622
     *
2623
     * @param   $nCatid
2624
     * @param   $logicOp
2625
     * @param   $oCat
2626
     *
2627
     * @return string
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
    private function _getSQLQuery($QueryType, $nCatid, $bDownwards, $lang, $date, $faqid = 0)
2659
    {
2660
        $now = date('YmdHis');
2661
        $query = sprintf("
2662
            SELECT
2663
                fd.id AS id,
2664
                fd.solution_id AS solution_id,
2665
                fd.revision_id AS revision_id,
2666
                fd.lang AS lang,
2667
                fcr.category_id AS category_id,
2668
                fd.active AS active,
2669
                fd.sticky AS sticky,
2670
                fd.keywords AS keywords,
2671
                fd.thema AS thema,
2672
                fd.content AS content,
2673
                fd.author AS author,
2674
                fd.email AS email,
2675
                fd.comment AS comment,
2676
                fd.updated AS updated,
2677
                fd.notes AS notes,
2678
                fv.visits AS visits,
2679
                fv.last_visit AS last_visit
2680
            FROM
2681
                %sfaqdata fd,
2682
                %sfaqvisits fv,
2683
                %sfaqcategoryrelations fcr
2684
            WHERE
2685
                fd.id = fcr.record_id
2686
            AND
2687
                fd.lang = fcr.record_lang
2688
            AND
2689
                fd.date_start <= '%s'
2690
            AND
2691
                fd.date_end   >= '%s'
2692
            AND ",
2693
            PMF_Db::getTablePrefix(),
2694
            PMF_Db::getTablePrefix(),
2695
            PMF_Db::getTablePrefix(),
2696
            $now,
2697
            $now);
2698
        // faqvisits data selection
2699
        if (!empty($faqid)) {
2700
            // Select ONLY the faq with the provided $faqid
2701
            $query .= "fd.id = '".$faqid."' AND ";
2702
        }
2703
        $query .= 'fd.id = fv.id
2704
            AND
2705
                fd.lang = fv.lang';
2706
        $needAndOp = true;
2707
        if ((!empty($nCatid)) && is_int($nCatid) && $nCatid > 0) {
2708
            if ($needAndOp) {
2709
                $query .= ' AND';
2710
            }
2711
            $query .= ' (fcr.category_id = '.$nCatid;
2712
            if ($bDownwards) {
2713
                $query .= $this->_getCatidWhereSequence($nCatid, 'OR');
2714
            }
2715
            $query .= ')';
2716
            $needAndOp = true;
2717
        }
2718 View Code Duplication
        if ((!empty($date)) && PMF_Utils::isLikeOnPMFDate($date)) {
2719
            if ($needAndOp) {
2720
                $query .= ' AND';
2721
            }
2722
            $query .= " fd.updated LIKE '".$date."'";
2723
            $needAndOp = true;
2724
        }
2725 View Code Duplication
        if ((!empty($lang)) && PMF_Utils::isLanguage($lang)) {
2726
            if ($needAndOp) {
2727
                $query .= ' AND';
2728
            }
2729
            $query .= " fd.lang = '".$lang."'";
2730
            $needAndOp = true;
2731
        }
2732
        switch ($QueryType) {
2733
            case FAQ_QUERY_TYPE_APPROVAL:
2734
                if ($needAndOp) {
2735
                    $query .= ' AND';
2736
                }
2737
                $query .= " fd.active = '".FAQ_SQL_ACTIVE_NO."'";
2738
                $needAndOp = true;
2739
                break;
2740
            case FAQ_QUERY_TYPE_EXPORT_PDF:
2741
            case FAQ_QUERY_TYPE_EXPORT_XHTML:
2742 View Code Duplication
            case FAQ_QUERY_TYPE_EXPORT_XML:
2743
                if ($needAndOp) {
2744
                    $query .= ' AND';
2745
                }
2746
                $query .= " fd.active = '".FAQ_SQL_ACTIVE_YES."'";
2747
                $needAndOp = true;
2748
                break;
2749 View Code Duplication
            default:
2750
                if ($needAndOp) {
2751
                    $query .= ' AND';
2752
                }
2753
                $query .= " fd.active = '".FAQ_SQL_ACTIVE_YES."'";
2754
                $needAndOp = true;
2755
                break;
2756
        }
2757
        // Sort criteria
2758
        switch ($QueryType) {
2759
            case FAQ_QUERY_TYPE_EXPORT_PDF:
2760
            case FAQ_QUERY_TYPE_EXPORT_XHTML:
2761
            case FAQ_QUERY_TYPE_EXPORT_XML:
2762
                $query .= "\nORDER BY fcr.category_id, fd.id";
2763
                break;
2764
            case FAQ_QUERY_TYPE_RSS_LATEST:
2765
                $query .= "\nORDER BY fd.updated DESC";
2766
                break;
2767
            default:
2768
                // Normal ordering
2769
                $query .= "\nORDER BY fcr.category_id, fd.id";
2770
                break;
2771
        }
2772
2773
        return $query;
2774
    }
2775
2776
    /**
2777
     * Adds the record permissions for users and groups.
2778
     *
2779
     * @param string $mode     'group' or 'user'
2780
     * @param int    $recordId ID of the current record
2781
     * @param array  $ids      Array of group or user IDs
2782
     *
2783
     * @return bool
2784
     */
2785
    public function addPermission($mode, $recordId, $ids)
2786
    {
2787
        if ('user' !== $mode && 'group' !== $mode) {
2788
            return false;
2789
        }
2790
2791
        foreach ($ids as $id) {
2792
            $query = sprintf('
2793
            INSERT INTO
2794
                %sfaqdata_%s
2795
            (record_id, %s_id)
2796
                VALUES
2797
            (%d, %d)',
2798
                PMF_Db::getTablePrefix(),
2799
                $mode,
2800
                $mode,
2801
                $recordId,
2802
                $id
2803
            );
2804
2805
            $this->_config->getDb()->query($query);
2806
        }
2807
2808
        return true;
2809
    }
2810
2811
    /**
2812
     * Deletes the record permissions for users and groups.
2813
     *
2814
     * @param string $mode      'group' or 'user'
2815
     * @param int    $record_id ID of the current record
2816
     *
2817
     * @return bool
2818
     *
2819
     * @author  Thorsten Rinne <[email protected]>
2820
     */
2821 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...
2822
    {
2823
        if (!($mode == 'user' || $mode == 'group')) {
2824
            return false;
2825
        }
2826
        if (!is_int($record_id)) {
2827
            return false;
2828
        }
2829
2830
        $query = sprintf('
2831
            DELETE FROM
2832
                %sfaqdata_%s
2833
            WHERE
2834
                record_id = %d',
2835
            PMF_Db::getTablePrefix(),
2836
            $mode,
2837
            $record_id);
2838
        $this->_config->getDb()->query($query);
2839
2840
        return true;
2841
    }
2842
2843
    /**
2844
     * Returns the record permissions for users and groups.
2845
     *
2846
     * @param string $mode     'group' or 'user'
2847
     * @param int    $recordId
2848
     *
2849
     * @return array
2850
     */
2851
    public function getPermission($mode, $recordId)
2852
    {
2853
        $permissions = [];
2854
2855
        if (!($mode == 'user' || $mode == 'group')) {
2856
            return false;
2857
        }
2858
2859
        $query = sprintf('
2860
            SELECT
2861
                %s_id AS permission
2862
            FROM
2863
                %sfaqdata_%s
2864
            WHERE
2865
                record_id = %d',
2866
            $mode,
2867
            PMF_Db::getTablePrefix(),
2868
            $mode,
2869
            (int) $recordId);
2870
2871
        $result = $this->_config->getDb()->query($query);
2872
2873 View Code Duplication
        if ($this->_config->getDb()->numRows($result) > 0) {
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...
2874
            while (($row = $this->_config->getDb()->fetchObject($result))) {
2875
                $permissions[] = (int) $row->permission;
2876
            }
2877
        }
2878
2879
        return $permissions;
2880
    }
2881
2882
    /**
2883
     * Returns all records of one category.
2884
     *
2885
     * @param int $category
2886
     *
2887
     * @return string
2888
     */
2889
    public function showAllRecordsWoPaging($category)
2890
    {
2891
        global $sids;
2892
2893
        $now = date('YmdHis');
2894
        $query = '
2895
            SELECT
2896
                fd.id AS id,
2897
                fd.lang AS lang,
2898
                fd.thema AS thema,
2899
                fcr.category_id AS category_id,
2900
                fv.visits AS visits
2901
            FROM
2902
                '.PMF_Db::getTablePrefix().'faqdata fd
2903
            LEFT JOIN
2904
                '.PMF_Db::getTablePrefix().'faqcategoryrelations fcr
2905
            ON
2906
                fd.id = fcr.record_id
2907
            AND
2908
                fd.lang = fcr.record_lang
2909
            LEFT JOIN
2910
                '.PMF_Db::getTablePrefix().'faqvisits fv
2911
            ON
2912
                fd.id = fv.id
2913
            AND
2914
                fv.lang = fd.lang
2915
            LEFT JOIN
2916
                '.PMF_Db::getTablePrefix().'faqdata_group fdg
2917
            ON
2918
                fd.id = fdg.record_id
2919
            LEFT JOIN
2920
                '.PMF_Db::getTablePrefix().'faqdata_user fdu
2921
            ON
2922
                fd.id = fdu.record_id
2923
            WHERE
2924
                fd.date_start <= \''.$now.'\'
2925
            AND
2926
                fd.date_end   >= \''.$now.'\'
2927
            AND
2928
                fd.active = \'yes\'
2929
            AND
2930
                fcr.category_id = '.$category.'
2931
            AND
2932
                fd.lang = \''.$this->_config->getLanguage()->getLanguage().'\'
2933
            GROUP BY
2934
                fd.id,fd.lang,fcr.category_id,fv.visits
2935
            ORDER BY
2936
                fd.id';
2937
2938
        $result = $this->_config->getDb()->query($query);
2939
2940
        $output = '<ul class="phpmyfaq_ul">';
2941
2942
        while (($row = $this->_config->getDb()->fetchObject($result))) {
2943
            $title = $row->thema;
2944
            $url = sprintf(
2945
                '%s?%saction=artikel&amp;cat=%d&amp;id=%d&amp;artlang=%s',
2946
                PMF_Link::getSystemRelativeUri(),
2947
                $sids,
2948
                $row->category_id,
2949
                $row->id,
2950
                $row->lang
2951
            );
2952
2953
            $oLink = new PMF_Link($url, $this->_config);
2954
            $oLink->itemTitle = $row->thema;
2955
            $oLink->text = $title;
2956
            $oLink->tooltip = $title;
2957
            $listItem = sprintf('<li>%s</li>', $oLink->toHtmlAnchor(), $this->pmf_lang['msgViews']);
2958
            $listItem = '<li>'.$oLink->toHtmlAnchor().'</li>';
2959
2960
            $output .= $listItem;
2961
        }
2962
2963
        $output .= '</ul>';
2964
2965
        return $output;
2966
    }
2967
2968
    /**
2969
     * Prints the open questions as a XHTML table.
2970
     *
2971
     * @return string
2972
     */
2973
    public function printOpenQuestions()
2974
    {
2975
        global $sids, $category;
2976
2977
        $date = new PMF_Date($this->_config);
2978
        $mail = new PMF_Mail($this->_config);
2979
2980
        $query = sprintf("
2981
            SELECT
2982
                COUNT(id) AS num
2983
            FROM
2984
                %sfaqquestions
2985
            WHERE
2986
                lang = '%s'
2987
            AND
2988
                is_visible != 'Y'",
2989
            PMF_Db::getTablePrefix(),
2990
            $this->_config->getLanguage()->getLanguage()
2991
        );
2992
2993
        $result = $this->_config->getDb()->query($query);
2994
        $row = $this->_config->getDb()->fetchObject($result);
2995
        $numOfInvisibles = $row->num;
2996
2997
        if ($numOfInvisibles > 0) {
2998
            $extraout = sprintf(
2999
                '<tr><td colspan="3"><small>%s %s</small></td></tr>',
3000
                $this->pmf_lang['msgQuestionsWaiting'],
3001
                $numOfInvisibles
3002
            );
3003
        } else {
3004
            $extraout = '';
3005
        }
3006
3007
        $query = sprintf("
3008
            SELECT
3009
                *
3010
            FROM
3011
                %sfaqquestions
3012
            WHERE
3013
                lang = '%s'
3014
            AND
3015
                is_visible = 'Y'
3016
            ORDER BY
3017
                created ASC",
3018
            PMF_Db::getTablePrefix(),
3019
            $this->_config->getLanguage()->getLanguage()
3020
        );
3021
3022
        $result = $this->_config->getDb()->query($query);
3023
        $output = '';
3024
3025
        if ($result && $this->_config->getDb()->numRows($result) > 0) {
3026
            while ($row = $this->_config->getDb()->fetchObject($result)) {
3027
                $output .= '<tr class="openquestions">';
3028
                $output .= sprintf(
3029
                    '<td><small>%s</small><br /><a href="mailto:%s">%s</a></td>',
3030
                    $date->format(PMF_Date::createIsoDate($row->created)),
3031
                    $mail->safeEmail($row->email),
3032
                    $row->username
3033
                );
3034
                $output .= sprintf(
3035
                    '<td><strong>%s:</strong><br />%s</td>',
3036
                    isset($category->categoryName[$row->category_id]['name']) ? $category->categoryName[$row->category_id]['name'] : '',
3037
                    strip_tags($row->question)
3038
                );
3039
                if ($this->_config->get('records.enableCloseQuestion') && $row->answer_id) {
3040
                    $output .= sprintf(
3041
                        '<td><a id="PMF_openQuestionAnswered" href="?%saction=artikel&amp;cat=%d&amp;id=%d">%s</a></td>',
3042
                        $sids,
3043
                        $row->category_id,
3044
                        $row->answer_id,
3045
                        $this->pmf_lang['msg2answerFAQ']
3046
                    );
3047
                } else {
3048
                    $output .= sprintf(
3049
                        '<td><a class="btn btn-primary" href="?%saction=add&amp;question=%d&amp;cat=%d">%s</a></td>',
3050
                        $sids,
3051
                        $row->id,
3052
                        $row->category_id,
3053
                        $this->pmf_lang['msg2answer']
3054
                    );
3055
                }
3056
                $output .= '</tr>';
3057
            }
3058
        } else {
3059
            $output = sprintf(
3060
                '<tr><td colspan="3">%s</td></tr>',
3061
                $this->pmf_lang['msgNoQuestionsAvailable']
3062
            );
3063
        }
3064
3065
        return $output.$extraout;
3066
    }
3067
3068
    /**
3069
     * Set or unset a faq item flag.
3070
     *
3071
     * @param int    $id   Record id
3072
     * @param string $lang language code which is valid with Language::isASupportedLanguage
3073
     * @param bool   $flag weither or not the record is set to sticky
3074
     * @param string $type type of the flag to set, use the column name
3075
     *
3076
     * @return bool
3077
     */
3078
    public function updateRecordFlag($id, $lang, $flag, $type)
3079
    {
3080
        $retval = false;
3081
3082
        switch ($type) {
3083
            case 'sticky':
3084
                $flag = ($flag === 'checked' ? 1 : 0);
3085
                break;
3086
3087
            case 'active':
3088
                $flag = ($flag === 'checked' ? "'yes'" : "'no'");
3089
                break;
3090
3091
            default:
3092
                // This is because we would run into unknown db column
3093
                $flag = null;
3094
                break;
3095
        }
3096
3097
        if (null !== $flag) {
3098
            $update = sprintf("
3099
                UPDATE 
3100
                    %sfaqdata 
3101
                SET 
3102
                    %s = %s 
3103
                WHERE 
3104
                    id = %d 
3105
                AND 
3106
                    lang = '%s'",
3107
                PMF_Db::getTablePrefix(),
3108
                $type,
3109
                $flag,
3110
                $id,
3111
                $lang
3112
            );
3113
3114
            $retval = (bool) $this->_config->getDb()->query($update);
3115
        }
3116
3117
        return $retval;
3118
    }
3119
3120
    /**
3121
     * Returns the sticky records with URL and Title.
3122
     *
3123
     * @return array
3124
     */
3125
    private function getStickyRecordsData()
3126
    {
3127
        global $sids;
3128
3129
        $now = date('YmdHis');
3130
        $query = sprintf("
3131
            SELECT
3132
                fd.id AS id,
3133
                fd.lang AS lang,
3134
                fd.thema AS thema,
3135
                fcr.category_id AS category_id
3136
            FROM
3137
                %sfaqdata fd
3138
            LEFT JOIN
3139
                %sfaqcategoryrelations fcr
3140
            ON
3141
                fd.id = fcr.record_id
3142
            AND
3143
                fd.lang = fcr.record_lang
3144
            LEFT JOIN
3145
                %sfaqdata_group AS fdg
3146
            ON
3147
                fd.id = fdg.record_id
3148
            LEFT JOIN
3149
                %sfaqdata_user AS fdu
3150
            ON
3151
                fd.id = fdu.record_id
3152
            WHERE
3153
                fd.lang = '%s'
3154
            AND 
3155
                fd.date_start <= '%s'
3156
            AND 
3157
                fd.date_end   >= '%s'
3158
            AND 
3159
                fd.active = 'yes'
3160
            AND 
3161
                fd.sticky = 1
3162
            %s",
3163
            PMF_Db::getTablePrefix(),
3164
            PMF_Db::getTablePrefix(),
3165
            PMF_Db::getTablePrefix(),
3166
            PMF_Db::getTablePrefix(),
3167
            $this->_config->getLanguage()->getLanguage(),
3168
            $now,
3169
            $now,
3170
            $this->queryPermission($this->groupSupport)
3171
        );
3172
3173
        $result = $this->_config->getDb()->query($query);
3174
        $sticky = [];
3175
        $data = [];
3176
3177
        $oldId = 0;
3178
        while (($row = $this->_config->getDb()->fetchObject($result))) {
3179
            if ($oldId != $row->id) {
3180
                $data['thema'] = $row->thema;
3181
3182
                $title = $row->thema;
3183
                $url = sprintf(
3184
                    '%s?%saction=artikel&amp;cat=%d&amp;id=%d&amp;artlang=%s',
3185
                    PMF_Link::getSystemRelativeUri(),
3186
                    $sids,
3187
                    $row->category_id,
3188
                    $row->id,
3189
                    $row->lang
3190
                );
3191
                $oLink = new PMF_Link($url, $this->_config);
3192
                $oLink->itemTitle = $row->thema;
3193
                $oLink->tooltip = $title;
3194
                $data['url'] = $oLink->toString();
3195
3196
                $sticky[] = $data;
3197
            }
3198
            $oldId = $row->id;
3199
        }
3200
3201
        return $sticky;
3202
    }
3203
3204
    /**
3205
     * Prepares and returns the sticky records for the frontend.
3206
     *
3207
     * @return array
3208
     */
3209
    public function getStickyRecords()
3210
    {
3211
        $result = $this->getStickyRecordsData();
3212
        $output = [];
3213
3214
        if (count($result) > 0) {
3215
            foreach ($result as $row) {
3216
                $output[] = array(
3217
                    'title' => PMF_Utils::makeShorterText($row['thema'], 8),
3218
                    'preview' => $row['thema'],
3219
                    'url' => $row['url'],
3220
                );
3221
            }
3222
        } else {
3223
            $output['error'] = sprintf('<li>%s</li>', $this->pmf_lang['err_noTopTen']);
3224
        }
3225
        if (!isset($output['error'])) {
3226
            $html = '';
3227
            foreach ($output as $entry) {
3228
                $html .= sprintf(
3229
                    '<li><a class="sticky-faqs" data-toggle="tooltip" data-placement="top" title="%s" href="%s">%s</a></li>',
3230
                    $entry['preview'],
3231
                    $entry['url'],
3232
                    $entry['title']
3233
                );
3234
            }
3235
            $output['html'] = $html;
3236
        }
3237
3238
        return $output;
3239
    }
3240
3241
    /**
3242
     * Updates field answer_id in faqquestion.
3243
     *
3244
     * @param int $openQuestionId
3245
     * @param int $faqId
3246
     * @param int $categoryId
3247
     *
3248
     * @return bool
3249
     */
3250 View Code Duplication
    public function updateQuestionAnswer($openQuestionId, $faqId, $categoryId)
3251
    {
3252
        $query = sprintf(
3253
            'UPDATE %sfaqquestions SET answer_id = %d, category_id= %d WHERE id= %d',
3254
            PMF_Db::getTablePrefix(),
3255
            $faqId,
3256
            $categoryId,
3257
            $openQuestionId
3258
        );
3259
3260
        return $this->_config->getDb()->query($query);
3261
    }
3262
3263
    /**
3264
     * Returns a part of a query to check permissions.
3265
     *
3266
     * @param bool $hasGroupSupport
3267
     *
3268
     * @return string
3269
     */
3270
    protected function queryPermission($hasGroupSupport = false)
3271
    {
3272
        if ($hasGroupSupport) {
3273
            if (-1 === $this->user) {
3274
                return sprintf(
3275
                    'AND fdg.group_id IN (%s)',
3276
                    implode(', ', $this->groups),
3277
                    $this->user,
3278
                    implode(', ', $this->groups));
3279 View Code Duplication
            } else {
3280
                return sprintf(
3281
                    'AND ( fdg.group_id IN (%s) OR (fdu.user_id = %d OR fdg.group_id IN (%s)) )',
3282
                    implode(', ', $this->groups),
3283
                    $this->user,
3284
                    implode(', ', $this->groups)
3285
                );
3286
            }
3287
        } else {
3288
            if (-1 !== $this->user) {
3289
                return sprintf(
3290
                    'AND ( fdu.user_id = %d OR fdu.user_id = -1 )',
3291
                    $this->user
3292
                );
3293
            } else {
3294
                return sprintf(
3295
                    'AND fdu.user_id = -1',
3296
                    $this->user
3297
                );
3298
            }
3299
        }
3300
    }
3301
}
3302