Passed
Push — 1.11.x ( b3f5d1...723780 )
by Julito
13:15
created

getAlreadyRegisteredInSessionLabel()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 9
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 5
nc 1
nop 0
dl 0
loc 9
rs 10
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 $categoryCode
414
     * @param string $keyword     The string that the user submitted
415
     * @param array  $limit
416
     * @param bool   $justVisible search only on visible courses in the catalogue
417
     * @param array  $conditions
418
     *
419
     * @return array an array containing a list of all the courses matching the the search term
420
     */
421
    public static function searchCourses($categoryCode, $keyword, $limit, $justVisible = false, $conditions = [])
422
    {
423
        $courseTable = Database::get_main_table(TABLE_MAIN_COURSE);
424
        $limitFilter = self::getLimitFilterFromArray($limit);
425
        $avoidCoursesCondition = self::getAvoidCourseCondition();
426
        $visibilityCondition = $justVisible ? CourseManager::getCourseVisibilitySQLCondition('s', true) : '';
427
        $keyword = Database::escape_string($keyword);
428
        $categoryCode = Database::escape_string($categoryCode);
429
430
        $sqlInjectJoins = '';
431
        $where = ' 1 = 1 ';
432
        $sqlInjectWhere = '';
433
        $injectExtraFields = '1';
434
        if (!empty($conditions)) {
435
            $sqlInjectJoins = $conditions['inject_joins'];
436
            $where = $conditions['where'];
437
            $sqlInjectWhere = $conditions['inject_where'];
438
            $injectExtraFields = !empty($conditions['inject_extra_fields']) ? $conditions['inject_extra_fields'] : 1;
439
            $injectExtraFields = rtrim($injectExtraFields, ', ');
440
        }
441
442
        $categoryFilter = '';
443
        if ($categoryCode === 'ALL') {
444
            // Nothing to do
445
        } elseif ($categoryCode === 'NONE') {
446
            $categoryFilter = ' AND category_code = "" ';
447
        } else {
448
            $categoryFilter = ' AND category_code = "'.$categoryCode.'" ';
449
        }
450
451
        $sql = "SELECT DISTINCT course.*, $injectExtraFields
452
                FROM $courseTable course
453
                $sqlInjectJoins
454
                WHERE (
455
                        course.code LIKE '%".$keyword."%' OR
456
                        course.title LIKE '%".$keyword."%' OR
457
                        course.tutor_name LIKE '%".$keyword."%'
458
                    )
459
                    $where
460
                    $categoryFilter
461
                    $sqlInjectWhere
462
                    $avoidCoursesCondition
463
                    $visibilityCondition
464
                ORDER BY title, visual_code ASC
465
                $limitFilter
466
                ";
467
468
        if (api_is_multiple_url_enabled()) {
469
            $urlId = api_get_current_access_url_id();
470
            if ($urlId != -1) {
471
                $tbl_url_rel_course = Database::get_main_table(TABLE_MAIN_ACCESS_URL_REL_COURSE);
472
                $urlCondition = ' access_url_id = '.$urlId.' AND';
473
                $allowBaseCategories = api_get_configuration_value('allow_base_course_category');
474
                if ($allowBaseCategories) {
475
                    $urlCondition = ' (access_url_id = '.$urlId.' OR access_url_id = 1) AND ';
476
                }
477
478
                $sql = "SELECT DISTINCT course.*, $injectExtraFields
479
                        FROM $courseTable as course
480
                        INNER JOIN $tbl_url_rel_course as url_rel_course
481
                        ON (url_rel_course.c_id = course.id)
482
                        $sqlInjectJoins
483
                        WHERE
484
                            access_url_id = $urlId AND
485
                            (
486
                                code LIKE '%".$keyword."%' OR
487
                                title LIKE '%".$keyword."%' OR
488
                                tutor_name LIKE '%".$keyword."%'
489
                            )
490
                            $where
491
                            $categoryFilter
492
                            $sqlInjectWhere
493
                            $avoidCoursesCondition
494
                            $visibilityCondition
495
                        ORDER BY title, visual_code ASC
496
                        $limitFilter
497
                       ";
498
            }
499
        }
500
501
        $result = Database::query($sql);
502
        $courses = [];
503
        while ($row = Database::fetch_array($result)) {
504
            $row['registration_code'] = !empty($row['registration_code']);
505
            $countUsers = CourseManager::get_user_list_from_course_code(
506
                $row['code'],
507
                0,
508
                null,
509
                null,
510
                null,
511
                true
512
            );
513
            $connectionsLastMonth = Tracking::get_course_connections_count(
514
                $row['id'],
515
                0,
516
                api_get_utc_datetime(time() - (30 * 86400))
517
            );
518
519
            $ranking = CourseManager::get_course_ranking($row['id'], 0);
520
            $courses[] = [
521
                'real_id' => $row['id'],
522
                'point_info' => $ranking,
523
                'code' => $row['code'],
524
                'directory' => $row['directory'],
525
                'visual_code' => $row['visual_code'],
526
                'title' => $row['title'],
527
                'tutor' => $row['tutor_name'],
528
                'subscribe' => $row['subscribe'],
529
                'unsubscribe' => $row['unsubscribe'],
530
                'registration_code' => $row['registration_code'],
531
                'creation_date' => $row['creation_date'],
532
                'visibility' => $row['visibility'],
533
                'count_users' => $countUsers,
534
                'count_connections' => $connectionsLastMonth,
535
            ];
536
        }
537
538
        return $courses;
539
    }
540
541
    /**
542
     * List the sessions.
543
     *
544
     * @param string $date
545
     * @param array  $limit
546
     * @param bool   $returnQueryBuilder
547
     * @param bool   $getCount
548
     *
549
     * @return array|\Doctrine\ORM\Query The session list
550
     */
551
    public static function browseSessions($date = null, $limit = [], $returnQueryBuilder = false, $getCount = false)
552
    {
553
        $urlId = api_get_current_access_url_id();
554
555
        /*$dql = "SELECT $select
556
                FROM ChamiloCoreBundle:Session s
557
                WHERE EXISTS
558
                    (
559
                        SELECT url.sessionId FROM ChamiloCoreBundle:AccessUrlRelSession url
560
                        WHERE url.sessionId = s.id AND url.accessUrlId = $urlId
561
                    ) AND
562
                    s.nbrCourses > 0
563
                ";
564
        if (!is_null($date)) {
565
            $date = Database::escape_string($date);
566
            $dql .= "
567
                AND (
568
                    (s.accessEndDate IS NULL)
569
                    OR
570
                    (
571
                    s.accessStartDate IS NOT NULL AND
572
                    s.accessEndDate IS NOT NULL AND
573
                    s.accessStartDate <= '$date' AND s.accessEndDate >= '$date')
574
                    OR
575
                    (
576
                        s.accessStartDate IS NULL AND
577
                        s.accessEndDate IS NOT NULL AND
578
                        s.accessEndDate >= '$date'
579
                    )
580
                )
581
            ";
582
        }*/
583
584
        $em = Database::getManager();
585
        $qb = $em->createQueryBuilder();
586
        $qb2 = $em->createQueryBuilder();
587
588
        $qb = $qb
589
            ->select('s')
590
            ->from('ChamiloCoreBundle:Session', 's')
591
            ->where(
592
                $qb->expr()->in(
593
                    's',
594
                    $qb2
595
                        ->select('s2')
596
                        ->from('ChamiloCoreBundle:AccessUrlRelSession', 'url')
597
                        ->join('ChamiloCoreBundle:Session', 's2')
598
                        ->where(
599
                            $qb->expr()->eq('url.sessionId ', 's2.id')
600
                        )->andWhere(
601
                            $qb->expr()->eq('url.accessUrlId ', $urlId))
602
                        ->getDQL()
603
                )
604
            )
605
            ->andWhere($qb->expr()->gt('s.nbrCourses', 0))
606
        ;
607
608
        if (!is_null($date)) {
609
            $qb->andWhere(
610
                $qb->expr()->orX(
611
                    $qb->expr()->isNull('s.accessEndDate'),
612
                    $qb->expr()->andX(
613
                        $qb->expr()->isNotNull('s.accessStartDate'),
614
                        $qb->expr()->isNotNull('s.accessEndDate'),
615
                        $qb->expr()->lte('s.accessStartDate', $date),
616
                        $qb->expr()->gte('s.accessEndDate', $date)
617
                    ),
618
                    $qb->expr()->andX(
619
                        $qb->expr()->isNull('s.accessStartDate'),
620
                        $qb->expr()->isNotNull('s.accessEndDate'),
621
                        $qb->expr()->gte('s.accessEndDate', $date)
622
                    )
623
                )
624
            );
625
        }
626
627
        if ($getCount) {
628
            $qb->select('count(s)');
629
        }
630
631
        $qb = self::hideFromSessionCatalogCondition($qb);
632
633
        if (!empty($limit)) {
634
            $qb
635
                ->setFirstResult($limit['start'])
636
                ->setMaxResults($limit['length'])
637
            ;
638
        }
639
640
        $query = $qb->getQuery();
641
642
        if ($returnQueryBuilder) {
643
            return $query;
644
        }
645
646
        if ($getCount) {
647
            return $query->getSingleScalarResult();
648
        }
649
650
        return $query->getResult();
651
    }
652
653
    /**
654
     * @param \Doctrine\ORM\QueryBuilder $qb
655
     *
656
     * @return mixed
657
     */
658
    public static function hideFromSessionCatalogCondition($qb)
659
    {
660
        $em = Database::getManager();
661
        $qb3 = $em->createQueryBuilder();
662
663
        $extraField = new \ExtraField('session');
664
        $extraFieldInfo = $extraField->get_handler_field_info_by_field_variable('hide_from_catalog');
665
        if (!empty($extraFieldInfo)) {
666
            $qb->andWhere(
667
                $qb->expr()->notIn(
668
                    's',
669
                    $qb3
670
                        ->select('s3')
671
                        ->from('ChamiloCoreBundle:ExtraFieldValues', 'fv')
672
                        ->innerJoin('ChamiloCoreBundle:Session', 's3', Join::WITH, 'fv.itemId = s3.id')
673
                        ->where(
674
                            $qb->expr()->eq('fv.field', $extraFieldInfo['id'])
675
                        )->andWhere(
676
                            $qb->expr()->eq('fv.value ', 1)
677
                        )
678
                        ->getDQL()
679
                )
680
            );
681
        }
682
683
        return $qb;
684
    }
685
686
    /**
687
     * Search sessions by the tags in their courses.
688
     *
689
     * @param string $termTag Term for search in tags
690
     * @param array  $limit   Limit info
691
     *
692
     * @return array The sessions
693
     */
694
    public static function browseSessionsByTags($termTag, array $limit)
695
    {
696
        $em = Database::getManager();
697
        $qb = $em->createQueryBuilder();
698
699
        $urlId = api_get_current_access_url_id();
700
701
        $qb->select('s')
702
            ->distinct()
703
            ->from('ChamiloCoreBundle:Session', 's')
704
            ->innerJoin(
705
                'ChamiloCoreBundle:SessionRelCourse',
706
                'src',
707
                Join::WITH,
708
                's.id = src.session'
709
            )
710
            ->innerJoin(
711
                'ChamiloCoreBundle:AccessUrlRelSession',
712
                'url',
713
                Join::WITH,
714
                'url.sessionId = s.id'
715
            )
716
            ->innerJoin(
717
                'ChamiloCoreBundle:ExtraFieldRelTag',
718
                'frt',
719
                Join::WITH,
720
                'src.course = frt.itemId'
721
            )
722
            ->innerJoin(
723
                'ChamiloCoreBundle:Tag',
724
                't',
725
                Join::WITH,
726
                'frt.tagId = t.id'
727
            )
728
            ->innerJoin(
729
                'ChamiloCoreBundle:ExtraField',
730
                'f',
731
                Join::WITH,
732
                'frt.fieldId = f.id'
733
            )
734
            ->where(
735
                $qb->expr()->like('t.tag', ':tag')
736
            )
737
            ->andWhere(
738
                $qb->expr()->eq('f.extraFieldType', ExtraField::COURSE_FIELD_TYPE)
739
            )
740
            ->andWhere(
741
                $qb->expr()->gt('s.nbrCourses', 0)
742
            )
743
            ->andWhere(
744
                $qb->expr()->eq('url.accessUrlId', $urlId)
745
            )
746
            ->setFirstResult($limit['start'])
747
            ->setMaxResults($limit['length'])
748
            ->setParameter('tag', "$termTag%")
749
            ;
750
751
        $qb = self::hideFromSessionCatalogCondition($qb);
752
753
        return $qb->getQuery()->getResult();
754
    }
755
756
    /**
757
     * Search sessions by the title.
758
     *
759
     * @param string $keyword
760
     * @param array  $limit   Limit info
761
     *
762
     * @return array The sessions
763
     */
764
    public static function getSessionsByName($keyword, array $limit)
765
    {
766
        $em = Database::getManager();
767
        $qb = $em->createQueryBuilder();
768
769
        $urlId = api_get_current_access_url_id();
770
771
        $qb->select('s')
772
            ->distinct()
773
            ->from('ChamiloCoreBundle:Session', 's')
774
            ->innerJoin(
775
                'ChamiloCoreBundle:SessionRelCourse',
776
                'src',
777
                Join::WITH,
778
                's.id = src.session'
779
            )
780
            ->innerJoin(
781
                'ChamiloCoreBundle:AccessUrlRelSession',
782
                'url',
783
                Join::WITH,
784
                'url.sessionId = s.id'
785
            )
786
            ->andWhere(
787
                $qb->expr()->eq('url.accessUrlId', $urlId)
788
            )->andWhere(
789
                's.name LIKE :keyword'
790
            )
791
            ->andWhere(
792
                $qb->expr()->gt('s.nbrCourses', 0)
793
            )
794
            ->setFirstResult($limit['start'])
795
            ->setMaxResults($limit['length'])
796
            ->setParameter('keyword', "%$keyword%")
797
        ;
798
799
        $qb = self::hideFromSessionCatalogCondition($qb);
800
801
        return $qb->getQuery()->getResult();
802
    }
803
804
    /**
805
     * Build a recursive tree of course categories.
806
     *
807
     * @param array $categories
808
     * @param int   $parentId
809
     * @param int   $level
810
     *
811
     * @return array
812
     */
813
    public static function buildCourseCategoryTree($categories, $parentId = 0, $level = 0)
814
    {
815
        $list = [];
816
        $count = 0;
817
        $level++;
818
        foreach ($categories as $category) {
819
            if (empty($category['parent_id'])) {
820
                continue;
821
            }
822
            if ($category['parent_id'] == $parentId) {
823
                $list[$category['code']] = $category;
824
                $count += $category['number_courses'];
825
                $list[$category['code']]['level'] = $level;
826
                list($subList, $childrenCount) = self::buildCourseCategoryTree(
827
                    $categories,
828
                    $category['code'],
829
                    $level
830
                );
831
                $list[$category['code']]['number_courses'] += $childrenCount;
832
                foreach ($subList as $item) {
833
                    $list[$item['code']] = $item;
834
                }
835
                $count += $childrenCount;
836
            }
837
        }
838
839
        return [$list, $count];
840
    }
841
842
    /**
843
     * List Code Search Category.
844
     *
845
     * @param string $code
846
     *
847
     * @return array
848
     */
849
    public static function childrenCategories($code)
850
    {
851
        $allCategories = CourseCategory::getAllCategories();
852
        $list = [];
853
        $row = [];
854
855
        if ($code !== 'ALL' and $code !== 'NONE') {
856
            foreach ($allCategories as $category) {
857
                if ($category['code'] === $code) {
858
                    $list = self::buildCourseCategoryTree($allCategories, $category['code'], 0);
859
                }
860
            }
861
            foreach ($list[0] as $item) {
862
                $row[] = $item['code'];
863
            }
864
        }
865
866
        return $row;
867
    }
868
869
    /**
870
     * Display the course catalog image of a course.
871
     *
872
     * @param array $course
873
     *
874
     * @return string HTML string
875
     */
876
    public static function returnThumbnail($course)
877
    {
878
        $course_path = api_get_path(SYS_COURSE_PATH).$course['directory'];
879
880
        if (file_exists($course_path.'/course-pic.png')) {
881
            // redimensioned image 85x85
882
            $courseMediumImage = api_get_path(WEB_COURSE_PATH).$course['directory'].'/course-pic.png';
883
        } else {
884
            // without picture
885
            $courseMediumImage = Display::return_icon(
886
                'session_default.png',
887
                null,
888
                null,
889
                null,
890
                null,
891
                true
892
            );
893
        }
894
895
        return $courseMediumImage;
896
    }
897
898
    /**
899
     * @param array $courseInfo
900
     *
901
     * @return string
902
     */
903
    public static function return_teacher($courseInfo)
904
    {
905
        $teachers = CourseManager::getTeachersFromCourse($courseInfo['real_id']);
906
        $length = count($teachers);
907
908
        if (!$length) {
909
            return '';
910
        }
911
912
        $html = '<div class="block-author">';
913
        if ($length > 6) {
914
            $html .= '<a
915
            id="plist"
916
            data-trigger="focus"
917
            tabindex="0" role="button"
918
            class="btn btn-default panel_popover"
919
            data-toggle="popover"
920
            title="'.addslashes(get_lang('CourseTeachers')).'"
921
            data-html="true"
922
        >
923
            <i class="fa fa-graduation-cap" aria-hidden="true"></i>
924
        </a>';
925
            $html .= '<div id="popover-content-plist" class="hide">';
926
            foreach ($teachers as $value) {
927
                $name = $value['firstname'].' '.$value['lastname'];
928
                $html .= '<div class="popover-teacher">';
929
                $html .= '<a href="'.$value['url'].'" class="ajax" data-title="'.$name.'" title="'.$name.'">
930
                        <img src="'.$value['avatar'].'" title="'.$name.'" alt="'.get_lang('UserPicture').'"/></a>';
931
                $html .= '<div class="teachers-details"><h5>
932
                        <a href="'.$value['url'].'" class="ajax" data-title="'.$name.'" title="'.$name.'">'
933
                    .$name.'</a></h5></div>';
934
                $html .= '</div>';
935
            }
936
            $html .= '</div>';
937
        } else {
938
            foreach ($teachers as $value) {
939
                $name = $value['firstname'].' '.$value['lastname'];
940
                if ($length > 2) {
941
                    $html .= '<a href="'.$value['url'].'" class="ajax" data-title="'.$name.'" title="'.$name.'">
942
                        <img src="'.$value['avatar'].'" title="'.$name.'" alt="'.get_lang('UserPicture').'"/></a>';
943
                } else {
944
                    $html .= '<a href="'.$value['url'].'" class="ajax" data-title="'.$name.'" title="'.$name.'">
945
                        <img src="'.$value['avatar'].'" title="'.$name.'" alt="'.get_lang('UserPicture').'"/></a>';
946
                    $html .= '<div class="teachers-details"><h5>
947
                        <a href="'.$value['url'].'" class="ajax" data-title="'.$name.'">'
948
                        .$name.'</a></h5><p>'.get_lang('Teacher').'</p></div>';
949
                }
950
            }
951
        }
952
        $html .= '</div>';
953
954
        return $html;
955
    }
956
957
    /**
958
     * Display the title of a course in course catalog.
959
     *
960
     * @param array $course
961
     *
962
     * @return string HTML string
963
     */
964
    public static function return_title($course)
965
    {
966
        $linkCourse = api_get_path(WEB_PATH).'course/'.$course['real_id'].'/about';
967
        $html = '<div class="block-title"><h4 class="title">';
968
        $html .= '<a title="'.$course['title'].'" href="'.$linkCourse.'">'.$course['title'].'</a>';
969
        $html .= '</h4></div>';
970
971
        return $html;
972
    }
973
974
    /**
975
     * Display the already registerd text in a course in the course catalog.
976
     *
977
     * @param $status
978
     *
979
     * @return string HTML string
980
     */
981
    public static function return_already_registered_label($status)
982
    {
983
        $icon = '<em class="fa fa-check"></em>';
984
        $title = get_lang('YouAreATeacherOfThisCourse');
985
        if ($status === 'student') {
986
            $icon = '<em class="fa fa-check"></em>';
987
            $title = get_lang('AlreadySubscribed');
988
        }
989
990
        $html = Display::tag(
991
            'span',
992
            $icon.' '.$title,
993
            [
994
                'id' => 'register',
995
                'class' => 'label-subscribed text-success',
996
                'title' => $title,
997
                'aria-label' => $title,
998
            ]
999
        );
1000
1001
        return $html.PHP_EOL;
1002
    }
1003
1004
    /**
1005
     * Display the register button of a course in the course catalog.
1006
     *
1007
     * @param $course
1008
     * @param $stok
1009
     * @param $categoryCode
1010
     * @param $search_term
1011
     *
1012
     * @return string
1013
     */
1014
    public static function return_register_button($course, $stok, $categoryCode, $search_term)
1015
    {
1016
        $title = get_lang('Subscribe');
1017
        $action = 'subscribe_course';
1018
        if (!empty($course['registration_code'])) {
1019
            $action = 'subscribe_course_validation';
1020
        }
1021
1022
        return Display::url(
1023
            Display::returnFontAwesomeIcon('check').' '.$title,
1024
            api_get_self().'?action='.$action.'&sec_token='.$stok.
1025
            '&course_code='.$course['code'].'&search_term='.$search_term.'&category_code='.$categoryCode,
1026
            ['class' => 'btn btn-success btn-sm', 'title' => $title, 'aria-label' => $title]
1027
        );
1028
    }
1029
1030
    /**
1031
     * Display the unregister button of a course in the course catalog.
1032
     *
1033
     * @param $course
1034
     * @param $stok
1035
     * @param $search_term
1036
     * @param $categoryCode
1037
     *
1038
     * @return string
1039
     */
1040
    public static function return_unregister_button($course, $stok, $search_term, $categoryCode)
1041
    {
1042
        $title = get_lang('Unsubscription');
1043
1044
        return Display::url(
1045
            Display::returnFontAwesomeIcon('sign-in').'&nbsp;'.$title,
1046
            api_get_self().'?action=unsubscribe&sec_token='.$stok
1047
            .'&course_code='.$course['code'].'&search_term='.$search_term.'&category_code='.$categoryCode,
1048
            ['class' => 'btn btn-danger', 'title' => $title, 'aria-label' => $title]
1049
        );
1050
    }
1051
1052
    /**
1053
     * Get a HTML button for subscribe to session.
1054
     *
1055
     * @param int    $sessionId         The session ID
1056
     * @param string $sessionName       The session name
1057
     * @param bool   $checkRequirements Optional.
1058
     *                                  Whether the session has requirement. Default is false
1059
     * @param bool   $includeText       Optional. Whether show the text in button
1060
     * @param bool   $btnBing
1061
     *
1062
     * @return string The button HTML
1063
     */
1064
    public static function getRegisteredInSessionButton(
1065
        $sessionId,
1066
        $sessionName,
1067
        $checkRequirements = false,
1068
        $includeText = false,
1069
        $btnBing = false
1070
    ) {
1071
        $sessionId = (int) $sessionId;
1072
1073
        if ($btnBing) {
1074
            $btnBing = 'btn-lg btn-block';
1075
        } else {
1076
            $btnBing = 'btn-sm';
1077
        }
1078
1079
        if ($checkRequirements) {
1080
            return self::getRequirements($sessionId, SequenceResource::SESSION_TYPE, $includeText, $btnBing);
1081
        }
1082
1083
        $catalogSessionAutoSubscriptionAllowed = false;
1084
        if (api_get_setting('catalog_allow_session_auto_subscription') === 'true') {
1085
            $catalogSessionAutoSubscriptionAllowed = true;
1086
        }
1087
1088
        $url = api_get_path(WEB_CODE_PATH);
1089
1090
        if ($catalogSessionAutoSubscriptionAllowed) {
1091
            $url .= 'auth/courses.php?';
1092
            $url .= http_build_query([
1093
                'action' => 'subscribe_to_session',
1094
                'session_id' => $sessionId,
1095
            ]);
1096
1097
            $result = Display::toolbarButton(
1098
                get_lang('Subscribe'),
1099
                $url,
1100
                'pencil',
1101
                'primary',
1102
                [
1103
                    'class' => $btnBing.' ajax',
1104
                    'data-title' => get_lang('AreYouSureToSubscribe'),
1105
                    'data-size' => 'md',
1106
                    'title' => get_lang('Subscribe'),
1107
                ],
1108
                $includeText
1109
            );
1110
        } else {
1111
            $url .= 'inc/email_editor.php?';
1112
            $url .= http_build_query([
1113
                'action' => 'subscribe_me_to_session',
1114
                'session' => Security::remove_XSS($sessionName),
1115
            ]);
1116
1117
            $result = Display::toolbarButton(
1118
                get_lang('SubscribeToSessionRequest'),
1119
                $url,
1120
                'pencil',
1121
                'primary',
1122
                ['class' => $btnBing],
1123
                $includeText
1124
            );
1125
        }
1126
1127
        $hook = HookResubscribe::create();
1128
        if (!empty($hook)) {
1129
            $hook->setEventData([
1130
                'session_id' => $sessionId,
1131
            ]);
1132
            try {
1133
                $hook->notifyResubscribe(HOOK_EVENT_TYPE_PRE);
1134
            } catch (Exception $exception) {
1135
                $result = $exception->getMessage();
1136
            }
1137
        }
1138
1139
        return $result;
1140
    }
1141
1142
    public static function getRequirements($id, $type, $includeText, $btnBing)
1143
    {
1144
        $id = (int) $id;
1145
        $type = (int) $type;
1146
1147
        $url = api_get_path(WEB_AJAX_PATH);
1148
        $url .= 'sequence.ajax.php?';
1149
        $url .= http_build_query(
1150
            [
1151
                'a' => 'get_requirements',
1152
                'id' => $id,
1153
                'type' => $type,
1154
            ]
1155
        );
1156
1157
        return Display::toolbarButton(
1158
            get_lang('CheckRequirements'),
1159
            $url,
1160
            'shield',
1161
            'info',
1162
            [
1163
                'class' => $btnBing.' ajax',
1164
                'data-title' => get_lang('CheckRequirements'),
1165
                'data-size' => 'md',
1166
                'title' => get_lang('CheckRequirements'),
1167
            ],
1168
            $includeText
1169
        );
1170
    }
1171
1172
    /**
1173
     * Generate a label if the user has been  registered in session.
1174
     *
1175
     * @return string The label
1176
     */
1177
    public static function getAlreadyRegisteredInSessionLabel()
1178
    {
1179
        $icon = '<em class="fa fa-graduation-cap"></em>';
1180
1181
        return Display::div(
1182
            $icon,
1183
            [
1184
                'class' => 'btn btn-default btn-sm registered',
1185
                'title' => get_lang("AlreadyRegisteredToSession"),
1186
            ]
1187
        );
1188
    }
1189
1190
    /**
1191
     * Get a icon for a session.
1192
     *
1193
     * @param string $sessionName The session name
1194
     *
1195
     * @return string The icon
1196
     */
1197
    public static function getSessionIcon($sessionName)
1198
    {
1199
        return Display::return_icon(
1200
            'window_list.png',
1201
            $sessionName,
1202
            null,
1203
            ICON_SIZE_MEDIUM
1204
        );
1205
    }
1206
1207
    /**
1208
     * Return Session catalog rendered view.
1209
     *
1210
     * @param array $limit
1211
     */
1212
    public static function sessionList($limit = [])
1213
    {
1214
        $date = isset($_POST['date']) ? $_POST['date'] : date('Y-m-d');
1215
        $limit = isset($limit) ? $limit : self::getLimitArray();
1216
1217
        $countSessions = self::browseSessions($date, [], false, true);
1218
        $sessions = self::browseSessions($date, $limit);
1219
1220
        $pageTotal = ceil($countSessions / $limit['length']);
1221
        // Do NOT show pagination if only one page or less
1222
        $pagination = $pageTotal > 1 ? self::getCatalogPagination($limit['current'], $limit['length'], $pageTotal) : '';
1223
        $sessionsBlocks = self::getFormattedSessionsBlock($sessions);
1224
1225
        // Get session search catalogue URL
1226
        $courseUrl = self::getCatalogUrl(
1227
            1,
1228
            $limit['length'],
1229
            null,
1230
            'subscribe'
1231
        );
1232
1233
        $tpl = new Template();
1234
        $tpl->assign('actions', self::getTabList(2));
1235
        $tpl->assign('show_courses', self::showCourses());
1236
        $tpl->assign('show_sessions', self::showSessions());
1237
        $tpl->assign('show_tutor', api_get_setting('show_session_coach') === 'true');
1238
        $tpl->assign('course_url', $courseUrl);
1239
        $tpl->assign('catalog_pagination', $pagination);
1240
        $tpl->assign('search_token', Security::get_token());
1241
        $tpl->assign('search_date', $date);
1242
        $tpl->assign('web_session_courses_ajax_url', api_get_path(WEB_AJAX_PATH).'course.ajax.php');
1243
        $tpl->assign('sessions', $sessionsBlocks);
1244
        $tpl->assign('already_subscribed_label', self::getAlreadyRegisteredInSessionLabel());
1245
        $tpl->assign('catalog_settings', self::getCatalogSearchSettings());
1246
1247
        $contentTemplate = $tpl->get_template('catalog/session_catalog.tpl');
1248
1249
        $tpl->display($contentTemplate);
1250
    }
1251
1252
    /**
1253
     * Show the Session Catalogue with filtered session by course tags.
1254
     *
1255
     * @param array $limit Limit info
1256
     */
1257
    public static function sessionsListByName(array $limit)
1258
    {
1259
        $keyword = isset($_POST['keyword']) ? $_POST['keyword'] : null;
1260
        $courseUrl = self::getCatalogUrl(
1261
            1,
1262
            $limit['length'],
1263
            null,
1264
            'subscribe'
1265
        );
1266
1267
        $sessions = self::getSessionsByName($keyword, $limit);
1268
        $sessionsBlocks = self::getFormattedSessionsBlock($sessions);
1269
1270
        $tpl = new Template();
1271
        $tpl->assign('actions', self::getTabList(2));
1272
        $tpl->assign('show_courses', self::showCourses());
1273
        $tpl->assign('show_sessions', self::showSessions());
1274
        $tpl->assign('show_tutor', api_get_setting('show_session_coach') === 'true');
1275
        $tpl->assign('course_url', $courseUrl);
1276
        $tpl->assign('already_subscribed_label', self::getAlreadyRegisteredInSessionLabel());
1277
        $tpl->assign('search_token', Security::get_token());
1278
        $tpl->assign('keyword', Security::remove_XSS($keyword));
1279
        $tpl->assign('sessions', $sessionsBlocks);
1280
        $tpl->assign('catalog_settings', self::getCatalogSearchSettings());
1281
1282
        $contentTemplate = $tpl->get_template('catalog/session_catalog.tpl');
1283
1284
        $tpl->display($contentTemplate);
1285
    }
1286
1287
    public static function getCatalogSearchSettings()
1288
    {
1289
        $settings = api_get_configuration_value('catalog_settings');
1290
        if (empty($settings)) {
1291
            // Default everything is visible
1292
            $settings = [
1293
                'sessions' => [
1294
                    'by_title' => true,
1295
                    'by_date' => true,
1296
                    'by_tag' => true,
1297
                    'show_session_info' => true,
1298
                    'show_session_date' => true,
1299
                ],
1300
            ];
1301
        }
1302
1303
        return $settings;
1304
    }
1305
1306
    /**
1307
     * @param int $active
1308
     *
1309
     * @return string
1310
     */
1311
    public static function getTabList($active = 1)
1312
    {
1313
        $pageLength = isset($_GET['pageLength']) ? (int) $_GET['pageLength'] : self::PAGE_LENGTH;
1314
1315
        $url = self::getCatalogUrl(1, $pageLength, null, 'display_sessions');
1316
        $headers = [];
1317
        if (self::showCourses()) {
1318
            $headers[] = [
1319
                'url' => api_get_self(),
1320
                'content' => get_lang('CourseManagement'),
1321
            ];
1322
        }
1323
1324
        if (self::showSessions()) {
1325
            $headers[] = [
1326
                'url' => $url,
1327
                'content' => get_lang('SessionList'),
1328
            ];
1329
        }
1330
1331
        return Display::tabsOnlyLink($headers, $active);
1332
    }
1333
1334
    /**
1335
     * Show the Session Catalogue with filtered session by course tags.
1336
     *
1337
     * @param array $limit Limit info
1338
     */
1339
    public static function sessionsListByCoursesTag(array $limit)
1340
    {
1341
        $searchTag = isset($_POST['search_tag']) ? $_POST['search_tag'] : null;
1342
        $searchDate = isset($_POST['date']) ? $_POST['date'] : date('Y-m-d');
1343
        $courseUrl = self::getCatalogUrl(
1344
            1,
1345
            $limit['length'],
1346
            null,
1347
            'subscribe'
1348
        );
1349
1350
        $sessions = self::browseSessionsByTags($searchTag, $limit);
1351
        $sessionsBlocks = self::getFormattedSessionsBlock($sessions);
1352
1353
        $tpl = new Template();
1354
        $tpl->assign('show_courses', self::showCourses());
1355
        $tpl->assign('show_sessions', self::showSessions());
1356
        $tpl->assign('show_tutor', api_get_setting('show_session_coach') === 'true');
1357
        $tpl->assign('course_url', $courseUrl);
1358
        $tpl->assign('already_subscribed_label', self::getAlreadyRegisteredInSessionLabel());
1359
        $tpl->assign('search_token', Security::get_token());
1360
        $tpl->assign('search_date', Security::remove_XSS($searchDate));
1361
        $tpl->assign('search_tag', Security::remove_XSS($searchTag));
1362
        $tpl->assign('sessions', $sessionsBlocks);
1363
1364
        $contentTemplate = $tpl->get_template('catalog/session_catalog.tpl');
1365
1366
        $tpl->display($contentTemplate);
1367
    }
1368
1369
    /**
1370
     * @return array
1371
     */
1372
    public static function getLimitArray()
1373
    {
1374
        $pageCurrent = isset($_REQUEST['pageCurrent']) ? (int) $_GET['pageCurrent'] : 1;
1375
        $pageLength = isset($_REQUEST['pageLength']) ? (int) $_GET['pageLength'] : self::PAGE_LENGTH;
1376
1377
        return [
1378
            'start' => ($pageCurrent - 1) * $pageLength,
1379
            'current' => $pageCurrent,
1380
            'length' => $pageLength,
1381
        ];
1382
    }
1383
1384
    /**
1385
     * Get the formatted data for sessions block to be displayed on Session Catalog page.
1386
     *
1387
     * @param array $sessions The session list
1388
     *
1389
     * @return array
1390
     */
1391
    public static function getFormattedSessionsBlock(array $sessions)
1392
    {
1393
        $extraFieldValue = new ExtraFieldValue('session');
1394
        $userId = api_get_user_id();
1395
        $sessionsBlocks = [];
1396
        $entityManager = Database::getManager();
1397
        $sessionRelCourseRepo = $entityManager->getRepository('ChamiloCoreBundle:SessionRelCourse');
1398
        $extraFieldRepo = $entityManager->getRepository('ChamiloCoreBundle:ExtraField');
1399
        $extraFieldRelTagRepo = $entityManager->getRepository('ChamiloCoreBundle:ExtraFieldRelTag');
1400
1401
        $tagsField = $extraFieldRepo->findOneBy([
1402
            'extraFieldType' => Chamilo\CoreBundle\Entity\ExtraField::COURSE_FIELD_TYPE,
1403
            'variable' => 'tags',
1404
        ]);
1405
1406
        /** @var \Chamilo\CoreBundle\Entity\Session $session */
1407
        foreach ($sessions as $session) {
1408
            $sessionDates = SessionManager::parseSessionDates([
1409
                'display_start_date' => $session->getDisplayStartDate(),
1410
                'display_end_date' => $session->getDisplayEndDate(),
1411
                'access_start_date' => $session->getAccessStartDate(),
1412
                'access_end_date' => $session->getAccessEndDate(),
1413
                'coach_access_start_date' => $session->getCoachAccessStartDate(),
1414
                'coach_access_end_date' => $session->getCoachAccessEndDate(),
1415
            ]);
1416
1417
            $imageField = $extraFieldValue->get_values_by_handler_and_field_variable(
1418
                $session->getId(),
1419
                'image'
1420
            );
1421
            $sessionCourseTags = [];
1422
            if (!is_null($tagsField)) {
1423
                $sessionRelCourses = $sessionRelCourseRepo->findBy([
1424
                    'session' => $session,
1425
                ]);
1426
                /** @var SessionRelCourse $sessionRelCourse */
1427
                foreach ($sessionRelCourses as $sessionRelCourse) {
1428
                    $courseTags = $extraFieldRelTagRepo->getTags(
1429
                        $tagsField,
1430
                        $sessionRelCourse->getCourse()->getId()
1431
                    );
1432
                    /** @var Tag $tag */
1433
                    foreach ($courseTags as $tag) {
1434
                        $sessionCourseTags[] = $tag->getTag();
1435
                    }
1436
                }
1437
            }
1438
1439
            if (!empty($sessionCourseTags)) {
1440
                $sessionCourseTags = array_unique($sessionCourseTags);
1441
            }
1442
1443
            /** @var SequenceResourceRepository $repo */
1444
            $repo = $entityManager->getRepository('ChamiloCoreBundle:SequenceResource');
1445
            $sequences = $repo->getRequirementsAndDependenciesWithinSequences(
1446
                $session->getId(),
1447
                SequenceResource::SESSION_TYPE
1448
            );
1449
1450
            $hasRequirements = false;
1451
            foreach ($sequences as $sequence) {
1452
                if (count($sequence['requirements']) === 0) {
1453
                    continue;
1454
                }
1455
                $hasRequirements = true;
1456
                break;
1457
            }
1458
            $cat = $session->getCategory();
1459
            if (empty($cat)) {
1460
                $cat = null;
1461
                $catName = '';
1462
            } else {
1463
                $catName = $cat->getName();
1464
            }
1465
1466
            $generalCoach = $session->getGeneralCoach();
1467
            $coachId = $generalCoach ? $generalCoach->getId() : 0;
1468
            $coachName = $generalCoach ? UserManager::formatUserFullName($session->getGeneralCoach()) : '';
1469
1470
            $actions = null;
1471
            if (api_is_platform_admin()) {
1472
                $actions = api_get_path(WEB_CODE_PATH).'session/resume_session.php?id_session='.$session->getId();
1473
            }
1474
1475
            $plugin = \BuyCoursesPlugin::create();
1476
            $isThisSessionOnSale = $plugin->getBuyCoursePluginPrice($session);
1477
1478
            $sessionsBlock = [
1479
                'id' => $session->getId(),
1480
                'name' => $session->getName(),
1481
                'image' => isset($imageField['value']) ? $imageField['value'] : null,
1482
                'nbr_courses' => $session->getNbrCourses(),
1483
                'nbr_users' => $session->getNbrUsers(),
1484
                'coach_id' => $coachId,
1485
                'coach_url' => $generalCoach
1486
                    ? api_get_path(WEB_AJAX_PATH).'user_manager.ajax.php?a=get_user_popup&user_id='.$coachId
1487
                    : '',
1488
                'coach_name' => $coachName,
1489
                'coach_avatar' => UserManager::getUserPicture(
1490
                    $coachId,
1491
                    USER_IMAGE_SIZE_SMALL
1492
                ),
1493
                'is_subscribed' => SessionManager::isUserSubscribedAsStudent(
1494
                    $session->getId(),
1495
                    $userId
1496
                ),
1497
                'icon' => self::getSessionIcon($session->getName()),
1498
                'date' => $sessionDates['display'],
1499
                'price' => !empty($isThisSessionOnSale['html']) ? $isThisSessionOnSale['html'] : '',
1500
                'subscribe_button' => isset($isThisSessionOnSale['buy_button']) ? $isThisSessionOnSale['buy_button'] : self::getRegisteredInSessionButton(
1501
                    $session->getId(),
1502
                    $session->getName(),
1503
                    $hasRequirements
1504
                ),
1505
                'show_description' => $session->getShowDescription(),
1506
                'description' => $session->getDescription(),
1507
                'category' => $catName,
1508
                'tags' => $sessionCourseTags,
1509
                'edit_actions' => $actions,
1510
                'duration' => SessionManager::getDayLeftInSession(
1511
                    ['id' => $session->getId(), 'duration' => $session->getDuration()],
1512
                    $userId
1513
                ),
1514
            ];
1515
1516
            $sessionsBlocks[] = array_merge($sessionsBlock, $sequences);
1517
        }
1518
1519
        return $sessionsBlocks;
1520
    }
1521
1522
    /**
1523
     * Get Pagination HTML div.
1524
     *
1525
     * @param int    $pageCurrent
1526
     * @param int    $pageLength
1527
     * @param int    $pageTotal
1528
     * @param string $categoryCode
1529
     * @param string $action
1530
     * @param array  $fields
1531
     *
1532
     * @return string
1533
     */
1534
    public static function getCatalogPagination($pageCurrent, $pageLength, $pageTotal, $categoryCode = '', $action = '', $fields = [])
1535
    {
1536
        // Start empty html
1537
        $pageDiv = '';
1538
        $html = '';
1539
        $pageBottom = max(1, $pageCurrent - 3);
1540
        $pageTop = min($pageTotal, $pageCurrent + 3);
1541
1542
        if ($pageBottom > 1) {
1543
            $pageDiv .= self::getPageNumberItem(1, $pageLength);
1544
            if ($pageBottom > 2) {
1545
                $pageDiv .= self::getPageNumberItem(
1546
                    $pageBottom - 1,
1547
                    $pageLength,
1548
                    null,
1549
                    '...',
1550
                    $categoryCode,
1551
                    $action,
1552
                    $fields
1553
                );
1554
            }
1555
        }
1556
1557
        // For each page add its page button to html
1558
        for ($i = $pageBottom; $i <= $pageTop; $i++) {
1559
            if ($i === $pageCurrent) {
1560
                $pageItemAttributes = ['class' => 'active'];
1561
            } else {
1562
                $pageItemAttributes = [];
1563
            }
1564
            $pageDiv .= self::getPageNumberItem(
1565
                $i,
1566
                $pageLength,
1567
                $pageItemAttributes,
1568
                '',
1569
                $categoryCode,
1570
                $action,
1571
                $fields
1572
            );
1573
        }
1574
1575
        // Check if current page is the last page
1576
        if ($pageTop < $pageTotal) {
1577
            if ($pageTop < ($pageTotal - 1)) {
1578
                $pageDiv .= self::getPageNumberItem(
1579
                    $pageTop + 1,
1580
                    $pageLength,
1581
                    null,
1582
                    '...',
1583
                    $categoryCode,
1584
                    $action,
1585
                    $fields
1586
                );
1587
            }
1588
            $pageDiv .= self::getPageNumberItem($pageTotal, $pageLength, [], '', $categoryCode, $action, $fields);
1589
        }
1590
1591
        // Complete pagination html
1592
        $pageDiv = Display::tag('ul', $pageDiv, ['class' => 'pagination']);
1593
        $html .= '<nav>'.$pageDiv.'</nav>';
1594
1595
        return $html;
1596
    }
1597
1598
    /**
1599
     * Get li HTML of page number.
1600
     *
1601
     * @param $pageNumber
1602
     * @param $pageLength
1603
     * @param array  $liAttributes
1604
     * @param string $content
1605
     * @param string $categoryCode
1606
     * @param string $action
1607
     * @param array  $fields
1608
     *
1609
     * @return string
1610
     */
1611
    public static function getPageNumberItem(
1612
        $pageNumber,
1613
        $pageLength,
1614
        $liAttributes = [],
1615
        $content = '',
1616
        $categoryCode = '',
1617
        $action = '',
1618
        $fields = []
1619
    ) {
1620
        // Get page URL
1621
        $url = self::getCatalogUrl($pageNumber, $pageLength, $categoryCode, $action, $fields);
1622
1623
        // If is current page ('active' class) clear URL
1624
        if (isset($liAttributes) && is_array($liAttributes) && isset($liAttributes['class'])) {
1625
            if (strpos('active', $liAttributes['class']) !== false) {
1626
                $url = '';
1627
            }
1628
        }
1629
1630
        $content = !empty($content) ? $content : $pageNumber;
1631
1632
        return Display::tag(
1633
            'li',
1634
            Display::url(
1635
                $content,
1636
                $url
1637
            ),
1638
            $liAttributes
1639
        );
1640
    }
1641
1642
    /**
1643
     * Return URL to course catalog.
1644
     *
1645
     * @param int    $pageCurrent
1646
     * @param int    $pageLength
1647
     * @param string $categoryCode
1648
     * @param string $action
1649
     * @param array  $extraFields
1650
     *
1651
     * @return string
1652
     */
1653
    public static function getCatalogUrl(
1654
        $pageCurrent,
1655
        $pageLength,
1656
        $categoryCode = null,
1657
        $action = null,
1658
        $extraFields = []
1659
    ) {
1660
        $requestAction = isset($_REQUEST['action']) ? Security::remove_XSS($_REQUEST['action']) : null;
1661
        $action = isset($action) ? Security::remove_XSS($action) : $requestAction;
1662
        $searchTerm = isset($_REQUEST['search_term']) ? Security::remove_XSS($_REQUEST['search_term']) : null;
1663
1664
        if ($action === 'subscribe_user_with_password') {
1665
            $action = 'subscribe';
1666
        }
1667
1668
        $categoryCode = !empty($categoryCode) ? Security::remove_XSS($categoryCode) : 'ALL';
1669
1670
        // Start URL with params
1671
        $pageUrl = api_get_self().
1672
            '?action='.$action.
1673
            '&category_code='.$categoryCode.
1674
            '&pageCurrent='.$pageCurrent.
1675
            '&pageLength='.$pageLength;
1676
1677
        if (!empty($extraFields)) {
1678
            $params = [];
1679
            foreach ($extraFields as $variable => $value) {
1680
                $params[Security::remove_XSS($variable)] = Security::remove_XSS($value);
1681
            }
1682
            if (!empty($params)) {
1683
                $pageUrl .= '&'.http_build_query($params);
1684
            }
1685
        }
1686
1687
        switch ($action) {
1688
            case 'subscribe':
1689
                // for search
1690
                $pageUrl .=
1691
                    '&search_term='.$searchTerm.
1692
                    '&sec_token='.Security::getTokenFromSession();
1693
                break;
1694
            case 'display_courses':
1695
            default:
1696
                break;
1697
        }
1698
1699
        return $pageUrl;
1700
    }
1701
}
1702