Passed
Push — 1.11.x ( bf773f...a00d57 )
by Julito
13:09 queued 12s
created

CoursesAndSessionsCatalog::sessionsListByName()   A

Complexity

Conditions 4
Paths 4

Size

Total Lines 31
Code Lines 22

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 4
eloc 22
nc 4
nop 1
dl 0
loc 31
rs 9.568
c 0
b 0
f 0
1
<?php
2
3
/* For licensing terms, see /license.txt */
4
5
use Chamilo\CoreBundle\Entity\ExtraField;
6
use Chamilo\CoreBundle\Entity\Repository\SequenceResourceRepository;
7
use Chamilo\CoreBundle\Entity\SequenceResource;
8
use Chamilo\CoreBundle\Entity\SessionRelCourse;
9
use Chamilo\CoreBundle\Entity\Tag;
10
use Doctrine\ORM\Query\Expr\Join;
11
12
/**
13
 * @todo change class name
14
 */
15
class CoursesAndSessionsCatalog
16
{
17
    const PAGE_LENGTH = 12;
18
19
    /**
20
     * Check the configuration for the courses and sessions catalog.
21
     *
22
     * @global array $_configuration Configuration
23
     *
24
     * @param int $value The value to check
25
     *
26
     * @return bool Whether the configuration is $value
27
     */
28
    public static function is($value = CATALOG_COURSES)
29
    {
30
        $showCoursesSessions = (int) api_get_setting('catalog_show_courses_sessions');
31
        if ($showCoursesSessions == $value) {
32
            return true;
33
        }
34
35
        return false;
36
    }
37
38
    /**
39
     * Check whether to display the sessions list.
40
     *
41
     * @global array $_configuration Configuration
42
     *
43
     * @return bool whether to display
44
     */
45
    public static function showSessions()
46
    {
47
        $catalogShow = (int) api_get_setting('catalog_show_courses_sessions');
48
49
        if ($catalogShow == CATALOG_SESSIONS || $catalogShow == CATALOG_COURSES_SESSIONS) {
50
            return true;
51
        }
52
53
        return false;
54
    }
55
56
    /**
57
     * Check whether to display the courses list.
58
     *
59
     * @global array $_configuration Configuration
60
     *
61
     * @return bool whether to display
62
     */
63
    public static function showCourses()
64
    {
65
        $catalogShow = (int) api_get_setting('catalog_show_courses_sessions');
66
67
        if ($catalogShow == CATALOG_COURSES || $catalogShow == CATALOG_COURSES_SESSIONS) {
68
            return true;
69
        }
70
71
        return false;
72
    }
73
74
    /**
75
     * @return array
76
     */
77
    public static function getCoursesToAvoid()
78
    {
79
        $TABLE_COURSE_FIELD = Database::get_main_table(TABLE_EXTRA_FIELD);
80
        $TABLE_COURSE_FIELD_VALUE = Database::get_main_table(TABLE_EXTRA_FIELD_VALUES);
81
82
        // Check special courses
83
        $courseListToAvoid = CourseManager::get_special_course_list();
84
85
        // Checks "hide_from_catalog" extra field
86
        $extraFieldType = ExtraField::COURSE_FIELD_TYPE;
87
88
        $sql = "SELECT item_id FROM $TABLE_COURSE_FIELD_VALUE tcfv
89
                INNER JOIN $TABLE_COURSE_FIELD tcf
90
                ON tcfv.field_id =  tcf.id
91
                WHERE
92
                    tcf.extra_field_type = $extraFieldType AND
93
                    tcf.variable = 'hide_from_catalog' AND
94
                    tcfv.value = 1
95
                ";
96
97
        $result = Database::query($sql);
98
        if (Database::num_rows($result) > 0) {
99
            while ($row = Database::fetch_array($result)) {
100
                $courseListToAvoid[] = $row['item_id'];
101
            }
102
        }
103
104
        return $courseListToAvoid;
105
    }
106
107
    /**
108
     * @return string
109
     */
110
    public static function getAvoidCourseCondition()
111
    {
112
        $courseListToAvoid = self::getCoursesToAvoid();
113
        $condition = '';
114
        if (!empty($courseListToAvoid)) {
115
            $courses = [];
116
            foreach ($courseListToAvoid as $courseId) {
117
                $courses[] = '"'.$courseId.'"';
118
            }
119
            $condition = ' AND course.id NOT IN ('.implode(',', $courses).')';
120
        }
121
122
        return $condition;
123
    }
124
125
    /**
126
     * Get available le courses count.
127
     *
128
     * @param int $accessUrlId (optional)
129
     *
130
     * @return int Number of courses
131
     */
132
    public static function countAvailableCoursesToShowInCatalog($accessUrlId = 1)
133
    {
134
        $tableCourse = Database::get_main_table(TABLE_MAIN_COURSE);
135
        $tableCourseRelAccessUrl = Database::get_main_table(TABLE_MAIN_ACCESS_URL_REL_COURSE);
136
        $courseToAvoidCondition = self::getAvoidCourseCondition();
137
        $visibilityCondition = CourseManager::getCourseVisibilitySQLCondition('course', true);
138
139
        $accessUrlId = (int) $accessUrlId;
140
        if (empty($accessUrlId)) {
141
            $accessUrlId = 1;
142
        }
143
144
        $sql = "SELECT count(course.id)
145
                FROM $tableCourse course
146
                INNER JOIN $tableCourseRelAccessUrl u
147
                ON (course.id = u.c_id)
148
                WHERE
149
                    u.access_url_id = $accessUrlId AND
150
                    course.visibility != 0 AND
151
                    course.visibility != 4
152
                    $courseToAvoidCondition
153
                    $visibilityCondition
154
                ";
155
156
        $res = Database::query($sql);
157
        $row = Database::fetch_row($res);
158
159
        return $row[0];
160
    }
161
162
    public static function getCourseCategoriesTree()
163
    {
164
        $urlId = 1;
165
        if (api_is_multiple_url_enabled()) {
166
            $urlId = api_get_current_access_url_id();
167
        }
168
169
        $countCourses = self::countAvailableCoursesToShowInCatalog($urlId);
170
        $categories = [];
171
        $list = [];
172
173
        $categories['ALL'] = [
174
            'id' => 0,
175
            'name' => get_lang('DisplayAll'),
176
            'code' => 'ALL',
177
            'parent_id' => null,
178
            'tree_pos' => 0,
179
            'number_courses' => $countCourses,
180
            'level' => 0,
181
        ];
182
183
        $allCategories = CourseCategory::getAllCategories();
184
        foreach ($allCategories as $category) {
185
            if (empty($category['parent_id'])) {
186
                $list[$category['code']] = $category;
187
                $list[$category['code']]['level'] = 0;
188
                list($subList, $childrenCount) = self::buildCourseCategoryTree($allCategories, $category['code'], 0);
189
                foreach ($subList as $item) {
190
                    $list[$item['code']] = $item;
191
                }
192
                // Real course count
193
                $countCourses = CourseCategory::countCoursesInCategory($category['code']);
194
                $list[$category['code']]['number_courses'] = $childrenCount + $countCourses;
195
            }
196
        }
197
198
        // count courses that are in no category
199
        $countCourses = CourseCategory::countCoursesInCategory();
200
        $categories['NONE'] = [
201
            'id' => 0,
202
            'name' => get_lang('WithoutCategory'),
203
            'code' => 'NONE',
204
            'parent_id' => null,
205
            'tree_pos' => 0,
206
            'children_count' => 0,
207
            'auth_course_child' => true,
208
            'auth_cat_child' => true,
209
            'number_courses' => $countCourses,
210
            'level' => 0,
211
        ];
212
213
        return array_merge($list, $categories);
214
    }
215
216
     /**
217
     * Return LIMIT to filter SQL query.
218
     *
219
     * @param array $limit
220
     *
221
     * @return string
222
     */
223
    public static function getLimitFilterFromArray($limit)
224
    {
225
        $limitFilter = '';
226
        if (!empty($limit) && is_array($limit)) {
227
            $limitStart = isset($limit['start']) ? (int) $limit['start'] : 0;
228
            $limitLength = isset($limit['length']) ? (int) $limit['length'] : 12;
229
            $limitFilter = 'LIMIT '.$limitStart.', '.$limitLength;
230
        }
231
232
        return $limitFilter;
233
    }
234
235
    /**
236
     * @param string $categoryCode
237
     * @param int    $randomValue
238
     * @param array  $limit         will be used if $randomValue is not set.
239
     *                              This array should contains 'start' and 'length' keys
240
     *
241
     * @return array
242
     */
243
    public static function getCoursesInCategory($categoryCode, $randomValue = null, $limit = [])
244
    {
245
        $tbl_course = Database::get_main_table(TABLE_MAIN_COURSE);
246
        $avoidCoursesCondition = self::getAvoidCourseCondition();
247
        $visibilityCondition = CourseManager::getCourseVisibilitySQLCondition('course', true);
248
249
        if (!empty($randomValue)) {
250
            $randomValue = (int) $randomValue;
251
252
            $sql = "SELECT COUNT(*) FROM $tbl_course";
253
            $result = Database::query($sql);
254
            list($num_records) = Database::fetch_row($result);
255
256
            if (api_is_multiple_url_enabled()) {
257
                $urlId = api_get_current_access_url_id();
258
                $tbl_url_rel_course = Database::get_main_table(TABLE_MAIN_ACCESS_URL_REL_COURSE);
259
260
                $urlCondition = ' access_url_id = '.$urlId.' ';
261
                $allowBaseCategories = api_get_configuration_value('allow_base_course_category');
262
                if ($allowBaseCategories) {
263
                    $urlCondition = ' (access_url_id = '.$urlId.' OR access_url_id = 1)  ';
264
                }
265
266
                $sql = "SELECT COUNT(*) FROM $tbl_course course
267
                        INNER JOIN $tbl_url_rel_course as url_rel_course
268
                        ON (url_rel_course.c_id = course.id)
269
                        WHERE access_url_id = '.$urlId.' ";
270
                $result = Database::query($sql);
271
                list($num_records) = Database::fetch_row($result);
272
273
                $sql = "SELECT course.id, course.id as real_id
274
                        FROM $tbl_course course
275
                        INNER JOIN $tbl_url_rel_course as url_rel_course
276
                        ON (url_rel_course.c_id = course.id)
277
                        WHERE
278
                            $urlCondition AND
279
                            RAND()*$num_records< $randomValue
280
                            $avoidCoursesCondition
281
                            $visibilityCondition
282
                        ORDER BY RAND()
283
                        LIMIT 0, $randomValue";
284
            } else {
285
                $sql = "SELECT id, id as real_id FROM $tbl_course course
286
                        WHERE
287
                            RAND()*$num_records< $randomValue
288
                            $avoidCoursesCondition
289
                            $visibilityCondition
290
                        ORDER BY RAND()
291
                        LIMIT 0, $randomValue";
292
            }
293
294
            $result = Database::query($sql);
295
            $id_in = null;
296
            while (list($id) = Database::fetch_row($result)) {
297
                if ($id_in) {
298
                    $id_in .= ",$id";
299
                } else {
300
                    $id_in = "$id";
301
                }
302
            }
303
            if ($id_in === null) {
304
                return [];
305
            }
306
            $sql = "SELECT *, id as real_id FROM $tbl_course WHERE id IN($id_in)";
307
        } else {
308
            $limitFilter = self::getLimitFilterFromArray($limit);
309
            $categoryCode = Database::escape_string($categoryCode);
310
            $listCode = self::childrenCategories($categoryCode);
311
            $conditionCode = ' ';
312
313
            if (empty($listCode)) {
314
                if ($categoryCode === 'NONE') {
315
                    $conditionCode .= " category_code='' ";
316
                } else {
317
                    $conditionCode .= " category_code='$categoryCode' ";
318
                }
319
            } else {
320
                foreach ($listCode as $code) {
321
                    $conditionCode .= " category_code='$code' OR ";
322
                }
323
                $conditionCode .= " category_code='$categoryCode' ";
324
            }
325
326
            if (empty($categoryCode) || $categoryCode == 'ALL') {
327
                $sql = "SELECT *, id as real_id
328
                        FROM $tbl_course course
329
                        WHERE
330
                          1=1
331
                          $avoidCoursesCondition
332
                          $visibilityCondition
333
                    ORDER BY title $limitFilter ";
334
            } else {
335
                $sql = "SELECT *, id as real_id FROM $tbl_course course
336
                        WHERE
337
                            $conditionCode
338
                            $avoidCoursesCondition
339
                            $visibilityCondition
340
                        ORDER BY title $limitFilter ";
341
            }
342
343
            // Showing only the courses of the current Chamilo access_url_id
344
            if (api_is_multiple_url_enabled()) {
345
                $urlId = api_get_current_access_url_id();
346
                $tbl_url_rel_course = Database::get_main_table(TABLE_MAIN_ACCESS_URL_REL_COURSE);
347
348
                $urlCondition = ' access_url_id = '.$urlId.' ';
349
                if ($categoryCode !== 'ALL') {
350
                    $sql = "SELECT *, course.id real_id FROM $tbl_course as course
351
                            INNER JOIN $tbl_url_rel_course as url_rel_course
352
                            ON (url_rel_course.c_id = course.id)
353
                            WHERE
354
                                $urlCondition AND
355
                                $conditionCode
356
                                $avoidCoursesCondition
357
                                $visibilityCondition
358
                            ORDER BY title $limitFilter";
359
                } else {
360
                    $sql = "SELECT *, course.id real_id FROM $tbl_course as course
361
                            INNER JOIN $tbl_url_rel_course as url_rel_course
362
                            ON (url_rel_course.c_id = course.id)
363
                            WHERE
364
                                $urlCondition
365
                                $avoidCoursesCondition
366
                                $visibilityCondition
367
                            ORDER BY title $limitFilter";
368
                }
369
            }
370
        }
371
372
        $result = Database::query($sql);
373
        $courses = [];
374
        while ($row = Database::fetch_array($result)) {
375
            $row['registration_code'] = !empty($row['registration_code']);
376
            $count_users = CourseManager::get_users_count_in_course($row['code']);
377
            $connectionsLastMonth = Tracking::get_course_connections_count(
378
                $row['id'],
379
                0,
380
                api_get_utc_datetime(time() - (30 * 86400))
381
            );
382
383
            if ($row['tutor_name'] == '0') {
384
                $row['tutor_name'] = get_lang('NoManager');
385
            }
386
387
            $courses[] = [
388
                'real_id' => $row['real_id'],
389
                'point_info' => CourseManager::get_course_ranking($row['id'], 0),
390
                'code' => $row['code'],
391
                'directory' => $row['directory'],
392
                'visual_code' => $row['visual_code'],
393
                'title' => $row['title'],
394
                'tutor' => $row['tutor_name'],
395
                'subscribe' => $row['subscribe'],
396
                'unsubscribe' => $row['unsubscribe'],
397
                'registration_code' => $row['registration_code'],
398
                'creation_date' => $row['creation_date'],
399
                'visibility' => $row['visibility'],
400
                'category' => $row['category_code'],
401
                'count_users' => $count_users,
402
                'count_connections' => $connectionsLastMonth,
403
            ];
404
        }
405
406
        return $courses;
407
    }
408
409
    /**
410
     * Search the courses database for a course that matches the search term.
411
     * The search is done on the code, title and tutor field of the course table.
412
     *
413
     * @param string $keyword The string that the user submitted
414
     * @param array  $limit
415
     * @param bool   $justVisible search only on visible courses in the catalogue
416
     * @param array  $conditions
417
     *
418
     * @return array an array containing a list of all the courses matching the the search term
419
     */
420
    public static function searchCourses($keyword, $limit, $justVisible = false, $conditions = [])
421
    {
422
        $courseTable = Database::get_main_table(TABLE_MAIN_COURSE);
423
        $limitFilter = self::getLimitFilterFromArray($limit);
424
        $avoidCoursesCondition = self::getAvoidCourseCondition();
425
        $visibilityCondition = $justVisible ? CourseManager::getCourseVisibilitySQLCondition('s', true) : '';
426
        $keyword = Database::escape_string($keyword);
427
428
        $sqlInjectJoins = '';
429
        $where = ' 1 = 1 ';
430
        $sqlInjectWhere = '';
431
        $injectExtraFields = '1';
432
        if (!empty($conditions)) {
433
            $sqlInjectJoins = $conditions['inject_joins'];
434
            $where = $conditions['where'];
435
            $sqlInjectWhere = $conditions['inject_where'];
436
            $injectExtraFields = !empty($conditions['inject_extra_fields']) ? $conditions['inject_extra_fields'] : 1;
437
            $injectExtraFields = rtrim($injectExtraFields, ', ');
438
        }
439
440
        $sql = "SELECT DISTINCT course.*, $injectExtraFields
441
                FROM $courseTable course
442
                $sqlInjectJoins
443
                WHERE (
444
                        course.code LIKE '%".$keyword."%' OR
445
                        course.title LIKE '%".$keyword."%' OR
446
                        course.tutor_name LIKE '%".$keyword."%'
447
                    )
448
                    $where
449
                    $sqlInjectWhere
450
                    $avoidCoursesCondition
451
                    $visibilityCondition
452
                ORDER BY title, visual_code ASC
453
                $limitFilter
454
                ";
455
456
        if (api_is_multiple_url_enabled()) {
457
            $urlId = api_get_current_access_url_id();
458
            if ($urlId != -1) {
459
                $tbl_url_rel_course = Database::get_main_table(TABLE_MAIN_ACCESS_URL_REL_COURSE);
460
                $urlCondition = ' access_url_id = '.$urlId.' AND';
461
                $allowBaseCategories = api_get_configuration_value('allow_base_course_category');
462
                if ($allowBaseCategories) {
463
                    $urlCondition = ' (access_url_id = '.$urlId.' OR access_url_id = 1) AND ';
464
                }
465
466
                $sql = "SELECT DISTINCT course.*, $injectExtraFields
467
                        FROM $courseTable as course
468
                        INNER JOIN $tbl_url_rel_course as url_rel_course
469
                        ON (url_rel_course.c_id = course.id)
470
                        $sqlInjectJoins
471
                        WHERE
472
                            access_url_id = $urlId AND
473
                            (
474
                                code LIKE '%".$keyword."%' OR
475
                                title LIKE '%".$keyword."%' OR
476
                                tutor_name LIKE '%".$keyword."%'
477
                            )
478
                            $where
479
                            $sqlInjectWhere
480
                            $avoidCoursesCondition
481
                            $visibilityCondition
482
                        ORDER BY title, visual_code ASC
483
                        $limitFilter
484
                       ";
485
            }
486
        }
487
        $result = Database::query($sql);
488
        $courses = [];
489
        while ($row = Database::fetch_array($result)) {
490
            $row['registration_code'] = !empty($row['registration_code']);
491
            $countUsers = CourseManager::get_user_list_from_course_code(
492
                $row['code'],
493
                0,
494
                null,
495
                null,
496
                null,
497
                true
498
            );
499
            $connectionsLastMonth = Tracking::get_course_connections_count(
500
                $row['id'],
501
                0,
502
                api_get_utc_datetime(time() - (30 * 86400))
503
            );
504
505
            $ranking = CourseManager::get_course_ranking($row['id'], 0);
506
            $courses[] = [
507
                'real_id' => $row['id'],
508
                'point_info' => $ranking,
509
                'code' => $row['code'],
510
                'directory' => $row['directory'],
511
                'visual_code' => $row['visual_code'],
512
                'title' => $row['title'],
513
                'tutor' => $row['tutor_name'],
514
                'subscribe' => $row['subscribe'],
515
                'unsubscribe' => $row['unsubscribe'],
516
                'registration_code' => $row['registration_code'],
517
                'creation_date' => $row['creation_date'],
518
                'visibility' => $row['visibility'],
519
                'count_users' => $countUsers,
520
                'count_connections' => $connectionsLastMonth,
521
            ];
522
        }
523
524
        return $courses;
525
    }
526
527
    /**
528
     * List the sessions.
529
     *
530
     * @param string $date
531
     * @param array  $limit
532
     * @param bool   $returnQueryBuilder
533
     * @param bool   $getCount
534
     *
535
     * @return array|\Doctrine\ORM\Query The session list
536
     */
537
    public static function browseSessions($date = null, $limit = [], $returnQueryBuilder = false, $getCount = false)
538
    {
539
        $urlId = api_get_current_access_url_id();
540
541
        /*$dql = "SELECT $select
542
                FROM ChamiloCoreBundle:Session s
543
                WHERE EXISTS
544
                    (
545
                        SELECT url.sessionId FROM ChamiloCoreBundle:AccessUrlRelSession url
546
                        WHERE url.sessionId = s.id AND url.accessUrlId = $urlId
547
                    ) AND
548
                    s.nbrCourses > 0
549
                ";
550
        if (!is_null($date)) {
551
            $date = Database::escape_string($date);
552
            $dql .= "
553
                AND (
554
                    (s.accessEndDate IS NULL)
555
                    OR
556
                    (
557
                    s.accessStartDate IS NOT NULL AND
558
                    s.accessEndDate IS NOT NULL AND
559
                    s.accessStartDate <= '$date' AND s.accessEndDate >= '$date')
560
                    OR
561
                    (
562
                        s.accessStartDate IS NULL AND
563
                        s.accessEndDate IS NOT NULL AND
564
                        s.accessEndDate >= '$date'
565
                    )
566
                )
567
            ";
568
        }*/
569
570
        $em = Database::getManager();
571
        $qb = $em->createQueryBuilder();
572
        $qb2 = $em->createQueryBuilder();
573
574
        $qb = $qb
575
            ->select('s')
576
            ->from('ChamiloCoreBundle:Session', 's')
577
            ->where(
578
                $qb->expr()->in(
579
                    's',
580
                    $qb2
581
                        ->select('s2')
582
                        ->from('ChamiloCoreBundle:AccessUrlRelSession', 'url')
583
                        ->join('ChamiloCoreBundle:Session', 's2')
584
                        ->where(
585
                            $qb->expr()->eq('url.sessionId ', 's2.id')
586
                        )->andWhere(
587
                            $qb->expr()->eq('url.accessUrlId ', $urlId))
588
                        ->getDQL()
589
                )
590
            )
591
            ->andWhere($qb->expr()->gt('s.nbrCourses', 0))
592
        ;
593
594
        if (!is_null($date)) {
595
            $qb->andWhere(
596
                $qb->expr()->orX(
597
                    $qb->expr()->isNull('s.accessEndDate'),
598
                    $qb->expr()->andX(
599
                        $qb->expr()->isNotNull('s.accessStartDate'),
600
                        $qb->expr()->isNotNull('s.accessEndDate'),
601
                        $qb->expr()->lte('s.accessStartDate', $date),
602
                        $qb->expr()->gte('s.accessEndDate', $date)
603
                    ),
604
                    $qb->expr()->andX(
605
                        $qb->expr()->isNull('s.accessStartDate'),
606
                        $qb->expr()->isNotNull('s.accessEndDate'),
607
                        $qb->expr()->gte('s.accessEndDate', $date)
608
                    )
609
                )
610
            );
611
        }
612
613
        if ($getCount) {
614
            $qb->select('count(s)');
615
        }
616
617
        $qb = self::hideFromSessionCatalogCondition($qb);
618
619
        if (!empty($limit)) {
620
            $qb
621
                ->setFirstResult($limit['start'])
622
                ->setMaxResults($limit['length'])
623
            ;
624
        }
625
626
        $query = $qb->getQuery();
627
628
        if ($returnQueryBuilder) {
629
            return $query;
630
        }
631
632
        if ($getCount) {
633
            return $query->getSingleScalarResult();
634
        }
635
636
        return $query->getResult();
637
    }
638
639
    /**
640
     * @param \Doctrine\ORM\QueryBuilder $qb
641
     *
642
     * @return mixed
643
     */
644
    public static function hideFromSessionCatalogCondition($qb)
645
    {
646
        $em = Database::getManager();
647
        $qb3 = $em->createQueryBuilder();
648
649
        $extraField = new \ExtraField('session');
650
        $extraFieldInfo = $extraField->get_handler_field_info_by_field_variable('hide_from_catalog');
651
        if (!empty($extraFieldInfo)) {
652
            $qb->andWhere(
653
                $qb->expr()->notIn(
654
                    's',
655
                    $qb3
656
                        ->select('s3')
657
                        ->from('ChamiloCoreBundle:ExtraFieldValues', 'fv')
658
                        ->innerJoin('ChamiloCoreBundle:Session', 's3', Join::WITH, 'fv.itemId = s3.id')
659
                        ->where(
660
                            $qb->expr()->eq('fv.field', $extraFieldInfo['id'])
661
                        )->andWhere(
662
                            $qb->expr()->eq('fv.value ', 1)
663
                        )
664
                        ->getDQL()
665
                )
666
            );
667
        }
668
669
        return $qb;
670
    }
671
672
    /**
673
     * Search sessions by the tags in their courses.
674
     *
675
     * @param string $termTag Term for search in tags
676
     * @param array  $limit   Limit info
677
     *
678
     * @return array The sessions
679
     */
680
    public static function browseSessionsByTags($termTag, array $limit)
681
    {
682
        $em = Database::getManager();
683
        $qb = $em->createQueryBuilder();
684
685
        $urlId = api_get_current_access_url_id();
686
687
        $qb->select('s')
688
            ->distinct()
689
            ->from('ChamiloCoreBundle:Session', 's')
690
            ->innerJoin(
691
                'ChamiloCoreBundle:SessionRelCourse',
692
                'src',
693
                Join::WITH,
694
                's.id = src.session'
695
            )
696
            ->innerJoin(
697
                'ChamiloCoreBundle:AccessUrlRelSession',
698
                'url',
699
                Join::WITH,
700
                'url.sessionId = s.id'
701
            )
702
            ->innerJoin(
703
                'ChamiloCoreBundle:ExtraFieldRelTag',
704
                'frt',
705
                Join::WITH,
706
                'src.course = frt.itemId'
707
            )
708
            ->innerJoin(
709
                'ChamiloCoreBundle:Tag',
710
                't',
711
                Join::WITH,
712
                'frt.tagId = t.id'
713
            )
714
            ->innerJoin(
715
                'ChamiloCoreBundle:ExtraField',
716
                'f',
717
                Join::WITH,
718
                'frt.fieldId = f.id'
719
            )
720
            ->where(
721
                $qb->expr()->like('t.tag', ':tag')
722
            )
723
            ->andWhere(
724
                $qb->expr()->eq('f.extraFieldType', ExtraField::COURSE_FIELD_TYPE)
725
            )
726
            ->andWhere(
727
                $qb->expr()->gt('s.nbrCourses', 0)
728
            )
729
            ->andWhere(
730
                $qb->expr()->eq('url.accessUrlId', $urlId)
731
            )
732
            ->setFirstResult($limit['start'])
733
            ->setMaxResults($limit['length'])
734
            ->setParameter('tag', "$termTag%")
735
            ;
736
737
        $qb = self::hideFromSessionCatalogCondition($qb);
738
739
        return $qb->getQuery()->getResult();
740
    }
741
742
    /**
743
     * Search sessions by the title.
744
     *
745
     * @param string $keyword
746
     * @param array  $limit   Limit info
747
     *
748
     * @return array The sessions
749
     */
750
    public static function getSessionsByName($keyword, array $limit)
751
    {
752
        $em = Database::getManager();
753
        $qb = $em->createQueryBuilder();
754
755
        $urlId = api_get_current_access_url_id();
756
757
        $qb->select('s')
758
            ->distinct()
759
            ->from('ChamiloCoreBundle:Session', 's')
760
            ->innerJoin(
761
                'ChamiloCoreBundle:SessionRelCourse',
762
                'src',
763
                Join::WITH,
764
                's.id = src.session'
765
            )
766
            ->innerJoin(
767
                'ChamiloCoreBundle:AccessUrlRelSession',
768
                'url',
769
                Join::WITH,
770
                'url.sessionId = s.id'
771
            )
772
            ->andWhere(
773
                $qb->expr()->eq('url.accessUrlId', $urlId)
774
            )->andWhere(
775
                's.name LIKE :keyword'
776
            )
777
            ->andWhere(
778
                $qb->expr()->gt('s.nbrCourses', 0)
779
            )
780
            ->setFirstResult($limit['start'])
781
            ->setMaxResults($limit['length'])
782
            ->setParameter('keyword', "%$keyword%")
783
        ;
784
785
        $qb = self::hideFromSessionCatalogCondition($qb);
786
787
        return $qb->getQuery()->getResult();
788
    }
789
790
    /**
791
     * Build a recursive tree of course categories.
792
     *
793
     * @param array $categories
794
     * @param int   $parentId
795
     * @param int   $level
796
     *
797
     * @return array
798
     */
799
    public static function buildCourseCategoryTree($categories, $parentId = 0, $level = 0)
800
    {
801
        $list = [];
802
        $count = 0;
803
        $level++;
804
        foreach ($categories as $category) {
805
            if (empty($category['parent_id'])) {
806
                continue;
807
            }
808
            if ($category['parent_id'] == $parentId) {
809
                $list[$category['code']] = $category;
810
                $count += $category['number_courses'];
811
                $list[$category['code']]['level'] = $level;
812
                list($subList, $childrenCount) = self::buildCourseCategoryTree(
813
                    $categories,
814
                    $category['code'],
815
                    $level
816
                );
817
                $list[$category['code']]['number_courses'] += $childrenCount;
818
                foreach ($subList as $item) {
819
                    $list[$item['code']] = $item;
820
                }
821
                $count += $childrenCount;
822
            }
823
        }
824
825
        return [$list, $count];
826
    }
827
828
    /**
829
     * List Code Search Category.
830
     *
831
     * @param string $code
832
     *
833
     * @return array
834
     */
835
    public static function childrenCategories($code)
836
    {
837
        $allCategories = CourseCategory::getAllCategories();
838
        $list = [];
839
        $row = [];
840
841
        if ($code !== 'ALL' and $code !== 'NONE') {
842
            foreach ($allCategories as $category) {
843
                if ($category['code'] === $code) {
844
                    $list = self::buildCourseCategoryTree($allCategories, $category['code'], 0);
845
                }
846
            }
847
            foreach ($list[0] as $item) {
848
                $row[] = $item['code'];
849
            }
850
        }
851
852
        return $row;
853
    }
854
855
    public static function getOptionSelect($categories, $codeType)
856
    {
857
        $html = '';
858
        $html .= '<select name="category_code" onchange="submit();" class="selectpicker form-control">';
859
        foreach ($categories as $category) {
860
            $categoryCode = Security::remove_XSS($category['code']);
861
            $categoryName = Security::remove_XSS($category['name']);
862
            $countCourse = (int) $category['number_courses'];
863
            $level = $category['level'];
864
            if (empty($countCourse)) {
865
                continue;
866
            }
867
            if ($level > 0) {
868
                $separate = str_repeat('--', $level);
869
            } else {
870
                $separate = '';
871
            }
872
            $html .= '<option '.($categoryCode == $codeType ? 'selected="selected" ' : '')
873
                .' value="'.$categoryCode.'">'.$separate.' '.$categoryName.' ('.$countCourse.') </option>';
874
        }
875
        $html .= '</select>';
876
877
        return $html;
878
    }
879
880
    /**
881
     * Display the course catalog image of a course.
882
     *
883
     * @param array $course
884
     *
885
     * @return string HTML string
886
     */
887
    public static function returnThumbnail($course)
888
    {
889
        $course_path = api_get_path(SYS_COURSE_PATH).$course['directory'];
890
891
        if (file_exists($course_path.'/course-pic.png')) {
892
            // redimensioned image 85x85
893
            $courseMediumImage = api_get_path(WEB_COURSE_PATH).$course['directory'].'/course-pic.png';
894
        } else {
895
            // without picture
896
            $courseMediumImage = Display::return_icon(
897
                'session_default.png',
898
                null,
899
                null,
900
                null,
901
                null,
902
                true
903
            );
904
        }
905
906
        return $courseMediumImage;
907
    }
908
909
    /**
910
     * @param array $courseInfo
911
     *
912
     * @return string
913
     */
914
    public static function return_teacher($courseInfo)
915
    {
916
        $teachers = CourseManager::getTeachersFromCourse($courseInfo['real_id']);
917
        $length = count($teachers);
918
919
        if (!$length) {
920
            return '';
921
        }
922
923
        $html = '<div class="block-author">';
924
        if ($length > 6) {
925
            $html .= '<a
926
            id="plist"
927
            data-trigger="focus"
928
            tabindex="0" role="button"
929
            class="btn btn-default panel_popover"
930
            data-toggle="popover"
931
            title="'.addslashes(get_lang('CourseTeachers')).'"
932
            data-html="true"
933
        >
934
            <i class="fa fa-graduation-cap" aria-hidden="true"></i>
935
        </a>';
936
            $html .= '<div id="popover-content-plist" class="hide">';
937
            foreach ($teachers as $value) {
938
                $name = $value['firstname'].' '.$value['lastname'];
939
                $html .= '<div class="popover-teacher">';
940
                $html .= '<a href="'.$value['url'].'" class="ajax" data-title="'.$name.'" title="'.$name.'">
941
                        <img src="'.$value['avatar'].'" title="'.$name.'" alt="'.get_lang('UserPicture').'"/></a>';
942
                $html .= '<div class="teachers-details"><h5>
943
                        <a href="'.$value['url'].'" class="ajax" data-title="'.$name.'" title="'.$name.'">'
944
                    .$name.'</a></h5></div>';
945
                $html .= '</div>';
946
            }
947
            $html .= '</div>';
948
        } else {
949
            foreach ($teachers as $value) {
950
                $name = $value['firstname'].' '.$value['lastname'];
951
                if ($length > 2) {
952
                    $html .= '<a href="'.$value['url'].'" class="ajax" data-title="'.$name.'" title="'.$name.'">
953
                        <img src="'.$value['avatar'].'" title="'.$name.'" alt="'.get_lang('UserPicture').'"/></a>';
954
                } else {
955
                    $html .= '<a href="'.$value['url'].'" class="ajax" data-title="'.$name.'" title="'.$name.'">
956
                        <img src="'.$value['avatar'].'" title="'.$name.'" alt="'.get_lang('UserPicture').'"/></a>';
957
                    $html .= '<div class="teachers-details"><h5>
958
                        <a href="'.$value['url'].'" class="ajax" data-title="'.$name.'">'
959
                        .$name.'</a></h5><p>'.get_lang('Teacher').'</p></div>';
960
                }
961
            }
962
        }
963
        $html .= '</div>';
964
965
        return $html;
966
    }
967
968
    /**
969
     * Display the title of a course in course catalog.
970
     *
971
     * @param array $course
972
     *
973
     * @return string HTML string
974
     */
975
    public static function return_title($course)
976
    {
977
        $linkCourse = api_get_path(WEB_PATH).'course/'.$course['real_id'].'/about';
978
        $html = '<div class="block-title"><h4 class="title">';
979
        $html .= '<a title="'.$course['title'].'" href="'.$linkCourse.'">'.$course['title'].'</a>';
980
        $html .= '</h4></div>';
981
982
        return $html;
983
    }
984
985
    /**
986
     * Display the already registerd text in a course in the course catalog.
987
     *
988
     * @param $status
989
     *
990
     * @return string HTML string
991
     */
992
    public static function return_already_registered_label($status)
993
    {
994
        $icon = '<em class="fa fa-check"></em>';
995
        $title = get_lang('YouAreATeacherOfThisCourse');
996
        if ($status === 'student') {
997
            $icon = '<em class="fa fa-check"></em>';
998
            $title = get_lang('AlreadySubscribed');
999
        }
1000
1001
        $html = Display::tag(
1002
            'span',
1003
            $icon.' '.$title,
1004
            [
1005
                'id' => 'register',
1006
                'class' => 'label-subscribed text-success',
1007
                'title' => $title,
1008
                'aria-label' => $title,
1009
            ]
1010
        );
1011
1012
        return $html.PHP_EOL;
1013
    }
1014
1015
    /**
1016
     * Display the register button of a course in the course catalog.
1017
     *
1018
     * @param $course
1019
     * @param $stok
1020
     * @param $categoryCode
1021
     * @param $search_term
1022
     *
1023
     * @return string
1024
     */
1025
    public static function return_register_button($course, $stok, $categoryCode, $search_term)
1026
    {
1027
        $title = get_lang('Subscribe');
1028
        $action = 'subscribe_course';
1029
        if (!empty($course['registration_code'])) {
1030
            $action = 'subscribe_course_validation';
1031
        }
1032
1033
        return Display::url(
1034
            Display::returnFontAwesomeIcon('check').' '.$title,
1035
            api_get_self().'?action='.$action.'&sec_token='.$stok.
1036
            '&course_code='.$course['code'].'&search_term='.$search_term.'&category_code='.$categoryCode,
1037
            ['class' => 'btn btn-success btn-sm', 'title' => $title, 'aria-label' => $title]
1038
        );
1039
    }
1040
1041
    /**
1042
     * Display the unregister button of a course in the course catalog.
1043
     *
1044
     * @param $course
1045
     * @param $stok
1046
     * @param $search_term
1047
     * @param $categoryCode
1048
     *
1049
     * @return string
1050
     */
1051
    public static function return_unregister_button($course, $stok, $search_term, $categoryCode)
1052
    {
1053
        $title = get_lang('Unsubscription');
1054
1055
        return Display::url(
1056
            Display::returnFontAwesomeIcon('sign-in').'&nbsp;'.$title,
1057
            api_get_self().'?action=unsubscribe&sec_token='.$stok
1058
            .'&course_code='.$course['code'].'&search_term='.$search_term.'&category_code='.$categoryCode,
1059
            ['class' => 'btn btn-danger', 'title' => $title, 'aria-label' => $title]
1060
        );
1061
    }
1062
1063
    /**
1064
     * Get a HTML button for subscribe to session.
1065
     *
1066
     * @param int    $sessionId         The session ID
1067
     * @param string $sessionName       The session name
1068
     * @param bool   $checkRequirements Optional.
1069
     *                                  Whether the session has requirement. Default is false
1070
     * @param bool   $includeText       Optional. Whether show the text in button
1071
     * @param bool   $btnBing
1072
     *
1073
     * @return string The button HTML
1074
     */
1075
    public static function getRegisteredInSessionButton(
1076
        $sessionId,
1077
        $sessionName,
1078
        $checkRequirements = false,
1079
        $includeText = false,
1080
        $btnBing = false
1081
    ) {
1082
        $sessionId = (int) $sessionId;
1083
1084
        if ($btnBing) {
1085
            $btnBing = 'btn-lg btn-block';
1086
        } else {
1087
            $btnBing = 'btn-sm';
1088
        }
1089
1090
        if ($checkRequirements) {
1091
            return self::getRequirements($sessionId, SequenceResource::SESSION_TYPE, $includeText, $btnBing);
1092
        }
1093
1094
        $catalogSessionAutoSubscriptionAllowed = false;
1095
        if (api_get_setting('catalog_allow_session_auto_subscription') === 'true') {
1096
            $catalogSessionAutoSubscriptionAllowed = true;
1097
        }
1098
1099
        $url = api_get_path(WEB_CODE_PATH);
1100
1101
        if ($catalogSessionAutoSubscriptionAllowed) {
1102
            $url .= 'auth/courses.php?';
1103
            $url .= http_build_query([
1104
                'action' => 'subscribe_to_session',
1105
                'session_id' => $sessionId,
1106
            ]);
1107
1108
            $result = Display::toolbarButton(
1109
                get_lang('Subscribe'),
1110
                $url,
1111
                'pencil',
1112
                'primary',
1113
                [
1114
                    'class' => $btnBing.' ajax',
1115
                    'data-title' => get_lang('AreYouSureToSubscribe'),
1116
                    'data-size' => 'md',
1117
                    'title' => get_lang('Subscribe'),
1118
                ],
1119
                $includeText
1120
            );
1121
        } else {
1122
            $url .= 'inc/email_editor.php?';
1123
            $url .= http_build_query([
1124
                'action' => 'subscribe_me_to_session',
1125
                'session' => Security::remove_XSS($sessionName),
1126
            ]);
1127
1128
            $result = Display::toolbarButton(
1129
                get_lang('SubscribeToSessionRequest'),
1130
                $url,
1131
                'pencil',
1132
                'primary',
1133
                ['class' => $btnBing],
1134
                $includeText
1135
            );
1136
        }
1137
1138
        $hook = HookResubscribe::create();
1139
        if (!empty($hook)) {
1140
            $hook->setEventData([
1141
                'session_id' => $sessionId,
1142
            ]);
1143
            try {
1144
                $hook->notifyResubscribe(HOOK_EVENT_TYPE_PRE);
1145
            } catch (Exception $exception) {
1146
                $result = $exception->getMessage();
1147
            }
1148
        }
1149
1150
        return $result;
1151
    }
1152
1153
    public static function getRequirements($id, $type, $includeText, $btnBing)
1154
    {
1155
        $id = (int) $id;
1156
        $type = (int) $type;
1157
1158
        $url = api_get_path(WEB_AJAX_PATH);
1159
        $url .= 'sequence.ajax.php?';
1160
        $url .= http_build_query(
1161
            [
1162
                'a' => 'get_requirements',
1163
                'id' => $id,
1164
                'type' => $type,
1165
            ]
1166
        );
1167
1168
        return Display::toolbarButton(
1169
            get_lang('CheckRequirements'),
1170
            $url,
1171
            'shield',
1172
            'info',
1173
            [
1174
                'class' => $btnBing.' ajax',
1175
                'data-title' => get_lang('CheckRequirements'),
1176
                'data-size' => 'md',
1177
                'title' => get_lang('CheckRequirements'),
1178
            ],
1179
            $includeText
1180
        );
1181
    }
1182
1183
    /**
1184
     * Generate a label if the user has been  registered in session.
1185
     *
1186
     * @return string The label
1187
     */
1188
    public static function getAlreadyRegisteredInSessionLabel()
1189
    {
1190
        $icon = '<em class="fa fa-graduation-cap"></em>';
1191
1192
        return Display::div(
1193
            $icon,
1194
            [
1195
                'class' => 'btn btn-default btn-sm registered',
1196
                'title' => get_lang("AlreadyRegisteredToSession"),
1197
            ]
1198
        );
1199
    }
1200
1201
    /**
1202
     * Get a icon for a session.
1203
     *
1204
     * @param string $sessionName The session name
1205
     *
1206
     * @return string The icon
1207
     */
1208
    public static function getSessionIcon($sessionName)
1209
    {
1210
        return Display::return_icon(
1211
            'window_list.png',
1212
            $sessionName,
1213
            null,
1214
            ICON_SIZE_MEDIUM
1215
        );
1216
    }
1217
1218
    /**
1219
     * Return Session catalog rendered view.
1220
     *
1221
     * @param array $limit
1222
     */
1223
    public static function sessionList($limit = [])
1224
    {
1225
        $date = isset($_POST['date']) ? $_POST['date'] : date('Y-m-d');
1226
        $hiddenLinks = isset($_GET['hidden_links']) ? $_GET['hidden_links'] == 1 : false;
1227
        $limit = isset($limit) ? $limit : self::getLimitArray();
1228
1229
        $countSessions = self::browseSessions($date, [], false, true);
1230
        $sessions = self::browseSessions($date, $limit);
1231
1232
        $pageTotal = ceil($countSessions / $limit['length']);
1233
        // Do NOT show pagination if only one page or less
1234
        $pagination = $pageTotal > 1 ? self::getCatalogPagination($limit['current'], $limit['length'], $pageTotal) : '';
1235
        $sessionsBlocks = self::getFormattedSessionsBlock($sessions);
1236
1237
        // Get session search catalogue URL
1238
        $courseUrl = self::getCatalogUrl(
1239
            1,
1240
            $limit['length'],
1241
            null,
1242
            0,
1243
            'subscribe'
1244
        );
1245
1246
        $tpl = new Template();
1247
        $tpl->assign('actions', self::getTabList(2));
1248
        $tpl->assign('show_courses', self::showCourses());
1249
        $tpl->assign('show_sessions', self::showSessions());
1250
        $tpl->assign('show_tutor', api_get_setting('show_session_coach') === 'true');
1251
        $tpl->assign('course_url', $courseUrl);
1252
        $tpl->assign('catalog_pagination', $pagination);
1253
        $tpl->assign('hidden_links', $hiddenLinks);
1254
        $tpl->assign('search_token', Security::get_token());
1255
        $tpl->assign('search_date', $date);
1256
        $tpl->assign('web_session_courses_ajax_url', api_get_path(WEB_AJAX_PATH).'course.ajax.php');
1257
        $tpl->assign('sessions', $sessionsBlocks);
1258
        $tpl->assign('already_subscribed_label', self::getAlreadyRegisteredInSessionLabel());
1259
        $tpl->assign('catalog_settings', self::getCatalogSearchSettings());
1260
1261
        $contentTemplate = $tpl->get_template('catalog/session_catalog.tpl');
1262
1263
        $tpl->display($contentTemplate);
1264
    }
1265
1266
    /**
1267
     * Show the Session Catalogue with filtered session by course tags.
1268
     *
1269
     * @param array $limit Limit info
1270
     */
1271
    public static function sessionsListByName(array $limit)
1272
    {
1273
        $keyword = isset($_POST['keyword']) ? $_POST['keyword'] : null;
1274
        $hiddenLinks = isset($_GET['hidden_links']) ? (int) $_GET['hidden_links'] == 1 : false;
1275
        $courseUrl = self::getCatalogUrl(
1276
            1,
1277
            $limit['length'],
1278
            null,
1279
            0,
1280
            'subscribe'
1281
        );
1282
1283
        $sessions = self::getSessionsByName($keyword, $limit);
1284
        $sessionsBlocks = self::getFormattedSessionsBlock($sessions);
1285
1286
        $tpl = new Template();
1287
        $tpl->assign('actions', self::getTabList(2));
1288
        $tpl->assign('show_courses', self::showCourses());
1289
        $tpl->assign('show_sessions', self::showSessions());
1290
        $tpl->assign('show_tutor', api_get_setting('show_session_coach') === 'true' ? true : false);
1291
        $tpl->assign('course_url', $courseUrl);
1292
        $tpl->assign('already_subscribed_label', self::getAlreadyRegisteredInSessionLabel());
1293
        $tpl->assign('hidden_links', $hiddenLinks);
1294
        $tpl->assign('search_token', Security::get_token());
1295
        $tpl->assign('keyword', Security::remove_XSS($keyword));
1296
        $tpl->assign('sessions', $sessionsBlocks);
1297
        $tpl->assign('catalog_settings', self::getCatalogSearchSettings());
1298
1299
        $contentTemplate = $tpl->get_template('catalog/session_catalog.tpl');
1300
1301
        $tpl->display($contentTemplate);
1302
    }
1303
1304
    public static function getCatalogSearchSettings()
1305
    {
1306
        $settings = api_get_configuration_value('catalog_settings');
1307
        if (empty($settings)) {
1308
            // Default everything is visible
1309
            $settings = [
1310
                'sessions' => [
1311
                    'by_title' => true,
1312
                    'by_date' => true,
1313
                    'by_tag' => true,
1314
                    'show_session_info' => true,
1315
                    'show_session_date' => true,
1316
                ],
1317
            ];
1318
        }
1319
1320
        return $settings;
1321
    }
1322
1323
    /**
1324
     * @param int $active
1325
     *
1326
     * @return string
1327
     */
1328
    public static function getTabList($active = 1)
1329
    {
1330
        $pageLength = isset($_GET['pageLength']) ? (int) $_GET['pageLength'] : self::PAGE_LENGTH;
1331
1332
        $url = self::getCatalogUrl(1, $pageLength, null, 0, 'display_sessions');
1333
        $headers = [];
1334
        if (self::showCourses()) {
1335
            $headers[] = [
1336
                'url' => api_get_self(),
1337
                'content' => get_lang('CourseManagement'),
1338
            ];
1339
        }
1340
1341
        if (self::showSessions()) {
1342
            $headers[] = [
1343
                'url' => $url,
1344
                'content' => get_lang('SessionList'),
1345
            ];
1346
        }
1347
1348
        return Display::tabsOnlyLink($headers, $active);
1349
    }
1350
1351
    /**
1352
     * Show the Session Catalogue with filtered session by course tags.
1353
     *
1354
     * @param array $limit Limit info
1355
     */
1356
    public static function sessionsListByCoursesTag(array $limit)
1357
    {
1358
        $searchTag = isset($_POST['search_tag']) ? $_POST['search_tag'] : null;
1359
        $searchDate = isset($_POST['date']) ? $_POST['date'] : date('Y-m-d');
1360
        $hiddenLinks = isset($_GET['hidden_links']) ? (int) $_GET['hidden_links'] == 1 : false;
1361
        $courseUrl = self::getCatalogUrl(
1362
            1,
1363
            $limit['length'],
1364
            null,
1365
            0,
1366
            'subscribe'
1367
        );
1368
1369
        $sessions = self::browseSessionsByTags($searchTag, $limit);
1370
        $sessionsBlocks = self::getFormattedSessionsBlock($sessions);
1371
1372
        $tpl = new Template();
1373
        $tpl->assign('show_courses', self::showCourses());
1374
        $tpl->assign('show_sessions', self::showSessions());
1375
        $tpl->assign('show_tutor', api_get_setting('show_session_coach') === 'true' ? true : false);
1376
        $tpl->assign('course_url', $courseUrl);
1377
        $tpl->assign('already_subscribed_label', self::getAlreadyRegisteredInSessionLabel());
1378
        $tpl->assign('hidden_links', $hiddenLinks);
1379
        $tpl->assign('search_token', Security::get_token());
1380
        $tpl->assign('search_date', Security::remove_XSS($searchDate));
1381
        $tpl->assign('search_tag', Security::remove_XSS($searchTag));
1382
        $tpl->assign('sessions', $sessionsBlocks);
1383
1384
        $contentTemplate = $tpl->get_template('catalog/session_catalog.tpl');
1385
1386
        $tpl->display($contentTemplate);
1387
    }
1388
1389
    /**
1390
     * @return array
1391
     */
1392
    public static function getLimitArray()
1393
    {
1394
        $pageCurrent = isset($_REQUEST['pageCurrent']) ? (int) $_GET['pageCurrent'] : 1;
1395
        $pageLength = isset($_REQUEST['pageLength']) ? (int) $_GET['pageLength'] : self::PAGE_LENGTH;
1396
1397
        return [
1398
            'start' => ($pageCurrent - 1) * $pageLength,
1399
            'current' => $pageCurrent,
1400
            'length' => $pageLength,
1401
        ];
1402
    }
1403
1404
    /**
1405
     * Get the formatted data for sessions block to be displayed on Session Catalog page.
1406
     *
1407
     * @param array $sessions The session list
1408
     *
1409
     * @return array
1410
     */
1411
    public static function getFormattedSessionsBlock(array $sessions)
1412
    {
1413
        $extraFieldValue = new ExtraFieldValue('session');
1414
        $userId = api_get_user_id();
1415
        $sessionsBlocks = [];
1416
        $entityManager = Database::getManager();
1417
        $sessionRelCourseRepo = $entityManager->getRepository('ChamiloCoreBundle:SessionRelCourse');
1418
        $extraFieldRepo = $entityManager->getRepository('ChamiloCoreBundle:ExtraField');
1419
        $extraFieldRelTagRepo = $entityManager->getRepository('ChamiloCoreBundle:ExtraFieldRelTag');
1420
1421
        $tagsField = $extraFieldRepo->findOneBy([
1422
            'extraFieldType' => Chamilo\CoreBundle\Entity\ExtraField::COURSE_FIELD_TYPE,
1423
            'variable' => 'tags',
1424
        ]);
1425
1426
        /** @var \Chamilo\CoreBundle\Entity\Session $session */
1427
        foreach ($sessions as $session) {
1428
            $sessionDates = SessionManager::parseSessionDates([
1429
                'display_start_date' => $session->getDisplayStartDate(),
1430
                'display_end_date' => $session->getDisplayEndDate(),
1431
                'access_start_date' => $session->getAccessStartDate(),
1432
                'access_end_date' => $session->getAccessEndDate(),
1433
                'coach_access_start_date' => $session->getCoachAccessStartDate(),
1434
                'coach_access_end_date' => $session->getCoachAccessEndDate(),
1435
            ]);
1436
1437
            $imageField = $extraFieldValue->get_values_by_handler_and_field_variable(
1438
                $session->getId(),
1439
                'image'
1440
            );
1441
            $sessionCourseTags = [];
1442
            if (!is_null($tagsField)) {
1443
                $sessionRelCourses = $sessionRelCourseRepo->findBy([
1444
                    'session' => $session,
1445
                ]);
1446
                /** @var SessionRelCourse $sessionRelCourse */
1447
                foreach ($sessionRelCourses as $sessionRelCourse) {
1448
                    $courseTags = $extraFieldRelTagRepo->getTags(
1449
                        $tagsField,
1450
                        $sessionRelCourse->getCourse()->getId()
1451
                    );
1452
                    /** @var Tag $tag */
1453
                    foreach ($courseTags as $tag) {
1454
                        $sessionCourseTags[] = $tag->getTag();
1455
                    }
1456
                }
1457
            }
1458
1459
            if (!empty($sessionCourseTags)) {
1460
                $sessionCourseTags = array_unique($sessionCourseTags);
1461
            }
1462
1463
            /** @var SequenceResourceRepository $repo */
1464
            $repo = $entityManager->getRepository('ChamiloCoreBundle:SequenceResource');
1465
            $sequences = $repo->getRequirementsAndDependenciesWithinSequences(
1466
                $session->getId(),
1467
                SequenceResource::SESSION_TYPE
1468
            );
1469
1470
            $hasRequirements = false;
1471
            foreach ($sequences as $sequence) {
1472
                if (count($sequence['requirements']) === 0) {
1473
                    continue;
1474
                }
1475
                $hasRequirements = true;
1476
                break;
1477
            }
1478
            $cat = $session->getCategory();
1479
            if (empty($cat)) {
1480
                $cat = null;
1481
                $catName = '';
1482
            } else {
1483
                $catName = $cat->getName();
1484
            }
1485
1486
            $generalCoach = $session->getGeneralCoach();
1487
            $coachId = $generalCoach ? $generalCoach->getId() : 0;
1488
            $coachName = $generalCoach ? UserManager::formatUserFullName($session->getGeneralCoach()) : '';
1489
1490
            $actions = null;
1491
            if (api_is_platform_admin()) {
1492
                $actions = api_get_path(WEB_CODE_PATH).'session/resume_session.php?id_session='.$session->getId();
1493
            }
1494
1495
            $plugin = \BuyCoursesPlugin::create();
1496
            $isThisSessionOnSale = $plugin->getBuyCoursePluginPrice($session);
1497
1498
            $sessionsBlock = [
1499
                'id' => $session->getId(),
1500
                'name' => $session->getName(),
1501
                'image' => isset($imageField['value']) ? $imageField['value'] : null,
1502
                'nbr_courses' => $session->getNbrCourses(),
1503
                'nbr_users' => $session->getNbrUsers(),
1504
                'coach_id' => $coachId,
1505
                'coach_url' => $generalCoach
1506
                    ? api_get_path(WEB_AJAX_PATH).'user_manager.ajax.php?a=get_user_popup&user_id='.$coachId
1507
                    : '',
1508
                'coach_name' => $coachName,
1509
                'coach_avatar' => UserManager::getUserPicture(
1510
                    $coachId,
1511
                    USER_IMAGE_SIZE_SMALL
1512
                ),
1513
                'is_subscribed' => SessionManager::isUserSubscribedAsStudent(
1514
                    $session->getId(),
1515
                    $userId
1516
                ),
1517
                'icon' => self::getSessionIcon($session->getName()),
1518
                'date' => $sessionDates['display'],
1519
                'price' => !empty($isThisSessionOnSale['html']) ? $isThisSessionOnSale['html'] : '',
1520
                'subscribe_button' => isset($isThisSessionOnSale['buy_button']) ? $isThisSessionOnSale['buy_button'] : self::getRegisteredInSessionButton(
1521
                    $session->getId(),
1522
                    $session->getName(),
1523
                    $hasRequirements
1524
                ),
1525
                'show_description' => $session->getShowDescription(),
1526
                'description' => $session->getDescription(),
1527
                'category' => $catName,
1528
                'tags' => $sessionCourseTags,
1529
                'edit_actions' => $actions,
1530
                'duration' => SessionManager::getDayLeftInSession(
1531
                    ['id' => $session->getId(), 'duration' => $session->getDuration()],
1532
                    $userId
1533
                ),
1534
            ];
1535
1536
            $sessionsBlocks[] = array_merge($sessionsBlock, $sequences);
1537
        }
1538
1539
        return $sessionsBlocks;
1540
    }
1541
1542
    /**
1543
     * Get Pagination HTML div.
1544
     *
1545
     * @param int    $pageCurrent
1546
     * @param int    $pageLength
1547
     * @param int    $pageTotal
1548
     * @param string $categoryCode
1549
     * @param string $action
1550
     * @param array  $fields
1551
     *
1552
     * @return string
1553
     */
1554
    public static function getCatalogPagination($pageCurrent, $pageLength, $pageTotal, $categoryCode = '', $action = '', $fields = [])
1555
    {
1556
        // Start empty html
1557
        $pageDiv = '';
1558
        $html = '';
1559
        $pageBottom = max(1, $pageCurrent - 3);
1560
        $pageTop = min($pageTotal, $pageCurrent + 3);
1561
1562
        if ($pageBottom > 1) {
1563
            $pageDiv .= self::getPageNumberItem(1, $pageLength);
1564
            if ($pageBottom > 2) {
1565
                $pageDiv .= self::getPageNumberItem(
1566
                    $pageBottom - 1,
1567
                    $pageLength,
1568
                    null,
1569
                    '...',
1570
                    $categoryCode,
1571
                    $action,
1572
                    $fields
1573
                );
1574
            }
1575
        }
1576
1577
        // For each page add its page button to html
1578
        for ($i = $pageBottom; $i <= $pageTop; $i++) {
1579
            if ($i === $pageCurrent) {
1580
                $pageItemAttributes = ['class' => 'active'];
1581
            } else {
1582
                $pageItemAttributes = [];
1583
            }
1584
            $pageDiv .= self::getPageNumberItem(
1585
                $i,
1586
                $pageLength,
1587
                $pageItemAttributes,
1588
                '',
1589
                $categoryCode,
1590
                $action,
1591
                $fields
1592
            );
1593
        }
1594
1595
        // Check if current page is the last page
1596
        if ($pageTop < $pageTotal) {
1597
            if ($pageTop < ($pageTotal - 1)) {
1598
                $pageDiv .= self::getPageNumberItem(
1599
                    $pageTop + 1,
1600
                    $pageLength,
1601
                    null,
1602
                    '...',
1603
                    $categoryCode,
1604
                    $action,
1605
                    $fields
1606
                );
1607
            }
1608
            $pageDiv .= self::getPageNumberItem($pageTotal, $pageLength, [], '', $categoryCode, $action, $fields);
1609
        }
1610
1611
        // Complete pagination html
1612
        $pageDiv = Display::tag('ul', $pageDiv, ['class' => 'pagination']);
1613
        $html .= '<nav>'.$pageDiv.'</nav>';
1614
1615
        return $html;
1616
    }
1617
1618
1619
    /**
1620
     * Get li HTML of page number.
1621
     *
1622
     * @param $pageNumber
1623
     * @param $pageLength
1624
     * @param array  $liAttributes
1625
     * @param string $content
1626
     * @param string $categoryCode
1627
     * @param string $action
1628
     * @param array $fields
1629
     *
1630
     * @return string
1631
     */
1632
    public static function getPageNumberItem(
1633
        $pageNumber,
1634
        $pageLength,
1635
        $liAttributes = [],
1636
        $content = '',
1637
        $categoryCode = '',
1638
        $action = '',
1639
        $fields = []
1640
    ) {
1641
        // Get page URL
1642
        $url = self::getCatalogUrl($pageNumber, $pageLength, $categoryCode, null, $action, $fields);
1643
1644
        // If is current page ('active' class) clear URL
1645
        if (isset($liAttributes) && is_array($liAttributes) && isset($liAttributes['class'])) {
1646
            if (strpos('active', $liAttributes['class']) !== false) {
1647
                $url = '';
1648
            }
1649
        }
1650
1651
        $content = !empty($content) ? $content : $pageNumber;
1652
1653
        return Display::tag(
1654
            'li',
1655
            Display::url(
1656
                $content,
1657
                $url
1658
            ),
1659
            $liAttributes
1660
        );
1661
    }
1662
1663
    /**
1664
     * Return URL to course catalog.
1665
     *
1666
     * @param int    $pageCurrent
1667
     * @param int    $pageLength
1668
     * @param string $categoryCode
1669
     * @param int    $hiddenLinks
1670
     * @param string $action
1671
     *
1672
     * @return string
1673
     */
1674
    public static function getCatalogUrl(
1675
        $pageCurrent,
1676
        $pageLength,
1677
        $categoryCode = null,
1678
        $hiddenLinks = null,
1679
        $action = null,
1680
        $extraFields = []
1681
    ) {
1682
        $requestAction = isset($_REQUEST['action']) ? Security::remove_XSS($_REQUEST['action']) : null;
1683
        $action = isset($action) ? Security::remove_XSS($action) : $requestAction;
1684
        $searchTerm = isset($_REQUEST['search_term']) ? Security::remove_XSS($_REQUEST['search_term']) : null;
1685
1686
        if ($action === 'subscribe_user_with_password') {
1687
            $action = 'subscribe';
1688
        }
1689
1690
        $categoryCodeRequest = isset($_REQUEST['category_code']) ? Security::remove_XSS($_REQUEST['category_code']) : null;
1691
        $categoryCode = !empty($categoryCode) ? Security::remove_XSS($categoryCode) : $categoryCodeRequest;
1692
        $hiddenLinksRequest = !empty($_REQUEST['hidden_links']) ? Security::remove_XSS($_REQUEST['hidden_links']) : null;
1693
        $hiddenLinks = !empty($hiddenLinks) ? Security::remove_XSS($hiddenLinksRequest) : $categoryCodeRequest;
1694
1695
        // Start URL with params
1696
        $pageUrl = api_get_self().
1697
            '?action='.$action.
1698
            '&category_code='.$categoryCode.
1699
            '&hidden_links='.$hiddenLinks.
1700
            '&pageCurrent='.$pageCurrent.
1701
            '&pageLength='.$pageLength;
1702
1703
        if (!empty($extraFields)) {
1704
            $params = [];
1705
            foreach ($extraFields as $variable => $value) {
1706
                $params[Security::remove_XSS($variable)] = Security::remove_XSS($value);
1707
            }
1708
            if (!empty($params)) {
1709
                $pageUrl .= '&'.http_build_query($params);
1710
            }
1711
        }
1712
1713
        switch ($action) {
1714
            case 'subscribe':
1715
                // for search
1716
                $pageUrl .=
1717
                    '&search_term='.$searchTerm.
1718
                    '&sec_token='.Security::getTokenFromSession();
1719
                break;
1720
            case 'display_courses':
1721
            default:
1722
                break;
1723
        }
1724
1725
        return $pageUrl;
1726
    }
1727
}
1728