Passed
Push — master ( b5271b...194f14 )
by Julito
17:56
created

CourseCategory::getCategory()   A

Complexity

Conditions 5
Paths 5

Size

Total Lines 26
Code Lines 16

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 5
eloc 16
c 1
b 0
f 0
nc 5
nop 1
dl 0
loc 26
rs 9.4222
1
<?php
2
3
/* For licensing terms, see /license.txt */
4
5
/**
6
 * Class CourseCategory.
7
 */
8
class CourseCategory
9
{
10
    /**
11
     * Returns the category fields from the database from an int ID.
12
     *
13
     * @param int $categoryId The category ID
14
     *
15
     * @return array
16
     */
17
    public static function getCategoryById($categoryId)
18
    {
19
        $table = Database::get_main_table(TABLE_MAIN_CATEGORY);
20
        $categoryId = (int) $categoryId;
21
        $sql = "SELECT * FROM $table WHERE id = $categoryId";
22
        $result = Database::query($sql);
23
        if (Database::num_rows($result)) {
24
            return Database::fetch_array($result, 'ASSOC');
25
        }
26
27
        return [];
28
    }
29
30
    /**
31
     * Get category details from a simple category code.
32
     *
33
     * @param string|null $categoryCode The literal category code
34
     *
35
     * @return array
36
     */
37
    public static function getCategory(string $categoryCode = null)
38
    {
39
        if (!empty($categoryCode)) {
40
            $table = Database::get_main_table(TABLE_MAIN_CATEGORY);
41
            $categoryCode = Database::escape_string($categoryCode);
42
            $sql = "SELECT * FROM $table WHERE code ='$categoryCode'";
43
            $result = Database::query($sql);
44
45
            if (Database::num_rows($result)) {
46
                $category = Database::fetch_array($result, 'ASSOC');
47
                if ($category) {
48
                    // Get access url id
49
                    $table = Database::get_main_table(TABLE_MAIN_ACCESS_URL_REL_COURSE_CATEGORY);
50
                    $sql = "SELECT * FROM $table WHERE course_category_id = ".$category['id'];
51
                    $result = Database::query($sql);
52
                    $result = Database::fetch_array($result);
53
                    if ($result) {
54
                        $category['access_url_id'] = $result['access_url_id'];
55
                    }
56
57
                    return $category;
58
                }
59
            }
60
        }
61
62
        return [];
63
    }
64
65
    /**
66
     * @param int|null $category Optional. Parent category ID.
67
     *
68
     * @return array
69
     */
70
    public static function getCategories($category = null)
71
    {
72
        $tbl_category = Database::get_main_table(TABLE_MAIN_CATEGORY);
73
        $tbl_course = Database::get_main_table(TABLE_MAIN_COURSE);
74
        $tbl_course_rel_category = Database::get_main_table(TABLE_MAIN_COURSE_REL_CATEGORY);
75
        $category = (int) $category;
76
        $conditions = null;
77
78
        $table = Database::get_main_table(TABLE_MAIN_ACCESS_URL_REL_COURSE_CATEGORY);
79
        $conditions = " INNER JOIN $table a ON (t1.id = a.course_category_id)";
80
        $whereCondition = " AND a.access_url_id = ".api_get_current_access_url_id();
81
        $allowBaseCategories = api_get_configuration_value('allow_base_course_category');
82
        if ($allowBaseCategories) {
83
            $whereCondition = " AND (a.access_url_id = ".api_get_current_access_url_id()." OR a.access_url_id = 1) ";
84
        }
85
86
        $parentIdCondition = " AND (t1.parent_id IS NULL OR t1.parent_id = '' )";
87
88
        if ($category) {
89
            $parentIdCondition = " AND t1.parent_id = $category ";
90
        }
91
92
        $sql = "SELECT
93
                t1.name,
94
                t1.code,
95
                t1.parent_id,
96
                t1.tree_pos,
97
                t1.children_count,
98
                COUNT(DISTINCT t4.code) AS nbr_courses,
99
                a.access_url_id
100
                FROM $tbl_category t1
101
                $conditions
102
                LEFT JOIN $tbl_category t2
103
                ON t1.id = t2.parent_id
104
                LEFT JOIN $tbl_course_rel_category t3
105
                ON t1.id = t3.course_category_id
106
                LEFT JOIN $tbl_course t4
107
                ON t3.course_id = t4.id
108
                WHERE
109
                    1 = 1
110
                    $parentIdCondition
111
                    $whereCondition
112
                GROUP BY t1.name,
113
                         t1.code,
114
                         t1.parent_id,
115
                         t1.tree_pos,
116
                         t1.children_count
117
                ORDER BY t1.tree_pos
118
        ";
119
120
        $result = Database::query($sql);
121
122
        return Database::store_result($result, 'ASSOC');
123
    }
124
125
    /**
126
     * Returns a flat list of all course categories in this URL. If the
127
     * allow_base_course_category option is true, then also show the
128
     * course categories of the base URL.
129
     *
130
     * @return array [id, name, code, parent_id, tree_pos, children_count, number_courses]
131
     */
132
    public static function getAllCategories()
133
    {
134
        $tbl_category = Database::get_main_table(TABLE_MAIN_CATEGORY);
135
        $tbl_course = Database::get_main_table(TABLE_MAIN_COURSE);
136
137
        $table = Database::get_main_table(TABLE_MAIN_ACCESS_URL_REL_COURSE_CATEGORY);
138
        $conditions = " INNER JOIN $table a ON (t1.id = a.course_category_id)";
139
        $whereCondition = " AND a.access_url_id = ".api_get_current_access_url_id();
140
        $allowBaseCategories = api_get_configuration_value('allow_base_course_category');
141
        if ($allowBaseCategories) {
142
            $whereCondition = " AND (a.access_url_id = ".api_get_current_access_url_id()." OR a.access_url_id = 1) ";
143
        }
144
145
        $sql = "SELECT
146
                t1.id,
147
                t1.name,
148
                t1.code,
149
                t1.parent_id,
150
                t1.tree_pos,
151
                t1.children_count,
152
                COUNT(DISTINCT t3.code) AS number_courses
153
                FROM $tbl_category t1
154
                $conditions
155
                LEFT JOIN $tbl_course t3
156
                ON t3.category_id=t1.id
157
                WHERE 1=1
158
                    $whereCondition
159
                GROUP BY
160
                    t1.name,
161
                    t1.code,
162
                    t1.parent_id,
163
                    t1.tree_pos,
164
                    t1.children_count
165
                ORDER BY t1.parent_id, t1.tree_pos";
166
167
        $result = Database::query($sql);
168
169
        return Database::store_result($result, 'ASSOC');
170
    }
171
172
    /**
173
     * @param string $code
174
     * @param string $name
175
     * @param string $canHaveCourses
176
     * @param int    $parent_id
177
     *
178
     * @return bool
179
     */
180
    public static function addNode($code, $name, $canHaveCourses, $parent_id)
181
    {
182
        $table = Database::get_main_table(TABLE_MAIN_CATEGORY);
183
        $code = trim($code);
184
        $name = trim($name);
185
        $parent_id = (int) $parent_id;
186
187
        $code = CourseManager::generate_course_code($code);
188
        $sql = "SELECT 1 FROM $table
189
                WHERE code = '".Database::escape_string($code)."'";
190
        $result = Database::query($sql);
191
        if (Database::num_rows($result)) {
192
            return false;
193
        }
194
        $result = Database::query("SELECT MAX(tree_pos) AS maxTreePos FROM $table");
195
        $row = Database::fetch_array($result);
196
        $tree_pos = $row['maxTreePos'] + 1;
197
198
        $params = [
199
            'name' => $name,
200
            'code' => $code,
201
            'parent_id' => empty($parent_id) ? null : $parent_id,
202
            'tree_pos' => $tree_pos,
203
            'children_count' => 0,
204
            'auth_course_child' => $canHaveCourses,
205
            'auth_cat_child' => 'TRUE',
206
        ];
207
208
        $categoryId = Database::insert($table, $params);
209
        if ($categoryId) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $categoryId of type false|integer is loosely compared to true; this is ambiguous if the integer can be 0. You might want to explicitly use !== false instead.

In PHP, under loose comparison (like ==, or !=, or switch conditions), values of different types might be equal.

For integer values, zero is a special case, in particular the following results might be unexpected:

0   == false // true
0   == null  // true
123 == false // false
123 == null  // false

// It is often better to use strict comparison
0 === false // false
0 === null  // false
Loading history...
210
            self::updateParentCategoryChildrenCount($parent_id, 1);
211
            UrlManager::addCourseCategoryListToUrl(
212
                [$categoryId],
213
                [api_get_current_access_url_id()]
214
            );
215
216
            return $categoryId;
217
        }
218
219
        return false;
220
    }
221
222
    /**
223
     * Recursive function that updates the count of children in the parent.
224
     *
225
     * @param string $categoryId Category ID
226
     * @param int    $delta      The number to add or delete (1 to add one, -1 to remove one)
227
     */
228
    public static function updateParentCategoryChildrenCount($categoryId, $delta = 1)
229
    {
230
        $table = Database::get_main_table(TABLE_MAIN_CATEGORY);
231
        $categoryId = Database::escape_string($categoryId);
232
        $delta = (int) $delta;
233
        // First get to the highest level possible in the tree
234
        $result = Database::query("SELECT parent_id FROM $table WHERE id = '$categoryId'");
235
        $row = Database::fetch_array($result);
236
        if (false !== $row && 0 != $row['parent_id']) {
237
            // if a parent was found, enter there to see if he's got one more parent
238
            self::updateParentCategoryChildrenCount($row['parent_id'], $delta);
239
        }
240
        // Now we're at the top, get back down to update each child
241
        $sql = "UPDATE $table SET children_count = (children_count - ".abs($delta).") WHERE id = '$categoryId'";
242
        if ($delta >= 0) {
243
            $sql = "UPDATE $table SET children_count = (children_count + $delta) WHERE id = '$categoryId'";
244
        }
245
        Database::query($sql);
246
    }
247
248
    /**
249
     * @param string $node
250
     *
251
     * @return bool
252
     */
253
    public static function deleteNode($node)
254
    {
255
        $category = self::getCategory($node);
256
257
        if (empty($category)) {
258
            return false;
259
        }
260
261
        $tbl_course = Database::get_main_table(TABLE_MAIN_COURSE);
262
        $tbl_category = Database::get_main_table(TABLE_MAIN_CATEGORY);
263
        $node = Database::escape_string($node);
264
        $result = Database::query("SELECT parent_id, tree_pos FROM $tbl_category WHERE code='$node'");
265
266
        if ($row = Database::fetch_array($result)) {
267
            if (!empty($row['parent_id'])) {
268
                Database::query(
269
                    "UPDATE $tbl_course SET category_id = '".$row['parent_id']."' WHERE category_id = {$category['id']}"
270
                );
271
                Database::query("UPDATE $tbl_category SET parent_id='".$row['parent_id']."' WHERE parent_id='$node'");
272
            } else {
273
                Database::query("UPDATE $tbl_course SET category_id = NULL WHERE category_id = ".$category['id']);
274
                Database::query("UPDATE $tbl_category SET parent_id=NULL WHERE parent_id='$node'");
275
            }
276
277
            $table = Database::get_main_table(TABLE_MAIN_ACCESS_URL_REL_COURSE_CATEGORY);
278
            $sql = "DELETE FROM $table WHERE course_category_id = ".$category['id'];
279
280
            Database::query($sql);
281
            Database::query("UPDATE $tbl_category SET tree_pos=tree_pos-1 WHERE tree_pos > '".$row['tree_pos']."'");
282
            Database::query("DELETE FROM $tbl_category WHERE code='$node'");
283
284
            if (!empty($row['parent_id'])) {
285
                self::updateParentCategoryChildrenCount($row['parent_id'], -1);
286
            }
287
288
            return true;
289
        }
290
    }
291
292
    /**
293
     * @param string $code
294
     * @param string $name
295
     * @param string $canHaveCourses
296
     * @param string $old_code
297
     *
298
     * @return bool
299
     */
300
    public static function editNode($code, $name, $canHaveCourses, $old_code)
301
    {
302
        $tbl_category = Database::get_main_table(TABLE_MAIN_CATEGORY);
303
304
        $code = trim(Database::escape_string($code));
305
        $name = trim(Database::escape_string($name));
306
        $old_code = Database::escape_string($old_code);
307
        $canHaveCourses = Database::escape_string($canHaveCourses);
308
309
        $code = CourseManager::generate_course_code($code);
310
        // Updating category
311
        $sql = "UPDATE $tbl_category SET
312
                    name='$name',
313
                    code='$code',
314
                    auth_course_child = '$canHaveCourses'
315
                WHERE code = '$old_code'";
316
        Database::query($sql);
317
318
        // Updating children
319
        $sql = "UPDATE $tbl_category SET parent_id = '$code'
320
            WHERE parent_id = '$old_code'";
321
        Database::query($sql);
322
323
        return true;
324
    }
325
326
    /**
327
     * Move a node up on display.
328
     *
329
     * @param string $code
330
     * @param int    $tree_pos
331
     * @param string $parent_id
332
     *
333
     * @return bool
334
     */
335
    public static function moveNodeUp($code, $tree_pos, $parent_id)
336
    {
337
        $table = Database::get_main_table(TABLE_MAIN_CATEGORY);
338
        $code = Database::escape_string($code);
339
        $tree_pos = (int) $tree_pos;
340
        $parent_id = Database::escape_string($parent_id);
341
342
        $parentIdCondition = " AND (parent_id IS NULL OR parent_id = '' )";
343
        if (!empty($parent_id)) {
344
            $parentIdCondition = " AND parent_id = '$parent_id' ";
345
        }
346
347
        $sql = "SELECT code,tree_pos
348
                FROM $table
349
                WHERE
350
                    tree_pos < $tree_pos
351
                    $parentIdCondition
352
                ORDER BY tree_pos DESC
353
                LIMIT 0,1";
354
355
        $result = Database::query($sql);
356
        if (!$row = Database::fetch_array($result)) {
357
            $sql = "SELECT code, tree_pos
358
                    FROM $table
359
                    WHERE
360
                        tree_pos > $tree_pos
361
                        $parentIdCondition
362
                    ORDER BY tree_pos DESC
363
                    LIMIT 0,1";
364
            $result2 = Database::query($sql);
365
            if (!$row = Database::fetch_array($result2)) {
366
                return false;
367
            }
368
        }
369
370
        $sql = "UPDATE $table
371
                SET tree_pos ='".$row['tree_pos']."'
372
                WHERE code='$code'";
373
        Database::query($sql);
374
375
        $sql = "UPDATE $table
376
                SET tree_pos = '$tree_pos'
377
                WHERE code= '".$row['code']."'";
378
        Database::query($sql);
379
380
        return true;
381
    }
382
383
    /**
384
     * @param string $categoryCode
385
     *
386
     * @return array
387
     */
388
    public static function getChildren($categoryCode)
389
    {
390
        $table = Database::get_main_table(TABLE_MAIN_CATEGORY);
391
        $categoryCode = Database::escape_string($categoryCode);
392
        $sql = "SELECT code, id FROM $table
393
                WHERE parent_id = '$categoryCode'";
394
        $result = Database::query($sql);
395
        $children = [];
396
        while ($row = Database::fetch_array($result, 'ASSOC')) {
397
            $children[] = $row;
398
            $subChildren = self::getChildren($row['code']);
399
            $children = array_merge($children, $subChildren);
400
        }
401
402
        return $children;
403
    }
404
405
    /**
406
     * @param string $categoryCode
407
     *
408
     * @return array
409
     */
410
    public static function getParents($categoryCode)
411
    {
412
        if (empty($categoryCode)) {
413
            return [];
414
        }
415
416
        $table = Database::get_main_table(TABLE_MAIN_CATEGORY);
417
        $categoryCode = Database::escape_string($categoryCode);
418
        $sql = "SELECT code, parent_id
419
                FROM $table
420
                WHERE code = '$categoryCode'";
421
422
        $result = Database::query($sql);
423
        $children = [];
424
        while ($row = Database::fetch_array($result, 'ASSOC')) {
425
            $parent = self::getCategory($row['parent_id']);
426
            $children[] = $row;
427
            $subChildren = self::getParents($parent ? $parent['code'] : null);
428
            $children = array_merge($children, $subChildren);
429
        }
430
431
        return $children;
432
    }
433
434
    /**
435
     * @param string $categoryCode
436
     *
437
     * @return string|null
438
     */
439
    public static function getParentsToString($categoryCode)
440
    {
441
        $parents = self::getParents($categoryCode);
442
443
        if (!empty($parents)) {
444
            $parents = array_reverse($parents);
445
            $categories = [];
446
            foreach ($parents as $category) {
447
                $categories[] = $category['code'];
448
            }
449
450
            return implode(' > ', $categories).' > ';
451
        }
452
453
        return null;
454
    }
455
456
    /**
457
     * @param array
458
     *
459
     * @return string
460
     */
461
    public static function listCategories(array $categorySource = [])
462
    {
463
        $categories = self::getCategories($categorySource ? $categorySource['id'] : null);
464
        $categoryCode = $categorySource ? Security::remove_XSS($categorySource['code']) : '';
465
466
        if (count($categories) > 0) {
467
            $table = new HTML_Table(['class' => 'data_table']);
468
            $column = 0;
469
            $row = 0;
470
            $headers = [
471
                get_lang('Category'),
472
                get_lang('Sub-categories'),
473
                get_lang('Courses'),
474
                get_lang('Detail'),
475
            ];
476
            foreach ($headers as $header) {
477
                $table->setHeaderContents($row, $column, $header);
478
                $column++;
479
            }
480
            $row++;
481
            $mainUrl = api_get_path(WEB_CODE_PATH).'admin/course_category.php?category='.$categoryCode;
482
483
            $editIcon = Display::return_icon(
484
                'edit.png',
485
                get_lang('Edit this category'),
486
                null,
487
                ICON_SIZE_SMALL
488
            );
489
            $deleteIcon = Display::return_icon(
490
                'delete.png',
491
                get_lang('Delete this category'),
492
                null,
493
                ICON_SIZE_SMALL
494
            );
495
            $moveIcon = Display::return_icon(
496
                'up.png',
497
                get_lang('Up in same level'),
498
                null,
499
                ICON_SIZE_SMALL
500
            );
501
502
            $urlId = api_get_current_access_url_id();
503
            foreach ($categories as $category) {
504
                $editUrl = $mainUrl.'&id='.$category['code'].'&action=edit';
505
                $moveUrl = $mainUrl.'&id='.$category['code'].'&action=moveUp&tree_pos='.$category['tree_pos'];
506
                $deleteUrl = $mainUrl.'&id='.$category['code'].'&action=delete';
507
508
                $actions = [];
509
510
                if ($urlId == $category['access_url_id']) {
511
                    $actions[] = Display::url($editIcon, $editUrl);
512
                    $actions[] = Display::url($moveIcon, $moveUrl);
513
                    $actions[] = Display::url($deleteIcon, $deleteUrl);
514
                }
515
516
                $url = api_get_path(WEB_CODE_PATH).'admin/course_category.php?category='.$category['code'];
517
                $title = Display::url(
518
                    Display::return_icon(
519
                        'folder_document.gif',
520
                        get_lang('Open this category'),
521
                        null,
522
                        ICON_SIZE_SMALL
523
                    ).' '.$category['name'].' ('.$category['code'].')',
524
                    $url
525
                );
526
                $countCourses = self::countCoursesInCategory($category['code'], null, false);
527
                $content = [
528
                    $title,
529
                    $category['children_count'],
530
                    $countCourses,
531
                    implode('', $actions),
532
                ];
533
                $column = 0;
534
                foreach ($content as $value) {
535
                    $table->setCellContents($row, $column, $value);
536
                    $column++;
537
                }
538
                $row++;
539
            }
540
541
            return $table->toHtml();
542
        }
543
        return Display::return_message(get_lang('NoCategories'), 'warning');
544
    }
545
546
    /**
547
     * @return array
548
     */
549
    public static function getCategoriesToDisplayInHomePage()
550
    {
551
        $table = Database::get_main_table(TABLE_MAIN_CATEGORY);
552
        $sql = "SELECT name FROM $table
553
                WHERE parent_id IS NULL
554
                ORDER BY tree_pos";
555
556
        return Database::store_result(Database::query($sql));
557
    }
558
559
    /**
560
     * @param string $categoryCode
561
     *
562
     * @return array
563
     */
564
    public static function getCategoriesCanBeAddedInCourse($categoryCode)
565
    {
566
        $table = Database::get_main_table(TABLE_MAIN_ACCESS_URL_REL_COURSE_CATEGORY);
567
        $conditions = " INNER JOIN $table a ON (c.id = a.course_category_id)";
568
        $whereCondition = ' AND a.access_url_id = '.api_get_current_access_url_id();
569
570
        $tbl_category = Database::get_main_table(TABLE_MAIN_CATEGORY);
571
        $sql = "SELECT c.id, c.code, name
572
                FROM $tbl_category c
573
                $conditions
574
                WHERE (auth_course_child = 'TRUE' OR code = '".Database::escape_string($categoryCode)."')
575
                $whereCondition
576
                ORDER BY tree_pos";
577
        $res = Database::query($sql);
578
579
        $categoryToAvoid = '';
580
        if (!api_is_platform_admin()) {
581
            $categoryToAvoid = api_get_configuration_value('course_category_code_to_use_as_model');
582
        }
583
        $categories[''] = '-';
0 ignored issues
show
Comprehensibility Best Practice introduced by
$categories was never initialized. Although not strictly required by PHP, it is generally a good practice to add $categories = array(); before regardless.
Loading history...
584
        while ($cat = Database::fetch_array($res)) {
585
            $categoryCode = $cat['code'];
586
            if (!empty($categoryToAvoid) && $categoryToAvoid == $categoryCode) {
587
                continue;
588
            }
589
            $categories[$cat['id']] = '('.$cat['code'].') '.$cat['name'];
590
            ksort($categories);
591
        }
592
593
        return $categories;
594
    }
595
596
    /**
597
     * @param string $category_code
598
     * @param string $keyword
599
     * @paran bool  $avoidCourses
600
     * @paran array $conditions
601
     *
602
     * @return int
603
     */
604
    public static function countCoursesInCategory(
605
        $category_code = '',
606
        $keyword = '',
607
        $avoidCourses = true,
608
        $conditions = []
609
    ) {
610
        return self::getCoursesInCategory($category_code, $keyword, $avoidCourses, $conditions, true);
611
    }
612
613
    public static function getCoursesInCategory($category_code = '', $keyword = '', $avoidCourses = true, $conditions = [], $getCount = false)
614
{
615
        $tbl_course = Database::get_main_table(TABLE_MAIN_COURSE);
616
        $tblCourseCategory = Database::get_main_table(TABLE_MAIN_CATEGORY);
617
        $keyword = Database::escape_string($keyword);
618
        $categoryCode = Database::escape_string($category_code);
619
        $avoidCoursesCondition = '';
620
        if ($avoidCourses) {
621
            $avoidCoursesCondition = CoursesAndSessionsCatalog::getAvoidCourseCondition();
622
        }
623
624
        $visibilityCondition = CourseManager::getCourseVisibilitySQLCondition('course', true);
625
626
        $sqlInjectJoins = '';
627
        $where = ' AND 1 = 1 ';
628
        $sqlInjectWhere = '';
629
        if (!empty($conditions)) {
630
            $sqlInjectJoins = $conditions['inject_joins'];
631
            $where = $conditions['where'];
632
            $sqlInjectWhere = $conditions['inject_where'];
633
        }
634
        $categoryFilter = '';
635
        if ($categoryCode === 'ALL' || empty($categoryCode)) {
636
            // Nothing to do
637
        } elseif ('NONE' === $categoryCode) {
638
            $categoryFilter = ' AND course.category_id IS NULL ';
639
        } else {
640
            $categoryJoin = " INNER JOIN $tblCourseCategory cat ON course.category_id = cat.id ";
641
            $categoryFilter = ' AND cat.code = "'.$categoryCode.'" ';
642
        }
643
644
        $searchFilter = '';
645
        if (!empty($keyword)) {
646
            $searchFilter = ' AND (
647
                course.code LIKE "%'.$keyword.'%" OR
648
                course.title LIKE "%'.$keyword.'%" OR
649
                course.tutor_name LIKE "%'.$keyword.'%"
650
            ) ';
651
        }
652
653
        $urlCondition = ' url_rel_course.access_url_id = '.api_get_current_access_url_id().' AND';
654
        $tbl_url_rel_course = Database::get_main_table(TABLE_MAIN_ACCESS_URL_REL_COURSE);
655
656
        $select = " DISTINCT course.id, course.code, course.title, course.category_code ";
657
        if ($getCount) {
658
            $select = "count(DISTINCT course.id) as count";
659
        }
660
        $sql = "SELECT $select
661
                FROM $tbl_course as course
662
                INNER JOIN $tbl_url_rel_course as url_rel_course
663
                ON (url_rel_course.c_id = course.id)
664
                $sqlInjectJoins
665
                WHERE
666
                    $urlCondition
667
                    course.visibility != '0' AND
668
                    course.visibility != '4'
669
                    $categoryFilter
670
                    $searchFilter
671
                    $avoidCoursesCondition
672
                    $visibilityCondition
673
                    $where
674
                    $sqlInjectWhere
675
            ";
676
677
        $result = Database::query($sql);
678
        if ($getCount) {
679
            $row = Database::fetch_array($result);
680
681
            return (int) $row['count'];
682
        }
683
684
        return Database::store_result($result, 'ASSOC');
685
    }
686
687
    /**
688
     * @param array $list
689
     *
690
     * @return array
691
     */
692
    public static function getCourseCategoryNotInList($list)
693
    {
694
        $table = Database::get_main_table(TABLE_MAIN_CATEGORY);
695
696
        if (empty($list)) {
697
            $sql = "SELECT * FROM $table
698
                    WHERE (parent_id IS NULL) ";
699
            $result = Database::query($sql);
700
701
            return Database::store_result($result, 'ASSOC');
702
        }
703
704
        $list = array_map('intval', $list);
705
        $listToString = implode("','", $list);
706
707
        $sql = "SELECT * FROM $table
708
                WHERE id NOT IN ('$listToString') AND (parent_id IS NULL) ";
709
        $result = Database::query($sql);
710
711
        return Database::store_result($result, 'ASSOC');
712
    }
713
714
    /**
715
     * @param string $keyword
716
     *
717
     * @return array|null
718
     */
719
    public static function searchCategoryByKeyword($keyword)
720
    {
721
        if (empty($keyword)) {
722
            return null;
723
        }
724
725
        $tableCategory = Database::get_main_table(TABLE_MAIN_CATEGORY);
726
        $table = Database::get_main_table(TABLE_MAIN_ACCESS_URL_REL_COURSE_CATEGORY);
727
        $conditions = " INNER JOIN $table a ON (c.id = a.course_category_id)";
728
        $whereCondition = " AND a.access_url_id = ".api_get_current_access_url_id();
729
730
        $allowBaseCategories = api_get_configuration_value('allow_base_course_category');
731
        if ($allowBaseCategories) {
732
            $whereCondition = " AND (a.access_url_id = ".api_get_current_access_url_id()." OR a.access_url_id = 1) ";
733
        }
734
735
        $keyword = Database::escape_string($keyword);
736
737
        $sql = "SELECT c.*, c.name as text
738
                FROM $tableCategory c $conditions
739
                WHERE
740
                (
741
                    c.code LIKE '%$keyword%' OR name LIKE '%$keyword%'
742
                ) AND auth_course_child = 'TRUE'
743
                $whereCondition ";
744
        $result = Database::query($sql);
745
746
        return Database::store_result($result, 'ASSOC');
747
    }
748
749
    /**
750
     * Get Pagination HTML div.
751
     *
752
     * @param $pageCurrent
753
     * @param $pageLength
754
     * @param $pageTotal
755
     *
756
     * @return string
757
     */
758
    public static function getCatalogPagination($pageCurrent, $pageLength, $pageTotal)
759
    {
760
        // Start empty html
761
        $pageDiv = '';
762
        $html = '';
763
        $pageBottom = max(1, $pageCurrent - 3);
764
        $pageTop = min($pageTotal, $pageCurrent + 3);
765
766
        if ($pageBottom > 1) {
767
            $pageDiv .= self::getPageNumberItem(1, $pageLength);
768
            if ($pageBottom > 2) {
769
                $pageDiv .= self::getPageNumberItem(
770
                    $pageBottom - 1,
771
                    $pageLength,
772
                    null,
773
                    '...'
774
                );
775
            }
776
        }
777
778
        // For each page add its page button to html
779
        for ($i = $pageBottom; $i <= $pageTop; $i++) {
780
            if ($i === $pageCurrent) {
781
                $pageItemAttributes = ['class' => 'page-item active'];
782
            } else {
783
                $pageItemAttributes = ['class' => 'page-item'];
784
            }
785
            $pageDiv .= self::getPageNumberItem(
786
                $i,
787
                $pageLength,
788
                $pageItemAttributes
789
            );
790
        }
791
792
        // Check if current page is the last page
793
        if ($pageTop < $pageTotal) {
794
            if ($pageTop < ($pageTotal - 1)) {
795
                $pageDiv .= self::getPageNumberItem(
796
                    $pageTop + 1,
797
                    $pageLength,
798
                    null,
799
                    '...'
800
                );
801
            }
802
            $pageDiv .= self::getPageNumberItem($pageTotal, $pageLength);
803
        }
804
805
        // Complete pagination html
806
        $pageDiv = Display::tag('ul', $pageDiv, ['class' => 'pagination']);
807
        $html .= '<nav>'.$pageDiv.'</nav>';
808
809
        return $html;
810
    }
811
812
    /**
813
     * Return URL to course catalog.
814
     *
815
     * @param int    $pageCurrent
816
     * @param int    $pageLength
817
     * @param string $categoryCode
818
     * @param int    $hiddenLinks
819
     * @param string $action
820
     *
821
     * @return string
822
     */
823
    public static function getCourseCategoryUrl(
824
        $pageCurrent,
825
        $pageLength,
826
        $categoryCode = null,
827
        $hiddenLinks = null,
828
        $action = null
829
    ) {
830
        $requestAction = isset($_REQUEST['action']) ? Security::remove_XSS($_REQUEST['action']) : null;
831
        $action = isset($action) ? Security::remove_XSS($action) : $requestAction;
832
        $searchTerm = isset($_REQUEST['search_term']) ? Security::remove_XSS($_REQUEST['search_term']) : null;
833
834
        if ('subscribe_user_with_password' === $action) {
835
            $action = 'subscribe';
836
        }
837
838
        $categoryCodeRequest = isset($_REQUEST['category_code']) ? Security::remove_XSS($_REQUEST['category_code']) : null;
839
        $categoryCode = isset($categoryCode) ? Security::remove_XSS($categoryCode) : $categoryCodeRequest;
840
        $hiddenLinksRequest = isset($_REQUEST['hidden_links']) ? Security::remove_XSS($_REQUEST['hidden_links']) : null;
841
        $hiddenLinks = isset($hiddenLinks) ? Security::remove_XSS($hiddenLinksRequest) : $categoryCodeRequest;
842
843
        // Start URL with params
844
        $pageUrl = api_get_self().
845
            '?action='.$action.
846
            '&category_code='.$categoryCode.
847
            '&hidden_links='.$hiddenLinks.
848
            '&pageCurrent='.$pageCurrent.
849
            '&pageLength='.$pageLength;
850
851
        switch ($action) {
852
            case 'subscribe':
853
                // for search
854
                $pageUrl .=
855
                    '&search_term='.$searchTerm.
856
                    '&search_course=1'.
857
                    '&sec_token='.Security::getTokenFromSession();
858
                break;
859
            case 'display_courses':
860
            default:
861
                break;
862
        }
863
864
        return $pageUrl;
865
    }
866
867
    /**
868
     * Get li HTML of page number.
869
     *
870
     * @param $pageNumber
871
     * @param $pageLength
872
     * @param array  $liAttributes
873
     * @param string $content
874
     *
875
     * @return string
876
     */
877
    public static function getPageNumberItem(
878
        $pageNumber,
879
        $pageLength,
880
        $liAttributes = [],
881
        $content = ''
882
    ) {
883
        // Get page URL
884
        $url = self::getCourseCategoryUrl(
885
            $pageNumber,
886
            $pageLength
887
        );
888
889
        // If is current page ('active' class) clear URL
890
        if (isset($liAttributes) && is_array($liAttributes) && isset($liAttributes['class'])) {
891
            if (false !== strpos('active', $liAttributes['class'])) {
892
                $url = '';
893
            }
894
        }
895
896
        $content = !empty($content) ? $content : $pageNumber;
897
898
        return Display::tag(
899
            'li',
900
            Display::url(
901
                $content,
902
                $url,
903
                ['class' => 'page-link']
904
            ),
905
            $liAttributes
906
        );
907
    }
908
909
    /**
910
     * Return the name tool by action.
911
     *
912
     * @param string $action
913
     *
914
     * @return string
915
     */
916
    public static function getCourseCatalogNameTools($action)
917
    {
918
        $nameTools = get_lang('My courses');
919
        if (empty($action)) {
920
            return $nameTools; //should never happen
921
        }
922
923
        switch ($action) {
924
            case 'subscribe':
925
            case 'subscribe_user_with_password':
926
            case 'display_random_courses':
927
            case 'display_courses':
928
                $nameTools = get_lang('Courses catalog');
929
                break;
930
            case 'display_sessions':
931
                $nameTools = get_lang('Course sessions');
932
                break;
933
            default:
934
                // Nothing to do
935
                break;
936
        }
937
938
        return $nameTools;
939
    }
940
941
    /**
942
     * Save image for a course category.
943
     *
944
     * @param int   $categoryId Course category ID
945
     * @param array $fileData   File data from $_FILES
946
     */
947
    public static function saveImage($categoryId, $fileData)
948
    {
949
        $categoryInfo = self::getCategoryById($categoryId);
950
        if (empty($categoryInfo)) {
951
            return;
952
        }
953
954
        if (!empty($fileData['error'])) {
955
            return;
956
        }
957
958
        $extension = getextension($fileData['name']);
959
        $dirName = 'course_category/';
960
        $fileDir = api_get_path(SYS_UPLOAD_PATH).$dirName;
961
        $fileName = "cc_$categoryId.{$extension[0]}";
962
963
        if (!file_exists($fileDir)) {
964
            mkdir($fileDir, api_get_permissions_for_new_directories(), true);
965
        }
966
967
        $image = new Image($fileData['tmp_name']);
0 ignored issues
show
Deprecated Code introduced by
The class Image has been deprecated. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-deprecated  annotation

967
        $image = /** @scrutinizer ignore-deprecated */ new Image($fileData['tmp_name']);
Loading history...
968
        $image->send_image($fileDir.$fileName);
969
970
        $table = Database::get_main_table(TABLE_MAIN_CATEGORY);
971
        Database::update(
972
            $table,
973
            ['image' => $dirName.$fileName],
974
            ['id = ?' => $categoryId]
975
        );
976
    }
977
978
    /**
979
     * @param $categoryId
980
     * @param string $description
981
     *
982
     * @return string
983
     */
984
    public static function saveDescription($categoryId, $description)
985
    {
986
        $categoryInfo = self::getCategoryById($categoryId);
987
        if (empty($categoryInfo)) {
988
            return false;
989
        }
990
        $table = Database::get_main_table(TABLE_MAIN_CATEGORY);
991
        Database::update(
992
            $table,
993
            ['description' => $description],
994
            ['id = ?' => $categoryId]
995
        );
996
997
        return true;
998
    }
999
}
1000