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