Passed
Push — master ( 8631fb...7f9d4e )
by Julito
18:15
created

CourseCategory::getCategory()   A

Complexity

Conditions 5
Paths 5

Size

Total Lines 26
Code Lines 16

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 5
eloc 16
nc 5
nop 1
dl 0
loc 26
rs 9.4222
c 0
b 0
f 0
1
<?php
2
3
/* For licensing terms, see /license.txt */
4
5
use Chamilo\CoreBundle\Entity\User;
6
use Chamilo\CoreBundle\Framework\Container;
7
use Chamilo\CoreBundle\Entity\CourseCategory as CourseCategoryEntity;
8
use Doctrine\Common\Collections\Criteria;
9
10
/**
11
 * Class CourseCategory.
12
 */
13
class CourseCategory
14
{
15
    /**
16
     * Returns the category fields from the database from an int ID.
17
     *
18
     * @param int $categoryId The category ID
19
     *
20
     * @return array
21
     */
22
    public static function getCategoryById($categoryId)
23
    {
24
        $table = Database::get_main_table(TABLE_MAIN_CATEGORY);
25
        $categoryId = (int) $categoryId;
26
        $sql = "SELECT * FROM $table WHERE id = $categoryId";
27
        $result = Database::query($sql);
28
        if (Database::num_rows($result)) {
29
            return Database::fetch_array($result, 'ASSOC');
30
        }
31
32
        return [];
33
    }
34
35
    /**
36
     * Get category details from a simple category code.
37
     *
38
     * @param string|null $categoryCode The literal category code
39
     *
40
     * @return array
41
     */
42
    public static function getCategory(string $categoryCode = null)
43
    {
44
        if (!empty($categoryCode)) {
45
            $table = Database::get_main_table(TABLE_MAIN_CATEGORY);
46
            $categoryCode = Database::escape_string($categoryCode);
47
            $sql = "SELECT * FROM $table WHERE code ='$categoryCode'";
48
            $result = Database::query($sql);
49
50
            if (Database::num_rows($result)) {
51
                $category = Database::fetch_array($result, 'ASSOC');
52
                if ($category) {
53
                    // Get access url id
54
                    $table = Database::get_main_table(TABLE_MAIN_ACCESS_URL_REL_COURSE_CATEGORY);
55
                    $sql = "SELECT * FROM $table WHERE course_category_id = ".$category['id'];
56
                    $result = Database::query($sql);
57
                    $result = Database::fetch_array($result);
58
                    if ($result) {
59
                        $category['access_url_id'] = $result['access_url_id'];
60
                    }
61
62
                    return $category;
63
                }
64
            }
65
        }
66
67
        return [];
68
    }
69
70
    /**
71
     * @param int|null $category Optional. Parent category ID.
72
     *
73
     * @return CourseCategoryEntity[]
74
     */
75
    public static function getCategories($category = null)
76
    {
77
        $repo = Container::getCourseCategoryRepository();
78
        $tbl_category = Database::get_main_table(TABLE_MAIN_CATEGORY);
79
        $tbl_course = Database::get_main_table(TABLE_MAIN_COURSE);
80
        $tbl_course_rel_category = Database::get_main_table(TABLE_MAIN_COURSE_REL_CATEGORY);
81
        $category = (int) $category;
82
        $conditions = null;
83
84
        return $repo->findAllInAccessUrl(
85
            api_get_current_access_url_id(),
86
            api_get_configuration_value('allow_base_course_category'),
87
            $category
88
        );
89
90
        /*
91
        $table = Database::get_main_table(TABLE_MAIN_ACCESS_URL_REL_COURSE_CATEGORY);
92
        $conditions = " INNER JOIN $table a ON (t1.id = a.course_category_id)";
93
        $whereCondition = " AND a.access_url_id = ".api_get_current_access_url_id();
94
        $allowBaseCategories = api_get_configuration_value('allow_base_course_category');
95
        if ($allowBaseCategories) {
96
            $whereCondition = " AND (a.access_url_id = ".api_get_current_access_url_id()." OR a.access_url_id = 1) ";
97
        }
98
99
        $parentIdCondition = " AND (t1.parent_id IS NULL OR t1.parent_id = '' )";
100
101
        if ($category) {
102
            $parentIdCondition = " AND t1.parent_id = $category ";
103
        }
104
105
        $sql = "SELECT
106
                t1.name,
107
                t1.code,
108
                t1.parent_id,
109
                t1.tree_pos,
110
                t1.children_count,
111
                COUNT(DISTINCT t4.code) AS nbr_courses,
112
                a.access_url_id
113
                FROM $tbl_category t1
114
                $conditions
115
                LEFT JOIN $tbl_category t2
116
                ON t1.id = t2.parent_id
117
                LEFT JOIN $tbl_course_rel_category t3
118
                ON t1.id = t3.course_category_id
119
                LEFT JOIN $tbl_course t4
120
                ON t3.course_id = t4.id
121
                WHERE
122
                    1 = 1
123
                    $parentIdCondition
124
                    $whereCondition
125
                GROUP BY t1.name,
126
                         t1.code,
127
                         t1.parent_id,
128
                         t1.tree_pos,
129
                         t1.children_count
130
                ORDER BY t1.tree_pos
131
        ";
132
133
        $result = Database::query($sql);
134
135
        return Database::store_result($result, 'ASSOC');*/
136
    }
137
138
    /**
139
     * Returns a flat list of all course categories in this URL. If the
140
     * allow_base_course_category option is true, then also show the
141
     * course categories of the base URL.
142
     *
143
     * @return array [id, name, code, parent_id, tree_pos, children_count, number_courses]
144
     */
145
    public static function getAllCategories()
146
    {
147
        $tbl_category = Database::get_main_table(TABLE_MAIN_CATEGORY);
148
        $tbl_course = Database::get_main_table(TABLE_MAIN_COURSE);
149
150
        $table = Database::get_main_table(TABLE_MAIN_ACCESS_URL_REL_COURSE_CATEGORY);
151
        $conditions = " INNER JOIN $table a ON (t1.id = a.course_category_id)";
152
        $whereCondition = " AND a.access_url_id = ".api_get_current_access_url_id();
153
        $allowBaseCategories = api_get_configuration_value('allow_base_course_category');
154
        if ($allowBaseCategories) {
155
            $whereCondition = " AND (a.access_url_id = ".api_get_current_access_url_id()." OR a.access_url_id = 1) ";
156
        }
157
158
        $sql = "SELECT
159
                t1.id,
160
                t1.name,
161
                t1.code,
162
                t1.parent_id,
163
                t1.tree_pos,
164
                t1.children_count,
165
                COUNT(DISTINCT t3.code) AS number_courses
166
                FROM $tbl_category t1
167
                $conditions
168
                LEFT JOIN $tbl_course t3
169
                ON t3.category_id=t1.id
170
                WHERE 1=1
171
                    $whereCondition
172
                GROUP BY
173
                    t1.name,
174
                    t1.code,
175
                    t1.parent_id,
176
                    t1.tree_pos,
177
                    t1.children_count
178
                ORDER BY t1.parent_id, t1.tree_pos";
179
180
        $result = Database::query($sql);
181
182
        return Database::store_result($result, 'ASSOC');
183
    }
184
185
    /**
186
     * @param string $code
187
     * @param string $name
188
     * @param string $canHaveCourses
189
     * @param int    $parent_id
190
     *
191
     * @return bool
192
     */
193
    public static function addNode($code, $name, $canHaveCourses, $parent_id)
194
    {
195
        $table = Database::get_main_table(TABLE_MAIN_CATEGORY);
196
        $code = trim($code);
197
        $name = trim($name);
198
        $parent_id = (int) $parent_id;
199
200
        $code = CourseManager::generate_course_code($code);
201
        $sql = "SELECT 1 FROM $table
202
                WHERE code = '".Database::escape_string($code)."'";
203
        $result = Database::query($sql);
204
        if (Database::num_rows($result)) {
205
            return false;
206
        }
207
        $result = Database::query("SELECT MAX(tree_pos) AS maxTreePos FROM $table");
208
        $row = Database::fetch_array($result);
209
        $tree_pos = $row['maxTreePos'] + 1;
210
211
        $params = [
212
            'name' => $name,
213
            'code' => $code,
214
            'parent_id' => empty($parent_id) ? null : $parent_id,
215
            'tree_pos' => $tree_pos,
216
            'children_count' => 0,
217
            'auth_course_child' => $canHaveCourses,
218
            'auth_cat_child' => 'TRUE',
219
        ];
220
221
        $categoryId = Database::insert($table, $params);
222
        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...
223
            self::updateParentCategoryChildrenCount($parent_id, 1);
224
            UrlManager::addCourseCategoryListToUrl(
225
                [$categoryId],
226
                [api_get_current_access_url_id()]
227
            );
228
229
            return $categoryId;
230
        }
231
232
        return false;
233
    }
234
235
    /**
236
     * Recursive function that updates the count of children in the parent.
237
     *
238
     * @param string $categoryId Category ID
239
     * @param int    $delta      The number to add or delete (1 to add one, -1 to remove one)
240
     */
241
    public static function updateParentCategoryChildrenCount($categoryId, $delta = 1)
242
    {
243
        $table = Database::get_main_table(TABLE_MAIN_CATEGORY);
244
        $categoryId = Database::escape_string($categoryId);
245
        $delta = (int) $delta;
246
        // First get to the highest level possible in the tree
247
        $result = Database::query("SELECT parent_id FROM $table WHERE id = '$categoryId'");
248
        $row = Database::fetch_array($result);
249
        if (false !== $row && 0 != $row['parent_id']) {
250
            // if a parent was found, enter there to see if he's got one more parent
251
            self::updateParentCategoryChildrenCount($row['parent_id'], $delta);
252
        }
253
        // Now we're at the top, get back down to update each child
254
        $sql = "UPDATE $table SET children_count = (children_count - ".abs($delta).") WHERE id = '$categoryId'";
255
        if ($delta >= 0) {
256
            $sql = "UPDATE $table SET children_count = (children_count + $delta) WHERE id = '$categoryId'";
257
        }
258
        Database::query($sql);
259
    }
260
261
    public static function delete($categoryId): bool
262
    {
263
        $repo = Container::getCourseCategoryRepository();
264
        $category = $repo->find($categoryId);
265
        if (null === $category) {
266
            return false;
267
        }
268
269
        $repo->delete($category);
270
271
        return true;
272
273
        // @todo check that doctrine deletes all the connections.
274
        /*$tbl_course = Database::get_main_table(TABLE_MAIN_COURSE);
275
        $tbl_category = Database::get_main_table(TABLE_MAIN_CATEGORY);
276
        $node = Database::escape_string($node);
277
        $result = Database::query("SELECT parent_id, tree_pos FROM $tbl_category WHERE code='$node'");
278
279
        if ($row = Database::fetch_array($result)) {
280
            if (!empty($row['parent_id'])) {
281
                Database::query(
282
                    "UPDATE $tbl_course SET category_id = '".$row['parent_id']."' WHERE category_id = {$category['id']}"
283
                );
284
                Database::query("UPDATE $tbl_category SET parent_id='".$row['parent_id']."' WHERE parent_id='$node'");
285
            } else {
286
                Database::query("UPDATE $tbl_course SET category_id = NULL WHERE category_id = ".$category['id']);
287
                Database::query("UPDATE $tbl_category SET parent_id=NULL WHERE parent_id='$node'");
288
            }
289
290
            $table = Database::get_main_table(TABLE_MAIN_ACCESS_URL_REL_COURSE_CATEGORY);
291
            $sql = "DELETE FROM $table WHERE course_category_id = ".$category['id'];
292
293
            Database::query($sql);
294
            Database::query("UPDATE $tbl_category SET tree_pos=tree_pos-1 WHERE tree_pos > '".$row['tree_pos']."'");
295
            Database::query("DELETE FROM $tbl_category WHERE code='$node'");
296
297
            if (!empty($row['parent_id'])) {
298
                self::updateParentCategoryChildrenCount($row['parent_id'], -1);
299
            }
300
301
            return true;
302
        }*/
303
    }
304
305
    /**
306
     * @param string $code
307
     * @param string $name
308
     * @param string $canHaveCourses
309
     * @param string $old_code
310
     *
311
     * @return bool
312
     */
313
    public static function editNode($code, $name, $canHaveCourses, $old_code)
314
    {
315
        $tbl_category = Database::get_main_table(TABLE_MAIN_CATEGORY);
316
317
        $code = trim(Database::escape_string($code));
318
        $name = trim(Database::escape_string($name));
319
        $old_code = Database::escape_string($old_code);
320
        $canHaveCourses = Database::escape_string($canHaveCourses);
321
322
        $code = CourseManager::generate_course_code($code);
323
        // Updating category
324
        $sql = "UPDATE $tbl_category SET
325
                    name='$name',
326
                    code='$code',
327
                    auth_course_child = '$canHaveCourses'
328
                WHERE code = '$old_code'";
329
        Database::query($sql);
330
331
        // Updating children
332
        $sql = "UPDATE $tbl_category SET parent_id = '$code'
333
            WHERE parent_id = '$old_code'";
334
        Database::query($sql);
335
336
        return true;
337
    }
338
339
    /**
340
     * Move a node up on display.
341
     *
342
     * @param string $code
343
     * @param int    $tree_pos
344
     * @param string $parent_id
345
     *
346
     * @return bool
347
     */
348
    public static function moveNodeUp($code, $tree_pos, $parent_id)
349
    {
350
        $table = Database::get_main_table(TABLE_MAIN_CATEGORY);
351
        $code = Database::escape_string($code);
352
        $tree_pos = (int) $tree_pos;
353
        $parent_id = Database::escape_string($parent_id);
354
355
        $parentIdCondition = " AND (parent_id IS NULL OR parent_id = '' )";
356
        if (!empty($parent_id)) {
357
            $parentIdCondition = " AND parent_id = '$parent_id' ";
358
        }
359
360
        $sql = "SELECT code,tree_pos
361
                FROM $table
362
                WHERE
363
                    tree_pos < $tree_pos
364
                    $parentIdCondition
365
                ORDER BY tree_pos DESC
366
                LIMIT 0,1";
367
368
        $result = Database::query($sql);
369
        if (!$row = Database::fetch_array($result)) {
370
            $sql = "SELECT code, tree_pos
371
                    FROM $table
372
                    WHERE
373
                        tree_pos > $tree_pos
374
                        $parentIdCondition
375
                    ORDER BY tree_pos DESC
376
                    LIMIT 0,1";
377
            $result2 = Database::query($sql);
378
            if (!$row = Database::fetch_array($result2)) {
379
                return false;
380
            }
381
        }
382
383
        $sql = "UPDATE $table
384
                SET tree_pos ='".$row['tree_pos']."'
385
                WHERE code='$code'";
386
        Database::query($sql);
387
388
        $sql = "UPDATE $table
389
                SET tree_pos = '$tree_pos'
390
                WHERE code= '".$row['code']."'";
391
        Database::query($sql);
392
393
        return true;
394
    }
395
396
    /**
397
     * @param string $categoryCode
398
     *
399
     * @return array
400
     */
401
    public static function getChildren($categoryCode)
402
    {
403
        $table = Database::get_main_table(TABLE_MAIN_CATEGORY);
404
        $categoryCode = Database::escape_string($categoryCode);
405
        $sql = "SELECT code, id FROM $table
406
                WHERE parent_id = '$categoryCode'";
407
        $result = Database::query($sql);
408
        $children = [];
409
        while ($row = Database::fetch_array($result, 'ASSOC')) {
410
            $children[] = $row;
411
            $subChildren = self::getChildren($row['code']);
412
            $children = array_merge($children, $subChildren);
413
        }
414
415
        return $children;
416
    }
417
418
    /**
419
     * @param string $categoryCode
420
     *
421
     * @return array
422
     */
423
    public static function getParents($categoryCode)
424
    {
425
        if (empty($categoryCode)) {
426
            return [];
427
        }
428
429
        $table = Database::get_main_table(TABLE_MAIN_CATEGORY);
430
        $categoryCode = Database::escape_string($categoryCode);
431
        $sql = "SELECT code, parent_id
432
                FROM $table
433
                WHERE code = '$categoryCode'";
434
435
        $result = Database::query($sql);
436
        $children = [];
437
        while ($row = Database::fetch_array($result, 'ASSOC')) {
438
            $parent = self::getCategory($row['parent_id']);
439
            $children[] = $row;
440
            $subChildren = self::getParents($parent ? $parent['code'] : null);
441
            $children = array_merge($children, $subChildren);
442
        }
443
444
        return $children;
445
    }
446
447
    /**
448
     * @param string $categoryCode
449
     *
450
     * @return string|null
451
     */
452
    public static function getParentsToString($categoryCode)
453
    {
454
        $parents = self::getParents($categoryCode);
455
456
        if (!empty($parents)) {
457
            $parents = array_reverse($parents);
458
            $categories = [];
459
            foreach ($parents as $category) {
460
                $categories[] = $category['code'];
461
            }
462
463
            return implode(' > ', $categories).' > ';
464
        }
465
466
        return null;
467
    }
468
469
    public static function listCategories(array $categorySource = []): string
470
    {
471
        $categories = self::getCategories($categorySource ? $categorySource['id'] : null);
472
        $categoryCode = $categorySource ? Security::remove_XSS($categorySource['code']) : '';
473
474
        if (count($categories) > 0) {
475
            $table = new HTML_Table(['class' => 'data_table']);
476
            $column = 0;
477
            $row = 0;
478
            $headers = [
479
                get_lang('Category'),
480
                get_lang('Sub-categories'),
481
                get_lang('Courses'),
482
                get_lang('Detail'),
483
            ];
484
            foreach ($headers as $header) {
485
                $table->setHeaderContents($row, $column, $header);
486
                $column++;
487
            }
488
            $row++;
489
            $mainUrl = api_get_path(WEB_CODE_PATH).'admin/course_category.php?category='.$categoryCode;
490
491
            $editIcon = Display::return_icon(
492
                'edit.png',
493
                get_lang('Edit this category'),
494
                null,
495
                ICON_SIZE_SMALL
496
            );
497
            $deleteIcon = Display::return_icon(
498
                'delete.png',
499
                get_lang('Delete this category'),
500
                null,
501
                ICON_SIZE_SMALL
502
            );
503
            $moveIcon = Display::return_icon(
504
                'up.png',
505
                get_lang('Up in same level'),
506
                null,
507
                ICON_SIZE_SMALL
508
            );
509
510
            $urlId = api_get_current_access_url_id();
511
            foreach ($categories as $category) {
512
                $code = $category->getCode();
513
                $editUrl = $mainUrl.'&id='.$code.'&action=edit';
514
                $moveUrl = $mainUrl.'&id='.$code.'&action=moveUp&tree_pos='.$category->getTreePos();
515
                $deleteUrl = $mainUrl.'&id='.$category->getId().'&action=delete';
516
517
                $actions = [];
518
                $criteria = Criteria::create();
519
                $criteria->where(Criteria::expr()->eq('status', User::STUDENT));
520
521
                $inUrl = $category->getUrls()->filter( function($entry) use ($urlId) {
522
                    return $entry->getUrl()->getId() === $urlId;
523
                });
524
525
                //if ($urlId == $category['access_url_id']) {
526
                if ($inUrl->count()> 0) {
527
                    $actions[] = Display::url($editIcon, $editUrl);
528
                    $actions[] = Display::url($moveIcon, $moveUrl);
529
                    $actions[] = Display::url($deleteIcon, $deleteUrl);
530
                }
531
532
                $url = api_get_path(WEB_CODE_PATH).'admin/course_category.php?category='.$code;
533
                $title = Display::url(
534
                    Display::return_icon(
535
                        'folder_document.gif',
536
                        get_lang('Open this category'),
537
                        null,
538
                        ICON_SIZE_SMALL
539
                    ).' '.$category->getName().' ('.$code.')',
540
                    $url
541
                );
542
543
                //$countCourses = self::countCoursesInCategory($code, null, false);
544
                $countCourses = $category->getCourses()->count();
545
                $content = [
546
                    $title,
547
                    $category->getChildrenCount(),
548
                    $countCourses,
549
                    implode('', $actions),
550
                ];
551
                $column = 0;
552
                foreach ($content as $value) {
553
                    $table->setCellContents($row, $column, $value);
554
                    $column++;
555
                }
556
                $row++;
557
            }
558
559
            return $table->toHtml();
560
        }
561
562
        return Display::return_message(get_lang('NoCategories'), 'warning');
563
    }
564
565
    /**
566
     * @return array
567
     */
568
    public static function getCategoriesToDisplayInHomePage()
569
    {
570
        $table = Database::get_main_table(TABLE_MAIN_CATEGORY);
571
        $sql = "SELECT name FROM $table
572
                WHERE parent_id IS NULL
573
                ORDER BY tree_pos";
574
575
        return Database::store_result(Database::query($sql));
576
    }
577
578
    /**
579
     * @param string $categoryCode
580
     *
581
     * @return array
582
     */
583
    public static function getCategoriesCanBeAddedInCourse($categoryCode)
584
    {
585
        $table = Database::get_main_table(TABLE_MAIN_ACCESS_URL_REL_COURSE_CATEGORY);
586
        $conditions = " INNER JOIN $table a ON (c.id = a.course_category_id)";
587
        $whereCondition = ' AND a.access_url_id = '.api_get_current_access_url_id();
588
589
        $tbl_category = Database::get_main_table(TABLE_MAIN_CATEGORY);
590
        $sql = "SELECT c.id, c.code, name
591
                FROM $tbl_category c
592
                $conditions
593
                WHERE (auth_course_child = 'TRUE' OR code = '".Database::escape_string($categoryCode)."')
594
                $whereCondition
595
                ORDER BY tree_pos";
596
        $res = Database::query($sql);
597
598
        $categoryToAvoid = '';
599
        if (!api_is_platform_admin()) {
600
            $categoryToAvoid = api_get_configuration_value('course_category_code_to_use_as_model');
601
        }
602
        $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...
603
        while ($cat = Database::fetch_array($res)) {
604
            $categoryCode = $cat['code'];
605
            if (!empty($categoryToAvoid) && $categoryToAvoid == $categoryCode) {
606
                continue;
607
            }
608
            $categories[$cat['id']] = '('.$cat['code'].') '.$cat['name'];
609
            ksort($categories);
610
        }
611
612
        return $categories;
613
    }
614
615
    /**
616
     * @param string $category_code
617
     * @param string $keyword
618
     * @paran bool  $avoidCourses
619
     * @paran array $conditions
620
     *
621
     * @return int
622
     */
623
    public static function countCoursesInCategory(
624
        $category_code = '',
625
        $keyword = '',
626
        $avoidCourses = true,
627
        $conditions = []
628
    ) {
629
        return self::getCoursesInCategory($category_code, $keyword, $avoidCourses, $conditions, true);
630
    }
631
632
    public static function getCoursesInCategory($category_code = '', $keyword = '', $avoidCourses = true, $conditions = [], $getCount = false)
633
    {
634
        $tbl_course = Database::get_main_table(TABLE_MAIN_COURSE);
635
        $tblCourseCategory = Database::get_main_table(TABLE_MAIN_CATEGORY);
636
        $keyword = Database::escape_string($keyword);
637
        $categoryCode = Database::escape_string($category_code);
638
        $avoidCoursesCondition = '';
639
        if ($avoidCourses) {
640
            $avoidCoursesCondition = CoursesAndSessionsCatalog::getAvoidCourseCondition();
641
        }
642
643
        $visibilityCondition = CourseManager::getCourseVisibilitySQLCondition('course', true);
644
645
        $sqlInjectJoins = '';
646
        $where = ' AND 1 = 1 ';
647
        $sqlInjectWhere = '';
648
        if (!empty($conditions)) {
649
            $sqlInjectJoins = $conditions['inject_joins'];
650
            $where = $conditions['where'];
651
            $sqlInjectWhere = $conditions['inject_where'];
652
        }
653
        $categoryFilter = '';
654
        if ('ALL' === $categoryCode || empty($categoryCode)) {
655
            // Nothing to do
656
        } elseif ('NONE' === $categoryCode) {
657
            $categoryFilter = ' AND course.category_id IS NULL ';
658
        } else {
659
            $categoryJoin = " INNER JOIN $tblCourseCategory cat ON course.category_id = cat.id ";
660
            $categoryFilter = ' AND cat.code = "'.$categoryCode.'" ';
661
        }
662
663
        $searchFilter = '';
664
        if (!empty($keyword)) {
665
            $searchFilter = ' AND (
666
                course.code LIKE "%'.$keyword.'%" OR
667
                course.title LIKE "%'.$keyword.'%" OR
668
                course.tutor_name LIKE "%'.$keyword.'%"
669
            ) ';
670
        }
671
672
        $urlCondition = ' url_rel_course.access_url_id = '.api_get_current_access_url_id().' AND';
673
        $tbl_url_rel_course = Database::get_main_table(TABLE_MAIN_ACCESS_URL_REL_COURSE);
674
675
        $select = " DISTINCT course.id, course.code, course.title ";
676
        if ($getCount) {
677
            $select = "count(DISTINCT course.id) as count";
678
        }
679
        $sql = "SELECT $select
680
                FROM $tbl_course as course
681
                INNER JOIN $tbl_url_rel_course as url_rel_course
682
                ON (url_rel_course.c_id = course.id)
683
                $sqlInjectJoins
684
                $categoryJoin
685
                WHERE
686
                    $urlCondition
687
                    course.visibility != '0' AND
688
                    course.visibility != '4'
689
                    $categoryFilter
690
                    $searchFilter
691
                    $avoidCoursesCondition
692
                    $visibilityCondition
693
                    $where
694
                    $sqlInjectWhere
695
            ";
696
697
        $result = Database::query($sql);
698
        if ($getCount) {
699
            $row = Database::fetch_array($result);
700
701
            return (int) $row['count'];
702
        }
703
704
        return Database::store_result($result, 'ASSOC');
705
    }
706
707
    /**
708
     * @param array $list
709
     *
710
     * @return array
711
     */
712
    public static function getCourseCategoryNotInList($list)
713
    {
714
        $table = Database::get_main_table(TABLE_MAIN_CATEGORY);
715
716
        if (empty($list)) {
717
            $sql = "SELECT * FROM $table
718
                    WHERE (parent_id IS NULL) ";
719
            $result = Database::query($sql);
720
721
            return Database::store_result($result, 'ASSOC');
722
        }
723
724
        $list = array_map('intval', $list);
725
        $listToString = implode("','", $list);
726
727
        $sql = "SELECT * FROM $table
728
                WHERE id NOT IN ('$listToString') AND (parent_id IS NULL) ";
729
        $result = Database::query($sql);
730
731
        return Database::store_result($result, 'ASSOC');
732
    }
733
734
    /**
735
     * @param string $keyword
736
     *
737
     * @return array|null
738
     */
739
    public static function searchCategoryByKeyword($keyword)
740
    {
741
        if (empty($keyword)) {
742
            return null;
743
        }
744
745
        $tableCategory = Database::get_main_table(TABLE_MAIN_CATEGORY);
746
        $table = Database::get_main_table(TABLE_MAIN_ACCESS_URL_REL_COURSE_CATEGORY);
747
        $conditions = " INNER JOIN $table a ON (c.id = a.course_category_id)";
748
        $whereCondition = " AND a.access_url_id = ".api_get_current_access_url_id();
749
750
        $allowBaseCategories = api_get_configuration_value('allow_base_course_category');
751
        if ($allowBaseCategories) {
752
            $whereCondition = " AND (a.access_url_id = ".api_get_current_access_url_id()." OR a.access_url_id = 1) ";
753
        }
754
755
        $keyword = Database::escape_string($keyword);
756
757
        $sql = "SELECT c.*, c.name as text
758
                FROM $tableCategory c $conditions
759
                WHERE
760
                (
761
                    c.code LIKE '%$keyword%' OR name LIKE '%$keyword%'
762
                ) AND auth_course_child = 'TRUE'
763
                $whereCondition ";
764
        $result = Database::query($sql);
765
766
        return Database::store_result($result, 'ASSOC');
767
    }
768
769
    /**
770
     * Get Pagination HTML div.
771
     *
772
     * @param $pageCurrent
773
     * @param $pageLength
774
     * @param $pageTotal
775
     *
776
     * @return string
777
     */
778
    public static function getCatalogPagination($pageCurrent, $pageLength, $pageTotal)
779
    {
780
        // Start empty html
781
        $pageDiv = '';
782
        $html = '';
783
        $pageBottom = max(1, $pageCurrent - 3);
784
        $pageTop = min($pageTotal, $pageCurrent + 3);
785
786
        if ($pageBottom > 1) {
787
            $pageDiv .= self::getPageNumberItem(1, $pageLength);
788
            if ($pageBottom > 2) {
789
                $pageDiv .= self::getPageNumberItem(
790
                    $pageBottom - 1,
791
                    $pageLength,
792
                    null,
793
                    '...'
794
                );
795
            }
796
        }
797
798
        // For each page add its page button to html
799
        for ($i = $pageBottom; $i <= $pageTop; $i++) {
800
            if ($i === $pageCurrent) {
801
                $pageItemAttributes = ['class' => 'page-item active'];
802
            } else {
803
                $pageItemAttributes = ['class' => 'page-item'];
804
            }
805
            $pageDiv .= self::getPageNumberItem(
806
                $i,
807
                $pageLength,
808
                $pageItemAttributes
809
            );
810
        }
811
812
        // Check if current page is the last page
813
        if ($pageTop < $pageTotal) {
814
            if ($pageTop < ($pageTotal - 1)) {
815
                $pageDiv .= self::getPageNumberItem(
816
                    $pageTop + 1,
817
                    $pageLength,
818
                    null,
819
                    '...'
820
                );
821
            }
822
            $pageDiv .= self::getPageNumberItem($pageTotal, $pageLength);
823
        }
824
825
        // Complete pagination html
826
        $pageDiv = Display::tag('ul', $pageDiv, ['class' => 'pagination']);
827
        $html .= '<nav>'.$pageDiv.'</nav>';
828
829
        return $html;
830
    }
831
832
    /**
833
     * Return URL to course catalog.
834
     *
835
     * @param int    $pageCurrent
836
     * @param int    $pageLength
837
     * @param string $categoryCode
838
     * @param int    $hiddenLinks
839
     * @param string $action
840
     *
841
     * @return string
842
     */
843
    public static function getCourseCategoryUrl(
844
        $pageCurrent,
845
        $pageLength,
846
        $categoryCode = null,
847
        $hiddenLinks = null,
848
        $action = null
849
    ) {
850
        $requestAction = isset($_REQUEST['action']) ? Security::remove_XSS($_REQUEST['action']) : null;
851
        $action = isset($action) ? Security::remove_XSS($action) : $requestAction;
852
        $searchTerm = isset($_REQUEST['search_term']) ? Security::remove_XSS($_REQUEST['search_term']) : null;
853
854
        if ('subscribe_user_with_password' === $action) {
855
            $action = 'subscribe';
856
        }
857
858
        $categoryCodeRequest = isset($_REQUEST['category_code']) ? Security::remove_XSS($_REQUEST['category_code']) : null;
859
        $categoryCode = isset($categoryCode) ? Security::remove_XSS($categoryCode) : $categoryCodeRequest;
860
        $hiddenLinksRequest = isset($_REQUEST['hidden_links']) ? Security::remove_XSS($_REQUEST['hidden_links']) : null;
861
        $hiddenLinks = isset($hiddenLinks) ? Security::remove_XSS($hiddenLinksRequest) : $categoryCodeRequest;
862
863
        // Start URL with params
864
        $pageUrl = api_get_self().
865
            '?action='.$action.
866
            '&category_code='.$categoryCode.
867
            '&hidden_links='.$hiddenLinks.
868
            '&pageCurrent='.$pageCurrent.
869
            '&pageLength='.$pageLength;
870
871
        switch ($action) {
872
            case 'subscribe':
873
                // for search
874
                $pageUrl .=
875
                    '&search_term='.$searchTerm.
876
                    '&search_course=1'.
877
                    '&sec_token='.Security::getTokenFromSession();
878
                break;
879
            case 'display_courses':
880
            default:
881
                break;
882
        }
883
884
        return $pageUrl;
885
    }
886
887
    /**
888
     * Get li HTML of page number.
889
     *
890
     * @param $pageNumber
891
     * @param $pageLength
892
     * @param array  $liAttributes
893
     * @param string $content
894
     *
895
     * @return string
896
     */
897
    public static function getPageNumberItem(
898
        $pageNumber,
899
        $pageLength,
900
        $liAttributes = [],
901
        $content = ''
902
    ) {
903
        // Get page URL
904
        $url = self::getCourseCategoryUrl(
905
            $pageNumber,
906
            $pageLength
907
        );
908
909
        // If is current page ('active' class) clear URL
910
        if (isset($liAttributes) && is_array($liAttributes) && isset($liAttributes['class'])) {
911
            if (false !== strpos('active', $liAttributes['class'])) {
912
                $url = '';
913
            }
914
        }
915
916
        $content = !empty($content) ? $content : $pageNumber;
917
918
        return Display::tag(
919
            'li',
920
            Display::url(
921
                $content,
922
                $url,
923
                ['class' => 'page-link']
924
            ),
925
            $liAttributes
926
        );
927
    }
928
929
    /**
930
     * Return the name tool by action.
931
     *
932
     * @param string $action
933
     *
934
     * @return string
935
     */
936
    public static function getCourseCatalogNameTools($action)
937
    {
938
        $nameTools = get_lang('My courses');
939
        if (empty($action)) {
940
            return $nameTools; //should never happen
941
        }
942
943
        switch ($action) {
944
            case 'subscribe':
945
            case 'subscribe_user_with_password':
946
            case 'display_random_courses':
947
            case 'display_courses':
948
                $nameTools = get_lang('Courses catalog');
949
                break;
950
            case 'display_sessions':
951
                $nameTools = get_lang('Course sessions');
952
                break;
953
            default:
954
                // Nothing to do
955
                break;
956
        }
957
958
        return $nameTools;
959
    }
960
961
    /**
962
     * Save image for a course category.
963
     *
964
     * @deprecated
965
     *
966
     * @param int   $categoryId Course category ID
967
     * @param array $fileData   File data from $_FILES
968
     */
969
    public static function saveImage($categoryId, $fileData)
970
    {
971
        /*
972
        $categoryInfo = self::getCategoryById($categoryId);
973
        if (empty($categoryInfo)) {
974
            return;
975
        }
976
977
        if (!empty($fileData['error'])) {
978
            return;
979
        }
980
981
        $extension = getextension($fileData['name']);
982
        $dirName = 'course_category/';
983
        $fileDir = api_get_path(SYS_UPLOAD_PATH).$dirName;
984
        $fileName = "cc_$categoryId.{$extension[0]}";
985
986
        if (!file_exists($fileDir)) {
987
            mkdir($fileDir, api_get_permissions_for_new_directories(), true);
988
        }
989
990
        $image = new Image($fileData['tmp_name']);
991
        $image->send_image($fileDir.$fileName);
992
993
        $table = Database::get_main_table(TABLE_MAIN_CATEGORY);
994
        Database::update(
995
            $table,
996
            ['image' => $dirName.$fileName],
997
            ['id = ?' => $categoryId]
998
        );*/
999
    }
1000
1001
    /**
1002
     * @param $categoryId
1003
     * @param string $description
1004
     *
1005
     * @return string
1006
     */
1007
    public static function saveDescription($categoryId, $description)
1008
    {
1009
        $categoryInfo = self::getCategoryById($categoryId);
1010
        if (empty($categoryInfo)) {
1011
            return false;
1012
        }
1013
        $table = Database::get_main_table(TABLE_MAIN_CATEGORY);
1014
        Database::update(
1015
            $table,
1016
            ['description' => $description],
1017
            ['id = ?' => $categoryId]
1018
        );
1019
1020
        return true;
1021
    }
1022
}
1023