Passed
Push — master ( 3b6b96...a0a481 )
by Julito
08:33
created

CourseCategory::saveDescription()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 5
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 3
nc 1
nop 2
dl 0
loc 5
rs 10
c 0
b 0
f 0
1
<?php
2
3
/* For licensing terms, see /license.txt */
4
5
use Chamilo\CoreBundle\Entity\Asset;
6
use Chamilo\CoreBundle\Entity\User;
7
use Chamilo\CoreBundle\Framework\Container;
8
use Chamilo\CoreBundle\Entity\CourseCategory as CourseCategoryEntity;
9
use Doctrine\Common\Collections\Criteria;
10
11
class CourseCategory
12
{
13
    /**
14
     * Get category details from a simple category code.
15
     *
16
     * @param string|null $categoryCode The literal category code
17
     *
18
     * @return array
19
     */
20
    public static function getCategory(string $categoryCode = null)
21
    {
22
        if (!empty($categoryCode)) {
23
            $table = Database::get_main_table(TABLE_MAIN_CATEGORY);
24
            $categoryCode = Database::escape_string($categoryCode);
25
            $sql = "SELECT * FROM $table WHERE code ='$categoryCode'";
26
            $result = Database::query($sql);
27
28
            if (Database::num_rows($result)) {
29
                $category = Database::fetch_array($result, 'ASSOC');
30
                if ($category) {
31
                    // Get access url id
32
                    $table = Database::get_main_table(TABLE_MAIN_ACCESS_URL_REL_COURSE_CATEGORY);
33
                    $sql = "SELECT * FROM $table WHERE course_category_id = ".$category['id'];
34
                    $result = Database::query($sql);
35
                    $result = Database::fetch_array($result);
36
                    if ($result) {
37
                        $category['access_url_id'] = $result['access_url_id'];
38
                    }
39
40
                    return $category;
41
                }
42
            }
43
        }
44
45
        return [];
46
    }
47
48
    /**
49
     * Returns the category fields from the database from an int ID.
50
     *
51
     * @param int $categoryId The category ID
52
     *
53
     * @return array
54
     */
55
    public static function getCategoryById($categoryId)
56
    {
57
        $table = Database::get_main_table(TABLE_MAIN_CATEGORY);
58
        $categoryId = (int) $categoryId;
59
        $sql = "SELECT * FROM $table WHERE id = $categoryId";
60
        $result = Database::query($sql);
61
        if (Database::num_rows($result)) {
62
            $category = Database::fetch_array($result, 'ASSOC');
63
            if ($category) {
64
                // Get access url id
65
                $table = Database::get_main_table(TABLE_MAIN_ACCESS_URL_REL_COURSE_CATEGORY);
66
                $sql = "SELECT * FROM $table WHERE course_category_id = ".$category['id'];
67
                $result = Database::query($sql);
68
                $result = Database::fetch_array($result);
69
                if ($result) {
70
                    $category['access_url_id'] = $result['access_url_id'];
71
                }
72
73
                return $category;
74
            }
75
        }
76
77
        return [];
78
    }
79
80
    /**
81
     * Returns a flat list of all course categories in this URL. If the
82
     * allow_base_course_category option is true, then also show the
83
     * course categories of the base URL.
84
     *
85
     * @return array [id, name, code, parent_id, tree_pos, children_count, number_courses]
86
     */
87
    public static function getAllCategories()
88
    {
89
        $tbl_category = Database::get_main_table(TABLE_MAIN_CATEGORY);
90
        $tbl_course = Database::get_main_table(TABLE_MAIN_COURSE);
91
92
        $table = Database::get_main_table(TABLE_MAIN_ACCESS_URL_REL_COURSE_CATEGORY);
93
        $conditions = " INNER JOIN $table a ON (t1.id = a.course_category_id)";
94
        $whereCondition = " AND a.access_url_id = ".api_get_current_access_url_id();
95
        $allowBaseCategories = api_get_configuration_value('allow_base_course_category');
96
        if ($allowBaseCategories) {
97
            $whereCondition = " AND (a.access_url_id = ".api_get_current_access_url_id()." OR a.access_url_id = 1) ";
98
        }
99
100
        $sql = "SELECT
101
                t1.id,
102
                t1.name,
103
                t1.code,
104
                t1.parent_id,
105
                t1.tree_pos,
106
                t1.children_count,
107
                COUNT(DISTINCT t3.code) AS number_courses
108
                FROM $tbl_category t1
109
                $conditions
110
                LEFT JOIN $tbl_course t3
111
                ON t3.category_id=t1.id
112
                WHERE 1=1
113
                    $whereCondition
114
                GROUP BY
115
                    t1.name,
116
                    t1.code,
117
                    t1.parent_id,
118
                    t1.tree_pos,
119
                    t1.children_count
120
                ORDER BY t1.parent_id, t1.tree_pos";
121
122
        $result = Database::query($sql);
123
124
        return Database::store_result($result, 'ASSOC');
125
    }
126
127
    /**
128
     * @param string $code
129
     * @param string $name
130
     * @param string $canHaveCourses
131
     * @param null|int    $parentId
132
     */
133
    public static function add($code, $name, $canHaveCourses, $description = '', $parentId = null): ?CourseCategoryEntity
134
    {
135
        $table = Database::get_main_table(TABLE_MAIN_CATEGORY);
136
        $code = trim($code);
137
        $name = trim($name);
138
        $parentId = (int) $parentId;
139
140
        $code = CourseManager::generate_course_code($code);
141
        $sql = "SELECT 1 FROM $table
142
                WHERE code = '".Database::escape_string($code)."'";
143
        $result = Database::query($sql);
144
        if (Database::num_rows($result)) {
145
            return null;
146
        }
147
        $result = Database::query("SELECT MAX(tree_pos) AS maxTreePos FROM $table");
148
        $row = Database::fetch_array($result);
149
        $tree_pos = $row['maxTreePos'] + 1;
150
        $parentId = empty($parentId) ? null : $parentId;
151
152
        $repo = Container::getCourseCategoryRepository();
153
        $category = new CourseCategoryEntity();
154
        $category
155
            ->setName($name)
156
            ->setCode($code)
157
            ->setDescription($description)
158
            ->setTreePos($tree_pos)
159
            ->setAuthCourseChild($canHaveCourses)
160
            ->setAuthCatChild('TRUE');
161
162
        if (!empty($parentId)) {
163
            $category->setParent($repo->find($parentId));
164
        }
165
166
        $repo->save($category);
167
168
        $categoryId = $category->getId();
169
        if ($categoryId) {
170
            self::updateParentCategoryChildrenCount($parentId, 1);
171
            UrlManager::addCourseCategoryListToUrl(
172
                [$categoryId],
173
                [api_get_current_access_url_id()]
174
            );
175
176
            return $category;
177
        }
178
179
        return null;
180
    }
181
182
    /**
183
     * Recursive function that updates the count of children in the parent.
184
     *
185
     * @param string $categoryId Category ID
186
     * @param int    $delta      The number to add or delete (1 to add one, -1 to remove one)
187
     */
188
    public static function updateParentCategoryChildrenCount($categoryId, $delta = 1)
189
    {
190
        $table = Database::get_main_table(TABLE_MAIN_CATEGORY);
191
        $categoryId = Database::escape_string($categoryId);
192
        $delta = (int) $delta;
193
        // First get to the highest level possible in the tree
194
        $result = Database::query("SELECT parent_id FROM $table WHERE id = '$categoryId'");
195
        $row = Database::fetch_array($result);
196
        if (false !== $row && 0 != $row['parent_id']) {
197
            // if a parent was found, enter there to see if he's got one more parent
198
            self::updateParentCategoryChildrenCount($row['parent_id'], $delta);
199
        }
200
        // Now we're at the top, get back down to update each child
201
        $sql = "UPDATE $table SET children_count = (children_count - ".abs($delta).") WHERE id = '$categoryId'";
202
        if ($delta >= 0) {
203
            $sql = "UPDATE $table SET children_count = (children_count + $delta) WHERE id = '$categoryId'";
204
        }
205
        Database::query($sql);
206
    }
207
208
    public static function delete($categoryId): bool
209
    {
210
        $repo = Container::getCourseCategoryRepository();
211
        $category = $repo->find($categoryId);
212
        if (null === $category) {
213
            return false;
214
        }
215
216
        $repo->delete($category);
217
218
        return true;
219
220
        // @todo check that doctrine deletes all the connections.
221
        /*$tbl_course = Database::get_main_table(TABLE_MAIN_COURSE);
222
        $tbl_category = Database::get_main_table(TABLE_MAIN_CATEGORY);
223
        $node = Database::escape_string($node);
224
        $result = Database::query("SELECT parent_id, tree_pos FROM $tbl_category WHERE code='$node'");
225
226
        if ($row = Database::fetch_array($result)) {
227
            if (!empty($row['parent_id'])) {
228
                Database::query(
229
                    "UPDATE $tbl_course SET category_id = '".$row['parent_id']."' WHERE category_id = {$category['id']}"
230
                );
231
                Database::query("UPDATE $tbl_category SET parent_id='".$row['parent_id']."' WHERE parent_id='$node'");
232
            } else {
233
                Database::query("UPDATE $tbl_course SET category_id = NULL WHERE category_id = ".$category['id']);
234
                Database::query("UPDATE $tbl_category SET parent_id=NULL WHERE parent_id='$node'");
235
            }
236
237
            $table = Database::get_main_table(TABLE_MAIN_ACCESS_URL_REL_COURSE_CATEGORY);
238
            $sql = "DELETE FROM $table WHERE course_category_id = ".$category['id'];
239
240
            Database::query($sql);
241
            Database::query("UPDATE $tbl_category SET tree_pos=tree_pos-1 WHERE tree_pos > '".$row['tree_pos']."'");
242
            Database::query("DELETE FROM $tbl_category WHERE code='$node'");
243
244
            if (!empty($row['parent_id'])) {
245
                self::updateParentCategoryChildrenCount($row['parent_id'], -1);
246
            }
247
248
            return true;
249
        }*/
250
    }
251
252
    public static function edit($categoryId, $name, $canHaveCourses, $code, $description): CourseCategoryEntity
253
    {
254
        $name = trim(Database::escape_string($name));
255
        $canHaveCourses = Database::escape_string($canHaveCourses);
256
257
        $repo = Container::getCourseCategoryRepository();
258
        $category = $repo->find($categoryId);
259
260
        $category
261
            ->setCode($name)
262
            ->setName($name)
263
            ->setDescription($description)
264
            ->setAuthCourseChild($canHaveCourses);
265
266
        $repo->save($category);
267
268
        // Updating children
269
        /*$sql = "UPDATE $tbl_category SET parent_id = '$code'
270
            WHERE parent_id = '$old_code'";
271
        Database::query($sql);*/
272
273
        return $category;
274
    }
275
276
    /**
277
     * Move a node up on display.
278
     *
279
     * @param string $code
280
     * @param int    $tree_pos
281
     * @param string $parent_id
282
     *
283
     * @return bool
284
     */
285
    public static function moveNodeUp($code, $tree_pos, $parent_id)
286
    {
287
        $table = Database::get_main_table(TABLE_MAIN_CATEGORY);
288
        $code = Database::escape_string($code);
289
        $tree_pos = (int) $tree_pos;
290
        $parent_id = Database::escape_string($parent_id);
291
292
        $parentIdCondition = " AND (parent_id IS NULL OR parent_id = '' )";
293
        if (!empty($parent_id)) {
294
            $parentIdCondition = " AND parent_id = '$parent_id' ";
295
        }
296
297
        $sql = "SELECT code,tree_pos
298
                FROM $table
299
                WHERE
300
                    tree_pos < $tree_pos
301
                    $parentIdCondition
302
                ORDER BY tree_pos DESC
303
                LIMIT 0,1";
304
305
        $result = Database::query($sql);
306
        if (!$row = Database::fetch_array($result)) {
307
            $sql = "SELECT code, tree_pos
308
                    FROM $table
309
                    WHERE
310
                        tree_pos > $tree_pos
311
                        $parentIdCondition
312
                    ORDER BY tree_pos DESC
313
                    LIMIT 0,1";
314
            $result2 = Database::query($sql);
315
            if (!$row = Database::fetch_array($result2)) {
316
                return false;
317
            }
318
        }
319
320
        $sql = "UPDATE $table
321
                SET tree_pos ='".$row['tree_pos']."'
322
                WHERE code='$code'";
323
        Database::query($sql);
324
325
        $sql = "UPDATE $table
326
                SET tree_pos = '$tree_pos'
327
                WHERE code= '".$row['code']."'";
328
        Database::query($sql);
329
330
        return true;
331
    }
332
333
    /**
334
     * @param string $categoryCode
335
     *
336
     * @return array
337
     */
338
    public static function getChildren($categoryCode)
339
    {
340
        $table = Database::get_main_table(TABLE_MAIN_CATEGORY);
341
        $categoryCode = Database::escape_string($categoryCode);
342
        $sql = "SELECT code, id FROM $table
343
                WHERE parent_id = '$categoryCode'";
344
        $result = Database::query($sql);
345
        $children = [];
346
        while ($row = Database::fetch_array($result, 'ASSOC')) {
347
            $children[] = $row;
348
            $subChildren = self::getChildren($row['code']);
349
            $children = array_merge($children, $subChildren);
350
        }
351
352
        return $children;
353
    }
354
355
    /**
356
     * @param string $categoryCode
357
     *
358
     * @return string|null
359
     */
360
    public static function getParentsToString($categoryCode)
361
    {
362
        $parents = self::getParents($categoryCode);
363
364
        if (!empty($parents)) {
365
            $parents = array_reverse($parents);
366
            $categories = [];
367
            foreach ($parents as $category) {
368
                $categories[] = $category['code'];
369
            }
370
371
            return implode(' > ', $categories).' > ';
372
        }
373
374
        return null;
375
    }
376
377
    /**
378
     * @param string $categoryCode
379
     *
380
     * @return array
381
     */
382
    public static function getParents($categoryCode)
383
    {
384
        if (empty($categoryCode)) {
385
            return [];
386
        }
387
388
        $table = Database::get_main_table(TABLE_MAIN_CATEGORY);
389
        $categoryCode = Database::escape_string($categoryCode);
390
        $sql = "SELECT code, parent_id
391
                FROM $table
392
                WHERE code = '$categoryCode'";
393
394
        $result = Database::query($sql);
395
        $children = [];
396
        while ($row = Database::fetch_array($result, 'ASSOC')) {
397
            $parent = self::getCategory($row['parent_id']);
398
            $children[] = $row;
399
            $subChildren = self::getParents($parent ? $parent['code'] : null);
400
            $children = array_merge($children, $subChildren);
401
        }
402
403
        return $children;
404
    }
405
406
    public static function listCategories(array $categorySource = []): string
407
    {
408
        $categories = self::getCategories($categorySource ? $categorySource['id'] : null);
409
        $categoryCode = $categorySource ? Security::remove_XSS($categorySource['code']) : '';
410
411
        if (count($categories) > 0) {
412
            $table = new HTML_Table(['class' => 'data_table']);
413
            $column = 0;
414
            $row = 0;
415
            $headers = [
416
                get_lang('Category'),
417
                get_lang('Sub-categories'),
418
                get_lang('Courses'),
419
                get_lang('Detail'),
420
            ];
421
            foreach ($headers as $header) {
422
                $table->setHeaderContents($row, $column, $header);
423
                $column++;
424
            }
425
            $row++;
426
            $mainUrl = api_get_path(WEB_CODE_PATH).'admin/course_category.php?category='.$categoryCode;
0 ignored issues
show
Bug introduced by
Are you sure $categoryCode of type array|string can be used in concatenation? ( Ignorable by Annotation )

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

426
            $mainUrl = api_get_path(WEB_CODE_PATH).'admin/course_category.php?category='./** @scrutinizer ignore-type */ $categoryCode;
Loading history...
427
428
            $editIcon = Display::return_icon(
429
                'edit.png',
430
                get_lang('Edit'),
431
                null,
432
                ICON_SIZE_SMALL
433
            );
434
            $exportIcon = Display::return_icon('export_csv.png', get_lang('ExportAsCSV'), '');
435
            $deleteIcon = Display::return_icon(
436
                'delete.png',
437
                get_lang('Delete'),
438
                null,
439
                ICON_SIZE_SMALL
440
            );
441
            $moveIcon = Display::return_icon(
442
                'up.png',
443
                get_lang('Up in same level'),
444
                null,
445
                ICON_SIZE_SMALL
446
            );
447
448
            $urlId = api_get_current_access_url_id();
449
            foreach ($categories as $category) {
450
                $categoryId = $category->getId();
451
                $code = $category->getCode();
452
                $editUrl = $mainUrl.'&id='.$categoryId.'&action=edit';
453
                $moveUrl = $mainUrl.'&id='.$categoryId.'&action=moveUp&tree_pos='.$category->getTreePos();
454
                $deleteUrl = $mainUrl.'&id='.$categoryId.'&action=delete';
455
                $exportUrl = $mainUrl.'&id='.$categoryId.'&action=export';
456
457
                $actions = [];
458
                $criteria = Criteria::create();
459
                $criteria->where(Criteria::expr()->eq('status', User::STUDENT));
460
461
                $inUrl = $category->getUrls()->filter(
462
                    function ($entry) use ($urlId) {
463
                        return $entry->getUrl()->getId() === $urlId;
464
                    }
465
                );
466
467
                if ($inUrl->count() > 0) {
468
                    $actions[] = Display::url($editIcon, $editUrl);
469
                    $actions[] = Display::url($moveIcon, $moveUrl);
470
                    $actions[] = Display::url($exportIcon, $exportUrl);
471
                    $actions[] = Display::url(
472
                        $deleteIcon,
473
                        $deleteUrl,
474
                        ['onclick' => 'javascript: if (!confirm(\''.addslashes(api_htmlentities(sprintf(get_lang('Please confirm your choice')), ENT_QUOTES)).'\')) return false;',]
475
                    );
476
                }
477
478
                $url = api_get_path(WEB_CODE_PATH).'admin/course_category.php?id='.$categoryId;
479
                $title = Display::url(
480
                    Display::return_icon(
481
                        'folder_document.gif',
482
                        get_lang('Open this category'),
483
                        null,
484
                        ICON_SIZE_SMALL
485
                    ).' '.$category->getName().' ('.$code.')',
486
                    $url
487
                );
488
489
                $countCourses = $category->getCourses()->count();
490
                $content = [
491
                    $title,
492
                    $category->getChildrenCount(),
493
                    $countCourses,
494
                    implode('', $actions),
495
                ];
496
                $column = 0;
497
                foreach ($content as $value) {
498
                    $table->setCellContents($row, $column, $value);
499
                    $column++;
500
                }
501
                $row++;
502
            }
503
504
            return $table->toHtml();
505
        }
506
507
        return Display::return_message(get_lang('There are no categories here'), 'warning');
508
    }
509
510
    /**
511
     * @param int|null $category Optional. Parent category ID.
512
     *
513
     * @return CourseCategoryEntity[]
514
     */
515
    public static function getCategories($category = null)
516
    {
517
        $repo = Container::getCourseCategoryRepository();
518
        $category = (int) $category;
519
520
        return $repo->findAllInAccessUrl(
521
            api_get_current_access_url_id(),
522
            api_get_configuration_value('allow_base_course_category'),
523
            $category
524
        );
525
526
        /*
527
        $table = Database::get_main_table(TABLE_MAIN_ACCESS_URL_REL_COURSE_CATEGORY);
528
        $conditions = " INNER JOIN $table a ON (t1.id = a.course_category_id)";
529
        $whereCondition = " AND a.access_url_id = ".api_get_current_access_url_id();
530
        $allowBaseCategories = api_get_configuration_value('allow_base_course_category');
531
        if ($allowBaseCategories) {
532
            $whereCondition = " AND (a.access_url_id = ".api_get_current_access_url_id()." OR a.access_url_id = 1) ";
533
        }
534
535
        $parentIdCondition = " AND (t1.parent_id IS NULL OR t1.parent_id = '' )";
536
537
        if ($category) {
538
            $parentIdCondition = " AND t1.parent_id = $category ";
539
        }
540
541
        $sql = "SELECT
542
                t1.name,
543
                t1.code,
544
                t1.parent_id,
545
                t1.tree_pos,
546
                t1.children_count,
547
                COUNT(DISTINCT t4.code) AS nbr_courses,
548
                a.access_url_id
549
                FROM $tbl_category t1
550
                $conditions
551
                LEFT JOIN $tbl_category t2
552
                ON t1.id = t2.parent_id
553
                LEFT JOIN $tbl_course_rel_category t3
554
                ON t1.id = t3.course_category_id
555
                LEFT JOIN $tbl_course t4
556
                ON t3.course_id = t4.id
557
                WHERE
558
                    1 = 1
559
                    $parentIdCondition
560
                    $whereCondition
561
                GROUP BY t1.name,
562
                         t1.code,
563
                         t1.parent_id,
564
                         t1.tree_pos,
565
                         t1.children_count
566
                ORDER BY t1.tree_pos
567
        ";
568
569
        $result = Database::query($sql);
570
571
        return Database::store_result($result, 'ASSOC');*/
572
    }
573
574
    /**
575
     * @return array
576
     */
577
    public static function getCategoriesToDisplayInHomePage()
578
    {
579
        $table = Database::get_main_table(TABLE_MAIN_CATEGORY);
580
        $sql = "SELECT name FROM $table
581
                WHERE parent_id IS NULL
582
                ORDER BY tree_pos";
583
584
        return Database::store_result(Database::query($sql));
585
    }
586
587
    /**
588
     * @param string $categoryCode
589
     *
590
     * @return array
591
     */
592
    public static function getCategoriesCanBeAddedInCourse($categoryCode)
593
    {
594
        $table = Database::get_main_table(TABLE_MAIN_ACCESS_URL_REL_COURSE_CATEGORY);
595
        $conditions = " INNER JOIN $table a ON (c.id = a.course_category_id)";
596
        $whereCondition = ' AND a.access_url_id = '.api_get_current_access_url_id();
597
598
        $tbl_category = Database::get_main_table(TABLE_MAIN_CATEGORY);
599
        $sql = "SELECT c.id, c.code, name
600
                FROM $tbl_category c
601
                $conditions
602
                WHERE (auth_course_child = 'TRUE' OR code = '".Database::escape_string($categoryCode)."')
603
                $whereCondition
604
                ORDER BY tree_pos";
605
        $res = Database::query($sql);
606
607
        $categoryToAvoid = '';
608
        if (!api_is_platform_admin()) {
609
            $categoryToAvoid = api_get_configuration_value('course_category_code_to_use_as_model');
610
        }
611
        $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...
612
        while ($cat = Database::fetch_array($res)) {
613
            $categoryCode = $cat['code'];
614
            if (!empty($categoryToAvoid) && $categoryToAvoid == $categoryCode) {
615
                continue;
616
            }
617
            $categories[$cat['id']] = '('.$cat['code'].') '.$cat['name'];
618
            ksort($categories);
619
        }
620
621
        return $categories;
622
    }
623
624
    /**
625
     * @param string $category_code
626
     * @param string $keyword
627
     *
628
     * @paran bool  $avoidCourses
629
     * @paran array $conditions
630
     *
631
     * @return int
632
     */
633
    public static function countCoursesInCategory(
634
        $category_code = '',
635
        $keyword = '',
636
        $avoidCourses = true,
637
        $conditions = []
638
    ) {
639
        return self::getCoursesInCategory($category_code, $keyword, $avoidCourses, $conditions, true);
640
    }
641
642
    /**
643
     * @return \Chamilo\CoreBundle\Entity\Course[]
644
     */
645
    public static function getCoursesInCategory(
646
        $categoryId,
647
        $keyword = '',
648
        $avoidCourses = true,
649
        $conditions = [],
650
        $getCount = false
651
    ) {
652
        $repo = Container::getCourseCategoryRepository();
653
        /** @var CourseCategoryEntity $category */
654
        $category = $repo->find($categoryId);
655
656
        // @todo add filters
657
658
        return $category->getCourses();
659
660
        $tbl_course = Database::get_main_table(TABLE_MAIN_COURSE);
0 ignored issues
show
Unused Code introduced by
$tbl_course = Database::...able(TABLE_MAIN_COURSE) is not reachable.

This check looks for unreachable code. It uses sophisticated control flow analysis techniques to find statements which will never be executed.

Unreachable code is most often the result of return, die or exit statements that have been added for debug purposes.

function fx() {
    try {
        doSomething();
        return true;
    }
    catch (\Exception $e) {
        return false;
    }

    return false;
}

In the above example, the last return false will never be executed, because a return statement has already been met in every possible execution path.

Loading history...
661
        $tblCourseCategory = Database::get_main_table(TABLE_MAIN_CATEGORY);
662
        $keyword = Database::escape_string($keyword);
663
        $categoryCode = Database::escape_string($category_code);
664
        $avoidCoursesCondition = '';
665
        if ($avoidCourses) {
666
            $avoidCoursesCondition = CoursesAndSessionsCatalog::getAvoidCourseCondition();
667
        }
668
669
        $visibilityCondition = CourseManager::getCourseVisibilitySQLCondition('course', true);
670
671
        $sqlInjectJoins = '';
672
        $where = ' AND 1 = 1 ';
673
        $sqlInjectWhere = '';
674
        if (!empty($conditions)) {
675
            $sqlInjectJoins = $conditions['inject_joins'];
676
            $where = $conditions['where'];
677
            $sqlInjectWhere = $conditions['inject_where'];
678
        }
679
        $categoryFilter = '';
680
        if ('ALL' === $categoryCode || empty($categoryCode)) {
681
            // Nothing to do
682
        } elseif ('NONE' === $categoryCode) {
683
            $categoryFilter = ' AND course.category_id IS NULL ';
684
        } else {
685
            $categoryJoin = " INNER JOIN $tblCourseCategory cat ON course.category_id = cat.id ";
686
            $categoryFilter = ' AND cat.code = "'.$categoryCode.'" ';
687
        }
688
689
        $searchFilter = '';
690
        if (!empty($keyword)) {
691
            $searchFilter = ' AND (
692
                course.code LIKE "%'.$keyword.'%" OR
693
                course.title LIKE "%'.$keyword.'%" OR
694
                course.tutor_name LIKE "%'.$keyword.'%"
695
            ) ';
696
        }
697
698
        $urlCondition = ' url_rel_course.access_url_id = '.api_get_current_access_url_id().' AND';
699
        $tbl_url_rel_course = Database::get_main_table(TABLE_MAIN_ACCESS_URL_REL_COURSE);
700
701
        $select = " DISTINCT course.id, course.code, course.title ";
702
        if ($getCount) {
703
            $select = "count(DISTINCT course.id) as count";
704
        }
705
        $sql = "SELECT $select
706
                FROM $tbl_course as course
707
                INNER JOIN $tbl_url_rel_course as url_rel_course
708
                ON (url_rel_course.c_id = course.id)
709
                $sqlInjectJoins
710
                $categoryJoin
711
                WHERE
712
                    $urlCondition
713
                    course.visibility != '0' AND
714
                    course.visibility != '4'
715
                    $categoryFilter
716
                    $searchFilter
717
                    $avoidCoursesCondition
718
                    $visibilityCondition
719
                    $where
720
                    $sqlInjectWhere
721
            ";
722
723
        $result = Database::query($sql);
724
        if ($getCount) {
725
            $row = Database::fetch_array($result);
726
727
            return (int) $row['count'];
728
        }
729
730
        return Database::store_result($result, 'ASSOC');
731
    }
732
733
    /**
734
     * @param array $list
735
     *
736
     * @return array
737
     */
738
    public static function getCourseCategoryNotInList($list)
739
    {
740
        $table = Database::get_main_table(TABLE_MAIN_CATEGORY);
741
742
        if (empty($list)) {
743
            $sql = "SELECT * FROM $table
744
                    WHERE (parent_id IS NULL) ";
745
            $result = Database::query($sql);
746
747
            return Database::store_result($result, 'ASSOC');
748
        }
749
750
        $list = array_map('intval', $list);
751
        $listToString = implode("','", $list);
752
753
        $sql = "SELECT * FROM $table
754
                WHERE id NOT IN ('$listToString') AND (parent_id IS NULL) ";
755
        $result = Database::query($sql);
756
757
        return Database::store_result($result, 'ASSOC');
758
    }
759
760
    /**
761
     * @param string $keyword
762
     *
763
     * @return array|null
764
     */
765
    public static function searchCategoryByKeyword($keyword)
766
    {
767
        if (empty($keyword)) {
768
            return null;
769
        }
770
771
        $tableCategory = Database::get_main_table(TABLE_MAIN_CATEGORY);
772
        $table = Database::get_main_table(TABLE_MAIN_ACCESS_URL_REL_COURSE_CATEGORY);
773
        $conditions = " INNER JOIN $table a ON (c.id = a.course_category_id)";
774
        $whereCondition = " AND a.access_url_id = ".api_get_current_access_url_id();
775
776
        $allowBaseCategories = api_get_configuration_value('allow_base_course_category');
777
        if ($allowBaseCategories) {
778
            $whereCondition = " AND (a.access_url_id = ".api_get_current_access_url_id()." OR a.access_url_id = 1) ";
779
        }
780
781
        $keyword = Database::escape_string($keyword);
782
783
        $sql = "SELECT c.*, c.name as text
784
                FROM $tableCategory c $conditions
785
                WHERE
786
                (
787
                    c.code LIKE '%$keyword%' OR name LIKE '%$keyword%'
788
                ) AND auth_course_child = 'TRUE'
789
                $whereCondition ";
790
        $result = Database::query($sql);
791
792
        return Database::store_result($result, 'ASSOC');
793
    }
794
795
    /**
796
     * Get Pagination HTML div.
797
     *
798
     * @param $pageCurrent
799
     * @param $pageLength
800
     * @param $pageTotal
801
     *
802
     * @return string
803
     */
804
    public static function getCatalogPagination($pageCurrent, $pageLength, $pageTotal)
805
    {
806
        // Start empty html
807
        $pageDiv = '';
808
        $html = '';
809
        $pageBottom = max(1, $pageCurrent - 3);
810
        $pageTop = min($pageTotal, $pageCurrent + 3);
811
812
        if ($pageBottom > 1) {
813
            $pageDiv .= self::getPageNumberItem(1, $pageLength);
814
            if ($pageBottom > 2) {
815
                $pageDiv .= self::getPageNumberItem(
816
                    $pageBottom - 1,
817
                    $pageLength,
818
                    null,
819
                    '...'
820
                );
821
            }
822
        }
823
824
        // For each page add its page button to html
825
        for ($i = $pageBottom; $i <= $pageTop; $i++) {
826
            if ($i === $pageCurrent) {
827
                $pageItemAttributes = ['class' => 'page-item active'];
828
            } else {
829
                $pageItemAttributes = ['class' => 'page-item'];
830
            }
831
            $pageDiv .= self::getPageNumberItem(
832
                $i,
833
                $pageLength,
834
                $pageItemAttributes
835
            );
836
        }
837
838
        // Check if current page is the last page
839
        if ($pageTop < $pageTotal) {
840
            if ($pageTop < ($pageTotal - 1)) {
841
                $pageDiv .= self::getPageNumberItem(
842
                    $pageTop + 1,
843
                    $pageLength,
844
                    null,
845
                    '...'
846
                );
847
            }
848
            $pageDiv .= self::getPageNumberItem($pageTotal, $pageLength);
849
        }
850
851
        // Complete pagination html
852
        $pageDiv = Display::tag('ul', $pageDiv, ['class' => 'pagination']);
853
        $html .= '<nav>'.$pageDiv.'</nav>';
854
855
        return $html;
856
    }
857
858
    /**
859
     * Get li HTML of page number.
860
     *
861
     * @param        $pageNumber
862
     * @param        $pageLength
863
     * @param array  $liAttributes
864
     * @param string $content
865
     *
866
     * @return string
867
     */
868
    public static function getPageNumberItem(
869
        $pageNumber,
870
        $pageLength,
871
        $liAttributes = [],
872
        $content = ''
873
    ) {
874
        // Get page URL
875
        $url = self::getCourseCategoryUrl(
876
            $pageNumber,
877
            $pageLength
878
        );
879
880
        // If is current page ('active' class) clear URL
881
        if (isset($liAttributes) && is_array($liAttributes) && isset($liAttributes['class'])) {
882
            if (false !== strpos('active', $liAttributes['class'])) {
883
                $url = '';
884
            }
885
        }
886
887
        $content = !empty($content) ? $content : $pageNumber;
888
889
        return Display::tag(
890
            'li',
891
            Display::url(
892
                $content,
893
                $url,
894
                ['class' => 'page-link']
895
            ),
896
            $liAttributes
897
        );
898
    }
899
900
    /**
901
     * Return URL to course catalog.
902
     *
903
     * @param int    $pageCurrent
904
     * @param int    $pageLength
905
     * @param string $categoryCode
906
     * @param int    $hiddenLinks
907
     * @param string $action
908
     *
909
     * @return string
910
     */
911
    public static function getCourseCategoryUrl(
912
        $pageCurrent,
913
        $pageLength,
914
        $categoryCode = null,
915
        $hiddenLinks = null,
916
        $action = null
917
    ) {
918
        $requestAction = isset($_REQUEST['action']) ? Security::remove_XSS($_REQUEST['action']) : null;
919
        $action = isset($action) ? Security::remove_XSS($action) : $requestAction;
920
        $searchTerm = isset($_REQUEST['search_term']) ? Security::remove_XSS($_REQUEST['search_term']) : null;
921
922
        if ('subscribe_user_with_password' === $action) {
923
            $action = 'subscribe';
924
        }
925
926
        $categoryCodeRequest = isset($_REQUEST['category_code']) ? Security::remove_XSS(
927
            $_REQUEST['category_code']
928
        ) : null;
929
        $categoryCode = isset($categoryCode) ? Security::remove_XSS($categoryCode) : $categoryCodeRequest;
930
        $hiddenLinksRequest = isset($_REQUEST['hidden_links']) ? Security::remove_XSS($_REQUEST['hidden_links']) : null;
931
        $hiddenLinks = isset($hiddenLinks) ? Security::remove_XSS($hiddenLinksRequest) : $categoryCodeRequest;
932
933
        // Start URL with params
934
        $pageUrl = api_get_self().
935
            '?action='.$action.
0 ignored issues
show
Bug introduced by
Are you sure $action of type array|null|string can be used in concatenation? ( Ignorable by Annotation )

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

935
            '?action='./** @scrutinizer ignore-type */ $action.
Loading history...
936
            '&category_code='.$categoryCode.
0 ignored issues
show
Bug introduced by
Are you sure $categoryCode of type array|null|string can be used in concatenation? ( Ignorable by Annotation )

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

936
            '&category_code='./** @scrutinizer ignore-type */ $categoryCode.
Loading history...
937
            '&hidden_links='.$hiddenLinks.
0 ignored issues
show
Bug introduced by
Are you sure $hiddenLinks of type array|null|string can be used in concatenation? ( Ignorable by Annotation )

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

937
            '&hidden_links='./** @scrutinizer ignore-type */ $hiddenLinks.
Loading history...
938
            '&pageCurrent='.$pageCurrent.
939
            '&pageLength='.$pageLength;
940
941
        switch ($action) {
942
            case 'subscribe':
943
                // for search
944
                $pageUrl .=
945
                    '&search_term='.$searchTerm.
0 ignored issues
show
Bug introduced by
Are you sure $searchTerm of type array|null|string can be used in concatenation? ( Ignorable by Annotation )

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

945
                    '&search_term='./** @scrutinizer ignore-type */ $searchTerm.
Loading history...
946
                    '&search_course=1'.
947
                    '&sec_token='.Security::getTokenFromSession();
948
                break;
949
            case 'display_courses':
950
            default:
951
                break;
952
        }
953
954
        return $pageUrl;
955
    }
956
957
    /**
958
     * Return the name tool by action.
959
     *
960
     * @param string $action
961
     *
962
     * @return string
963
     */
964
    public static function getCourseCatalogNameTools($action)
965
    {
966
        $nameTools = get_lang('My courses');
967
        if (empty($action)) {
968
            return $nameTools; //should never happen
969
        }
970
971
        switch ($action) {
972
            case 'subscribe':
973
            case 'subscribe_user_with_password':
974
            case 'display_random_courses':
975
            case 'display_courses':
976
                $nameTools = get_lang('Courses catalog');
977
                break;
978
            case 'display_sessions':
979
                $nameTools = get_lang('Course sessions');
980
                break;
981
            default:
982
                // Nothing to do
983
                break;
984
        }
985
986
        return $nameTools;
987
    }
988
989
    public static function deleteImage(CourseCategoryEntity $category)
990
    {
991
        $assetRepo = Container::getAssetRepository();
992
        $assetId = $category->getImage();
993
        $asset = $assetRepo->find($assetId);
994
        $assetRepo->delete($asset);
995
996
        $category->setImage('');
997
        $repo = Container::getCourseCategoryRepository();
998
        $repo->save($category);
999
    }
1000
1001
    /**
1002
     * Save image for a course category.
1003
     *
1004
     * @param array $fileData File data from $_FILES
1005
     */
1006
    public static function saveImage(CourseCategoryEntity $category, $fileData)
1007
    {
1008
        if (isset($fileData['tmp_name']) && !empty($fileData['tmp_name'])) {
1009
            $categoryId = $category->getId();
1010
            $extension = getextension($fileData['name']);
1011
            $fileName = "cc_$categoryId.{$extension[0]}";
1012
1013
            $repo = Container::getAssetRepository();
1014
            $asset = new Asset();
1015
            $asset
1016
                ->setCategory(Asset::COURSE_CATEGORY)
1017
                ->setTitle($fileName);
1018
            $asset = $repo->createFromRequest($asset, $fileData);
1019
1020
            $category->setImage($asset->getId());
1021
            $repo = Container::getCourseCategoryRepository();
1022
            $repo->save($category);
1023
        }
1024
    }
1025
}
1026