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 ( 9ab307...5749f1 )
by Thorsten
15:15
created

PMF_Category::getOwner()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 1 Features 0
Metric Value
cc 2
eloc 2
nc 2
nop 1
dl 0
loc 4
rs 10
c 1
b 1
f 0
1
<?php
2
3
/**
4
 * The main category 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
 *
14
 * @author    Thorsten Rinne <[email protected]>
15
 * @author    Lars Tiedemann <[email protected]>
16
 * @author    Matteo Scaramuccia <[email protected]>
17
 * @author    Rudi Ferrari <[email protected]>
18
 * @copyright 2004-2016 phpMyFAQ Team
19
 * @license   http://www.mozilla.org/MPL/2.0/ Mozilla Public License Version 2.0
20
 *
21
 * @link      http://www.phpmyfaq.de
22
 * @since     2004-02-16
23
 */
24
if (!defined('IS_VALID_PHPMYFAQ')) {
25
    exit();
26
}
27
28
/**
29
 * Category.
30
 *
31
 * @category  phpMyFAQ
32
 *
33
 * @author    Thorsten Rinne <[email protected]>
34
 * @author    Lars Tiedemann <[email protected]>
35
 * @author    Matteo Scaramuccia <[email protected]>
36
 * @author    Rudi Ferrari <[email protected]>
37
 * @copyright 2004-2016 phpMyFAQ Team
38
 * @license   http://www.mozilla.org/MPL/2.0/ Mozilla Public License Version 2.0
39
 *
40
 * @link      http://www.phpmyfaq.de
41
 * @since     2004-02-16
42
 */
43
class PMF_Category
44
{
45
    /**
46
     * @var PMF_Configuration
47
     */
48
    private $_config = null;
49
50
    /**
51
     * User ID.
52
     *
53
     * @var int
54
     */
55
    private $user = -1;
56
57
    /**
58
     * Groupd.
59
     *
60
     * @var array
61
     */
62
    private $groups = array(-1);
63
64
    /**
65
     * The categories as an array.
66
     *
67
     * @var array
68
     */
69
    public $categories = [];
70
71
    /**
72
     * The category names as an array.
73
     *
74
     * @var array
75
     */
76
    public $categoryName = [];
77
78
    /**
79
     * The category tree.
80
     *
81
     * @var array
82
     */
83
    public $catTree = [];
84
85
    /**
86
     * The children nodes.
87
     *
88
     * @var array
89
     */
90
    private $children = [];
91
92
    /**
93
     * The current language.
94
     *
95
     * @var string
96
     */
97
    private $language = null;
98
99
    /**
100
     * The lines of tabs.
101
     *
102
     * @var array
103
     */
104
    private $lineTab = [];
105
106
    /**
107
     * The tree with the tabs.
108
     *
109
     * @var array
110
     */
111
    public $treeTab = [];
112
113
    /**
114
     * Category owners
115
     *
116
     * @var array
117
     */
118
    private $owner = array();
119
120
    /**
121
     * Symbol for each item
122
     * NOTE: We do not use this currently.
123
     *
124
     * @var array
125
     */
126
    private $symbols = array(
127
        'vertical' => '|',
128
        'plus' => '+',
129
        'minus' => '-',
130
        'space' => '&nbsp;',
131
        'angle' => '-',
132
        'medium' => '|-', );
133
134
    /**
135
     * Constructor.
136
     *
137
     * @param PMF_Configuration $config   Configuration object
138
     * @param array             $groups   Array with group IDs
139
     * @param bool              $withperm With or without permission check
140
     */
141
    public function __construct(PMF_Configuration $config, $groups = [], $withperm = true)
142
    {
143
        $this->_config = $config;
144
145
        $this->setGroups($groups);
146
        $this->setLanguage($this->_config->getLanguage()->getLanguage());
147
148
        $this->lineTab = $this->getOrderedCategories($withperm);
149
        foreach (array_keys($this->lineTab) as $i) {
150
            $this->lineTab[$i]['level'] = $this->levelOf($this->lineTab[$i]['id']);
151
        }
152
    }
153
154
    /**
155
     * @param int $userId
156
     */
157
    public function setUser($userId = -1)
158
    {
159
        $this->user = $userId;
160
    }
161
162
    /**
163
     * @param array $groups
164
     */
165
    public function setGroups(Array $groups)
166
    {
167
        if (0 === count($groups)) {
168
            $groups = array(-1);
169
        }
170
        $this->groups = $groups;
171
    }
172
173
    /**
174
     * Returns all categories with ordered category IDs according to the user
175
     * and group permissions.
176
     *
177
     * @param bool $withperm With or without permission check
178
     *
179
     * @return array
180
     */
181
    private function getOrderedCategories($withperm = true)
182
    {
183
        $where = '';
184
185 View Code Duplication
        if ($withperm) {
186
            $where = sprintf('
187
                WHERE
188
                    ( fg.group_id IN (%s)
189
                OR
190
                    (fu.user_id = %d AND fg.group_id IN (%s)))',
191
                implode(', ', $this->groups),
192
                $this->user,
193
                implode(', ', $this->groups)
194
            );
195
        }
196
197
        if (isset($this->language) && preg_match("/^[a-z\-]{2,}$/", $this->language)) {
198
            $where .= empty($where) ? '
199
            WHERE' : '
200
            AND';
201
            $where .= "
202
                fc.lang = '".$this->language."'";
203
        }
204
205
        $query = sprintf('
206
            SELECT
207
                fc.id AS id,
208
                fc.lang AS lang,
209
                fc.parent_id AS parent_id,
210
                fc.name AS name,
211
                fc.description AS description,
212
                fc.user_id AS user_id,
213
                fc.group_id AS group_id,
214
                fc.active AS active
215
            FROM
216
                %sfaqcategories fc
217
            LEFT JOIN
218
                %sfaqcategory_group fg
219
            ON
220
                fc.id = fg.category_id
221
            LEFT JOIN
222
                %sfaqcategory_user fu
223
            ON
224
                fc.id = fu.category_id
225
            %s
226
            GROUP BY
227
                fc.id, fc.lang, fc.parent_id, fc.name, fc.description, fc.user_id
228
            ORDER BY
229
                fc.parent_id, fc.id',
230
            PMF_Db::getTablePrefix(),
231
            PMF_Db::getTablePrefix(),
232
            PMF_Db::getTablePrefix(),
233
            $where
234
        );
235
236
        $result = $this->_config->getDb()->query($query);
237
238
        if ($result) {
239 View Code Duplication
            while ($row = $this->_config->getDb()->fetchArray($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...
240
                $this->categoryName[$row['id']] = $row;
241
                $this->categories[] =& $this->categoryName[$row['id']];
242
                $this->children[$row['parent_id']][$row['id']] =& $this->categoryName[$row['id']];
243
                $this->owner[$row['id']] =& $row['user_id'];
244
            }
245
        }
246
247
        return $this->categories;
248
    }
249
250
    /**
251
     * Gets the main categories and write them in an array.
252
     *
253
     * @param string $categories Array of parent category ids
254
     * @param bool   $parentId  Only top level categories?
255
     *
256
     * @return array
257
     */
258
    public function getCategories($categories, $parentId = true)
259
    {
260
        $_query = '';
261
        $query = sprintf('
262
            SELECT
263
                id, lang, parent_id, name, description, user_id, group_id, active
264
            FROM
265
                %sfaqcategories
266
            WHERE ',
267
            PMF_Db::getTablePrefix());
268
269
        if (true === $parentId) {
270
            $query .= 'parent_id = 0';
271
        }
272
        foreach (explode(',', $categories) as $cats) {
273
            $_query .= ' OR parent_id = '.$cats;
274
        }
275
        if (false === $parentId && 0 < PMF_String::strlen($_query)) {
276
            $query .= PMF_String::substr($_query, 4);
277
        }
278 View Code Duplication
        if (isset($this->language) && preg_match("/^[a-z\-]{2,}$/", $this->language)) {
279
            $query .= " AND lang = '".$this->language."'";
280
        }
281
        $query .= ' ORDER BY id';
282
        $result = $this->_config->getDb()->query($query);
283 View Code Duplication
        while ($row = $this->_config->getDb()->fetchArray($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...
284
            $this->categories[$row['id']] = $row;
285
        }
286
287
        return $this->categories;
288
    }
289
290
    /**
291
     * Gets all categories and write them in an array.
292
     *
293
     * @return array
294
     */
295
    public function getAllCategories()
296
    {
297
        $query = sprintf('
298
            SELECT
299
                id, lang, parent_id, name, description, user_id, group_id, active
300
            FROM
301
                %sfaqcategories',
302
            PMF_Db::getTablePrefix());
303 View Code Duplication
        if (isset($this->language) && preg_match("/^[a-z\-]{2,}$/", $this->language)) {
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...
304
            $query .= " WHERE lang = '".$this->language."'";
305
        }
306
        $result = $this->_config->getDb()->query($query);
307
        while ($row = $this->_config->getDb()->fetchArray($result)) {
308
            $this->categories[$row['id']] = [
309
                'id' => (int)$row['id'],
310
                'lang' => $row['lang'],
311
                'parent_id' => (int)$row['parent_id'],
312
                'name' => $row['name'],
313
                'description' => $row['description'],
314
                'user_id' => (int)$row['user_id'],
315
                'group_id' => (int)$row['group_id'],
316
                'active' => (int)$row['active'],
317
                'level' => (int)$this->levelOf($row['id'])
318
            ];
319
        }
320
321
        return $this->categories;
322
    }
323
324
    /**
325
     * Gets all category IDs
326
     *
327
     * @return array
328
     */
329
    public function getAllCategoryIds()
330
    {
331
        $categories = [];
332
333
        $query = sprintf('
334
            SELECT
335
                id
336
            FROM
337
                %sfaqcategories',
338
            PMF_Db::getTablePrefix()
339
        );
340
341 View Code Duplication
        if (isset($this->language) && preg_match("/^[a-z\-]{2,}$/", $this->language)) {
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...
342
            $query .= sprintf(" WHERE lang = '%s'", $this->language);
343
        }
344
345
        $result = $this->_config->getDb()->query($query);
346
347
        while ($row = $this->_config->getDb()->fetchArray($result)) {
348
            $categories[] = (int) $row['id'];
349
        }
350
351
        return $categories;
352
    }
353
354
    /**
355
     * Builds the category tree.
356
     *
357
     * @param int $id_parent Parent id
358
     * @param int $indent    Indention
359
     */
360
    public function buildTree($id_parent = 0, $indent = 0)
361
    {
362
        $tt = [];
363
        $x = 0;
364
365
        foreach ($this->categories as $categoryId => $n) {
366
            if (isset($n['parent_id']) && $n['parent_id'] == $id_parent) {
367
                $tt[$x++] = $categoryId;
368
            }
369
        }
370
371
        if ($x != 0) {
372
            foreach ($tt as $d) {
373
                $tmp = [];
374
                if (isset($this->categories[$d])) {
375
                    foreach ($this->categories[$d] as $key => $value) {
376
                        $tmp[$key] = $value;
377
                    }
378
                    $tmp['indent'] = $indent;
379
                    $this->catTree[] = $tmp;
380
                    $this->buildTree($tmp['id'], $indent + 1);
381
                }
382
            }
383
        }
384
    }
385
386
    /**
387
     * Get the level of the item id.
388
     *
389
     * @param int $id Category id
390
     *
391
     * @return int
392
     */
393
    private function levelOf($id)
394
    {
395
        $alreadies = array($id);
396
        $ret = 0;
397
        while ((isset($this->categoryName[$id]['parent_id'])) && ($this->categoryName[$id]['parent_id'] != 0)) {
398
            ++$ret;
399
            $id = $this->categoryName[$id]['parent_id'];
400
401
            if (in_array($id, $alreadies)) {
402
                break;
403
            } else {
404
                array_push($alreadies, $id);
405
            }
406
        }
407
408
        return $ret;
409
    }
410
411
    /**
412
     * Transforms the linear array in a 1D array in the order of the tree, with
413
     * the info.
414
     *
415
     * @param int $id Category id
416
     */
417
    public function transform($id)
418
    {
419
        $parentId = $level = 0;
420
        $tree = [];
421
        $tabs = isset($this->children[$id]) ? array_keys($this->children[$id]) : [];
422
        $num = count($tabs);
423
        $symbol = 'minus';
424
        $name = $description = '';
425
        $active = true;
426
427
        if ($id > 0) {
428
            $active = $this->categoryName[$id]['active'];
429
            $description = $this->categoryName[$id]['description'];
430
            $level = $this->categoryName[$id]['level'];
431
            $name = $this->categoryName[$id]['name'];
432
            $parentId = $this->categoryName[$id]['parent_id'];
433
        }
434
435
        if ($num < 0) {
436
            $temp = isset($this->children[$parentId]) ? array_keys($this->children[$parentId]) : [];
437
            if (isset($temp[count($temp) - 1])) {
438
                $symbol = ($id == $temp[count($temp) - 1]) ? 'angle' : 'medium';
439
            }
440
        }
441
442
        $ascendants = $this->getNodes($id);
443
        $numAscendants = count($ascendants);
444
445
        if ($id > 0) {
446
            for ($i = 0; $i < $numAscendants; ++$i) {
447
                $brothers = $this->getBrothers($ascendants[$i]);
448
                $tree[$i] = ($ascendants[$i] == $brothers[count($brothers) - 1]) ? 'space' : 'vertical';
449
            }
450
        }
451
452
        if ($id > 0) {
453
            $this->treeTab[] = array(
454
                'id' => $id,
455
                'symbol' => $symbol,
456
                'name' => $name,
457
                'numChilds' => count($tabs),
458
                'level' => $level,
459
                'parent_id' => $parentId,
460
                'childs' => $tabs,
461
                'tree' => $tree,
462
                'description' => $description,
463
                'active' => $active,
464
            );
465
        }
466
467
        foreach ($tabs as $i) {
468
            $this->transform($i);
469
        }
470
    }
471
472
    /**
473
     * Get the line number where to find the node $id in the category tree.
474
     *
475
     * @param int $id Category id
476
     *
477
     * @return int
478
     */
479
    private function getLineCategory($id)
480
    {
481
        $num = count($this->treeTab);
482
        for ($i = 0; $i < $num; ++$i) {
483
            if (isset($this->treeTab[$i]['id']) && $this->treeTab[$i]['id'] == $id) {
484
                return $i;
485
            }
486
        }
487
    }
488
489
    //
490
    /**
491
     * List in a array of the $id of the child.
492
     *
493
     * @param int $id Category id
494
     *
495
     * @return array
496
     *
497
     * @author Thorsten Rinne <[email protected]>
498
     */
499
    public function getChildren($id)
500
    {
501
        return isset($this->children[$id]) ? array_keys($this->children[$id]) : [];
502
    }
503
504
    /**
505
     * list in a array of the $id of the child.
506
     *
507
     * @param int $id Category id
508
     *
509
     * @return array
510
     */
511
    public function getChildNodes($id)
512
    {
513
        $childs = [];
514
515
        if (isset($this->children[$id])) {
516
            foreach (array_keys($this->children[$id]) as $childId) {
517
                $childs = array_merge($childs, array($childId));
518
                $childs = array_merge($childs, $this->getChildNodes($childId));
519
            }
520
        }
521
522
        return $childs;
523
    }
524
525
    /**
526
     * List in array the root, super-root, ... of the $id.
527
     *
528
     * @param int $id Category id
529
     *
530
     * @return array
531
     */
532
    private function getNodes($id)
533
    {
534
        if (($id > 0) && (isset($this->categoryName[$id]['level']))) {
535
            $thisLevel = $this->categoryName[$id]['level'];
536
            $temp = [];
537
            for ($i = $thisLevel; $i > 0; --$i) {
538
                $id = $this->categoryName[$id]['parent_id'];
539
                array_unshift($temp, $id);
540
            }
541
542
            return $temp;
543
        }
544
    }
545
546
    /**
547
     * Collapse the complete category tree.
548
     */
549 View Code Duplication
    public function collapseAll()
550
    {
551
        $numTreeTab = count($this->treeTab);
552
        for ($i = 0; $i < $numTreeTab; ++$i) {
553
            if ($this->treeTab[$i]['symbol'] == 'minus') {
554
                $this->treeTab[$i]['symbol'] = 'plus';
555
            }
556
        }
557
    }
558
559
    /**
560
     * expand the node $id.
561
     *
562
     * @param int $id Category id
563
     */
564
    public function expand($id)
565
    {
566
        $this->treeTab[$this->getLineCategory($id)]['symbol'] = 'minus';
567
    }
568
569
    /**
570
     * Try to expand from the parent_id to the node $id
571
     *
572
     * @param int $id
573
     *
574
     * @return void
575
     */
576
    public function expandTo($id)
577
    {
578
        $this->collapseAll();
579
        $ascendants = $this->getNodes($id);
580
        $ascendants[] = $id;
581
        $numAscendants = count($ascendants);
582
        for ($i = 0; $i < $numAscendants; ++$i) {
583
            if (isset($this->treeTab[$this->getLineCategory($ascendants[$i])]['numChilds'])) {
584
                $numChilds = $this->treeTab[$this->getLineCategory($ascendants[$i])]['numChilds'];
585
                if ($numChilds > 0) {
586
                    $this->expand($ascendants[$i]);
587
                } else {
588
                    $i = count($ascendants);
589
                }
590
            }
591
        }
592
    }
593
594
    /**
595
     * Expand the entire tree
596
     *
597
     * @return void
598
     */
599 View Code Duplication
    public function expandAll()
600
    {
601
        $numTreeTab = count($this->treeTab);
602
        for ($i = 0; $i < $numTreeTab; ++$i) {
603
            if ($this->treeTab[$i]['symbol'] == 'plus') {
604
                $this->treeTab[$i]['symbol'] = 'minus';
605
            }
606
        }
607
    }
608
609
    /**
610
     * Total height of the expanded tree.
611
     *
612
     * @return int
613
     */
614
    public function height()
615
    {
616
        return count($this->treeTab);
617
    }
618
619
    /**
620
     * print the static tree with the number of records.
621
     *
622
     * @return string
623
     */
624
    public function viewTree()
625
    {
626
        global $sids, $plr;
627
628
        $number = [];
629
630
        $query = sprintf('
631
            SELECT
632
                fcr.category_id AS category_id,
633
                count(fcr.category_id) AS number
634
            FROM
635
                %sfaqcategoryrelations fcr,
636
                %sfaqdata fd
637
            WHERE
638
                fcr.record_id = fd.id
639
            AND
640
                fcr.record_lang = fd.lang',
641
            PMF_Db::getTablePrefix(),
642
            PMF_Db::getTablePrefix());
643
644
        if (strlen($this->language) > 0) {
645
            $query .= sprintf(" AND fd.lang = '%s'",
646
                $this->language);
647
        }
648
649
        $query .= sprintf("
650
            AND
651
                fd.active = 'yes'
652
            GROUP BY
653
                fcr.category_id",
654
            PMF_Db::getTablePrefix(),
655
            PMF_Db::getTablePrefix());
656
        $result = $this->_config->getDb()->query($query);
657
658 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...
659
            while ($row = $this->_config->getDb()->fetchObject($result)) {
660
                $number[$row->category_id] = $row->number;
661
            }
662
        }
663
664
        $output = '<ul class="pmf-category-overview">';
665
        $open = 0;
666
        $this->expandAll();
667
668
        for ($y = 0;$y < $this->height(); $y = $this->getNextLineTree($y)) {
669
            list($hasChild, $categoryName, $parent, $description) = $this->getLineDisplay($y);
670
            $level = $this->treeTab[$y]['level'];
671
            $levelDiff = $open - $level;
672
673
            if (!isset($number[$parent])) {
674
                $number[$parent] = 0;
675
            }
676
677 View Code Duplication
            if ($this->_config->get('records.hideEmptyCategories') && 0 === $number[$parent] && '-' === $hasChild) {
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...
678
                continue;
679
            }
680
681
            if ($levelDiff > 1) {
682
                $output .= '</li>';
683
                for ($i = $levelDiff; $i > 1; --$i) {
684
                    $output .= '</ul></li>';
685
                }
686
            }
687
688
            if ($level < $open) {
689
                if (($level - $open) == -1) {
690
                    $output .= '</li>';
691
                }
692
                $output .= '</ul></li>';
693
            } elseif ($level == $open && $y != 0) {
694
                $output .= '</li>';
695
            }
696
697
            if ($level > $open) {
698
                $output .= sprintf(
699
                    '<ul><li data-category-id="%d" data-category-level="%d">',
700
                    $parent,
701
                    $level
702
                );
703
            } else {
704
                $output .= sprintf(
705
                    '<li data-category-id="%d" data-category-level="%d">',
706
                    $parent,
707
                    $level
708
                );
709
            }
710
711
            if (0 === $number[$parent] && 0 === $level) {
712
                $numFaqs = '';
713
            } else {
714
                $numFaqs = '<span class="rssCategoryLink"> ('.$plr->GetMsg('plmsgEntries', $number[$parent]);
715
                if ($this->_config->get('main.enableRssFeeds')) {
716
                    $numFaqs .= sprintf(
717
                        ' <a href="feed/category/rss.php?category_id=%d&category_lang=%s" target="_blank"><i aria-hidden="true" class="fa fa-rss"></i></a>',
718
                        $parent,
719
                        $this->language,
720
                        $parent
721
                    );
722
                }
723
                $numFaqs .= ')</span>';
724
            }
725
726
            $url = sprintf(
727
                '%s?%saction=show&amp;cat=%d',
728
                PMF_Link::getSystemRelativeUri(),
729
                $sids,
730
                $parent
731
            );
732
            $oLink = new PMF_Link($url, $this->_config);
733
            $oLink->itemTitle = $categoryName;
734
            $oLink->text = $categoryName;
735
            $oLink->tooltip = $description;
736
737
            $output .= $oLink->toHtmlAnchor().$numFaqs;
738
            $open = $level;
739
        }
740
741
        if (isset($level) && $level > 0) {
742
            $output .= str_repeat('</li></ul>', $level);
743
        }
744
745
        $output .= '</li></ul>';
746
747
        return $output;
748
    }
749
750
    /**
751
     * Returns the four parts of a line to display: category name, the ID of
752
     * the root node, the description and if the category is active
753
     *
754
     * @param integer $node
755
     *
756
     * @return array
757
     */
758
    public function getLineDisplay($node)
759
    {
760
        return [
761
            $this->symbols[$this->treeTab[$node]['symbol']],
762
            $this->treeTab[$node]['name'],
763
            $this->treeTab[$node]['id'],
764
            $this->treeTab[$node]['description'],
765
            $this->treeTab[$node]['active']
766
        ];
767
    }
768
769
    /**
770
     * Gets the next line in the array treeTab, depending of the
771
     * collapse/expand node.
772
     *
773
     * @param int $line Current line
774
     *
775
     * @return int
776
     */
777
    public function getNextLineTree($line)
778
    {
779
        if ($this->treeTab[$line]['symbol'] !== 'plus') {
780
            return $line + 1;
781
        } else {
782
            for ($i = $line + 1; $i < $this->height(); ++$i) {
783
                if ($this->treeTab[$i]['level'] <= $this->treeTab[$line]['level']) {
784
                    return $i;
785
                }
786
            }
787
        }
788
789
        return $this->height();
790
    }
791
792
    /**
793
     * Gets the list of the brothers of $id (include $id).
794
     *
795
     * @param int $id Brothers
796
     *
797
     * @return array
798
     */
799
    private function getBrothers($id)
800
    {
801
        return $this->getChildren($this->categoryName[$id]['parent_id']);
802
    }
803
804
    /**
805
     * Creates a category link.
806
     *
807
     * @param string $sids         Session id
808
     * @param int    $categoryId   Parent category
809
     * @param string $categoryName Category name
810
     * @param string $description  Description
811
     * @param bool   $hasChildren  Child categories available
812
     * @param bool   $isActive     Sets a link active via CSS
813
     *
814
     * @return string
815
     */
816
    public function addCategoryLink($sids, $categoryId, $categoryName, $description, $hasChildren = false, $isActive = false)
817
    {
818
        $url = sprintf(
819
            '%s?%saction=show&amp;cat=%d',
820
            PMF_Link::getSystemRelativeUri(),
821
            $sids,
822
            $categoryId
823
        );
824
825
        $oLink = new PMF_Link($url, $this->_config);
826
        $oLink->id = 'category_'.$categoryId;
827
        $oLink->itemTitle = $categoryName;
828
        $oLink->text = $categoryName;
829
830
        if ($hasChildren) {
831
            $oLink->text .= sprintf(
832
                '<i aria-hidden="true" class="fa fa-caret-right"></i>',
833
                $categoryName);
834
        }
835
836
        if ($isActive) {
837
            $oLink->class = 'active';
838
        }
839
840
        $oLink->tooltip = $description;
841
842
        return $oLink->toHtmlAnchor();
843
    }
844
845
    /**
846
     * Gets the path from root to child as breadcrumbs.
847
     *
848
     * @param int    $id                Category ID
849
     * @param string $separator         Path separator
850
     * @param bool   $renderAsMicroData Renders breadcrumbs as HTML5 microdata
851
     * @param string $useCssClass       Use CSS class "breadcrumb"
852
     *
853
     * @return string
854
     */
855
    public function getPath($id, $separator = ' / ', $renderAsMicroData = false, $useCssClass = 'breadcrumb')
856
    {
857
        global $sids;
858
859
        $ids = $this->getNodes($id);
860
        $num = count($ids);
861
862
        $temp = $catid = $desc = $breadcrumb = [];
863
864
        for ($i = 0; $i < $num; ++$i) {
865
            $t = $this->getLineCategory($ids[$i]);
866
            if (array_key_exists($t, $this->treeTab)) {
867
                $temp[] = $this->treeTab[$this->getLineCategory($ids[$i])]['name'];
868
                $catid[] = $this->treeTab[$this->getLineCategory($ids[$i])]['id'];
869
                $desc[] = $this->treeTab[$this->getLineCategory($ids[$i])]['description'];
870
            }
871
        }
872
        if (isset($this->treeTab[$this->getLineCategory($id)]['name'])) {
873
            $temp[] = $this->treeTab[$this->getLineCategory($id)]['name'];
874
            $catid[] = $this->treeTab[$this->getLineCategory($id)]['id'];
875
            $desc[] = $this->treeTab[$this->getLineCategory($id)]['description'];
876
        }
877
878
        // @todo Maybe this should be done somewhere else ...
879
        if ($renderAsMicroData) {
880
            foreach ($temp as $k => $category) {
881
                $url = sprintf(
882
                    '%s?%saction=show&amp;cat=%d',
883
                    PMF_Link::getSystemRelativeUri(),
884
                    $sids,
885
                    $catid[$k]
886
                );
887
                $oLink = new PMF_Link($url, $this->_config);
888
                $oLink->text = sprintf('<span itemprop="title">%s</span>', $category);
889
                $oLink->itemTitle = $category;
890
                $oLink->tooltip = $desc[$k];
891
                $oLink->setItemProperty('url');
892
                if (0 == $k) {
893
                    $oLink->setRelation('index');
894
                }
895
896
                $breadcrumb[] = sprintf(
897
                    '<li itemscope itemtype="http://data-vocabulary.org/Breadcrumb">%s</li>',
898
                    $oLink->toHtmlAnchor()
899
                );
900
            }
901
902
            $temp = $breadcrumb;
903
904
            return sprintf(
905
                '<ul class="%s">%s</ul>',
906
                $useCssClass,
907
                implode('', $temp)
908
            );
909
        } else {
910
            return implode($separator, $temp);
911
        }
912
    }
913
914
    /**
915
     * Returns the categories from a record id and language.
916
     *
917
     * @param int $record_id   record id
918
     * @param int $record_lang record language
919
     *
920
     * @return array
921
     */
922 View Code Duplication
    public function getCategoryRelationsFromArticle($record_id, $record_lang)
923
    {
924
        $categories = [];
925
926
        $query = sprintf("
927
            SELECT
928
                category_id, category_lang
929
            FROM
930
                %sfaqcategoryrelations
931
            WHERE
932
                record_id = %d
933
            AND
934
                record_lang = '%s'",
935
            PMF_Db::getTablePrefix(),
936
            $record_id,
937
            $record_lang);
938
939
        $result = $this->_config->getDb()->query($query);
940
        while ($row = $this->_config->getDb()->fetchObject($result)) {
941
            $categories[$row->category_id] = array(
942
                'category_id' => $row->category_id,
943
                'category_lang' => $row->category_lang, );
944
        }
945
946
        return $categories;
947
    }
948
949
    /**
950
     * Returns all categories that are related to the given article-id and
951
     * the current language $this->language in an unsorted array which consists
952
     * of associative arrays with the keys 'name', 'id', 'lang',
953
     * 'parent_id' and 'description'.
954
     *
955
     * @param int $articleId Record id
956
     *
957
     * @return array
958
     */
959
    public function getCategoriesFromArticle($articleId)
960
    {
961
        $query = sprintf("
962
            SELECT
963
                fc.id AS id,
964
                fc.lang AS lang,
965
                fc.parent_id AS parent_id,
966
                fc.name AS name,
967
                fc.description AS description
968
            FROM
969
                %sfaqcategoryrelations fcr,
970
                %sfaqcategories fc
971
            WHERE
972
                fc.id = fcr.category_id
973
            AND
974
                fcr.record_id = %d
975
            AND
976
                fcr.category_lang = '%s'
977
            AND
978
                fc.lang = '%s'",
979
            PMF_Db::getTablePrefix(),
980
            PMF_Db::getTablePrefix(),
981
            $articleId,
982
            $this->language,
983
            $this->language);
984
985
        $result = $this->_config->getDb()->query($query);
986
        $num = $this->_config->getDb()->numRows($result);
987
        $this->categories = [];
988
        if ($num > 0) {
989 View Code Duplication
            while ($row = $this->_config->getDb()->fetchArray($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...
990
                $this->categories[intval($row['id'])] = $row;
991
            }
992
        }
993
994
        return $this->categories;
995
    }
996
997
    /**
998
     * Returns the ID of a category that associated with the given article.
999
     *
1000
     * @param int $article_id Record id
1001
     *
1002
     * @return int
1003
     */
1004
    public function getCategoryIdFromArticle($article_id)
1005
    {
1006
        $cats = $this->getCategoryIdsFromArticle($article_id);
1007
        if (isset($cats[0])) {
1008
            return $cats[0];
1009
        } else {
1010
            return 0;
1011
        }
1012
    }
1013
1014
    /**
1015
     * Returns an array with the IDs of all categories that are associated with
1016
     * the given article.
1017
     *
1018
     * @param int $article_id Record id
1019
     *
1020
     * @return array
1021
     */
1022
    public function getCategoryIdsFromArticle($article_id)
1023
    {
1024
        $cats = $this->getCategoriesFromArticle($article_id);
1025
        $arr = [];
1026
        foreach ($cats as $cat) {
1027
            $arr[] = $cat['id'];
1028
        }
1029
1030
        return $arr;
1031
    }
1032
1033
    /**
1034
<<<<<<< HEAD
1035
     * Returns the admin user of the given category.
1036
     *
1037
     * @param int $categoryId
1038
     *
1039
     * @return int
1040
     */
1041
    public function getCategoryUser($categoryId)
1042
    {
1043
        if (isset($this->categories[$categoryId]['user_id'])) {
1044
            return $this->categories[$categoryId]['user_id'];
1045
        } else {
1046
            return 1;
1047
        }
1048
    }
1049
1050
    /**
1051
     * Returns the moderator group ID of the given category.
1052
=======
1053
     * Adds a new category entry
1054
>>>>>>> Fixed broken category tree, closes #1125
1055
     *
1056
     * @param int $categoryId
1057
     *
1058
     * @return int
1059
     */
1060
    public function getModeratorGroupId($categoryId)
1061
    {
1062
        return $this->categories[$categoryId]['group_id'];
1063
    }
1064
1065
    /**
1066
     * Adds a new category entry.
1067
     *
1068
     * @param array $categoryData Array of category data
1069
     * @param int   $parentId     Parent id
1070
     * @param int   $id           Category id
1071
     *
1072
     * @return int
1073
     */
1074
    public function addCategory(Array $categoryData, $parentId = 0, $id = null)
1075
    {
1076
        // If we only need a new language, we don't need a new category id
1077
        if (is_null($id)) {
1078
            $id = $this->_config->getDb()->nextId(PMF_Db::getTablePrefix().'faqcategories', 'id');
1079
        }
1080
1081
        $query = sprintf("
1082
            INSERT INTO
1083
                %sfaqcategories
1084
            (id, lang, parent_id, name, description, user_id, group_id, active)
1085
                VALUES
1086
            (%d, '%s', %d, '%s', '%s', %d, %d, %d)",
1087
            PMF_Db::getTablePrefix(),
1088
            $id,
1089
            $categoryData['lang'],
1090
            $parentId,
1091
            $categoryData['name'],
1092
            $categoryData['description'],
1093
            $categoryData['user_id'],
1094
            $categoryData['group_id'],
1095
            $categoryData['active']
1096
        );
1097
        $this->_config->getDb()->query($query);
1098
1099
        return $id;
1100
    }
1101
1102
    /**
1103
     * Updates an existent category entry.
1104
     *
1105
     * @param array $categoryData Array of category data
1106
     *
1107
     * @return bool
1108
     */
1109
    public function updateCategory(Array $categoryData)
1110
    {
1111
        $query = sprintf("
1112
            UPDATE
1113
                %sfaqcategories
1114
            SET
1115
                name = '%s',
1116
                description = '%s',
1117
                user_id = %d,
1118
                group_id = %d,
1119
                active = %d
1120
            WHERE
1121
                id = %d
1122
            AND
1123
                lang = '%s'",
1124
            PMF_Db::getTablePrefix(),
1125
            $categoryData['name'],
1126
            $categoryData['description'],
1127
            $categoryData['user_id'],
1128
            $categoryData['group_id'],
1129
            $categoryData['active'],
1130
            $categoryData['id'],
1131
            $categoryData['lang']
1132
        );
1133
        $this->_config->getDb()->query($query);
1134
1135
        return true;
1136
    }
1137
1138
    /**
1139
     * Returns the data of the given category.
1140
     *
1141
     * @param int $categoryId
1142
     *
1143
     * @return PMF_Entity_Category
1144
     */
1145
    public function getCategoryData($categoryId)
1146
    {
1147
        $entity = new PMF_Entity_Category();
1148
1149
        $query = sprintf(
1150
            "SELECT * FROM %sfaqcategories WHERE id = %d AND lang = '%s'",
1151
            PMF_Db::getTablePrefix(),
1152
            $categoryId,
1153
            $this->language
1154
        );
1155
1156
        $result = $this->_config->getDb()->query($query);
1157
1158
        if ($row = $this->_config->getDb()->fetchObject($result)) {
1159
            $entity->setId($row->id)
1160
                ->setLang($row->lang)
1161
                ->setParentId($row->parent_id)
1162
                ->setName($row->name)
1163
                ->setDescription($row->description)
1164
                ->setUserId($row->user_id)
1165
                ->setGroupId($row->group_id)
1166
                ->setActive($row->active);
1167
        }
1168
1169
        return $entity;
1170
    }
1171
1172
    /**
1173
     * Move the categories ownership for users.
1174
     *
1175
     * @param int $from Old user id
1176
     * @param int $to   New user id
1177
     *
1178
     * @return bool
1179
     */
1180
    public function moveOwnership($from, $to)
1181
    {
1182
        if (!is_numeric($from) || !is_numeric($to)) {
1183
            return false;
1184
        }
1185
1186
        $query = sprintf('
1187
            UPDATE
1188
                %sfaqcategories
1189
            SET
1190
                user_id = %d
1191
            WHERE
1192
                user_id = %d',
1193
            PMF_Db::getTablePrefix(),
1194
            $to,
1195
            $from
1196
        );
1197
        $this->_config->getDb()->query($query);
1198
1199
        return true;
1200
    }
1201
1202
    /**
1203
     * Checks if a language is already defined for a category id.
1204
     *
1205
     * @param int    $category_id   Category id
1206
     * @param string $category_lang Category language
1207
     *
1208
     * @return bool
1209
     */
1210
    public function checkLanguage($category_id, $category_lang)
1211
    {
1212
        $query = sprintf("
1213
            SELECT
1214
                lang
1215
            FROM
1216
                %sfaqcategories
1217
            WHERE
1218
                id = %d
1219
            AND
1220
                lang = '%s'",
1221
            PMF_Db::getTablePrefix(),
1222
            $category_id,
1223
            $category_lang);
1224
1225
        $result = $this->_config->getDb()->query($query);
1226
1227
        return $this->_config->getDb()->numRows($result);
1228
    }
1229
1230
    /**
1231
     * Swaps two categories.
1232
     *
1233
     * @param int $category_id_1 First category
1234
     * @param int $category_id_2 Second category
1235
     *
1236
     * @return bool
1237
     */
1238
    public function swapCategories($category_id_1, $category_id_2)
1239
    {
1240
        $temp_cat = rand(200000, 400000);
1241
1242
        $tables = array(
1243
            array('faqcategories' => 'id'),
1244
            array('faqcategories' => 'parent_id'),
1245
            array('faqcategoryrelations' => 'category_id'),
1246
            array('faqcategory_group' => 'category_id'),
1247
            array('faqcategory_user' => 'category_id'), );
1248
1249
        $result = true;
1250 View Code Duplication
        foreach ($tables as $pair) {
1251
            foreach ($pair as $_table => $_field) {
1252
                $result = $result && $this->_config->getDb()->query(sprintf('UPDATE %s SET %s = %d WHERE %s = %d',
1253
                    PMF_Db::getTablePrefix().$_table,
1254
                    $_field,
1255
                    $temp_cat,
1256
                    $_field,
1257
                    $category_id_2));
1258
                $result = $result && $this->_config->getDb()->query(sprintf('UPDATE %s SET %s = %d WHERE %s = %d',
1259
                    PMF_Db::getTablePrefix().$_table,
1260
                    $_field,
1261
                    $category_id_2,
1262
                    $_field,
1263
                    $category_id_1));
1264
                $result = $result && $this->_config->getDb()->query(sprintf('UPDATE %s SET %s = %d WHERE %s = %d',
1265
                    PMF_Db::getTablePrefix().$_table,
1266
                    $_field,
1267
                    $category_id_1,
1268
                    $_field,
1269
                    $temp_cat));
1270
            }
1271
        }
1272
1273
        $tables2 = array(array('faqquestions' => 'category_id'));
1274
1275 View Code Duplication
        foreach ($tables2 as $pair) {
1276
            foreach ($pair as $_table => $_field) {
1277
                $result = $result && $this->_config->getDb()->query(sprintf("UPDATE %s SET %s = '%d' WHERE %s = '%d'",
1278
                    PMF_Db::getTablePrefix().$_table,
1279
                    $_field,
1280
                    $temp_cat,
1281
                    $_field,
1282
                    $category_id_2));
1283
                $result = $result && $this->_config->getDb()->query(sprintf("UPDATE %s SET %s = '%d' WHERE %s = '%d'",
1284
                    PMF_Db::getTablePrefix().$_table,
1285
                    $_field,
1286
                    $category_id_2,
1287
                    $_field,
1288
                    $category_id_1));
1289
                $result = $result && $this->_config->getDb()->query(sprintf("UPDATE %s SET %s = '%d' WHERE %s = '%d'",
1290
                    PMF_Db::getTablePrefix().$_table,
1291
                    $_field,
1292
                    $category_id_1,
1293
                    $_field,
1294
                    $temp_cat));
1295
            }
1296
        }
1297
1298
        return $result;
1299
    }
1300
1301
    /**
1302
     * Updates the parent category.
1303
     *
1304
     * @param int $category_id Category id
1305
     * @param int $parent_id   Parent category id
1306
     *
1307
     * @return bool
1308
     */
1309
    public function updateParentCategory($category_id, $parent_id)
1310
    {
1311
        if ((!is_numeric($category_id) || !is_numeric($parent_id)) && $category_id != $parent_id) {
1312
            return false;
1313
        }
1314
1315
        $query = sprintf('
1316
            UPDATE
1317
                %sfaqcategories
1318
            SET
1319
                parent_id = %d
1320
            WHERE
1321
                id = %d',
1322
            PMF_Db::getTablePrefix(),
1323
            $parent_id,
1324
            $category_id);
1325
        $this->_config->getDb()->query($query);
1326
1327
        return true;
1328
    }
1329
1330
    /**
1331
     * Deletes a category.
1332
     *
1333
     * @param int    $category_id   Category id
1334
     * @param string $category_lang Categiry language
1335
     * @param bool   $delete_all    Delete all languages?
1336
     *
1337
     * @return bool
1338
     */
1339 View Code Duplication
    public function deleteCategory($category_id, $category_lang, $delete_all = false)
1340
    {
1341
        $query = sprintf('
1342
            DELETE FROM
1343
                %sfaqcategories
1344
            WHERE
1345
                id = %d',
1346
            PMF_Db::getTablePrefix(),
1347
            $category_id);
1348
        if (!$delete_all) {
1349
            $query .= " AND lang = '".$category_lang."'";
1350
        }
1351
        $this->_config->getDb()->query($query);
1352
1353
        return true;
1354
    }
1355
    /**
1356
     * Deletes a category relation.
1357
     *
1358
     * @param int    $category_id   Category id
1359
     * @param string $category_lang Categiry language
1360
     * @param bool   $delete_all    Delete all languages?
1361
     *
1362
     * @return bool
1363
     */
1364 View Code Duplication
    public function deleteCategoryRelation($category_id, $category_lang, $delete_all = false)
1365
    {
1366
        $query = sprintf('
1367
            DELETE FROM
1368
                %sfaqcategoryrelations
1369
            WHERE
1370
                category_id = %d',
1371
            PMF_Db::getTablePrefix(),
1372
            $category_id);
1373
        if (!$delete_all) {
1374
            $query .= " AND category_lang = '".$category_lang."'";
1375
        }
1376
        $this->_config->getDb()->query($query);
1377
1378
        return true;
1379
    }
1380
1381
    /**
1382
     * Create array with translated categories.
1383
     *
1384
     * @param int $category_id
1385
     *
1386
     * @return array
1387
     *
1388
     * @since   2006-09-10
1389
     *
1390
     * @author  Rudi Ferrari <[email protected]>
1391
     */
1392
    public function getCategoryLanguagesTranslated($category_id)
1393
    {
1394
        global $languageCodes;
1395
1396
        $existcatlang = $this->_config->getLanguage()->languageAvailable($category_id, 'faqcategories');
1397
        $translated = [];
1398
1399
        foreach ($existcatlang as $language) {
1400
            $query = sprintf("
1401
               SELECT
1402
                  name, description
1403
               FROM
1404
                   %sfaqcategories
1405
               WHERE
1406
                   id = %d
1407
               AND
1408
                   lang = '%s'",
1409
               PMF_Db::getTablePrefix(),
1410
               $category_id,
1411
               $language);
1412
            $result = $this->_config->getDb()->query($query);
1413
            if ($row = $this->_config->getDb()->fetchArray($result)) {
1414
                $translated[$languageCodes[strtoupper($language)]] = $row['name'].('' == $row['description'] ? '' : '  ('.$row['description'].')');
1415
            }
1416
        }
1417
        ksort($translated);
1418
1419
        return $translated;
1420
    }
1421
1422
    /**
1423
     * Create all languages which can be used for translation as <option>.
1424
     *
1425
     * @param int    $category_id   Category id
1426
     * @param string $selected_lang Selected language
1427
     *
1428
     * @return string
1429
     */
1430
    public function getCategoryLanguagesToTranslate($category_id, $selected_lang)
1431
    {
1432
        $output = '';
1433
        $existcatlang = $this->_config->getLanguage()->languageAvailable($category_id, 'faqcategories');
1434
1435
        foreach (PMF_Language::getAvailableLanguages() as $lang => $langname) {
1436
            if (!in_array(strtolower($lang), $existcatlang)) {
1437
                $output .= "\t<option value=\"".strtolower($lang).'"';
1438
                if ($lang == $selected_lang) {
1439
                    $output .= ' selected="selected"';
1440
                }
1441
                $output .=  '>'.$langname."</option>\n";
1442
            }
1443
        }
1444
1445
        return $output;
1446
    }
1447
1448
    /**
1449
     * Gets all categories which are not translated in actual language
1450
     * to add in this->categories (used in admin section).
1451
     */
1452
    public function getMissingCategories()
1453
    {
1454
        $query = sprintf('
1455
            SELECT
1456
                id, lang, parent_id, name, description, user_id
1457
            FROM
1458
                %sfaqcategories',
1459
            PMF_Db::getTablePrefix());
1460 View Code Duplication
        if (isset($this->language) && preg_match("/^[a-z\-]{2,}$/", $this->language)) {
1461
            $query .= " WHERE lang != '".$this->language."'";
1462
        }
1463
        $query .= ' ORDER BY id';
1464
        $result = $this->_config->getDb()->query($query);
1465 View Code Duplication
        while ($row = $this->_config->getDb()->fetchArray($result)) {
1466
            if (!array_key_exists($row['id'], $this->categoryName)) {
1467
                $this->categoryName[$row['id']] = $row;
1468
                $this->categories[$row['id']] = &$this->categoryName[$row['id']];
1469
                $this->children[$row['parent_id']][$row['id']] = &$this->categoryName[$row['id']];
1470
            }
1471
        }
1472
    }
1473
1474
    /**
1475
     * Get number of nodes at the same parent_id level.
1476
     *
1477
     * @param int $parent_id Parent id
1478
     *
1479
     * @return int
1480
     */
1481
    public function numParent($parent_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...
1482
    {
1483
        $query = sprintf('
1484
            SELECT distinct
1485
                id
1486
            FROM
1487
                %sfaqcategories
1488
            WHERE
1489
                parent_id = %d',
1490
            PMF_Db::getTablePrefix(),
1491
            $parent_id);
1492
        $result = $this->_config->getDb()->query($query);
1493
1494
        return $this->_config->getDb()->numRows($result);
1495
    }
1496
1497
    /**
1498
     * Adds the category permissions for users and groups.
1499
     *
1500
     * @param string $mode       'group' or 'user'
1501
     * @param array  $categories ID of the current category
1502
     * @param array  $ids        Array of group or user IDs
1503
     *
1504
     * @return bool
1505
     */
1506
    public function addPermission($mode, Array $categories, Array $ids)
1507
    {
1508
        if ('user' !== $mode && 'group' !== $mode) {
1509
            return false;
1510
        }
1511
1512
        foreach ($categories as $categoryId) {
1513
            foreach ($ids as $id) {
1514
                $query = sprintf(
1515
                    'SELECT * FROM %sfaqcategory_%s WHERE category_id = %d AND %s_id = %d',
1516
                    PMF_Db::getTablePrefix(),
1517
                    $mode,
1518
                    $categoryId,
1519
                    $mode,
1520
                    $id
1521
                );
1522
1523
                if ($this->_config->getDb()->numRows($this->_config->getDb()->query($query))) {
1524
                    continue;
1525
                }
1526
1527
                $query = sprintf(
1528
                    'INSERT INTO %sfaqcategory_%s (category_id, %s_id) VALUES (%d, %d)',
1529
                    PMF_Db::getTablePrefix(),
1530
                    $mode,
1531
                    $mode,
1532
                    $categoryId,
1533
                    $id
1534
                );
1535
1536
                $this->_config->getDb()->query($query);
1537
            }
1538
        }
1539
1540
        return true;
1541
    }
1542
1543
    /**
1544
     * Deletes the category permissions for users and groups.
1545
     *
1546
     * @param string $mode       'group' or 'user'
1547
     * @param array  $categories ID of the current category
1548
     *
1549
     * @return bool
1550
     */
1551 View Code Duplication
    public function deletePermission($mode, $categories)
1552
    {
1553
        if (!($mode == 'user' || $mode == 'group')) {
1554
            return false;
1555
        }
1556
        if (!is_array($categories)) {
1557
            return false;
1558
        }
1559
1560
        foreach ($categories as $category_id) {
1561
            $query = sprintf('
1562
                DELETE FROM
1563
                    %sfaqcategory_%s
1564
                WHERE
1565
                    category_id = %d',
1566
                PMF_Db::getTablePrefix(),
1567
                $mode,
1568
                $category_id);
1569
            $this->_config->getDb()->query($query);
1570
        }
1571
1572
        return true;
1573
    }
1574
1575
    /**
1576
     * Returns the category permissions for users and groups.
1577
     *
1578
     * @param string $mode       'group' or 'user'
1579
     * @param array  $categories Array of category ids
1580
     *
1581
     * @return array
1582
     */
1583
    public function getPermissions($mode, Array $categories)
1584
    {
1585
        $permissions = [];
1586
        if (!($mode === 'user' || $mode === 'group')) {
1587
            return $permissions;
1588
        }
1589
        if (!is_array($categories)) {
1590
            return $permissions;
1591
        }
1592
1593
        $query = sprintf('
1594
            SELECT
1595
                %s_id AS permission
1596
            FROM
1597
                %sfaqcategory_%s
1598
            WHERE
1599
                category_id IN (%s)',
1600
            $mode,
1601
            PMF_Db::getTablePrefix(),
1602
            $mode,
1603
            implode(', ', $categories));
1604
1605
        $result = $this->_config->getDb()->query($query);
1606
        while ($row = $this->_config->getDb()->fetchObject($result)) {
1607
            $permissions[] = $row->permission;
1608
        }
1609
1610
        return $permissions;
1611
    }
1612
1613
    /**
1614
     * Returns the number of records in each category.
1615
     *
1616
     * @return array
1617
     */
1618
    public function getNumberOfRecordsOfCategory()
1619
    {
1620
        $numRecordsByCat = [];
1621
1622
        $query = sprintf('
1623
            SELECT
1624
                fcr.category_id AS category_id,
1625
                COUNT(fcr.record_id) AS number
1626
            FROM
1627
                %sfaqcategoryrelations fcr, %sfaqdata fd
1628
            WHERE
1629
                fcr.record_id = fd.id
1630
            AND
1631
                fcr.record_lang = fd.lang
1632
            GROUP BY fcr.category_id',
1633
            PMF_Db::getTablePrefix(),
1634
            PMF_Db::getTablePrefix());
1635
1636
        $result = $this->_config->getDb()->query($query);
1637
1638 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...
1639
            while ($row = $this->_config->getDb()->fetchObject($result)) {
1640
                $numRecordsByCat[$row->category_id] = $row->number;
1641
            }
1642
        }
1643
1644
        return $numRecordsByCat;
1645
    }
1646
1647
    /**
1648
     * Create a matrix for representing categories and faq records.
1649
     *
1650
     * @return array
1651
     */
1652
    public function getCategoryRecordsMatrix()
1653
    {
1654
        $matrix = [];
1655
1656
        $query = sprintf('
1657
            SELECT
1658
                fcr.category_id AS id_cat,
1659
                fd.id AS id
1660
            FROM
1661
                %sfaqdata fd
1662
            INNER JOIN
1663
                %sfaqcategoryrelations fcr
1664
            ON
1665
                fd.id = fcr.record_id
1666
            AND
1667
                fd.lang = fcr.category_lang
1668
            ORDER BY
1669
                fcr.category_id, fd.id',
1670
             PMF_Db::getTablePrefix(),
1671
             PMF_Db::getTablePrefix());
1672
        $result = $this->_config->getDb()->query($query);
1673
1674 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...
1675
            while ($row = $this->_config->getDb()->fetchObject($result)) {
1676
                $matrix[$row->id_cat][$row->id] = true;
1677
            }
1678
        }
1679
1680
        return $matrix;
1681
    }
1682
1683
    /**
1684
     * Sets language.
1685
     *
1686
     * @param string $language
1687
     */
1688
    public function setLanguage($language)
1689
    {
1690
        $this->language = $language;
1691
    }
1692
1693
    /**
1694
     * Returns the user id of the category owner
1695
     *
1696
     * @param integer $categoryId
1697
     *
1698
     * @return integer
1699
     */
1700
    public function getOwner($categoryId)
1701
    {
1702
        return isset($this->owner[$categoryId]) ? $this->owner[$categoryId] : 1;
1703
    }
1704
}
1705