Passed
Push — 1.11.x ( bce6cd...c146d9 )
by Angel Fernando Quiroz
12:25
created

main/inc/lib/sessionmanager.lib.php (3 issues)

1
<?php
2
3
/* For licensing terms, see /license.txt */
4
5
use Chamilo\CoreBundle\Entity\Course;
6
use Chamilo\CoreBundle\Entity\ExtraField;
7
use Chamilo\CoreBundle\Entity\Repository\SequenceResourceRepository;
8
use Chamilo\CoreBundle\Entity\SequenceResource;
9
use Chamilo\CoreBundle\Entity\Session;
10
use Chamilo\CoreBundle\Entity\SessionRelCourse;
11
use Chamilo\CoreBundle\Entity\SessionRelCourseRelUser;
12
use Chamilo\CoreBundle\Entity\SessionRelUser;
13
use Chamilo\UserBundle\Entity\User;
14
use ExtraField as ExtraFieldModel;
15
use Monolog\Logger;
16
17
/**
18
 * Class SessionManager.
19
 *
20
 * This is the session library for Chamilo
21
 * (as in courses>session, not as in PHP session)
22
 * All main sessions functions should be placed here.
23
 * This class provides methods for sessions management.
24
 * Include/require it in your code to use its features.
25
 */
26
class SessionManager
27
{
28
    const STATUS_PLANNED = 1;
29
    const STATUS_PROGRESS = 2;
30
    const STATUS_FINISHED = 3;
31
    const STATUS_CANCELLED = 4;
32
33
    public static $_debug = false;
34
35
    /**
36
     * Constructor.
37
     */
38
    public function __construct()
39
    {
40
    }
41
42
    /**
43
     * Fetches a session from the database.
44
     *
45
     * @param int $id Session Id
46
     *
47
     * @return array Session details
48
     */
49
    public static function fetch($id)
50
    {
51
        $em = Database::getManager();
52
53
        if (empty($id)) {
54
            return [];
55
        }
56
57
        /** @var Session $session */
58
        $session = $em->find('ChamiloCoreBundle:Session', $id);
59
60
        if (!$session) {
61
            return [];
62
        }
63
64
        $result = [
65
            'id' => $session->getId(),
66
            'id_coach' => $session->getGeneralCoach() ? $session->getGeneralCoach()->getId() : null,
67
            'session_category_id' => $session->getCategory() ? $session->getCategory()->getId() : null,
68
            'name' => $session->getName(),
69
            'description' => $session->getDescription(),
70
            'show_description' => $session->getShowDescription(),
71
            'duration' => $session->getDuration(),
72
            'nbr_courses' => $session->getNbrCourses(),
73
            'nbr_users' => $session->getNbrUsers(),
74
            'nbr_classes' => $session->getNbrClasses(),
75
            'session_admin_id' => $session->getSessionAdminId(),
76
            'visibility' => $session->getVisibility(),
77
            'promotion_id' => $session->getPromotionId(),
78
            'display_start_date' => $session->getDisplayStartDate()
79
                ? $session->getDisplayStartDate()->format('Y-m-d H:i:s')
80
                : null,
81
            'display_end_date' => $session->getDisplayEndDate()
82
                ? $session->getDisplayEndDate()->format('Y-m-d H:i:s')
83
                : null,
84
            'access_start_date' => $session->getAccessStartDate()
85
                ? $session->getAccessStartDate()->format('Y-m-d H:i:s')
86
                : null,
87
            'access_end_date' => $session->getAccessEndDate()
88
                ? $session->getAccessEndDate()->format('Y-m-d H:i:s')
89
                : null,
90
            'coach_access_start_date' => $session->getCoachAccessStartDate()
91
                ? $session->getCoachAccessStartDate()->format('Y-m-d H:i:s')
92
                : null,
93
            'coach_access_end_date' => $session->getCoachAccessEndDate()
94
                ? $session->getCoachAccessEndDate()->format('Y-m-d H:i:s')
95
                : null,
96
            'send_subscription_notification' => $session->getSendSubscriptionNotification(),
97
        ];
98
99
        if (api_get_configuration_value('allow_session_status')) {
100
            $table = Database::get_main_table(TABLE_MAIN_SESSION);
101
            $sql = "SELECT status FROM $table WHERE id = $id";
102
            $resultQuery = Database::query($sql);
103
            $row = Database::fetch_array($resultQuery);
104
            $result['status'] = $row['status'];
105
            $result['status_label'] = self::getStatusLabel($row['status']);
106
        }
107
108
        // Converted to local values
109
        $variables = [
110
            'display_start_date',
111
            'display_end_date',
112
            'access_start_date',
113
            'access_end_date',
114
            'coach_access_start_date',
115
            'coach_access_end_date',
116
        ];
117
118
        foreach ($variables as $value) {
119
            $result[$value.'_to_local_time'] = null;
120
            if (!empty($result[$value])) {
121
                $result[$value.'_to_local_time'] = api_get_local_time($result[$value]);
122
            }
123
        }
124
125
        return $result;
126
    }
127
128
    /**
129
     * Create a session.
130
     *
131
     * @author Carlos Vargas <[email protected]>, from existing code
132
     *
133
     * @param string $name
134
     * @param string $startDate                    (YYYY-MM-DD hh:mm:ss)
135
     * @param string $endDate                      (YYYY-MM-DD hh:mm:ss)
136
     * @param string $displayStartDate             (YYYY-MM-DD hh:mm:ss)
137
     * @param string $displayEndDate               (YYYY-MM-DD hh:mm:ss)
138
     * @param string $coachStartDate               (YYYY-MM-DD hh:mm:ss)
139
     * @param string $coachEndDate                 (YYYY-MM-DD hh:mm:ss)
140
     * @param mixed  $coachId                      If int, this is the session coach id,
141
     *                                             if string, the coach ID will be looked for from the user table
142
     * @param int    $sessionCategoryId            ID of the session category in which this session is registered
143
     * @param int    $visibility                   Visibility after end date (0 = read-only, 1 = invisible, 2 = accessible)
144
     * @param bool   $fixSessionNameIfExists
145
     * @param string $duration
146
     * @param string $description                  Optional. The session description
147
     * @param int    $showDescription              Optional. Whether show the session description
148
     * @param array  $extraFields
149
     * @param int    $sessionAdminId               Optional. If this sessions was created by a session admin, assign it to him
150
     * @param bool   $sendSubscriptionNotification Optional.
151
     *                                             Whether send a mail notification to users being subscribed
152
     * @param int    $accessUrlId                  Optional.
153
     * @param int    $status
154
     *
155
     * @return mixed Session ID on success, error message otherwise
156
     *
157
     * @todo   use an array to replace all this parameters or use the model.lib.php ...
158
     */
159
    public static function create_session(
160
        $name,
161
        $startDate,
162
        $endDate,
163
        $displayStartDate,
164
        $displayEndDate,
165
        $coachStartDate,
166
        $coachEndDate,
167
        $coachId,
168
        $sessionCategoryId,
169
        $visibility = 1,
170
        $fixSessionNameIfExists = false,
171
        $duration = null,
172
        $description = null,
173
        $showDescription = 0,
174
        $extraFields = [],
175
        $sessionAdminId = 0,
176
        $sendSubscriptionNotification = false,
177
        $accessUrlId = 0,
178
        $status = 0
179
    ) {
180
        global $_configuration;
181
182
        // Check portal limits
183
        $accessUrlId = api_is_multiple_url_enabled()
184
            ? (empty($accessUrlId) ? api_get_current_access_url_id() : (int) $accessUrlId)
185
            : 1;
186
187
        if (isset($_configuration[$accessUrlId]) &&
188
            is_array($_configuration[$accessUrlId]) &&
189
            isset($_configuration[$accessUrlId]['hosting_limit_sessions']) &&
190
            $_configuration[$accessUrlId]['hosting_limit_sessions'] > 0
191
        ) {
192
            $num = self::count_sessions();
193
            if ($num >= $_configuration[$accessUrlId]['hosting_limit_sessions']) {
194
                api_warn_hosting_contact('hosting_limit_sessions');
195
196
                return get_lang('PortalSessionsLimitReached');
197
            }
198
        }
199
200
        $name = Database::escape_string(trim($name));
201
        $sessionCategoryId = (int) $sessionCategoryId;
202
        $visibility = (int) $visibility;
203
        $tbl_session = Database::get_main_table(TABLE_MAIN_SESSION);
204
205
        $startDate = Database::escape_string($startDate);
206
        $endDate = Database::escape_string($endDate);
207
208
        if (empty($name)) {
209
            $msg = get_lang('SessionNameIsRequired');
210
211
            return $msg;
212
        } elseif (!empty($startDate) && !api_is_valid_date($startDate, 'Y-m-d H:i') &&
213
            !api_is_valid_date($startDate, 'Y-m-d H:i:s')
214
        ) {
215
            $msg = get_lang('InvalidStartDate');
216
217
            return $msg;
218
        } elseif (!empty($endDate) && !api_is_valid_date($endDate, 'Y-m-d H:i') &&
219
            !api_is_valid_date($endDate, 'Y-m-d H:i:s')
220
        ) {
221
            $msg = get_lang('InvalidEndDate');
222
223
            return $msg;
224
        } elseif (!empty($startDate) && !empty($endDate) && $startDate >= $endDate) {
225
            $msg = get_lang('StartDateShouldBeBeforeEndDate');
226
227
            return $msg;
228
        } else {
229
            $ready_to_create = false;
230
            if ($fixSessionNameIfExists) {
231
                $name = self::generateNextSessionName($name);
232
                if ($name) {
233
                    $ready_to_create = true;
234
                } else {
235
                    $msg = get_lang('SessionNameAlreadyExists');
236
237
                    return $msg;
238
                }
239
            } else {
240
                $rs = Database::query("SELECT 1 FROM $tbl_session WHERE name='".$name."'");
241
                if (Database::num_rows($rs)) {
242
                    $msg = get_lang('SessionNameAlreadyExists');
243
244
                    return $msg;
245
                }
246
                $ready_to_create = true;
247
            }
248
249
            if ($ready_to_create) {
250
                $sessionAdminId = !empty($sessionAdminId) ? $sessionAdminId : api_get_user_id();
251
                $values = [
252
                    'name' => $name,
253
                    'id_coach' => $coachId,
254
                    'session_admin_id' => $sessionAdminId,
255
                    'visibility' => $visibility,
256
                    'description' => $description,
257
                    'show_description' => $showDescription,
258
                    'send_subscription_notification' => (int) $sendSubscriptionNotification,
259
                ];
260
261
                if (!empty($startDate)) {
262
                    $values['access_start_date'] = api_get_utc_datetime($startDate);
263
                }
264
265
                if (!empty($endDate)) {
266
                    $values['access_end_date'] = api_get_utc_datetime($endDate);
267
                }
268
269
                if (!empty($displayStartDate)) {
270
                    $values['display_start_date'] = api_get_utc_datetime($displayStartDate);
271
                }
272
273
                if (!empty($displayEndDate)) {
274
                    $values['display_end_date'] = api_get_utc_datetime($displayEndDate);
275
                }
276
277
                if (!empty($coachStartDate)) {
278
                    $values['coach_access_start_date'] = api_get_utc_datetime($coachStartDate);
279
                }
280
                if (!empty($coachEndDate)) {
281
                    $values['coach_access_end_date'] = api_get_utc_datetime($coachEndDate);
282
                }
283
284
                if (!empty($sessionCategoryId)) {
285
                    $values['session_category_id'] = $sessionCategoryId;
286
                }
287
288
                if (api_get_configuration_value('allow_session_status')) {
289
                    $values['status'] = $status;
290
                }
291
292
                $session_id = Database::insert($tbl_session, $values);
293
                $duration = (int) $duration;
294
295
                if (!empty($duration)) {
296
                    $sql = "UPDATE $tbl_session SET
297
                        access_start_date = NULL,
298
                        access_end_date = NULL,
299
                        display_start_date = NULL,
300
                        display_end_date = NULL,
301
                        coach_access_start_date = NULL,
302
                        coach_access_end_date = NULL,
303
                        duration = $duration
304
                    WHERE id = $session_id";
305
                    Database::query($sql);
306
                } else {
307
                    $sql = "UPDATE $tbl_session
308
                        SET duration = 0
309
                        WHERE id = $session_id";
310
                    Database::query($sql);
311
                }
312
313
                if (!empty($session_id)) {
314
                    $extraFields['item_id'] = $session_id;
315
                    $sessionFieldValue = new ExtraFieldValue('session');
316
                    $sessionFieldValue->saveFieldValues($extraFields);
317
318
                    // Adding to the correct URL
319
                    UrlManager::add_session_to_url($session_id, $accessUrlId);
320
321
                    // add event to system log
322
                    Event::addEvent(
323
                        LOG_SESSION_CREATE,
324
                        LOG_SESSION_ID,
325
                        $session_id,
326
                        api_get_utc_datetime(),
327
                        api_get_user_id()
328
                    );
329
                }
330
331
                return $session_id;
332
            }
333
        }
334
    }
335
336
    /**
337
     * @param string $name
338
     *
339
     * @return bool
340
     */
341
    public static function sessionNameExists($name)
342
    {
343
        $name = Database::escape_string($name);
344
        $sql = "SELECT COUNT(*) as count FROM ".Database::get_main_table(TABLE_MAIN_SESSION)."
345
                WHERE name = '$name'";
346
        $result = Database::fetch_array(Database::query($sql));
347
348
        return $result['count'] > 0;
349
    }
350
351
    /**
352
     * @param string $where_condition
353
     *
354
     * @return mixed
355
     */
356
    public static function get_count_admin($where_condition = '')
357
    {
358
        $tbl_session = Database::get_main_table(TABLE_MAIN_SESSION);
359
        $tbl_session_category = Database::get_main_table(TABLE_MAIN_SESSION_CATEGORY);
360
        $tbl_user = Database::get_main_table(TABLE_MAIN_USER);
361
        $table_access_url_rel_session = Database::get_main_table(TABLE_MAIN_ACCESS_URL_REL_SESSION);
362
        $tbl_session_rel_user = Database::get_main_table(TABLE_MAIN_SESSION_USER);
363
364
        $where = 'WHERE 1=1 ';
365
        $user_id = api_get_user_id();
366
        $extraJoin = '';
367
368
        if (api_is_session_admin() &&
369
            api_get_setting('allow_session_admins_to_manage_all_sessions') == 'false'
370
        ) {
371
            $where .= " AND (
372
                            s.session_admin_id = $user_id  OR
373
                            sru.user_id = '$user_id' AND
374
                            sru.relation_type = '".SESSION_RELATION_TYPE_RRHH."'
375
                            )
376
                      ";
377
378
            $extraJoin = " INNER JOIN $tbl_session_rel_user sru
379
                           ON sru.session_id = s.id ";
380
        }
381
382
        $today = api_get_utc_datetime();
383
        $today = api_strtotime($today, 'UTC');
384
        $today = date('Y-m-d', $today);
385
386
        if (!empty($where_condition)) {
387
            $where_condition = str_replace("(  session_active = ':'  )", '1=1', $where_condition);
388
389
            $where_condition = str_replace('category_name', 'sc.name', $where_condition);
390
            $where_condition = str_replace(
391
                ["AND session_active = '1'  )", " AND (  session_active = '1'  )"],
392
                [') GROUP BY s.name HAVING session_active = 1 ', " GROUP BY s.name HAVING session_active = 1 "],
393
                $where_condition
394
            );
395
            $where_condition = str_replace(
396
                ["AND session_active = '0'  )", " AND (  session_active = '0'  )"],
397
                [') GROUP BY s.name HAVING session_active = 0 ', " GROUP BY s.name HAVING session_active = '0' "],
398
                $where_condition
399
            );
400
        } else {
401
            $where_condition = " AND 1 = 1";
402
        }
403
404
        $courseCondition = null;
405
        if (strpos($where_condition, 'c.id')) {
406
            $table = Database::get_main_table(TABLE_MAIN_SESSION_COURSE);
407
            $tableCourse = Database::get_main_table(TABLE_MAIN_COURSE);
408
            $courseCondition = " INNER JOIN $table course_rel_session
409
                                 ON (s.id = course_rel_session.session_id)
410
                                 INNER JOIN $tableCourse c
411
                                 ON (course_rel_session.c_id = c.id)
412
                                ";
413
        }
414
415
        $sql = "SELECT COUNT(id) as total_rows FROM (
416
                SELECT DISTINCT
417
                 IF (
418
					(s.access_start_date <= '$today' AND '$today' <= s.access_end_date) OR
419
                    (s.access_start_date IS NULL AND s.access_end_date IS NULL ) OR
420
					(s.access_start_date <= '$today' AND s.access_end_date IS NULL) OR
421
					('$today' <= s.access_end_date AND s.access_start_date IS NULL)
422
				, 1, 0) as session_active,
423
                s.id
424
                FROM $tbl_session s
425
                LEFT JOIN $tbl_session_category sc
426
                ON s.session_category_id = sc.id
427
                INNER JOIN $tbl_user u
428
                ON s.id_coach = u.id
429
                $courseCondition
430
                $extraJoin
431
                $where $where_condition ) as session_table";
432
433
        if (api_is_multiple_url_enabled()) {
434
            $access_url_id = api_get_current_access_url_id();
435
            if ($access_url_id != -1) {
436
                $where .= " AND ar.access_url_id = $access_url_id ";
437
438
                $sql = "SELECT count(id) as total_rows FROM (
439
                SELECT DISTINCT
440
                  IF (
441
					(s.access_start_date <= '$today' AND '$today' <= s.access_end_date) OR
442
                    (s.access_start_date IS NULL AND s.access_end_date IS NULL) OR
443
					(s.access_start_date <= '$today' AND s.access_end_date IS NULL) OR
444
					('$today' <= s.access_end_date AND s.access_start_date IS NULL)
445
				, 1, 0)
446
				as session_active,
447
				s.id
448
                FROM $tbl_session s
449
                    LEFT JOIN  $tbl_session_category sc
450
                    ON s.session_category_id = sc.id
451
                    INNER JOIN $tbl_user u ON s.id_coach = u.user_id
452
                    INNER JOIN $table_access_url_rel_session ar
453
                    ON ar.session_id = s.id
454
                    $courseCondition
455
                    $extraJoin
456
                $where $where_condition) as session_table";
457
            }
458
        }
459
460
        $result_rows = Database::query($sql);
461
        $row = Database::fetch_array($result_rows);
462
        $num = $row['total_rows'];
463
464
        return $num;
465
    }
466
467
    /**
468
     * Get session list for a session admin or platform admin.
469
     *
470
     * @param int    $userId   User Id for the session admin.
471
     * @param array  $options  Order and limit keys.
472
     * @param bool   $getCount Whether to get all the results or only the count.
473
     * @param array  $columns  Columns from jqGrid.
474
     * @param string $listType
475
     *
476
     * @return array
477
     */
478
    public static function getSessionsForAdmin(
479
        $userId,
480
        $options = [],
481
        $getCount = false,
482
        $columns = [],
483
        $listType = 'all'
484
    ) {
485
        $tblSession = Database::get_main_table(TABLE_MAIN_SESSION);
486
        $sessionCategoryTable = Database::get_main_table(TABLE_MAIN_SESSION_CATEGORY);
487
488
        $where = 'WHERE 1 = 1 ';
489
490
        $userId = (int) $userId;
491
492
        if (!api_is_platform_admin()) {
493
            if (api_is_session_admin() &&
494
                'false' === api_get_setting('allow_session_admins_to_manage_all_sessions')
495
            ) {
496
                $where .= " AND s.session_admin_id = $userId ";
497
            }
498
        }
499
500
        if (!api_is_platform_admin() &&
501
            api_is_teacher() &&
502
            'true' === api_get_setting('allow_teachers_to_create_sessions')
503
        ) {
504
            $where .= " AND s.id_coach = $userId ";
505
        }
506
507
        $extraFieldModel = new ExtraFieldModel('session');
508
        $conditions = $extraFieldModel->parseConditions($options);
509
510
        $sqlInjectJoins = $conditions['inject_joins'];
511
        $where .= $conditions['where'];
512
        $sqlInjectWhere = $conditions['inject_where'];
513
        $injectExtraFields = $conditions['inject_extra_fields'];
514
        $order = $conditions['order'];
515
        $limit = $conditions['limit'];
516
517
        $isMakingOrder = false;
518
        $showCountUsers = false;
519
520
        if (true === $getCount) {
521
            $select = ' SELECT count(DISTINCT s.id) as total_rows ';
522
        } else {
523
            if (!empty($columns['column_model'])) {
524
                foreach ($columns['column_model'] as $column) {
525
                    if ('users' == $column['name']) {
526
                        $showCountUsers = true;
527
                    }
528
                }
529
            }
530
531
            $select =
532
                "SELECT DISTINCT
533
                     s.name,
534
                     s.display_start_date,
535
                     s.display_end_date,
536
                     access_start_date,
537
                     access_end_date,
538
                     s.visibility,
539
                     s.session_category_id,
540
                     $injectExtraFields
541
                     s.id
542
             ";
543
544
            if ($showCountUsers) {
545
                $select .= ', count(su.user_id) users';
546
            }
547
548
            if (api_get_configuration_value('allow_session_status')) {
549
                $select .= ', status';
550
            }
551
552
            if (isset($options['order'])) {
553
                $isMakingOrder = 0 === strpos($options['order'], 'category_name');
554
            }
555
        }
556
557
        $isFilteringSessionCategory = strpos($where, 'category_name') !== false;
558
        $isFilteringSessionCategoryWithName = strpos($where, 'sc.name') !== false;
559
560
        if ($isMakingOrder || $isFilteringSessionCategory || $isFilteringSessionCategoryWithName) {
561
            $sqlInjectJoins .= " LEFT JOIN $sessionCategoryTable sc ON s.session_category_id = sc.id ";
562
563
            if ($isFilteringSessionCategory) {
564
                $where = str_replace('category_name', 'sc.name', $where);
565
            }
566
567
            if ($isMakingOrder) {
568
                $order = str_replace('category_name', 'sc.name', $order);
569
            }
570
        }
571
572
        if ($showCountUsers) {
573
            $tblSessionRelUser = Database::get_main_table(TABLE_MAIN_SESSION_USER);
574
            $sqlInjectJoins .= " LEFT JOIN $tblSessionRelUser su ON (su.session_id = s.id)";
575
        }
576
577
        $query = "$select FROM $tblSession s $sqlInjectJoins $where $sqlInjectWhere";
578
579
        if (api_is_multiple_url_enabled()) {
580
            $tblAccessUrlRelSession = Database::get_main_table(TABLE_MAIN_ACCESS_URL_REL_SESSION);
581
            $accessUrlId = api_get_current_access_url_id();
582
583
            if ($accessUrlId != -1) {
584
                $where .= " AND ar.access_url_id = $accessUrlId ";
585
                $query = "$select
586
                    FROM $tblSession s $sqlInjectJoins
587
                    INNER JOIN $tblAccessUrlRelSession ar
588
                    ON (ar.session_id = s.id) $where";
589
            }
590
        }
591
592
        $date = api_get_utc_datetime();
593
594
        switch ($listType) {
595
            case 'all':
596
                break;
597
            case 'active':
598
                $query .= "AND (
599
                    (s.access_end_date IS NULL)
600
                    OR
601
                    (
602
                    s.access_start_date IS NOT NULL AND
603
                    s.access_end_date IS NOT NULL AND
604
                    s.access_start_date <= '$date' AND s.access_end_date >= '$date')
605
                    OR
606
                    (
607
                        s.access_start_date IS NULL AND
608
                        s.access_end_date IS NOT NULL AND
609
                        s.access_end_date >= '$date'
610
                    )
611
                )";
612
                break;
613
            case 'close':
614
                $query .= "AND (
615
                    (
616
                    s.access_start_date IS NOT NULL AND
617
                    s.access_end_date IS NOT NULL AND
618
                    s.access_start_date <= '$date' AND s.access_end_date <= '$date')
619
                    OR
620
                    (
621
                        s.access_start_date IS NULL AND
622
                        s.access_end_date IS NOT NULL AND
623
                        s.access_end_date <= '$date'
624
                    )
625
                )";
626
                break;
627
        }
628
629
        if ($showCountUsers) {
630
            $query .= ' GROUP by s.id';
631
        }
632
633
        $allowOrder = api_get_configuration_value('session_list_order');
634
635
        if ($allowOrder) {
636
            $order = ' ORDER BY position ASC';
637
        }
638
639
        $query .= $order;
640
        $query .= $limit;
641
        $result = Database::query($query);
642
643
        $sessions = Database::store_result($result, 'ASSOC');
644
645
        if ('all' === $listType) {
646
            if ($getCount) {
647
                return $sessions[0]['total_rows'];
648
            }
649
650
            return $sessions;
651
        }
652
653
        return $sessions;
654
    }
655
656
    /**
657
     * Gets the admin session list callback of the session/session_list.php page.
658
     *
659
     * @param array  $options           order and limit keys
660
     * @param bool   $getCount          Whether to get all the results or only the count
661
     * @param array  $columns
662
     * @param array  $extraFieldsToLoad
663
     * @param string $listType
664
     *
665
     * @return mixed Integer for number of rows, or array of results
666
     * @assert ([],true) !== false
667
     */
668
    public static function formatSessionsAdminForGrid(
669
        $options = [],
670
        $getCount = false,
671
        $columns = [],
672
        $extraFieldsToLoad = [],
673
        $listType = 'all'
674
    ) {
675
        $showCountUsers = false;
676
        if (!$getCount && !empty($columns['column_model'])) {
677
            foreach ($columns['column_model'] as $column) {
678
                if ('users' === $column['name']) {
679
                    $showCountUsers = true;
680
                }
681
            }
682
        }
683
684
        $userId = api_get_user_id();
685
        $sessions = self::getSessionsForAdmin($userId, $options, $getCount, $columns, $listType);
686
        if ($getCount) {
687
            return (int) $sessions;
688
        }
689
690
        $formattedSessions = [];
691
        $categories = self::get_all_session_category();
692
        $orderedCategories = [];
693
        if (!empty($categories)) {
694
            foreach ($categories as $category) {
695
                $orderedCategories[$category['id']] = $category['name'];
696
            }
697
        }
698
699
        $activeIcon = Display::return_icon('accept.png', get_lang('Active'));
700
        $inactiveIcon = Display::return_icon('error.png', get_lang('Inactive'));
701
        $webPath = api_get_path(WEB_PATH);
702
703
        foreach ($sessions as $session) {
704
            if ($showCountUsers) {
705
                $session['users'] = self::get_users_by_session($session['id'], 0, true);
706
            }
707
            $url = $webPath.'main/session/resume_session.php?id_session='.$session['id'];
708
            if ($extraFieldsToLoad || api_is_drh()) {
709
                $url = $webPath.'session/'.$session['id'].'/about/';
710
            }
711
712
            $session['name'] = Display::url($session['name'], $url);
713
714
            if (!empty($extraFieldsToLoad)) {
715
                foreach ($extraFieldsToLoad as $field) {
716
                    $extraFieldValue = new ExtraFieldValue('session');
717
                    $fieldData = $extraFieldValue->getAllValuesByItemAndField(
718
                        $session['id'],
719
                        $field['id']
720
                    );
721
                    $fieldDataArray = [];
722
                    $fieldDataToString = '';
723
                    if (!empty($fieldData)) {
724
                        foreach ($fieldData as $data) {
725
                            $fieldDataArray[] = $data['value'];
726
                        }
727
                        $fieldDataToString = implode(', ', $fieldDataArray);
728
                    }
729
                    $session[$field['variable']] = $fieldDataToString;
730
                }
731
            }
732
            if (isset($session['session_active']) && $session['session_active'] == 1) {
733
                $session['session_active'] = $activeIcon;
734
            } else {
735
                $session['session_active'] = $inactiveIcon;
736
            }
737
738
            $session = self::convert_dates_to_local($session, true);
739
740
            switch ($session['visibility']) {
741
                case SESSION_VISIBLE_READ_ONLY: //1
742
                    $session['visibility'] = get_lang('ReadOnly');
743
                    break;
744
                case SESSION_VISIBLE:           //2
745
                case SESSION_AVAILABLE:         //4
746
                    $session['visibility'] = get_lang('Visible');
747
                    break;
748
                case SESSION_INVISIBLE:         //3
749
                    $session['visibility'] = api_ucfirst(get_lang('Invisible'));
750
                    break;
751
            }
752
753
            // Cleaning double selects.
754
            foreach ($session as $key => &$value) {
755
                if (isset($optionsByDouble[$key]) || isset($optionsByDouble[$key.'_second'])) {
756
                    $options = explode('::', $value);
757
                }
758
                $original_key = $key;
759
                if (strpos($key, '_second') !== false) {
760
                    $key = str_replace('_second', '', $key);
761
                }
762
763
                if (isset($optionsByDouble[$key]) &&
764
                    isset($options[0]) &&
765
                    isset($optionsByDouble[$key][$options[0]])
766
                ) {
767
                    if (strpos($original_key, '_second') === false) {
768
                        $value = $optionsByDouble[$key][$options[0]]['option_display_text'];
769
                    } else {
770
                        $value = $optionsByDouble[$key][$options[1]]['option_display_text'];
771
                    }
772
                }
773
            }
774
775
            $categoryName = isset($orderedCategories[$session['session_category_id']]) ? $orderedCategories[$session['session_category_id']] : '';
776
            $session['category_name'] = $categoryName;
777
            if (isset($session['status'])) {
778
                $session['status'] = self::getStatusLabel($session['status']);
779
            }
780
781
            $formattedSessions[] = $session;
782
        }
783
784
        return $formattedSessions;
785
    }
786
787
    /**
788
     * Gets the progress of learning paths in the given session.
789
     *
790
     * @param int    $sessionId
791
     * @param int    $courseId
792
     * @param string $date_from
793
     * @param string $date_to
794
     * @param array options order and limit keys
795
     *
796
     * @return array table with user name, lp name, progress
797
     */
798
    public static function get_session_lp_progress(
799
        $sessionId,
800
        $courseId,
801
        $date_from,
802
        $date_to,
803
        $options
804
    ) {
805
        //escaping vars
806
        $sessionId = $sessionId === 'T' ? 'T' : intval($sessionId);
807
        $courseId = intval($courseId);
808
809
        //tables
810
        $session_course_user = Database::get_main_table(TABLE_MAIN_SESSION_COURSE_USER);
811
        $user = Database::get_main_table(TABLE_MAIN_USER);
812
        $tbl_course_lp_view = Database::get_course_table(TABLE_LP_VIEW);
813
814
        $course = api_get_course_info_by_id($courseId);
815
        $sessionCond = 'and session_id = %s';
816
        if ($sessionId === 'T') {
817
            $sessionCond = '';
818
        }
819
820
        $where = " WHERE c_id = '%s' AND s.status <> 2 $sessionCond";
821
822
        $limit = null;
823
        if (!empty($options['limit'])) {
824
            $limit = " LIMIT ".$options['limit'];
825
        }
826
827
        if (!empty($options['where'])) {
828
            $where .= ' '.$options['where'];
829
        }
830
831
        $order = null;
832
        if (!empty($options['order'])) {
833
            $order = " ORDER BY ".$options['order']." ";
834
        }
835
836
        $sql = "SELECT u.id as user_id, u.lastname, u.firstname, u.username, u.email, s.c_id
837
                FROM $session_course_user s
838
                INNER JOIN $user u ON u.id = s.user_id
839
                $where
840
                $order
841
                $limit";
842
843
        $sql_query = sprintf($sql, Database::escape_string($course['real_id']), $sessionId);
844
845
        $rs = Database::query($sql_query);
846
        while ($user = Database::fetch_array($rs)) {
847
            $users[$user['user_id']] = $user;
848
        }
849
850
        // Get lessons
851
        $lessons = LearnpathList::get_course_lessons($course['code'], $sessionId);
852
853
        $table = [];
854
        foreach ($users as $user) {
855
            $data = [
856
                'lastname' => $user[1],
857
                'firstname' => $user[2],
858
                'username' => $user[3],
859
            ];
860
861
            $sessionCond = 'AND v.session_id = %d';
862
            if ($sessionId == 'T') {
863
                $sessionCond = "";
864
            }
865
866
            //Get lessons progress by user
867
            $sql = "SELECT v.lp_id as id, v.progress
868
                    FROM  $tbl_course_lp_view v
869
                    WHERE v.c_id = %d
870
                    AND v.user_id = %d
871
            $sessionCond";
872
873
            $sql_query = sprintf(
874
                $sql,
875
                intval($courseId),
876
                intval($user['user_id']),
877
                $sessionId
878
            );
879
880
            $result = Database::query($sql_query);
881
882
            $user_lessons = [];
883
            while ($row = Database::fetch_array($result)) {
884
                $user_lessons[$row['id']] = $row;
885
            }
886
887
            //Match course lessons with user progress
888
            $progress = 0;
889
            $count = 0;
890
            foreach ($lessons as $lesson) {
891
                $data[$lesson['id']] = (!empty($user_lessons[$lesson['id']]['progress'])) ? $user_lessons[$lesson['id']]['progress'] : 0;
892
                $progress += $data[$lesson['id']];
893
                $data[$lesson['id']] = $data[$lesson['id']].'%';
894
                $count++;
895
            }
896
            if ($count == 0) {
897
                $data['total'] = 0;
898
            } else {
899
                $data['total'] = round($progress / $count, 2).'%';
900
            }
901
            $table[] = $data;
902
        }
903
904
        return $table;
905
    }
906
907
    /**
908
     * Gets the survey answers.
909
     *
910
     * @param int $sessionId
911
     * @param int $courseId
912
     * @param int $surveyId
913
     * @param array options order and limit keys
914
     *
915
     * @todo fix the query
916
     *
917
     * @return array table with user name, lp name, progress
918
     */
919
    public static function get_survey_overview(
920
        $sessionId,
921
        $courseId,
922
        $surveyId,
923
        $date_from,
924
        $date_to,
925
        $options
926
    ) {
927
        //escaping vars
928
        $sessionId = intval($sessionId);
929
        $courseId = intval($courseId);
930
        $surveyId = intval($surveyId);
931
932
        //tables
933
        $session_course_user = Database::get_main_table(TABLE_MAIN_SESSION_COURSE_USER);
934
        $user = Database::get_main_table(TABLE_MAIN_USER);
935
        $c_survey = Database::get_course_table(TABLE_SURVEY);
936
        $c_survey_answer = Database::get_course_table(TABLE_SURVEY_ANSWER);
937
        $c_survey_question = Database::get_course_table(TABLE_SURVEY_QUESTION);
938
        $c_survey_question_option = Database::get_course_table(TABLE_SURVEY_QUESTION_OPTION);
939
940
        $course = api_get_course_info_by_id($courseId);
941
942
        $where = " WHERE c_id = '%s' AND s.status <> 2 AND session_id = %s";
943
944
        $limit = null;
945
        if (!empty($options['limit'])) {
946
            $limit = " LIMIT ".$options['limit'];
947
        }
948
949
        if (!empty($options['where'])) {
950
            $where .= ' '.$options['where'];
951
        }
952
953
        $order = null;
954
        if (!empty($options['order'])) {
955
            $order = " ORDER BY ".$options['order'];
956
        }
957
958
        $sql = "SELECT u.user_id, u.lastname, u.firstname, u.username, u.email, s.c_id
959
                FROM $session_course_user s
960
                INNER JOIN $user u ON u.user_id = s.user_id
961
                $where $order $limit";
962
963
        $sql_query = sprintf($sql, intval($course['real_id']), $sessionId);
964
        $rs = Database::query($sql_query);
965
        while ($user = Database::fetch_array($rs)) {
966
            $users[$user['user_id']] = $user;
967
        }
968
969
        //Get survey questions
970
        $questions = SurveyManager::get_questions($surveyId, $courseId);
971
972
        //Survey is anonymous?
973
        $result = Database::query(sprintf("SELECT anonymous FROM $c_survey WHERE survey_id = %d", $surveyId));
974
        $row = Database::fetch_array($result);
975
        $anonymous = ($row['anonymous'] == 1) ? true : false;
976
977
        $table = [];
978
        foreach ($users as $user) {
979
            $data = [
980
                'lastname' => ($anonymous ? '***' : $user[1]),
981
                'firstname' => ($anonymous ? '***' : $user[2]),
982
                'username' => ($anonymous ? '***' : $user[3]),
983
            ];
984
985
            //Get questions by user
986
            $sql = "SELECT sa.question_id, sa.option_id, sqo.option_text, sq.type
987
                    FROM $c_survey_answer sa
988
                    INNER JOIN $c_survey_question sq
989
                    ON sq.question_id = sa.question_id
990
                    LEFT JOIN $c_survey_question_option sqo
991
                    ON
992
                      sqo.c_id = sa.c_id AND
993
                      sqo.question_id = sq.question_id AND
994
                      sqo.question_option_id = sa.option_id AND
995
                      sqo.survey_id = sq.survey_id
996
                    WHERE
997
                      sa.survey_id = %d AND
998
                      sa.c_id = %d AND
999
                      sa.user = %d
1000
            "; //. $where_survey;
1001
            $sql_query = sprintf($sql, $surveyId, $courseId, $user['user_id']);
1002
1003
            $result = Database::query($sql_query);
1004
1005
            $user_questions = [];
1006
            while ($row = Database::fetch_array($result)) {
1007
                $user_questions[$row['question_id']] = $row;
1008
            }
1009
1010
            //Match course lessons with user progress
1011
            foreach ($questions as $question_id => $question) {
1012
                $option_text = 'option_text';
1013
                if ($user_questions[$question_id]['type'] == 'open') {
1014
                    $option_text = 'option_id';
1015
                }
1016
                $data[$question_id] = $user_questions[$question_id][$option_text];
1017
            }
1018
1019
            $table[] = $data;
1020
        }
1021
1022
        return $table;
1023
    }
1024
1025
    /**
1026
     * Gets the progress of the given session.
1027
     *
1028
     * @param int $sessionId
1029
     * @param int $courseId
1030
     * @param array options order and limit keys
1031
     *
1032
     * @return array table with user name, lp name, progress
1033
     */
1034
    public static function get_session_progress(
1035
        $sessionId,
1036
        $courseId,
1037
        $date_from,
1038
        $date_to,
1039
        $options
1040
    ) {
1041
        $sessionId = (int) $sessionId;
1042
1043
        $getAllSessions = false;
1044
        if (empty($sessionId)) {
1045
            $sessionId = 0;
1046
            $getAllSessions = true;
1047
        }
1048
1049
        //tables
1050
        $session_course_user = Database::get_main_table(TABLE_MAIN_SESSION_COURSE_USER);
1051
        $user = Database::get_main_table(TABLE_MAIN_USER);
1052
        $workTable = Database::get_course_table(TABLE_STUDENT_PUBLICATION);
1053
        $workTableAssignment = Database::get_course_table(TABLE_STUDENT_PUBLICATION_ASSIGNMENT);
1054
        $tbl_course_lp = Database::get_course_table(TABLE_LP_MAIN);
1055
        $wiki = Database::get_course_table(TABLE_WIKI);
1056
        $table_stats_default = Database::get_main_table(TABLE_STATISTIC_TRACK_E_DEFAULT);
1057
        $table_stats_access = Database::get_main_table(TABLE_STATISTIC_TRACK_E_ACCESS);
1058
1059
        $course = api_get_course_info_by_id($courseId);
1060
        $where = " WHERE c_id = '%s' AND s.status <> 2 ";
1061
1062
        $limit = null;
1063
        if (!empty($options['limit'])) {
1064
            $limit = " LIMIT ".$options['limit'];
1065
        }
1066
1067
        if (!empty($options['where'])) {
1068
            $where .= ' '.$options['where'];
1069
        }
1070
1071
        $order = null;
1072
        if (!empty($options['order'])) {
1073
            $order = " ORDER BY ".$options['order'];
1074
        }
1075
1076
        //TODO, fix create report without session
1077
        $queryVariables = [$course['real_id']];
1078
        if (!empty($sessionId)) {
1079
            $where .= ' AND session_id = %s';
1080
            $queryVariables[] = $sessionId;
1081
            $sql = "SELECT
1082
                        u.user_id, u.lastname, u.firstname, u.username,
1083
                        u.email, s.c_id, s.session_id
1084
                    FROM $session_course_user s
1085
                    INNER JOIN $user u
1086
                    ON u.user_id = s.user_id
1087
                    $where $order $limit";
1088
        } else {
1089
            $sql = "SELECT
1090
                        u.user_id, u.lastname, u.firstname, u.username,
1091
                        u.email, s.c_id, s.session_id
1092
                    FROM $session_course_user s
1093
                    INNER JOIN $user u ON u.user_id = s.user_id
1094
                    $where $order $limit";
1095
        }
1096
1097
        $sql_query = vsprintf($sql, $queryVariables);
1098
        $rs = Database::query($sql_query);
1099
        while ($user = Database::fetch_array($rs)) {
1100
            $users[$user['user_id']] = $user;
1101
        }
1102
1103
        /**
1104
         *  Lessons.
1105
         */
1106
        $sql = "SELECT * FROM $tbl_course_lp WHERE c_id = %s "; //AND session_id = %s
1107
        $sql_query = sprintf($sql, $course['real_id']);
1108
        $result = Database::query($sql_query);
1109
        $arrLesson = [[]];
1110
        while ($row = Database::fetch_array($result)) {
1111
            if (empty($arrLesson[$row['session_id']]['lessons_total'])) {
1112
                $arrLesson[$row['session_id']]['lessons_total'] = 1;
1113
            } else {
1114
                $arrLesson[$row['session_id']]['lessons_total']++;
1115
            }
1116
        }
1117
1118
        /**
1119
         *  Exercises.
1120
         */
1121
        $exercises = ExerciseLib::get_all_exercises(
1122
            $course,
1123
            $sessionId,
1124
            false,
1125
            '',
1126
            $getAllSessions
1127
        );
1128
        $exercises_total = count($exercises);
1129
1130
        /**
1131
         *  Assignments.
1132
         */
1133
        //total
1134
        $params = [$course['real_id']];
1135
        if ($getAllSessions) {
1136
            $sql = "SELECT count(w.id) as count
1137
                    FROM $workTable w
1138
                    LEFT JOIN $workTableAssignment a
1139
                    ON (a.publication_id = w.id AND a.c_id = w.c_id)
1140
                    WHERE
1141
                        w.c_id = %s AND
1142
                        parent_id = 0 AND
1143
                        active IN (1, 0)";
1144
        } else {
1145
            $sql = "SELECT count(w.id) as count
1146
                    FROM $workTable w
1147
                    LEFT JOIN $workTableAssignment a
1148
                    ON (a.publication_id = w.id AND a.c_id = w.c_id)
1149
                    WHERE
1150
                        w.c_id = %s AND
1151
                        parent_id = 0 AND
1152
                        active IN (1, 0)";
1153
1154
            if (empty($sessionId)) {
1155
                $sql .= ' AND w.session_id = NULL ';
1156
            } else {
1157
                $sql .= ' AND w.session_id = %s ';
1158
                $params[] = $sessionId;
1159
            }
1160
        }
1161
1162
        $sql_query = vsprintf($sql, $params);
1163
        $result = Database::query($sql_query);
1164
        $row = Database::fetch_array($result);
1165
        $assignments_total = $row['count'];
1166
1167
        /**
1168
         * Wiki.
1169
         */
1170
        if ($getAllSessions) {
1171
            $sql = "SELECT count(distinct page_id)  as count FROM $wiki
1172
                    WHERE c_id = %s";
1173
        } else {
1174
            $sql = "SELECT count(distinct page_id)  as count FROM $wiki
1175
                    WHERE c_id = %s and session_id = %s";
1176
        }
1177
        $sql_query = sprintf($sql, $course['real_id'], $sessionId);
1178
        $result = Database::query($sql_query);
1179
        $row = Database::fetch_array($result);
1180
        $wiki_total = $row['count'];
1181
1182
        /**
1183
         * Surveys.
1184
         */
1185
        $survey_user_list = [];
1186
        $survey_list = SurveyManager::get_surveys($course['code'], $sessionId);
1187
1188
        $surveys_total = count($survey_list);
1189
        foreach ($survey_list as $survey) {
1190
            $user_list = SurveyManager::get_people_who_filled_survey(
1191
                $survey['survey_id'],
1192
                false,
1193
                $course['real_id']
1194
            );
1195
            foreach ($user_list as $user_id) {
1196
                isset($survey_user_list[$user_id]) ? $survey_user_list[$user_id]++ : $survey_user_list[$user_id] = 1;
1197
            }
1198
        }
1199
1200
        /**
1201
         * Forums.
1202
         */
1203
        $forums_total = CourseManager::getCountForum(
1204
            $course['real_id'],
1205
            $sessionId,
1206
            $getAllSessions
1207
        );
1208
1209
        //process table info
1210
        foreach ($users as $user) {
1211
            //Course description
1212
            $sql = "SELECT count(*) as count
1213
                    FROM $table_stats_access
1214
                    WHERE access_tool = 'course_description'
1215
                    AND c_id = '%s'
1216
                    AND access_session_id = %s
1217
                    AND access_user_id = %s ";
1218
            $sql_query = sprintf($sql, $course['real_id'], $user['id_session'], $user['user_id']);
1219
1220
            $result = Database::query($sql_query);
1221
            $row = Database::fetch_array($result);
1222
            $course_description_progress = ($row['count'] > 0) ? 100 : 0;
1223
1224
            if (!empty($arrLesson[$user['id_session']]['lessons_total'])) {
1225
                $lessons_total = $arrLesson[$user['id_session']]['lessons_total'];
1226
            } else {
1227
                $lessons_total = !empty($arrLesson[0]['lessons_total']) ? $arrLesson[0]['lessons_total'] : 0;
1228
            }
1229
1230
            //Lessons
1231
            //TODO: Lessons done and left is calculated by progress per item in lesson, maybe we should calculate it only per completed lesson?
1232
            $lessons_progress = Tracking::get_avg_student_progress(
1233
                $user['user_id'],
1234
                $course['code'],
1235
                [],
1236
                $user['id_session']
1237
            );
1238
            $lessons_done = ($lessons_progress * $lessons_total) / 100;
1239
            $lessons_left = $lessons_total - $lessons_done;
1240
1241
            // Exercises
1242
            $exercises_progress = str_replace(
1243
                '%',
1244
                '',
1245
                Tracking::get_exercise_student_progress(
1246
                    $exercises,
1247
                    $user['user_id'],
1248
                    $course['real_id'],
1249
                    $user['id_session']
1250
                )
1251
            );
1252
            $exercises_done = round(($exercises_progress * $exercises_total) / 100);
1253
            $exercises_left = $exercises_total - $exercises_done;
1254
1255
            //Assignments
1256
            $assignments_done = Tracking::count_student_assignments($user['user_id'], $course['code'], $user['id_session']);
1257
            $assignments_left = $assignments_total - $assignments_done;
1258
            if (!empty($assignments_total)) {
1259
                $assignments_progress = round((($assignments_done * 100) / $assignments_total), 2);
1260
            } else {
1261
                $assignments_progress = 0;
1262
            }
1263
1264
            // Wiki
1265
            // total revisions per user
1266
            $sql = "SELECT count(*) as count
1267
                    FROM $wiki
1268
                    WHERE c_id = %s and session_id = %s and user_id = %s";
1269
            $sql_query = sprintf($sql, $course['real_id'], $user['id_session'], $user['user_id']);
1270
            $result = Database::query($sql_query);
1271
            $row = Database::fetch_array($result);
1272
            $wiki_revisions = $row['count'];
1273
            //count visited wiki pages
1274
            $sql = "SELECT count(distinct default_value) as count
1275
                    FROM $table_stats_default
1276
                    WHERE
1277
                        default_user_id = %s AND
1278
                        default_event_type = 'wiki_page_view' AND
1279
                        default_value_type = 'wiki_page_id' AND
1280
                        c_id = %s
1281
                    ";
1282
            $sql_query = sprintf($sql, $user['user_id'], $course['real_id']);
1283
            $result = Database::query($sql_query);
1284
            $row = Database::fetch_array($result);
1285
1286
            $wiki_read = $row['count'];
1287
            $wiki_unread = $wiki_total - $wiki_read;
1288
            if (!empty($wiki_total)) {
1289
                $wiki_progress = round((($wiki_read * 100) / $wiki_total), 2);
1290
            } else {
1291
                $wiki_progress = 0;
1292
            }
1293
1294
            //Surveys
1295
            $surveys_done = (isset($survey_user_list[$user['user_id']]) ? $survey_user_list[$user['user_id']] : 0);
1296
            $surveys_left = $surveys_total - $surveys_done;
1297
            if (!empty($surveys_total)) {
1298
                $surveys_progress = round((($surveys_done * 100) / $surveys_total), 2);
1299
            } else {
1300
                $surveys_progress = 0;
1301
            }
1302
1303
            //Forums
1304
            $forums_done = CourseManager::getCountForumPerUser(
1305
                $user['user_id'],
1306
                $course['real_id'],
1307
                $user['id_session']
1308
            );
1309
            $forums_left = $forums_total - $forums_done;
1310
            if (!empty($forums_total)) {
1311
                $forums_progress = round((($forums_done * 100) / $forums_total), 2);
1312
            } else {
1313
                $forums_progress = 0;
1314
            }
1315
1316
            // Overall Total
1317
            $overall_total = ($course_description_progress + $exercises_progress + $forums_progress + $assignments_progress + $wiki_progress + $surveys_progress) / 6;
1318
1319
            $link = '<a href="'.api_get_path(WEB_CODE_PATH).'mySpace/myStudents.php?student='.$user[0].'&details=true&course='.$course['code'].'&id_session='.$user['id_session'].'"> %s </a>';
1320
            $linkForum = '<a href="'.api_get_path(WEB_CODE_PATH).'forum/index.php?cidReq='.$course['code'].'&id_session='.$user['id_session'].'"> %s </a>';
1321
            $linkWork = '<a href="'.api_get_path(WEB_CODE_PATH).'work/work.php?cidReq='.$course['code'].'&id_session='.$user['id_session'].'"> %s </a>';
1322
            $linkWiki = '<a href="'.api_get_path(WEB_CODE_PATH).'wiki/index.php?cidReq='.$course['code'].'&session_id='.$user['id_session'].'&action=statistics"> %s </a>';
1323
            $linkSurvey = '<a href="'.api_get_path(WEB_CODE_PATH).'survey/survey_list.php?cidReq='.$course['code'].'&id_session='.$user['id_session'].'"> %s </a>';
1324
1325
            $table[] = [
1326
                'lastname' => $user[1],
1327
                'firstname' => $user[2],
1328
                'username' => $user[3],
1329
                //'profile'   => '',
1330
                'total' => round($overall_total, 2).'%',
1331
                'courses' => sprintf($link, $course_description_progress.'%'),
1332
                'lessons' => sprintf($link, $lessons_progress.'%'),
1333
                'exercises' => sprintf($link, $exercises_progress.'%'),
1334
                'forums' => sprintf($link, $forums_progress.'%'),
1335
                'homeworks' => sprintf($link, $assignments_progress.'%'),
1336
                'wikis' => sprintf($link, $wiki_progress.'%'),
1337
                'surveys' => sprintf($link, $surveys_progress.'%'),
1338
                //course description
1339
                'course_description_progress' => $course_description_progress.'%',
1340
                //lessons
1341
                'lessons_total' => sprintf($link, $lessons_total),
1342
                'lessons_done' => sprintf($link, $lessons_done),
1343
                'lessons_left' => sprintf($link, $lessons_left),
1344
                'lessons_progress' => sprintf($link, $lessons_progress.'%'),
1345
                //exercises
1346
                'exercises_total' => sprintf($link, $exercises_total),
1347
                'exercises_done' => sprintf($link, $exercises_done),
1348
                'exercises_left' => sprintf($link, $exercises_left),
1349
                'exercises_progress' => sprintf($link, $exercises_progress.'%'),
1350
                //forums
1351
                'forums_total' => sprintf($linkForum, $forums_total),
1352
                'forums_done' => sprintf($linkForum, $forums_done),
1353
                'forums_left' => sprintf($linkForum, $forums_left),
1354
                'forums_progress' => sprintf($linkForum, $forums_progress.'%'),
1355
                //assignments
1356
                'assignments_total' => sprintf($linkWork, $assignments_total),
1357
                'assignments_done' => sprintf($linkWork, $assignments_done),
1358
                'assignments_left' => sprintf($linkWork, $assignments_left),
1359
                'assignments_progress' => sprintf($linkWork, $assignments_progress.'%'),
1360
                //wiki
1361
                'wiki_total' => sprintf($linkWiki, $wiki_total),
1362
                'wiki_revisions' => sprintf($linkWiki, $wiki_revisions),
1363
                'wiki_read' => sprintf($linkWiki, $wiki_read),
1364
                'wiki_unread' => sprintf($linkWiki, $wiki_unread),
1365
                'wiki_progress' => sprintf($linkWiki, $wiki_progress.'%'),
1366
                //survey
1367
                'surveys_total' => sprintf($linkSurvey, $surveys_total),
1368
                'surveys_done' => sprintf($linkSurvey, $surveys_done),
1369
                'surveys_left' => sprintf($linkSurvey, $surveys_left),
1370
                'surveys_progress' => sprintf($linkSurvey, $surveys_progress.'%'),
1371
            ];
1372
        }
1373
1374
        return $table;
1375
    }
1376
1377
    /**
1378
     * Get the ip, total of clicks, login date and time logged in for all user, in one session.
1379
     *
1380
     * @todo track_e_course_access table should have ip so we dont have to look for it in track_e_login
1381
     *
1382
     * @author César Perales <[email protected]>, Beeznest Team
1383
     *
1384
     * @version 1.9.6
1385
     */
1386
    public static function get_user_data_access_tracking_overview(
1387
        $sessionId,
1388
        $courseId,
1389
        $studentId = 0,
1390
        $profile = '',
1391
        $date_from = '',
1392
        $date_to = '',
1393
        $options = []
1394
    ) {
1395
        $sessionId = intval($sessionId);
1396
        $courseId = intval($courseId);
1397
        $studentId = intval($studentId);
1398
        $profile = intval($profile);
1399
        $date_from = Database::escape_string($date_from);
1400
        $date_to = Database::escape_string($date_to);
1401
1402
        // database table definition
1403
        $user = Database::get_main_table(TABLE_MAIN_USER);
1404
        $course = Database::get_main_table(TABLE_MAIN_COURSE);
1405
        $track_e_login = Database::get_main_table(TABLE_STATISTIC_TRACK_E_LOGIN);
1406
        $track_e_course_access = Database::get_main_table(TABLE_STATISTIC_TRACK_E_COURSE_ACCESS);
1407
        $sessionTable = Database::get_main_table(TABLE_MAIN_SESSION);
1408
1409
        global $export_csv;
1410
        if ($export_csv) {
1411
            $is_western_name_order = api_is_western_name_order(PERSON_NAME_DATA_EXPORT);
1412
        } else {
1413
            $is_western_name_order = api_is_western_name_order();
1414
        }
1415
1416
        $where = null;
1417
        if (isset($sessionId) && !empty($sessionId)) {
1418
            $where = sprintf(" WHERE a.session_id = %d", $sessionId);
1419
        }
1420
        if (isset($courseId) && !empty($courseId)) {
1421
            $where .= sprintf(" AND c.id = %d", $courseId);
1422
        }
1423
        if (isset($studentId) && !empty($studentId)) {
1424
            $where .= sprintf(" AND u.user_id = %d", $studentId);
1425
        }
1426
        if (isset($profile) && !empty($profile)) {
1427
            $where .= sprintf(" AND u.status = %d", $profile);
1428
        }
1429
        if (!empty($date_to) && !empty($date_from)) {
1430
            $where .= sprintf(
1431
                " AND a.login_course_date >= '%s 00:00:00'
1432
                 AND a.login_course_date <= '%s 23:59:59'",
1433
                $date_from,
1434
                $date_to
1435
            );
1436
        }
1437
1438
        $limit = null;
1439
        if (!empty($options['limit'])) {
1440
            $limit = " LIMIT ".$options['limit'];
1441
        }
1442
1443
        if (!empty($options['where'])) {
1444
            $where .= ' '.$options['where'];
1445
        }
1446
1447
        $order = null;
1448
        if (!empty($options['order'])) {
1449
            $order = " ORDER BY ".$options['order'];
1450
        }
1451
1452
        //TODO add course name
1453
        $sql = "SELECT
1454
                a.login_course_date ,
1455
                u.username ,
1456
                ".($is_western_name_order ? "
1457
                    u.firstname,
1458
                    u.lastname,
1459
                    " : "
1460
                    u.lastname,
1461
                    u.firstname,
1462
                ")."
1463
                a.logout_course_date,
1464
                a.counter,
1465
                c.title,
1466
                c.code,
1467
                u.user_id,
1468
                a.session_id
1469
            FROM $track_e_course_access a
1470
            INNER JOIN $user u ON a.user_id = u.user_id
1471
            INNER JOIN $course c ON a.c_id = c.id
1472
            $where $order $limit";
1473
        $result = Database::query(sprintf($sql, $sessionId, $courseId));
1474
1475
        $data = [];
1476
        while ($user = Database::fetch_assoc($result)) {
1477
            $data[] = $user;
1478
        }
1479
1480
        foreach ($data as $key => $info) {
1481
            $sql = "SELECT
1482
                    name
1483
                    FROM $sessionTable
1484
                    WHERE
1485
                    id = {$info['session_id']}";
1486
            $result = Database::query($sql);
1487
            $session = Database::fetch_assoc($result);
1488
1489
            // building array to display
1490
            $return[] = [
1491
                'user_id' => $info['user_id'],
1492
                'logindate' => $info['login_course_date'],
1493
                'username' => $info['username'],
1494
                'firstname' => $info['firstname'],
1495
                'lastname' => $info['lastname'],
1496
                'clicks' => $info['counter'], //+ $clicks[$info['user_id']],
1497
                'ip' => '',
1498
                'timeLoggedIn' => gmdate("H:i:s", strtotime($info['logout_course_date']) - strtotime($info['login_course_date'])),
1499
                'session' => $session['name'],
1500
            ];
1501
        }
1502
1503
        foreach ($return as $key => $info) {
1504
            //Search for ip, we do less querys if we iterate the final array
1505
            $sql = sprintf(
1506
                "SELECT user_ip FROM $track_e_login WHERE login_user_id = %d AND login_date < '%s' ORDER BY login_date DESC LIMIT 1",
1507
                $info['user_id'],
1508
                $info['logindate']
1509
            ); //TODO add select by user too
1510
            $result = Database::query($sql);
1511
            $ip = Database::fetch_assoc($result);
1512
            //if no ip founded, we search the closest higher ip
1513
            if (empty($ip['user_ip'])) {
1514
                $sql = sprintf(
1515
                    "SELECT user_ip FROM $track_e_login WHERE login_user_id = %d AND login_date > '%s'  ORDER BY login_date ASC LIMIT 1",
1516
                    $info['user_id'],
1517
                    $info['logindate']
1518
                ); //TODO add select by user too
1519
                $result = Database::query($sql);
1520
                $ip = Database::fetch_assoc($result);
1521
            }
1522
            //add ip to final array
1523
            $return[$key]['ip'] = $ip['user_ip'];
1524
        }
1525
1526
        return $return;
1527
    }
1528
1529
    /**
1530
     * Creates a new course code based in given code.
1531
     *
1532
     * @param string $session_name
1533
     *                             <code>
1534
     *                             $wanted_code = 'curse' if there are in the DB codes like curse1 curse2 the function will return: course3
1535
     *                             if the course code doest not exist in the DB the same course code will be returned
1536
     *                             </code>
1537
     *
1538
     * @return string wanted unused code
1539
     */
1540
    public static function generateNextSessionName($session_name)
1541
    {
1542
        $session_name_ok = !self::sessionNameExists($session_name);
1543
        if (!$session_name_ok) {
1544
            $table = Database::get_main_table(TABLE_MAIN_SESSION);
1545
            $session_name = Database::escape_string($session_name);
1546
            $sql = "SELECT count(*) as count FROM $table
1547
                    WHERE name LIKE '$session_name%'";
1548
            $result = Database::query($sql);
1549
            if (Database::num_rows($result) > 0) {
1550
                $row = Database::fetch_array($result);
1551
                $count = $row['count'] + 1;
1552
                $session_name = $session_name.'_'.$count;
1553
                $result = self::sessionNameExists($session_name);
1554
                if (!$result) {
1555
                    return $session_name;
1556
                }
1557
            }
1558
1559
            return false;
1560
        }
1561
1562
        return $session_name;
1563
    }
1564
1565
    /**
1566
     * Edit a session.
1567
     *
1568
     * @author Carlos Vargas from existing code
1569
     *
1570
     * @param int    $id                           Session primary key
1571
     * @param string $name
1572
     * @param string $startDate
1573
     * @param string $endDate
1574
     * @param string $displayStartDate
1575
     * @param string $displayEndDate
1576
     * @param string $coachStartDate
1577
     * @param string $coachEndDate
1578
     * @param int    $coachId
1579
     * @param int    $sessionCategoryId
1580
     * @param int    $visibility
1581
     * @param string $description
1582
     * @param int    $showDescription
1583
     * @param int    $duration
1584
     * @param array  $extraFields
1585
     * @param int    $sessionAdminId
1586
     * @param bool   $sendSubscriptionNotification Optional. Whether send a mail notification to users being subscribed
1587
     * @param int    $status
1588
     *
1589
     * @return mixed
1590
     */
1591
    public static function edit_session(
1592
        $id,
1593
        $name,
1594
        $startDate,
1595
        $endDate,
1596
        $displayStartDate,
1597
        $displayEndDate,
1598
        $coachStartDate,
1599
        $coachEndDate,
1600
        $coachId,
1601
        $sessionCategoryId,
1602
        $visibility,
1603
        $description = null,
1604
        $showDescription = 0,
1605
        $duration = null,
1606
        $extraFields = [],
1607
        $sessionAdminId = 0,
1608
        $sendSubscriptionNotification = false,
1609
        $status = 0
1610
    ) {
1611
        $status = (int) $status;
1612
        $coachId = (int) $coachId;
1613
        $sessionCategoryId = (int) $sessionCategoryId;
1614
        $visibility = (int) $visibility;
1615
        $tbl_session = Database::get_main_table(TABLE_MAIN_SESSION);
1616
1617
        if (empty($name)) {
1618
            Display::addFlash(
1619
                Display::return_message(get_lang('SessionNameIsRequired'), 'warning')
1620
            );
1621
1622
            return false;
1623
        } elseif (empty($coachId)) {
1624
            Display::addFlash(
1625
                Display::return_message(get_lang('CoachIsRequired'), 'warning')
1626
            );
1627
1628
            return false;
1629
        } elseif (!empty($startDate) &&
1630
            !api_is_valid_date($startDate, 'Y-m-d H:i') &&
1631
            !api_is_valid_date($startDate, 'Y-m-d H:i:s')
1632
        ) {
1633
            Display::addFlash(
1634
                Display::return_message(get_lang('InvalidStartDate'), 'warning')
1635
            );
1636
1637
            return false;
1638
        } elseif (!empty($endDate) &&
1639
            !api_is_valid_date($endDate, 'Y-m-d H:i') &&
1640
            !api_is_valid_date($endDate, 'Y-m-d H:i:s')
1641
        ) {
1642
            Display::addFlash(
1643
                Display::return_message(get_lang('InvalidEndDate'), 'warning')
1644
            );
1645
1646
            return false;
1647
        } elseif (!empty($startDate) && !empty($endDate) && $startDate >= $endDate) {
1648
            Display::addFlash(
1649
                Display::return_message(get_lang('StartDateShouldBeBeforeEndDate'), 'warning')
1650
            );
1651
1652
            return false;
1653
        } else {
1654
            $sessionInfo = self::get_session_by_name($name);
1655
            $exists = false;
1656
1657
            if (!empty($sessionInfo)) {
1658
                if ($sessionInfo['id'] != $id) {
1659
                    $exists = true;
1660
                }
1661
            }
1662
1663
            if ($exists) {
1664
                Display::addFlash(
1665
                    Display::return_message(get_lang('SessionNameAlreadyExists'), 'warning')
1666
                );
1667
1668
                return false;
1669
            } else {
1670
                $values = [
1671
                    'name' => $name,
1672
                    'duration' => $duration,
1673
                    'id_coach' => $coachId,
1674
                    'description' => $description,
1675
                    'show_description' => intval($showDescription),
1676
                    'visibility' => $visibility,
1677
                    'send_subscription_notification' => $sendSubscriptionNotification,
1678
                    'access_start_date' => null,
1679
                    'access_end_date' => null,
1680
                    'display_start_date' => null,
1681
                    'display_end_date' => null,
1682
                    'coach_access_start_date' => null,
1683
                    'coach_access_end_date' => null,
1684
                ];
1685
1686
                if (!empty($sessionAdminId)) {
1687
                    $values['session_admin_id'] = $sessionAdminId;
1688
                }
1689
1690
                if (!empty($startDate)) {
1691
                    $values['access_start_date'] = api_get_utc_datetime($startDate);
1692
                }
1693
1694
                if (!empty($endDate)) {
1695
                    $values['access_end_date'] = api_get_utc_datetime($endDate);
1696
                }
1697
1698
                if (!empty($displayStartDate)) {
1699
                    $values['display_start_date'] = api_get_utc_datetime($displayStartDate);
1700
                }
1701
1702
                if (!empty($displayEndDate)) {
1703
                    $values['display_end_date'] = api_get_utc_datetime($displayEndDate);
1704
                }
1705
1706
                if (!empty($coachStartDate)) {
1707
                    $values['coach_access_start_date'] = api_get_utc_datetime($coachStartDate);
1708
                }
1709
                if (!empty($coachEndDate)) {
1710
                    $values['coach_access_end_date'] = api_get_utc_datetime($coachEndDate);
1711
                }
1712
1713
                $values['session_category_id'] = null;
1714
                if (!empty($sessionCategoryId)) {
1715
                    $values['session_category_id'] = $sessionCategoryId;
1716
                }
1717
1718
                if (api_get_configuration_value('allow_session_status')) {
1719
                    $values['status'] = $status;
1720
                }
1721
1722
                Database::update(
1723
                    $tbl_session,
1724
                    $values,
1725
                    ['id = ?' => $id]
1726
                );
1727
1728
                if (!empty($extraFields)) {
1729
                    $extraFields['item_id'] = $id;
1730
                    $sessionFieldValue = new ExtraFieldValue('session');
1731
                    $sessionFieldValue->saveFieldValues($extraFields);
1732
                }
1733
1734
                return $id;
1735
            }
1736
        }
1737
    }
1738
1739
    /**
1740
     * Delete session.
1741
     *
1742
     * @author Carlos Vargas  from existing code
1743
     *
1744
     * @param array $id_checked an array to delete sessions
1745
     * @param bool  $from_ws    optional, true if the function is called
1746
     *                          by a webservice, false otherwise
1747
     *
1748
     * @return bool
1749
     * */
1750
    public static function delete($id_checked, $from_ws = false)
1751
    {
1752
        $tbl_session = Database::get_main_table(TABLE_MAIN_SESSION);
1753
        $tbl_session_rel_course = Database::get_main_table(TABLE_MAIN_SESSION_COURSE);
1754
        $tbl_session_rel_course_rel_user = Database::get_main_table(TABLE_MAIN_SESSION_COURSE_USER);
1755
        $tbl_session_rel_user = Database::get_main_table(TABLE_MAIN_SESSION_USER);
1756
        $tbl_url_session = Database::get_main_table(TABLE_MAIN_ACCESS_URL_REL_SESSION);
1757
        $tbl_item_properties = Database::get_course_table(TABLE_ITEM_PROPERTY);
1758
        $tbl_student_publication = Database::get_course_table(TABLE_STUDENT_PUBLICATION);
1759
        $tbl_student_publication_assignment = Database::get_course_table(TABLE_STUDENT_PUBLICATION_ASSIGNMENT);
1760
        $userGroupSessionTable = Database::get_main_table(TABLE_USERGROUP_REL_SESSION);
1761
        $trackCourseAccess = Database::get_main_table(TABLE_STATISTIC_TRACK_E_COURSE_ACCESS);
1762
        $trackAccess = Database::get_main_table(TABLE_STATISTIC_TRACK_E_ACCESS);
1763
1764
        $ticket = Database::get_main_table(TABLE_TICKET_TICKET);
1765
        $em = Database::getManager();
1766
        $userId = api_get_user_id();
1767
1768
        /** @var SequenceResourceRepository $repo */
1769
        $repo = Database::getManager()->getRepository('ChamiloCoreBundle:SequenceResource');
1770
        $sequenceResource = $repo->findRequirementForResource(
1771
            $id_checked,
1772
            SequenceResource::SESSION_TYPE
1773
        );
1774
1775
        if ($sequenceResource) {
1776
            Display::addFlash(
1777
                Display::return_message(
1778
                    get_lang('ThereIsASequenceResourceLinkedToThisSessionYouNeedToDeleteItFirst'),
1779
                    'error'
1780
                )
1781
            );
1782
1783
            return false;
1784
        }
1785
1786
        if (is_array($id_checked)) {
1787
            foreach ($id_checked as $sessionId) {
1788
                self::delete($sessionId);
1789
            }
1790
        } else {
1791
            $id_checked = intval($id_checked);
1792
        }
1793
1794
        if (self::allowed($id_checked) && !$from_ws) {
1795
            $qb = $em
1796
                ->createQuery('
1797
                    SELECT s.sessionAdminId FROM ChamiloCoreBundle:Session s
1798
                    WHERE s.id = ?1
1799
                ')
1800
                ->setParameter(1, $id_checked);
1801
1802
            $res = $qb->getSingleScalarResult();
1803
1804
            if ($res != $userId && !api_is_platform_admin()) {
1805
                api_not_allowed(true);
1806
            }
1807
        }
1808
1809
        $sessionInfo = api_get_session_info($id_checked);
1810
1811
        // Delete documents inside a session
1812
        $courses = self::getCoursesInSession($id_checked);
1813
        foreach ($courses as $courseId) {
1814
            $courseInfo = api_get_course_info_by_id($courseId);
1815
            DocumentManager::deleteDocumentsFromSession($courseInfo, $id_checked);
1816
            $works = Database::select(
1817
                '*',
1818
                $tbl_student_publication,
1819
                [
1820
                    'where' => ['session_id = ? AND c_id = ?' => [$id_checked, $courseId]],
1821
                ]
1822
            );
1823
1824
            $currentCourseRepositorySys = api_get_path(SYS_COURSE_PATH).$courseInfo['path'].'/';
1825
            foreach ($works as $index => $work) {
1826
                if ($work['filetype'] = 'folder') {
1827
                    Database::query("DELETE FROM $tbl_student_publication_assignment WHERE publication_id = $index");
1828
                }
1829
                my_delete($currentCourseRepositorySys.'/'.$work['url']);
1830
            }
1831
        }
1832
1833
        // Class
1834
        $sql = "DELETE FROM $userGroupSessionTable
1835
                WHERE session_id IN($id_checked)";
1836
        Database::query($sql);
1837
1838
        Database::query("DELETE FROM $tbl_student_publication WHERE session_id IN($id_checked)");
1839
        Database::query("DELETE FROM $tbl_session_rel_course WHERE session_id IN($id_checked)");
1840
        Database::query("DELETE FROM $tbl_session_rel_course_rel_user WHERE session_id IN($id_checked)");
1841
        Database::query("DELETE FROM $tbl_session_rel_user WHERE session_id IN($id_checked)");
1842
        Database::query("DELETE FROM $tbl_item_properties WHERE session_id IN ($id_checked)");
1843
        Database::query("DELETE FROM $tbl_url_session WHERE session_id IN($id_checked)");
1844
1845
        Database::query("DELETE FROM $trackCourseAccess WHERE session_id IN($id_checked)");
1846
        Database::query("DELETE FROM $trackAccess WHERE access_session_id IN($id_checked)");
1847
1848
        if (api_get_configuration_value('allow_lp_subscription_to_usergroups')) {
1849
            $tableGroup = Database::get_course_table(TABLE_LP_REL_USERGROUP);
1850
            Database::query("DELETE FROM $tableGroup WHERE session_id IN($id_checked)");
1851
            $tableGroup = Database::get_course_table(TABLE_LP_CATEGORY_REL_USERGROUP);
1852
            Database::query("DELETE FROM $tableGroup WHERE session_id IN($id_checked)");
1853
        }
1854
1855
        $sql = "UPDATE $ticket SET session_id = NULL WHERE session_id IN ($id_checked)";
1856
        Database::query($sql);
1857
1858
        $app_plugin = new AppPlugin();
1859
        $app_plugin->performActionsWhenDeletingItem('session', $id_checked);
1860
1861
        $sql = "DELETE FROM $tbl_session WHERE id IN ($id_checked)";
1862
        Database::query($sql);
1863
1864
        $extraFieldValue = new ExtraFieldValue('session');
1865
        $extraFieldValue->deleteValuesByItem($id_checked);
1866
1867
        $repo->deleteResource(
1868
            $id_checked,
1869
            SequenceResource::SESSION_TYPE
1870
        );
1871
1872
        // Add event to system log
1873
        Event::addEvent(
1874
            LOG_SESSION_DELETE,
1875
            LOG_SESSION_ID,
1876
            $sessionInfo['name'].' - id:'.$id_checked,
1877
            api_get_utc_datetime(),
1878
            $userId
1879
        );
1880
1881
        return true;
1882
    }
1883
1884
    /**
1885
     * @param int $id promotion id
1886
     *
1887
     * @return bool
1888
     */
1889
    public static function clear_session_ref_promotion($id)
1890
    {
1891
        $tbl_session = Database::get_main_table(TABLE_MAIN_SESSION);
1892
        $id = intval($id);
1893
        $sql = "UPDATE $tbl_session
1894
                SET promotion_id = 0
1895
                WHERE promotion_id = $id";
1896
        if (Database::query($sql)) {
1897
            return true;
1898
        } else {
1899
            return false;
1900
        }
1901
    }
1902
1903
    /**
1904
     * Subscribes students to the given session and optionally (default)
1905
     * unsubscribes previous users.
1906
     *
1907
     * @author Carlos Vargas from existing code
1908
     * @author Julio Montoya. Cleaning code.
1909
     *
1910
     * @param int   $sessionId
1911
     * @param array $userList
1912
     * @param int   $session_visibility
1913
     * @param bool  $empty_users
1914
     * @param bool  $registerUsersToAllCourses
1915
     *
1916
     * @return bool
1917
     */
1918
    public static function subscribeUsersToSession(
1919
        $sessionId,
1920
        $userList,
1921
        $session_visibility = SESSION_VISIBLE_READ_ONLY,
1922
        $empty_users = true,
1923
        $registerUsersToAllCourses = true
1924
    ) {
1925
        $sessionId = (int) $sessionId;
1926
1927
        if (empty($sessionId)) {
1928
            return false;
1929
        }
1930
1931
        foreach ($userList as $intUser) {
1932
            if ($intUser != strval(intval($intUser))) {
1933
                return false;
1934
            }
1935
        }
1936
1937
        $tbl_session_rel_course = Database::get_main_table(TABLE_MAIN_SESSION_COURSE);
1938
        $tbl_session_rel_course_rel_user = Database::get_main_table(TABLE_MAIN_SESSION_COURSE_USER);
1939
        $tbl_session_rel_user = Database::get_main_table(TABLE_MAIN_SESSION_USER);
1940
        $tbl_session = Database::get_main_table(TABLE_MAIN_SESSION);
1941
1942
        $session = api_get_session_entity($sessionId);
1943
1944
        // from function parameter
1945
        if (empty($session_visibility)) {
1946
            $session_visibility = $session->getVisibility();
1947
            //default status loaded if empty
1948
            // by default readonly 1
1949
            if (empty($session_visibility)) {
1950
                $session_visibility = SESSION_VISIBLE_READ_ONLY;
1951
            }
1952
        } else {
1953
            if (!in_array($session_visibility, [SESSION_VISIBLE_READ_ONLY, SESSION_VISIBLE, SESSION_INVISIBLE])) {
1954
                $session_visibility = SESSION_VISIBLE_READ_ONLY;
1955
            }
1956
        }
1957
1958
        $sql = "SELECT user_id FROM $tbl_session_rel_course_rel_user
1959
                WHERE session_id = $sessionId AND status = 0";
1960
        $result = Database::query($sql);
1961
        $existingUsers = [];
1962
        while ($row = Database::fetch_array($result)) {
1963
            $existingUsers[] = $row['user_id'];
1964
        }
1965
1966
        $sql = "SELECT c_id FROM $tbl_session_rel_course
1967
                WHERE session_id = $sessionId";
1968
        $result = Database::query($sql);
1969
        $course_list = [];
1970
        while ($row = Database::fetch_array($result)) {
1971
            $course_list[] = $row['c_id'];
1972
        }
1973
1974
        if ($session->getSendSubscriptionNotification() &&
1975
            is_array($userList)
1976
        ) {
1977
            // Sending emails only
1978
            foreach ($userList as $user_id) {
1979
                if (in_array($user_id, $existingUsers)) {
1980
                    continue;
1981
                }
1982
1983
                $tplSubject = new Template(
1984
                    null,
1985
                    false,
1986
                    false,
1987
                    false,
1988
                    false,
1989
                    false
1990
                );
1991
                $layoutSubject = $tplSubject->get_template(
1992
                    'mail/subject_subscription_to_session_confirmation.tpl'
1993
                );
1994
                $subject = $tplSubject->fetch($layoutSubject);
1995
                $user_info = api_get_user_info($user_id);
1996
1997
                $tplContent = new Template(
1998
                    null,
1999
                    false,
2000
                    false,
2001
                    false,
2002
                    false,
2003
                    false
2004
                );
2005
                // Variables for default template
2006
                $tplContent->assign('complete_name', stripslashes($user_info['complete_name']));
2007
                $tplContent->assign('session_name', $session->getName());
2008
                $tplContent->assign('session_coach', $session->getGeneralCoach()->getCompleteName());
2009
                $layoutContent = $tplContent->get_template(
2010
                    'mail/content_subscription_to_session_confirmation.tpl'
2011
                );
2012
                $content = $tplContent->fetch($layoutContent);
2013
2014
                api_mail_html(
2015
                    $user_info['complete_name'],
2016
                    $user_info['mail'],
2017
                    $subject,
2018
                    $content,
2019
                    api_get_person_name(
2020
                        api_get_setting('administratorName'),
2021
                        api_get_setting('administratorSurname')
2022
                    ),
2023
                    api_get_setting('emailAdministrator')
2024
                );
2025
            }
2026
        }
2027
2028
        if ($registerUsersToAllCourses) {
2029
            foreach ($course_list as $courseId) {
2030
                // for each course in the session
2031
                $courseId = (int) $courseId;
2032
2033
                $sql = "SELECT DISTINCT user_id
2034
                        FROM $tbl_session_rel_course_rel_user
2035
                        WHERE
2036
                            session_id = $sessionId AND
2037
                            c_id = $courseId AND
2038
                            status = 0
2039
                        ";
2040
                $result = Database::query($sql);
2041
                $existingUsers = [];
2042
                while ($row = Database::fetch_array($result)) {
2043
                    $existingUsers[] = $row['user_id'];
2044
                }
2045
2046
                // Delete existing users
2047
                if ($empty_users) {
2048
                    foreach ($existingUsers as $existing_user) {
2049
                        if (!in_array($existing_user, $userList)) {
2050
                            self::unSubscribeUserFromCourseSession($existing_user, $courseId, $sessionId);
2051
                        }
2052
                    }
2053
                }
2054
2055
                $usersToSubscribeInCourse = array_filter(
2056
                    $userList,
2057
                    function ($userId) use ($existingUsers) {
2058
                        return !in_array($userId, $existingUsers);
2059
                    }
2060
                );
2061
2062
                self::insertUsersInCourse(
2063
                    $usersToSubscribeInCourse,
2064
                    $courseId,
2065
                    $sessionId,
2066
                    ['visibility' => $session_visibility],
2067
                    false
2068
                );
2069
            }
2070
        }
2071
2072
        // Delete users from the session
2073
        if (true === $empty_users) {
2074
            $sql = "DELETE FROM $tbl_session_rel_user
2075
                    WHERE
2076
                      session_id = $sessionId AND
2077
                      relation_type <> ".SESSION_RELATION_TYPE_RRHH;
2078
            // Don't reset session_rel_user.registered_at of users that will be registered later anyways.
2079
            if (!empty($userList)) {
2080
                $avoidDeleteThisUsers = " AND user_id NOT IN ('".implode("','", $userList)."')";
2081
                $sql .= $avoidDeleteThisUsers;
2082
            }
2083
            Event::addEvent(
2084
                LOG_SESSION_DELETE_USER,
2085
                LOG_USER_ID,
2086
                'all',
2087
                api_get_utc_datetime(),
2088
                api_get_user_id(),
2089
                null,
2090
                $sessionId
2091
            );
2092
            Database::query($sql);
2093
        }
2094
2095
        // Insert missing users into session
2096
        foreach ($userList as $enreg_user) {
2097
            $isUserSubscribed = self::isUserSubscribedAsStudent($sessionId, $enreg_user);
2098
            if ($isUserSubscribed === false) {
2099
                $enreg_user = (int) $enreg_user;
2100
                $sql = "INSERT IGNORE INTO $tbl_session_rel_user (relation_type, session_id, user_id, registered_at)
2101
                        VALUES (0, $sessionId, $enreg_user, '".api_get_utc_datetime()."')";
2102
                Database::query($sql);
2103
                Event::addEvent(
2104
                    LOG_SESSION_ADD_USER,
2105
                    LOG_USER_ID,
2106
                    $enreg_user,
2107
                    api_get_utc_datetime(),
2108
                    api_get_user_id(),
2109
                    null,
2110
                    $sessionId
2111
                );
2112
            }
2113
        }
2114
2115
        // update number of users in the session
2116
        $sql = "UPDATE $tbl_session
2117
                SET nbr_users = (SELECT count(user_id) FROM $tbl_session_rel_user WHERE session_id = $sessionId)
2118
                WHERE id = $sessionId";
2119
        Database::query($sql);
2120
2121
        return true;
2122
    }
2123
2124
    /**
2125
     * Returns user list of the current users subscribed in the course-session.
2126
     *
2127
     * @param int   $sessionId
2128
     * @param array $courseInfo
2129
     * @param int   $status
2130
     *
2131
     * @return array
2132
     */
2133
    public static function getUsersByCourseSession(
2134
        $sessionId,
2135
        $courseInfo,
2136
        $status = null
2137
    ) {
2138
        $sessionId = (int) $sessionId;
2139
        $courseId = $courseInfo['real_id'];
2140
2141
        if (empty($sessionId) || empty($courseId)) {
2142
            return [];
2143
        }
2144
2145
        $statusCondition = null;
2146
        if (isset($status) && !is_null($status)) {
2147
            $status = (int) $status;
2148
            $statusCondition = " AND status = $status";
2149
        }
2150
2151
        $table = Database::get_main_table(TABLE_MAIN_SESSION_COURSE_USER);
2152
2153
        $sql = "SELECT DISTINCT user_id
2154
                FROM $table
2155
                WHERE
2156
                    session_id = $sessionId AND
2157
                    c_id = $courseId
2158
                    $statusCondition
2159
                ";
2160
2161
        $result = Database::query($sql);
2162
        $existingUsers = [];
2163
        while ($row = Database::fetch_array($result)) {
2164
            $existingUsers[] = $row['user_id'];
2165
        }
2166
2167
        return $existingUsers;
2168
    }
2169
2170
    /**
2171
     * Returns user list of the current users subscribed in the course-session.
2172
     *
2173
     * @param array $sessionList
2174
     * @param array $courseList
2175
     * @param int   $status
2176
     * @param int   $start
2177
     * @param int   $limit
2178
     *
2179
     * @return array
2180
     */
2181
    public static function getUsersByCourseAndSessionList(
2182
        $sessionList,
2183
        $courseList,
2184
        $status = null,
2185
        $start = null,
2186
        $limit = null
2187
    ) {
2188
        if (empty($sessionList) || empty($courseList)) {
2189
            return [];
2190
        }
2191
        $sessionListToString = implode("','", $sessionList);
2192
        $courseListToString = implode("','", $courseList);
2193
2194
        $statusCondition = null;
2195
        if (isset($status) && !is_null($status)) {
2196
            $status = (int) $status;
2197
            $statusCondition = " AND status = $status";
2198
        }
2199
2200
        $table = Database::get_main_table(TABLE_MAIN_SESSION_COURSE_USER);
2201
2202
        $sql = "SELECT DISTINCT user_id
2203
                FROM $table
2204
                WHERE
2205
                    session_id IN ('$sessionListToString') AND
2206
                    c_id IN ('$courseListToString')
2207
                    $statusCondition
2208
                ";
2209
        if (!is_null($start) && !is_null($limit)) {
2210
            $start = (int) $start;
2211
            $limit = (int) $limit;
2212
            $sql .= "LIMIT $start, $limit";
2213
        }
2214
        $result = Database::query($sql);
2215
        $existingUsers = [];
2216
        while ($row = Database::fetch_array($result)) {
2217
            $existingUsers[] = $row['user_id'];
2218
        }
2219
2220
        return $existingUsers;
2221
    }
2222
2223
    /**
2224
     * Remove a list of users from a course-session.
2225
     *
2226
     * @param array $userList
2227
     * @param int   $sessionId
2228
     * @param array $courseInfo
2229
     * @param int   $status
2230
     * @param bool  $updateTotal
2231
     *
2232
     * @return bool
2233
     */
2234
    public static function removeUsersFromCourseSession(
2235
        $userList,
2236
        $sessionId,
2237
        $courseInfo,
2238
        $status = null,
2239
        $updateTotal = true
2240
    ) {
2241
        $table = Database::get_main_table(TABLE_MAIN_SESSION_COURSE_USER);
2242
        $tableSessionCourse = Database::get_main_table(TABLE_MAIN_SESSION_COURSE);
2243
        $sessionId = (int) $sessionId;
2244
2245
        if (empty($sessionId) || empty($userList) || empty($courseInfo)) {
2246
            return false;
2247
        }
2248
2249
        is_array($courseInfo) ? $courseId = $courseInfo['real_id'] : $courseId = $courseInfo;
2250
2251
        $statusCondition = null;
2252
        if (isset($status) && !is_null($status)) {
2253
            $status = (int) $status;
2254
            $statusCondition = " AND status = $status";
2255
        }
2256
2257
        foreach ($userList as $userId) {
2258
            $userId = (int) $userId;
2259
            $sql = "DELETE FROM $table
2260
                    WHERE
2261
                        session_id = $sessionId AND
2262
                        c_id = $courseId AND
2263
                        user_id = $userId
2264
                        $statusCondition
2265
                    ";
2266
            Database::query($sql);
2267
2268
            Event::addEvent(
2269
                LOG_SESSION_DELETE_USER_COURSE,
2270
                LOG_USER_ID,
2271
                $userId,
2272
                api_get_utc_datetime(),
2273
                api_get_user_id(),
2274
                $courseId,
2275
                $sessionId
2276
            );
2277
        }
2278
2279
        if ($updateTotal) {
2280
            // Count users in this session-course relation
2281
            $sql = "SELECT COUNT(user_id) as nbUsers
2282
                    FROM $table
2283
                    WHERE
2284
                        session_id = $sessionId AND
2285
                        c_id = $courseId AND
2286
                        status <> 2";
2287
            $result = Database::query($sql);
2288
            [$userCount] = Database::fetch_array($result);
2289
2290
            // update the session-course relation to add the users total
2291
            $sql = "UPDATE $tableSessionCourse
2292
                    SET nbr_users = $userCount
2293
                    WHERE
2294
                        session_id = $sessionId AND
2295
                        c_id = $courseId";
2296
            Database::query($sql);
2297
        }
2298
    }
2299
2300
    /**
2301
     * Subscribe a user to an specific course inside a session.
2302
     *
2303
     * @param array  $user_list
2304
     * @param int    $session_id
2305
     * @param string $course_code
2306
     * @param int    $session_visibility
2307
     * @param bool   $removeUsersNotInList
2308
     *
2309
     * @return bool
2310
     */
2311
    public static function subscribe_users_to_session_course(
2312
        $user_list,
2313
        $session_id,
2314
        $course_code,
2315
        $session_visibility = SESSION_VISIBLE_READ_ONLY,
2316
        $removeUsersNotInList = false
2317
    ) {
2318
        if (empty($session_id) || empty($course_code)) {
2319
            return false;
2320
        }
2321
2322
        $session_id = (int) $session_id;
2323
        $session_visibility = (int) $session_visibility;
2324
        $course_code = Database::escape_string($course_code);
2325
        $courseInfo = api_get_course_info($course_code);
2326
        $courseId = $courseInfo['real_id'];
2327
        $subscribe = (int) api_get_course_setting('subscribe_users_to_forum_notifications', $courseInfo);
2328
        $forums = [];
2329
        if ($subscribe === 1) {
2330
            require_once api_get_path(SYS_CODE_PATH).'forum/forumfunction.inc.php';
2331
            $forums = get_forums(0, $course_code, true, $session_id);
2332
        }
2333
2334
        if ($removeUsersNotInList) {
2335
            $currentUsers = self::getUsersByCourseSession($session_id, $courseInfo, 0);
2336
2337
            if (!empty($user_list)) {
2338
                $userToDelete = array_diff($currentUsers, $user_list);
2339
            } else {
2340
                $userToDelete = $currentUsers;
2341
            }
2342
2343
            if (!empty($userToDelete)) {
2344
                self::removeUsersFromCourseSession(
2345
                    $userToDelete,
2346
                    $session_id,
2347
                    $courseInfo,
2348
                    0,
2349
                    true
2350
                );
2351
            }
2352
        }
2353
2354
        self::insertUsersInCourse(
2355
            $user_list,
2356
            $courseId,
2357
            $session_id,
2358
            ['visibility' => $session_visibility]
2359
        );
2360
2361
        if (!empty($forums)) {
2362
            foreach ($user_list as $enreg_user) {
2363
                $userInfo = api_get_user_info($enreg_user);
2364
                foreach ($forums as $forum) {
2365
                    $forumId = $forum['iid'];
2366
                    set_notification('forum', $forumId, false, $userInfo, $courseInfo);
2367
                }
2368
            }
2369
        }
2370
    }
2371
2372
    /**
2373
     * Unsubscribe user from session.
2374
     *
2375
     * @param int Session id
2376
     * @param int User id
2377
     *
2378
     * @return bool True in case of success, false in case of error
2379
     */
2380
    public static function unsubscribe_user_from_session($session_id, $user_id)
2381
    {
2382
        $session_id = (int) $session_id;
2383
        $user_id = (int) $user_id;
2384
2385
        $tbl_session_rel_user = Database::get_main_table(TABLE_MAIN_SESSION_USER);
2386
        $tbl_session = Database::get_main_table(TABLE_MAIN_SESSION);
2387
2388
        $sql = "DELETE FROM $tbl_session_rel_user
2389
                WHERE
2390
                    session_id = $session_id AND
2391
                    user_id = $user_id AND
2392
                    relation_type <> ".SESSION_RELATION_TYPE_RRHH;
2393
        $result = Database::query($sql);
2394
        $return = Database::affected_rows($result);
2395
2396
        // Update number of users
2397
        $sql = "UPDATE $tbl_session
2398
                SET nbr_users = nbr_users - $return
2399
                WHERE id = $session_id ";
2400
        Database::query($sql);
2401
2402
        Event::addEvent(
2403
            LOG_SESSION_DELETE_USER,
2404
            LOG_USER_ID,
2405
            $user_id,
2406
            api_get_utc_datetime(),
2407
            api_get_user_id(),
2408
            null,
2409
            $session_id
2410
        );
2411
2412
        // Get the list of courses related to this session
2413
        $course_list = self::get_course_list_by_session_id($session_id);
2414
        if (!empty($course_list)) {
2415
            foreach ($course_list as $course) {
2416
                self::unSubscribeUserFromCourseSession($user_id, $course['id'], $session_id);
2417
            }
2418
        }
2419
2420
        return true;
2421
    }
2422
2423
    /**
2424
     * @param int $user_id
2425
     * @param int $courseId
2426
     * @param int $session_id
2427
     */
2428
    public static function unSubscribeUserFromCourseSession($user_id, $courseId, $session_id)
2429
    {
2430
        $user_id = (int) $user_id;
2431
        $courseId = (int) $courseId;
2432
        $session_id = (int) $session_id;
2433
2434
        $tbl_session_rel_course_rel_user = Database::get_main_table(TABLE_MAIN_SESSION_COURSE_USER);
2435
        $tbl_session_rel_course = Database::get_main_table(TABLE_MAIN_SESSION_COURSE);
2436
2437
        // Delete user from course
2438
        $sql = "DELETE FROM $tbl_session_rel_course_rel_user
2439
                WHERE session_id = $session_id AND c_id = $courseId AND user_id = $user_id";
2440
        $result = Database::query($sql);
2441
2442
        if (Database::affected_rows($result)) {
2443
            // Update number of users in this relation
2444
            $sql = "UPDATE $tbl_session_rel_course SET
2445
                    nbr_users = nbr_users - 1
2446
                    WHERE session_id = $session_id AND c_id = $courseId";
2447
            Database::query($sql);
2448
        }
2449
2450
        Event::addEvent(
2451
            LOG_SESSION_DELETE_USER_COURSE,
2452
            LOG_USER_ID,
2453
            $user_id,
2454
            api_get_utc_datetime(),
2455
            api_get_user_id(),
2456
            $courseId,
2457
            $session_id
2458
        );
2459
    }
2460
2461
    /**
2462
     * Subscribes courses to the given session and optionally (default)
2463
     * unsubscribe previous users.
2464
     *
2465
     * @author Carlos Vargas from existing code
2466
     *
2467
     * @param int   $sessionId
2468
     * @param array $courseList                     List of courses int ids
2469
     * @param bool  $removeExistingCoursesWithUsers Whether to unsubscribe
2470
     *                                              existing courses and users (true, default) or not (false)
2471
     * @param bool  $copyEvaluation                 from base course to session course
2472
     * @param bool  $copyCourseTeachersAsCoach
2473
     * @param bool  $importAssignments
2474
     *
2475
     * @throws Exception
2476
     *
2477
     * @return bool False on failure, true otherwise
2478
     * */
2479
    public static function add_courses_to_session(
2480
        $sessionId,
2481
        $courseList,
2482
        $removeExistingCoursesWithUsers = true,
2483
        $copyEvaluation = false,
2484
        $copyCourseTeachersAsCoach = false,
2485
        $importAssignments = false
2486
    ) {
2487
        $sessionId = (int) $sessionId;
2488
2489
        if (empty($sessionId) || empty($courseList)) {
2490
            return false;
2491
        }
2492
2493
        if ($importAssignments) {
2494
            require_once api_get_path(SYS_CODE_PATH).'work/work.lib.php';
2495
        }
2496
2497
        $session = api_get_session_entity($sessionId);
2498
2499
        if (!$session) {
2500
            return false;
2501
        }
2502
        $sessionVisibility = $session->getVisibility();
2503
2504
        $tbl_session_rel_course_rel_user = Database::get_main_table(TABLE_MAIN_SESSION_COURSE_USER);
2505
        $tbl_session = Database::get_main_table(TABLE_MAIN_SESSION);
2506
        $tbl_session_rel_user = Database::get_main_table(TABLE_MAIN_SESSION_USER);
2507
        $tbl_session_rel_course = Database::get_main_table(TABLE_MAIN_SESSION_COURSE);
2508
2509
        // Get list of courses subscribed to this session
2510
        $sql = "SELECT c_id
2511
                FROM $tbl_session_rel_course
2512
                WHERE session_id = $sessionId";
2513
        $rs = Database::query($sql);
2514
        $existingCourses = Database::store_result($rs);
2515
        $nbr_courses = count($existingCourses);
2516
2517
        // Get list of users subscribed to this session
2518
        $sql = "SELECT user_id
2519
                FROM $tbl_session_rel_user
2520
                WHERE
2521
                    session_id = $sessionId AND
2522
                    relation_type<>".SESSION_RELATION_TYPE_RRHH;
2523
        $result = Database::query($sql);
2524
        $user_list = Database::store_result($result);
2525
2526
        // Remove existing courses from the session.
2527
        if ($removeExistingCoursesWithUsers === true && !empty($existingCourses)) {
2528
            foreach ($existingCourses as $existingCourse) {
2529
                if (!in_array($existingCourse['c_id'], $courseList)) {
2530
                    $sql = "DELETE FROM $tbl_session_rel_course
2531
                            WHERE
2532
                                c_id = ".$existingCourse['c_id']." AND
2533
                                session_id = $sessionId";
2534
                    Database::query($sql);
2535
2536
                    $sql = "DELETE FROM $tbl_session_rel_course_rel_user
2537
                            WHERE
2538
                                c_id = ".$existingCourse['c_id']." AND
2539
                                session_id = $sessionId";
2540
                    Database::query($sql);
2541
2542
                    Event::addEvent(
2543
                        LOG_SESSION_DELETE_COURSE,
2544
                        LOG_COURSE_ID,
2545
                        $existingCourse['c_id'],
2546
                        api_get_utc_datetime(),
2547
                        api_get_user_id(),
2548
                        $existingCourse['c_id'],
2549
                        $sessionId
2550
                    );
2551
2552
                    CourseManager::remove_course_ranking(
2553
                        $existingCourse['c_id'],
2554
                        $sessionId
2555
                    );
2556
                    $nbr_courses--;
2557
                }
2558
            }
2559
        }
2560
2561
        // Pass through the courses list we want to add to the session
2562
        foreach ($courseList as $courseId) {
2563
            $courseInfo = api_get_course_info_by_id($courseId);
2564
2565
            // If course doesn't exists continue!
2566
            if (empty($courseInfo)) {
2567
                continue;
2568
            }
2569
2570
            $exists = false;
2571
            // check if the course we want to add is already subscribed
2572
            foreach ($existingCourses as $existingCourse) {
2573
                if ($courseId == $existingCourse['c_id']) {
2574
                    $exists = true;
2575
                }
2576
            }
2577
2578
            if (!$exists) {
2579
                // Copy gradebook categories and links (from base course)
2580
                // to the new course session
2581
                if ($copyEvaluation) {
2582
                    $cats = Category::load(null, null, $courseInfo['code']);
2583
                    if (!empty($cats)) {
2584
                        $sessionCategory = Category:: load(
2585
                            null,
2586
                            null,
2587
                            $courseInfo['code'],
2588
                            null,
2589
                            null,
2590
                            $sessionId,
2591
                            false
2592
                        );
2593
2594
                        // @todo remove commented code
2595
                        if (empty($sessionCategory)) {
2596
                            // There is no category for this course+session, so create one
2597
                            $cat = new Category();
2598
                            $sessionName = $session->getName();
2599
                            $cat->set_name($courseInfo['code'].' - '.get_lang('Session').' '.$sessionName);
2600
                            $cat->set_session_id($sessionId);
2601
                            $cat->set_course_code($courseInfo['code']);
2602
                            $cat->set_description(null);
2603
                            //$cat->set_user_id($stud_id);
2604
                            $cat->set_parent_id(0);
2605
                            $cat->set_weight(100);
2606
                            $cat->set_visible(0);
2607
                            $cat->set_certificate_min_score(75);
2608
                            $cat->add();
2609
                            $sessionGradeBookCategoryId = $cat->get_id();
2610
                        } else {
2611
                            if (!empty($sessionCategory[0])) {
2612
                                $sessionGradeBookCategoryId = $sessionCategory[0]->get_id();
2613
                            }
2614
                        }
2615
2616
                        $categoryIdList = [];
2617
                        /** @var Category $cat */
2618
                        foreach ($cats as $cat) {
2619
                            $categoryIdList[$cat->get_id()] = $cat->get_id();
2620
                        }
2621
2622
                        $newCategoryIdList = [];
2623
                        foreach ($cats as $cat) {
2624
                            $links = $cat->get_links(
2625
                                null,
2626
                                false,
2627
                                $courseInfo['code'],
2628
                                0
2629
                            );
2630
2631
                            //$cat->set_session_id($sessionId);
2632
                            //$oldCategoryId = $cat->get_id();
2633
                            //$newId = $cat->add();
2634
                            //$newCategoryIdList[$oldCategoryId] = $newId;
2635
                            //$parentId = $cat->get_parent_id();
2636
2637
                            /*if (!empty($parentId)) {
2638
                                $newParentId = $newCategoryIdList[$parentId];
2639
                                $cat->set_parent_id($newParentId);
2640
                                $cat->save();
2641
                            }*/
2642
2643
                            if (!empty($links)) {
2644
                                /** @var AbstractLink $link */
2645
                                foreach ($links as $link) {
2646
                                    //$newCategoryId = $newCategoryIdList[$link->get_category_id()];
2647
                                    $link->set_category_id($sessionGradeBookCategoryId);
2648
                                    $link->add();
2649
                                }
2650
                            }
2651
2652
                            $evaluationList = $cat->get_evaluations(
2653
                                null,
2654
                                false,
2655
                                $courseInfo['code'],
2656
                                0
2657
                            );
2658
2659
                            if (!empty($evaluationList)) {
2660
                                /** @var Evaluation $evaluation */
2661
                                foreach ($evaluationList as $evaluation) {
2662
                                    //$evaluationId = $newCategoryIdList[$evaluation->get_category_id()];
2663
                                    $evaluation->set_category_id($sessionGradeBookCategoryId);
2664
                                    $evaluation->add();
2665
                                }
2666
                            }
2667
                        }
2668
2669
                        // Create
2670
                        DocumentManager::generateDefaultCertificate(
2671
                            $courseInfo,
2672
                            true,
2673
                            $sessionId
2674
                        );
2675
                    }
2676
                }
2677
2678
                if ($importAssignments) {
2679
                    $workTable = Database::get_course_table(TABLE_STUDENT_PUBLICATION);
2680
                    $sql = " SELECT * FROM $workTable
2681
                             WHERE active = 1 AND
2682
                                   c_id = $courseId AND
2683
                                   parent_id = 0 AND
2684
                                   (session_id IS NULL OR session_id = 0)";
2685
                    $result = Database::query($sql);
2686
                    $workList = Database::store_result($result, 'ASSOC');
2687
2688
                    foreach ($workList as $work) {
2689
                        $values = [
2690
                            'work_title' => $work['title'],
2691
                            'new_dir' => $work['url'].'_session_'.$sessionId,
2692
                            'description' => $work['description'],
2693
                            'qualification' => $work['qualification'],
2694
                            'allow_text_assignment' => $work['allow_text_assignment'],
2695
                        ];
2696
2697
                        addDir(
2698
                            $values,
2699
                            api_get_user_id(),
2700
                            $courseInfo,
2701
                            0,
2702
                            $sessionId
2703
                        );
2704
                    }
2705
                }
2706
2707
                // If the course isn't subscribed yet
2708
                $sql = "INSERT INTO $tbl_session_rel_course (session_id, c_id, nbr_users, position)
2709
                        VALUES ($sessionId, $courseId, 0, 0)";
2710
                Database::query($sql);
2711
2712
                Event::addEvent(
2713
                    LOG_SESSION_ADD_COURSE,
2714
                    LOG_COURSE_ID,
2715
                    $courseId,
2716
                    api_get_utc_datetime(),
2717
                    api_get_user_id(),
2718
                    $courseId,
2719
                    $sessionId
2720
                );
2721
2722
                // We add the current course in the existing courses array,
2723
                // to avoid adding another time the current course
2724
                $existingCourses[] = ['c_id' => $courseId];
2725
                $nbr_courses++;
2726
2727
                // Subscribe all the users from the session to this course inside the session
2728
                self::insertUsersInCourse(
2729
                    array_column($user_list, 'user_id'),
2730
                    $courseId,
2731
                    $sessionId,
2732
                    ['visibility' => $sessionVisibility]
2733
                );
2734
            }
2735
2736
            if ($copyCourseTeachersAsCoach) {
2737
                $teachers = CourseManager::get_teacher_list_from_course_code($courseInfo['code']);
2738
                if (!empty($teachers)) {
2739
                    foreach ($teachers as $teacher) {
2740
                        self::updateCoaches(
2741
                            $sessionId,
2742
                            $courseId,
2743
                            [$teacher['user_id']],
2744
                            false
2745
                        );
2746
                    }
2747
                }
2748
            }
2749
        }
2750
2751
        $sql = "UPDATE $tbl_session SET nbr_courses = $nbr_courses WHERE id = $sessionId";
2752
        Database::query($sql);
2753
2754
        return true;
2755
    }
2756
2757
    /**
2758
     * Unsubscribe course from a session.
2759
     *
2760
     * @param int $session_id
2761
     * @param int $course_id
2762
     *
2763
     * @return bool True in case of success, false otherwise
2764
     */
2765
    public static function unsubscribe_course_from_session($session_id, $course_id)
2766
    {
2767
        $session_id = (int) $session_id;
2768
        $course_id = (int) $course_id;
2769
2770
        $tbl_session_rel_course = Database::get_main_table(TABLE_MAIN_SESSION_COURSE);
2771
        $tbl_session_rel_course_rel_user = Database::get_main_table(TABLE_MAIN_SESSION_COURSE_USER);
2772
        $tbl_session = Database::get_main_table(TABLE_MAIN_SESSION);
2773
2774
        // Get course code
2775
        $course_code = CourseManager::get_course_code_from_course_id($course_id);
2776
2777
        if (empty($course_code)) {
2778
            return false;
2779
        }
2780
2781
        // Unsubscribe course
2782
        $sql = "DELETE FROM $tbl_session_rel_course
2783
                WHERE c_id = $course_id AND session_id = $session_id";
2784
        $result = Database::query($sql);
2785
        $nb_affected = Database::affected_rows($result);
2786
2787
        $sql = "DELETE FROM $tbl_session_rel_course_rel_user
2788
                WHERE c_id = $course_id AND session_id = $session_id";
2789
        Database::query($sql);
2790
2791
        Event::addEvent(
2792
            LOG_SESSION_DELETE_COURSE,
2793
            LOG_COURSE_ID,
2794
            $course_id,
2795
            api_get_utc_datetime(),
2796
            api_get_user_id(),
2797
            $course_id,
2798
            $session_id
2799
        );
2800
2801
        if ($nb_affected > 0) {
2802
            // Update number of courses in the session
2803
            $sql = "UPDATE $tbl_session SET nbr_courses= nbr_courses - $nb_affected
2804
                    WHERE id = $session_id";
2805
            Database::query($sql);
2806
2807
            return true;
2808
        }
2809
2810
        return false;
2811
    }
2812
2813
    /**
2814
     * Creates a new extra field for a given session.
2815
     *
2816
     * @param string $variable    Field's internal variable name
2817
     * @param int    $fieldType   Field's type
2818
     * @param string $displayText Field's language var name
2819
     * @param string $default     Field's default value
2820
     *
2821
     * @return int new extra field id
2822
     */
2823
    public static function create_session_extra_field(
2824
        $variable,
2825
        $fieldType,
2826
        $displayText,
2827
        $default = ''
2828
    ) {
2829
        $extraField = new ExtraFieldModel('session');
2830
        $params = [
2831
            'variable' => $variable,
2832
            'field_type' => $fieldType,
2833
            'display_text' => $displayText,
2834
            'default_value' => $default,
2835
        ];
2836
2837
        return $extraField->save($params);
2838
    }
2839
2840
    /**
2841
     * Update an extra field value for a given session.
2842
     *
2843
     * @param int    $sessionId Session ID
2844
     * @param string $variable  Field variable name
2845
     * @param string $value     Optional. Default field value
2846
     *
2847
     * @return bool|int An integer when register a new extra field. And boolean when update the extrafield
2848
     */
2849
    public static function update_session_extra_field_value($sessionId, $variable, $value = '')
2850
    {
2851
        $extraFieldValue = new ExtraFieldValue('session');
2852
        $params = [
2853
            'item_id' => $sessionId,
2854
            'variable' => $variable,
2855
            'value' => $value,
2856
        ];
2857
2858
        return $extraFieldValue->save($params);
2859
    }
2860
2861
    /**
2862
     * Checks the relationship between a session and a course.
2863
     *
2864
     * @param int $session_id
2865
     * @param int $courseId
2866
     *
2867
     * @return bool returns TRUE if the session and the course are related, FALSE otherwise
2868
     * */
2869
    public static function relation_session_course_exist($session_id, $courseId)
2870
    {
2871
        $tbl_session_course = Database::get_main_table(TABLE_MAIN_SESSION_COURSE);
2872
        $return_value = false;
2873
        $sql = "SELECT c_id FROM $tbl_session_course
2874
                WHERE
2875
                  session_id = ".intval($session_id)." AND
2876
                  c_id = ".intval($courseId);
2877
        $result = Database::query($sql);
2878
        $num = Database::num_rows($result);
2879
        if ($num > 0) {
2880
            $return_value = true;
2881
        }
2882
2883
        return $return_value;
2884
    }
2885
2886
    /**
2887
     * Get the session information by name.
2888
     *
2889
     * @param string $name
2890
     *
2891
     * @return mixed false if the session does not exist, array if the session exist
2892
     */
2893
    public static function get_session_by_name($name)
2894
    {
2895
        $tbl_session = Database::get_main_table(TABLE_MAIN_SESSION);
2896
        $name = Database::escape_string(trim($name));
2897
        if (empty($name)) {
2898
            return false;
2899
        }
2900
2901
        $sql = 'SELECT *
2902
		        FROM '.$tbl_session.'
2903
		        WHERE name = "'.$name.'"';
2904
        $result = Database::query($sql);
2905
        $num = Database::num_rows($result);
2906
        if ($num > 0) {
2907
            return Database::fetch_array($result);
2908
        } else {
2909
            return false;
2910
        }
2911
    }
2912
2913
    /**
2914
     * @param int $sessionId
2915
     * @param int $name
2916
     *
2917
     * @return bool
2918
     */
2919
    public static function sessionNameExistBesidesMySession($sessionId, $name)
2920
    {
2921
        $table = Database::get_main_table(TABLE_MAIN_SESSION);
2922
        $name = Database::escape_string(trim($name));
2923
        $sessionId = (int) $sessionId;
2924
2925
        if (empty($name)) {
2926
            return false;
2927
        }
2928
2929
        $sql = "SELECT *
2930
		        FROM $table
2931
		        WHERE name = '$name' AND id <> $sessionId ";
2932
        $result = Database::query($sql);
2933
        $num = Database::num_rows($result);
2934
        if ($num > 0) {
2935
            return true;
2936
        }
2937
2938
        return false;
2939
    }
2940
2941
    /**
2942
     * Create a session category.
2943
     *
2944
     * @author Jhon Hinojosa <[email protected]>, from existing code
2945
     *
2946
     * @param string        name
2947
     * @param int        year_start
2948
     * @param int        month_start
2949
     * @param int        day_start
2950
     * @param int        year_end
2951
     * @param int        month_end
2952
     * @param int        day_end
2953
     *
2954
     * @return int session ID
2955
     * */
2956
    public static function create_category_session(
2957
        $sname,
2958
        $syear_start,
2959
        $smonth_start,
2960
        $sday_start,
2961
        $syear_end,
2962
        $smonth_end,
2963
        $sday_end
2964
    ) {
2965
        $tbl_session_category = Database::get_main_table(TABLE_MAIN_SESSION_CATEGORY);
2966
        $name = trim($sname);
2967
        $year_start = intval($syear_start);
2968
        $month_start = intval($smonth_start);
2969
        $day_start = intval($sday_start);
2970
        $year_end = intval($syear_end);
2971
        $month_end = intval($smonth_end);
2972
        $day_end = intval($sday_end);
2973
2974
        $date_start = "$year_start-".(($month_start < 10) ? "0$month_start" : $month_start)."-".(($day_start < 10) ? "0$day_start" : $day_start);
2975
        $date_end = "$year_end-".(($month_end < 10) ? "0$month_end" : $month_end)."-".(($day_end < 10) ? "0$day_end" : $day_end);
2976
2977
        if (empty($name)) {
2978
            $msg = get_lang('SessionCategoryNameIsRequired');
2979
2980
            return $msg;
2981
        } elseif (!$month_start || !$day_start || !$year_start || !checkdate($month_start, $day_start, $year_start)) {
2982
            $msg = get_lang('InvalidStartDate');
2983
2984
            return $msg;
2985
        } elseif (!$month_end && !$day_end && !$year_end) {
2986
            $date_end = '';
2987
        } elseif (!$month_end || !$day_end || !$year_end || !checkdate($month_end, $day_end, $year_end)) {
2988
            $msg = get_lang('InvalidEndDate');
2989
2990
            return $msg;
2991
        } elseif ($date_start >= $date_end) {
2992
            $msg = get_lang('StartDateShouldBeBeforeEndDate');
2993
2994
            return $msg;
2995
        }
2996
2997
        $access_url_id = api_get_current_access_url_id();
2998
        $params = [
2999
            'name' => $name,
3000
            'date_start' => $date_start,
3001
            'access_url_id' => $access_url_id,
3002
        ];
3003
3004
        if (!empty($date_end)) {
3005
            $params['date_end'] = $date_end;
3006
        }
3007
3008
        $id = Database::insert($tbl_session_category, $params);
3009
3010
        // Add event to system log
3011
        $user_id = api_get_user_id();
3012
        Event::addEvent(
3013
            LOG_SESSION_CATEGORY_CREATE,
3014
            LOG_SESSION_CATEGORY_ID,
3015
            $id,
3016
            api_get_utc_datetime(),
3017
            $user_id
3018
        );
3019
3020
        return $id;
3021
    }
3022
3023
    /**
3024
     * Edit a sessions category.
3025
     *
3026
     * @author Jhon Hinojosa <[email protected]>,from existing code
3027
     *
3028
     * @param int        id
3029
     * @param string        name
3030
     * @param int        year_start
3031
     * @param int        month_start
3032
     * @param int        day_start
3033
     * @param int        year_end
3034
     * @param int        month_end
3035
     * @param int        day_end
3036
     *
3037
     * @return bool
3038
     *              The parameter id is a primary key
3039
     * */
3040
    public static function edit_category_session(
3041
        $id,
3042
        $sname,
3043
        $syear_start,
3044
        $smonth_start,
3045
        $sday_start,
3046
        $syear_end,
3047
        $smonth_end,
3048
        $sday_end
3049
    ) {
3050
        $tbl_session_category = Database::get_main_table(TABLE_MAIN_SESSION_CATEGORY);
3051
        $name = trim($sname);
3052
        $year_start = intval($syear_start);
3053
        $month_start = intval($smonth_start);
3054
        $day_start = intval($sday_start);
3055
        $year_end = intval($syear_end);
3056
        $month_end = intval($smonth_end);
3057
        $day_end = intval($sday_end);
3058
        $id = intval($id);
3059
        $date_start = "$year_start-".(($month_start < 10) ? "0$month_start" : $month_start)."-".(($day_start < 10) ? "0$day_start" : $day_start);
3060
        $date_end = "$year_end-".(($month_end < 10) ? "0$month_end" : $month_end)."-".(($day_end < 10) ? "0$day_end" : $day_end);
3061
3062
        if (empty($name)) {
3063
            $msg = get_lang('SessionCategoryNameIsRequired');
3064
3065
            return $msg;
3066
        } elseif (!$month_start || !$day_start || !$year_start || !checkdate($month_start, $day_start, $year_start)) {
3067
            $msg = get_lang('InvalidStartDate');
3068
3069
            return $msg;
3070
        } elseif (!$month_end && !$day_end && !$year_end) {
3071
            $date_end = null;
3072
        } elseif (!$month_end || !$day_end || !$year_end || !checkdate($month_end, $day_end, $year_end)) {
3073
            $msg = get_lang('InvalidEndDate');
3074
3075
            return $msg;
3076
        } elseif ($date_start >= $date_end) {
3077
            $msg = get_lang('StartDateShouldBeBeforeEndDate');
3078
3079
            return $msg;
3080
        }
3081
        if ($date_end != null) {
3082
            $sql = "UPDATE $tbl_session_category
3083
                    SET
3084
                        name = '".Database::escape_string($name)."',
3085
                        date_start = '$date_start' ,
3086
                        date_end = '$date_end'
3087
                    WHERE id= $id";
3088
        } else {
3089
            $sql = "UPDATE $tbl_session_category SET
3090
                        name = '".Database::escape_string($name)."',
3091
                        date_start = '$date_start',
3092
                        date_end = NULL
3093
                    WHERE id= $id";
3094
        }
3095
        $result = Database::query($sql);
3096
3097
        return $result ? true : false;
3098
    }
3099
3100
    /**
3101
     * Delete sessions categories.
3102
     *
3103
     * @param array|int $categoryId
3104
     * @param bool      $deleteSessions Optional. Include delete session.
3105
     * @param bool      $fromWs         Optional. True if the function is called by a webservice, false otherwise.
3106
     *
3107
     * @return bool Nothing, or false on error
3108
     *              The parameters is a array to delete sessions
3109
     *
3110
     * @author Jhon Hinojosa <[email protected]>, from existing code
3111
     */
3112
    public static function delete_session_category($categoryId, $deleteSessions = false, $fromWs = false)
3113
    {
3114
        $tblSessionCategory = Database::get_main_table(TABLE_MAIN_SESSION_CATEGORY);
3115
        $tblSession = Database::get_main_table(TABLE_MAIN_SESSION);
3116
3117
        if (is_array($categoryId)) {
3118
            $categoryId = array_map('intval', $categoryId);
3119
        } else {
3120
            $categoryId = [(int) $categoryId];
3121
        }
3122
3123
        $categoryId = implode(', ', $categoryId);
3124
3125
        if ($deleteSessions) {
3126
            $sql = "SELECT id FROM $tblSession WHERE session_category_id IN ($categoryId)";
3127
            $result = Database::query($sql);
3128
            while ($rows = Database::fetch_array($result)) {
3129
                $sessionId = $rows['id'];
3130
                self::delete($sessionId, $fromWs);
3131
            }
3132
        } else {
3133
            $sql = "UPDATE $tblSession SET session_category_id = NULL WHERE session_category_id IN ($categoryId)";
3134
            Database::query($sql);
3135
        }
3136
3137
        $sql = "DELETE FROM $tblSessionCategory WHERE id IN ($categoryId)";
3138
        Database::query($sql);
3139
3140
        // Add event to system log
3141
        Event::addEvent(
3142
            LOG_SESSION_CATEGORY_DELETE,
3143
            LOG_SESSION_CATEGORY_ID,
3144
            $categoryId,
3145
            api_get_utc_datetime(),
3146
            api_get_user_id()
3147
        );
3148
3149
        return true;
3150
    }
3151
3152
    /**
3153
     * Get a list of sessions of which the given conditions match with an = 'cond'.
3154
     *
3155
     * @param array $conditions          a list of condition example :
3156
     *                                   array('status' => STUDENT) or
3157
     *                                   array('s.name' => array('operator' => 'LIKE', value = '%$needle%'))
3158
     * @param array $order_by            a list of fields on which sort
3159
     * @param int   $urlId
3160
     * @param array $onlyThisSessionList
3161
     *
3162
     * @return array an array with all sessions of the platform
3163
     *
3164
     * @todo   optional course code parameter, optional sorting parameters...
3165
     */
3166
    public static function get_sessions_list(
3167
        $conditions = [],
3168
        $order_by = [],
3169
        $from = null,
3170
        $to = null,
3171
        $urlId = 0,
3172
        $onlyThisSessionList = []
3173
    ) {
3174
        $session_table = Database::get_main_table(TABLE_MAIN_SESSION);
3175
        $session_category_table = Database::get_main_table(TABLE_MAIN_SESSION_CATEGORY);
3176
        $user_table = Database::get_main_table(TABLE_MAIN_USER);
3177
        $table_access_url_rel_session = Database::get_main_table(TABLE_MAIN_ACCESS_URL_REL_SESSION);
3178
        $session_course_table = Database::get_main_table(TABLE_MAIN_SESSION_COURSE);
3179
        $course_table = Database::get_main_table(TABLE_MAIN_COURSE);
3180
        $urlId = empty($urlId) ? api_get_current_access_url_id() : (int) $urlId;
3181
        $return_array = [];
3182
3183
        $sql_query = " SELECT
3184
                    DISTINCT(s.id),
3185
                    s.name,
3186
                    s.nbr_courses,
3187
                    s.access_start_date,
3188
                    s.access_end_date,
3189
                    u.firstname,
3190
                    u.lastname,
3191
                    sc.name as category_name,
3192
                    s.promotion_id
3193
				FROM $session_table s
3194
				INNER JOIN $user_table u ON s.id_coach = u.user_id
3195
				INNER JOIN $table_access_url_rel_session ar ON ar.session_id = s.id
3196
				LEFT JOIN  $session_category_table sc ON s.session_category_id = sc.id
3197
				LEFT JOIN $session_course_table sco ON (sco.session_id = s.id)
3198
				INNER JOIN $course_table c ON sco.c_id = c.id
3199
				WHERE ar.access_url_id = $urlId ";
3200
3201
        $availableFields = [
3202
            's.id',
3203
            's.name',
3204
            'c.id',
3205
        ];
3206
3207
        $availableOperator = [
3208
            'like',
3209
            '>=',
3210
            '<=',
3211
            '=',
3212
        ];
3213
3214
        if (count($conditions) > 0) {
3215
            foreach ($conditions as $field => $options) {
3216
                $operator = strtolower($options['operator']);
3217
                $value = Database::escape_string($options['value']);
3218
                if (in_array($field, $availableFields) && in_array($operator, $availableOperator)) {
3219
                    $sql_query .= ' AND '.$field." $operator '".$value."'";
3220
                }
3221
            }
3222
        }
3223
3224
        if (!empty($onlyThisSessionList)) {
3225
            $onlyThisSessionList = array_map('intval', $onlyThisSessionList);
3226
            $onlyThisSessionList = implode("','", $onlyThisSessionList);
3227
            $sql_query .= " AND s.id IN ('$onlyThisSessionList') ";
3228
        }
3229
3230
        $orderAvailableList = ['name'];
3231
        if (count($order_by) > 0) {
3232
            $order = null;
3233
            $direction = null;
3234
            if (isset($order_by[0]) && in_array($order_by[0], $orderAvailableList)) {
3235
                $order = $order_by[0];
3236
            }
3237
            if (isset($order_by[1]) && in_array(strtolower($order_by[1]), ['desc', 'asc'])) {
3238
                $direction = $order_by[1];
3239
            }
3240
3241
            if (!empty($order)) {
3242
                $sql_query .= " ORDER BY `$order` $direction ";
3243
            }
3244
        }
3245
3246
        if (!is_null($from) && !is_null($to)) {
3247
            $to = (int) $to;
3248
            $from = (int) $from;
3249
            $sql_query .= "LIMIT $from, $to";
3250
        }
3251
3252
        $sql_result = Database::query($sql_query);
3253
        if (Database::num_rows($sql_result) > 0) {
3254
            while ($result = Database::fetch_array($sql_result)) {
3255
                $return_array[$result['id']] = $result;
3256
            }
3257
        }
3258
3259
        return $return_array;
3260
    }
3261
3262
    /**
3263
     * Get the session category information by id.
3264
     *
3265
     * @param string session category ID
3266
     *
3267
     * @return mixed false if the session category does not exist, array if the session category exists
3268
     */
3269
    public static function get_session_category($id)
3270
    {
3271
        $table = Database::get_main_table(TABLE_MAIN_SESSION_CATEGORY);
3272
        $id = (int) $id;
3273
        $sql = "SELECT id, name, date_start, date_end
3274
                FROM $table
3275
                WHERE id= $id";
3276
        $result = Database::query($sql);
3277
        $num = Database::num_rows($result);
3278
        if ($num > 0) {
3279
            return Database::fetch_array($result);
3280
        } else {
3281
            return false;
3282
        }
3283
    }
3284
3285
    /**
3286
     * Get Hot Sessions (limit 8).
3287
     *
3288
     * @return array with sessions
3289
     */
3290
    public static function getHotSessions()
3291
    {
3292
        $tbl_session = Database::get_main_table(TABLE_MAIN_SESSION);
3293
        $tbl_session_category = Database::get_main_table(TABLE_MAIN_SESSION_CATEGORY);
3294
        $tbl_users = Database::get_main_table(TABLE_MAIN_USER);
3295
        $tbl_extra_fields = Database::get_main_table(TABLE_EXTRA_FIELD_VALUES);
3296
        $tbl_session_user = Database::get_main_table(TABLE_MAIN_SESSION_USER);
3297
        $tbl_lp = Database::get_course_table(TABLE_LP_MAIN);
3298
3299
        $extraField = new ExtraFieldModel('session');
3300
        $field = $extraField->get_handler_field_info_by_field_variable('image');
3301
3302
        $sql = "SELECT
3303
                s.id,
3304
                s.name,
3305
                s.id_coach,
3306
                u.firstname,
3307
                u.lastname,
3308
                s.session_category_id,
3309
                c.name as category_name,
3310
                s.description,
3311
                (SELECT COUNT(*) FROM $tbl_session_user WHERE session_id = s.id) as users,
3312
				(SELECT COUNT(*) FROM $tbl_lp WHERE session_id = s.id) as lessons ";
3313
        if ($field !== false) {
3314
            $fieldId = $field['id'];
3315
            $sql .= ",(SELECT value FROM $tbl_extra_fields WHERE field_id = $fieldId AND item_id = s.id) as image ";
3316
        }
3317
        $sql .= " FROM $tbl_session s
3318
                LEFT JOIN $tbl_session_category c
3319
                    ON s.session_category_id = c.id
3320
                INNER JOIN $tbl_users u
3321
                    ON s.id_coach = u.id
3322
                ORDER BY 9 DESC
3323
                LIMIT 8";
3324
        $result = Database::query($sql);
3325
3326
        if (Database::num_rows($result) > 0) {
3327
            $plugin = BuyCoursesPlugin::create();
3328
            $checker = $plugin->isEnabled();
3329
            $sessions = [];
3330
            while ($row = Database::fetch_array($result, 'ASSOC')) {
3331
                if (!isset($row['image'])) {
3332
                    $row['image'] = '';
3333
                }
3334
                $row['on_sale'] = '';
3335
                if ($checker) {
3336
                    $row['on_sale'] = $plugin->getItemByProduct(
3337
                        $row['id'],
3338
                        BuyCoursesPlugin::PRODUCT_TYPE_SESSION
3339
                    );
3340
                }
3341
                $sessions[] = $row;
3342
            }
3343
3344
            return $sessions;
3345
        }
3346
3347
        return false;
3348
    }
3349
3350
    /**
3351
     * Get all session categories (filter by access_url_id).
3352
     *
3353
     * @return mixed false if the session category does not exist, array if the session category exists
3354
     */
3355
    public static function get_all_session_category()
3356
    {
3357
        $table = Database::get_main_table(TABLE_MAIN_SESSION_CATEGORY);
3358
        $id = api_get_current_access_url_id();
3359
        $sql = 'SELECT * FROM '.$table.'
3360
                WHERE access_url_id = '.$id.'
3361
                ORDER BY name ASC';
3362
        $result = Database::query($sql);
3363
        if (Database::num_rows($result) > 0) {
3364
            $data = Database::store_result($result, 'ASSOC');
3365
3366
            return $data;
3367
        }
3368
3369
        return false;
3370
    }
3371
3372
    /**
3373
     * Assign a coach to course in session with status = 2.
3374
     *
3375
     * @param int  $userId
3376
     * @param int  $sessionId
3377
     * @param int  $courseId
3378
     * @param bool $noCoach   optional, if is true the user don't be a coach now,
3379
     *                        otherwise it'll assign a coach
3380
     *
3381
     * @return bool true if there are affected rows, otherwise false
3382
     */
3383
    public static function set_coach_to_course_session(
3384
        $userId,
3385
        $sessionId = 0,
3386
        $courseId = 0,
3387
        $noCoach = false
3388
    ) {
3389
        // Definition of variables
3390
        $userId = (int) $userId;
3391
3392
        $sessionId = !empty($sessionId) ? (int) $sessionId : api_get_session_id();
3393
        $courseId = !empty($courseId) ? (int) $courseId : api_get_course_id();
3394
3395
        if (empty($sessionId) || empty($courseId) || empty($userId)) {
3396
            return false;
3397
        }
3398
3399
        // Table definition
3400
        $tblSessionRelCourseRelUser = Database::get_main_table(TABLE_MAIN_SESSION_COURSE_USER);
3401
        $tblSessionRelUser = Database::get_main_table(TABLE_MAIN_SESSION_USER);
3402
        $tblUser = Database::get_main_table(TABLE_MAIN_USER);
3403
3404
        // check if user is a teacher
3405
        $sql = "SELECT * FROM $tblUser
3406
                WHERE status = 1 AND user_id = $userId";
3407
3408
        $rsCheckUser = Database::query($sql);
3409
3410
        if (Database::num_rows($rsCheckUser) <= 0) {
3411
            return false;
3412
        }
3413
3414
        if ($noCoach) {
3415
            // check if user_id exists in session_rel_user (if the user is
3416
            // subscribed to the session in any manner)
3417
            $sql = "SELECT user_id FROM $tblSessionRelUser
3418
                    WHERE
3419
                        session_id = $sessionId AND
3420
                        user_id = $userId";
3421
            $res = Database::query($sql);
3422
3423
            if (Database::num_rows($res) > 0) {
3424
                // The user is already subscribed to the session. Change the
3425
                // record so the user is NOT a coach for this course anymore
3426
                // and then exit
3427
                $sql = "UPDATE $tblSessionRelCourseRelUser
3428
                        SET status = 0
3429
                        WHERE
3430
                            session_id = $sessionId AND
3431
                            c_id = $courseId AND
3432
                            user_id = $userId ";
3433
                $result = Database::query($sql);
3434
3435
                return Database::affected_rows($result) > 0;
3436
            }
3437
3438
            // The user is not subscribed to the session, so make sure
3439
            // he isn't subscribed to a course in this session either
3440
            // and then exit
3441
            $sql = "DELETE FROM $tblSessionRelCourseRelUser
3442
                    WHERE
3443
                        session_id = $sessionId AND
3444
                        c_id = $courseId AND
3445
                        user_id = $userId ";
3446
            $result = Database::query($sql);
3447
3448
            return Database::affected_rows($result) > 0;
3449
        }
3450
3451
        // Assign user as a coach to course
3452
        // First check if the user is registered to the course
3453
        $sql = "SELECT user_id FROM $tblSessionRelCourseRelUser
3454
                WHERE
3455
                    session_id = $sessionId AND
3456
                    c_id = $courseId AND
3457
                    user_id = $userId";
3458
        $rs_check = Database::query($sql);
3459
3460
        // Then update or insert.
3461
        if (Database::num_rows($rs_check) > 0) {
3462
            $sql = "UPDATE $tblSessionRelCourseRelUser SET status = 2
3463
                    WHERE
3464
                        session_id = $sessionId AND
3465
                        c_id = $courseId AND
3466
                        user_id = $userId ";
3467
            $result = Database::query($sql);
3468
3469
            return Database::affected_rows($result) > 0;
3470
        }
3471
3472
        $sql = "INSERT INTO $tblSessionRelCourseRelUser(session_id, c_id, user_id, status)
3473
                VALUES($sessionId, $courseId, $userId, 2)";
3474
        $result = Database::query($sql);
3475
3476
        return Database::affected_rows($result) > 0;
3477
    }
3478
3479
    /**
3480
     * @param int $sessionId
3481
     *
3482
     * @return bool
3483
     */
3484
    public static function removeAllDrhFromSession($sessionId)
3485
    {
3486
        $tbl_session_rel_user = Database::get_main_table(TABLE_MAIN_SESSION_USER);
3487
        $sessionId = (int) $sessionId;
3488
3489
        if (empty($sessionId)) {
3490
            return false;
3491
        }
3492
3493
        $sql = "DELETE FROM $tbl_session_rel_user
3494
                WHERE
3495
                    session_id = $sessionId AND
3496
                    relation_type =".SESSION_RELATION_TYPE_RRHH;
3497
        Database::query($sql);
3498
3499
        return true;
3500
    }
3501
3502
    /**
3503
     * Subscribes sessions to human resource manager (Dashboard feature).
3504
     *
3505
     * @param array $userInfo               Human Resource Manager info
3506
     * @param array $sessions_list          Sessions id
3507
     * @param bool  $sendEmail
3508
     * @param bool  $removeSessionsFromUser
3509
     *
3510
     * @return int
3511
     * */
3512
    public static function subscribeSessionsToDrh(
3513
        $userInfo,
3514
        $sessions_list,
3515
        $sendEmail = false,
3516
        $removeSessionsFromUser = true
3517
    ) {
3518
        // Database Table Definitions
3519
        $tbl_session_rel_user = Database::get_main_table(TABLE_MAIN_SESSION_USER);
3520
        $tbl_session_rel_access_url = Database::get_main_table(TABLE_MAIN_ACCESS_URL_REL_SESSION);
3521
3522
        if (empty($userInfo)) {
3523
            return 0;
3524
        }
3525
3526
        $userId = $userInfo['user_id'];
3527
3528
        // Only subscribe DRH users.
3529
        $rolesAllowed = [
3530
            DRH,
3531
            SESSIONADMIN,
3532
            PLATFORM_ADMIN,
3533
            COURSE_TUTOR,
3534
        ];
3535
        $isAdmin = api_is_platform_admin_by_id($userInfo['user_id']);
3536
        if (!$isAdmin && !in_array($userInfo['status'], $rolesAllowed)) {
3537
            return 0;
3538
        }
3539
3540
        $affected_rows = 0;
3541
        // Deleting assigned sessions to hrm_id.
3542
        if ($removeSessionsFromUser) {
3543
            if (api_is_multiple_url_enabled()) {
3544
                $sql = "SELECT s.session_id
3545
                        FROM $tbl_session_rel_user s
3546
                        INNER JOIN $tbl_session_rel_access_url a
3547
                        ON (a.session_id = s.session_id)
3548
                        WHERE
3549
                            s.user_id = $userId AND
3550
                            relation_type = ".SESSION_RELATION_TYPE_RRHH." AND
3551
                            access_url_id = ".api_get_current_access_url_id();
3552
            } else {
3553
                $sql = "SELECT s.session_id
3554
                        FROM $tbl_session_rel_user s
3555
                        WHERE user_id = $userId AND relation_type=".SESSION_RELATION_TYPE_RRHH;
3556
            }
3557
            $result = Database::query($sql);
3558
3559
            if (Database::num_rows($result) > 0) {
3560
                while ($row = Database::fetch_array($result)) {
3561
                    $sql = "DELETE FROM $tbl_session_rel_user
3562
                            WHERE
3563
                                session_id = {$row['session_id']} AND
3564
                                user_id = $userId AND
3565
                                relation_type =".SESSION_RELATION_TYPE_RRHH;
3566
                    Database::query($sql);
3567
3568
                    Event::addEvent(
3569
                        LOG_SESSION_DELETE_USER,
3570
                        LOG_USER_ID,
3571
                        $userId,
3572
                        api_get_utc_datetime(),
3573
                        api_get_user_id(),
3574
                        null,
3575
                        $row['session_id']
3576
                    );
3577
                }
3578
            }
3579
        }
3580
3581
        // Inserting new sessions list.
3582
        if (!empty($sessions_list) && is_array($sessions_list)) {
3583
            foreach ($sessions_list as $session_id) {
3584
                $session_id = (int) $session_id;
3585
                $sql = "SELECT session_id
3586
                        FROM $tbl_session_rel_user
3587
                        WHERE
3588
                            session_id = $session_id AND
3589
                            user_id = $userId AND
3590
                            relation_type = '".SESSION_RELATION_TYPE_RRHH."'";
3591
                $result = Database::query($sql);
3592
                if (Database::num_rows($result) == 0) {
3593
                    $sql = "INSERT IGNORE INTO $tbl_session_rel_user (session_id, user_id, relation_type, registered_at)
3594
                            VALUES (
3595
                                $session_id,
3596
                                $userId,
3597
                                '".SESSION_RELATION_TYPE_RRHH."',
3598
                                '".api_get_utc_datetime()."'
3599
                            )";
3600
                    Database::query($sql);
3601
3602
                    Event::addEvent(
3603
                        LOG_SESSION_ADD_USER,
3604
                        LOG_USER_ID,
3605
                        $userId,
3606
                        api_get_utc_datetime(),
3607
                        api_get_user_id(),
3608
                        null,
3609
                        $session_id
3610
                    );
3611
3612
                    $affected_rows++;
3613
                }
3614
            }
3615
        }
3616
3617
        return $affected_rows;
3618
    }
3619
3620
    /**
3621
     * @param int $sessionId
3622
     *
3623
     * @return array
3624
     */
3625
    public static function getDrhUsersInSession($sessionId)
3626
    {
3627
        return self::get_users_by_session($sessionId, SESSION_RELATION_TYPE_RRHH);
3628
    }
3629
3630
    /**
3631
     * @param int $userId
3632
     * @param int $sessionId
3633
     *
3634
     * @return array
3635
     */
3636
    public static function getSessionFollowedByDrh($userId, $sessionId)
3637
    {
3638
        $tbl_session = Database::get_main_table(TABLE_MAIN_SESSION);
3639
        $tbl_session_rel_user = Database::get_main_table(TABLE_MAIN_SESSION_USER);
3640
        $tbl_session_rel_access_url = Database::get_main_table(TABLE_MAIN_ACCESS_URL_REL_SESSION);
3641
3642
        $userId = (int) $userId;
3643
        $sessionId = (int) $sessionId;
3644
3645
        $select = " SELECT * ";
3646
        if (api_is_multiple_url_enabled()) {
3647
            $sql = " $select FROM $tbl_session s
3648
                    INNER JOIN $tbl_session_rel_user sru ON (sru.session_id = s.id)
3649
                    LEFT JOIN $tbl_session_rel_access_url a ON (s.id = a.session_id)
3650
                    WHERE
3651
                        sru.user_id = '$userId' AND
3652
                        sru.session_id = '$sessionId' AND
3653
                        sru.relation_type = '".SESSION_RELATION_TYPE_RRHH."' AND
3654
                        access_url_id = ".api_get_current_access_url_id()."
3655
                    ";
3656
        } else {
3657
            $sql = "$select FROM $tbl_session s
3658
                     INNER JOIN $tbl_session_rel_user sru
3659
                     ON
3660
                        sru.session_id = s.id AND
3661
                        sru.user_id = '$userId' AND
3662
                        sru.session_id = '$sessionId' AND
3663
                        sru.relation_type = '".SESSION_RELATION_TYPE_RRHH."'
3664
                    ";
3665
        }
3666
3667
        $result = Database::query($sql);
3668
        if (Database::num_rows($result)) {
3669
            $row = Database::fetch_array($result, 'ASSOC');
3670
            $row['course_list'] = self::get_course_list_by_session_id($sessionId);
3671
3672
            return $row;
3673
        }
3674
3675
        return [];
3676
    }
3677
3678
    /**
3679
     * Get sessions followed by human resources manager.
3680
     *
3681
     * @param int    $userId
3682
     * @param int    $start
3683
     * @param int    $limit
3684
     * @param bool   $getCount
3685
     * @param bool   $getOnlySessionId
3686
     * @param bool   $getSql
3687
     * @param string $orderCondition
3688
     * @param string $keyword
3689
     * @param string $description
3690
     * @param array  $options
3691
     *
3692
     * @return array sessions
3693
     */
3694
    public static function get_sessions_followed_by_drh(
3695
        $userId,
3696
        $start = null,
3697
        $limit = null,
3698
        $getCount = false,
3699
        $getOnlySessionId = false,
3700
        $getSql = false,
3701
        $orderCondition = null,
3702
        $keyword = '',
3703
        $description = '',
3704
        $options = []
3705
    ) {
3706
        return self::getSessionsFollowedByUser(
3707
            $userId,
3708
            DRH,
3709
            $start,
3710
            $limit,
3711
            $getCount,
3712
            $getOnlySessionId,
3713
            $getSql,
3714
            $orderCondition,
3715
            $keyword,
3716
            $description,
3717
            $options
3718
        );
3719
    }
3720
3721
    /**
3722
     * Get sessions followed by human resources manager.
3723
     *
3724
     * @param int    $userId
3725
     * @param int    $status           DRH Optional
3726
     * @param int    $start
3727
     * @param int    $limit
3728
     * @param bool   $getCount
3729
     * @param bool   $getOnlySessionId
3730
     * @param bool   $getSql
3731
     * @param string $orderCondition
3732
     * @param string $keyword
3733
     * @param string $description
3734
     * @param array  $options
3735
     *
3736
     * @return array sessions
3737
     */
3738
    public static function getSessionsFollowedByUser(
3739
        $userId,
3740
        $status = null,
3741
        $start = null,
3742
        $limit = null,
3743
        $getCount = false,
3744
        $getOnlySessionId = false,
3745
        $getSql = false,
3746
        $orderCondition = null,
3747
        $keyword = '',
3748
        $description = '',
3749
        $options = []
3750
    ) {
3751
        // Database Table Definitions
3752
        $tbl_session = Database::get_main_table(TABLE_MAIN_SESSION);
3753
        $tbl_session_rel_user = Database::get_main_table(TABLE_MAIN_SESSION_USER);
3754
        $tbl_session_rel_course_rel_user = Database::get_main_table(TABLE_MAIN_SESSION_COURSE_USER);
3755
        $tbl_session_rel_access_url = Database::get_main_table(TABLE_MAIN_ACCESS_URL_REL_SESSION);
3756
3757
        $extraFieldModel = new ExtraFieldModel('session');
3758
        $conditions = $extraFieldModel->parseConditions($options);
3759
        $sqlInjectJoins = $conditions['inject_joins'];
3760
        $extraFieldsConditions = $conditions['where'];
3761
        $sqlInjectWhere = $conditions['inject_where'];
3762
        $injectExtraFields = $conditions['inject_extra_fields'];
3763
3764
        if (!empty($injectExtraFields)) {
3765
            $injectExtraFields = ' , '.$injectExtraFields.' s.id';
3766
        }
3767
3768
        $userId = (int) $userId;
3769
3770
        $select = ' SELECT DISTINCT * '.$injectExtraFields;
3771
        if ($getCount) {
3772
            $select = ' SELECT count(DISTINCT(s.id)) as count ';
3773
        }
3774
3775
        if ($getOnlySessionId) {
3776
            $select = ' SELECT DISTINCT(s.id) ';
3777
        }
3778
3779
        $limitCondition = null;
3780
        if (!is_null($start) && !is_null($limit)) {
3781
            $limitCondition = " LIMIT ".intval($start).", ".intval($limit);
3782
        }
3783
3784
        if (empty($orderCondition)) {
3785
            $orderCondition = ' ORDER BY s.name ';
3786
        }
3787
3788
        $whereConditions = null;
3789
        $sessionCourseConditions = null;
3790
        $sessionConditions = null;
3791
        $sessionQuery = '';
3792
        $courseSessionQuery = null;
3793
        switch ($status) {
3794
            case DRH:
3795
                $sessionQuery = "SELECT sru.session_id
3796
                                 FROM
3797
                                 $tbl_session_rel_user sru
3798
                                 WHERE
3799
                                    sru.relation_type = '".SESSION_RELATION_TYPE_RRHH."' AND
3800
                                    sru.user_id = $userId";
3801
                break;
3802
            case COURSEMANAGER:
3803
                $courseSessionQuery = "
3804
                    SELECT scu.session_id as id
3805
                    FROM $tbl_session_rel_course_rel_user scu
3806
                    WHERE (scu.status = 2 AND scu.user_id = $userId)";
3807
3808
                $whereConditions = " OR (s.id_coach = $userId) ";
3809
                break;
3810
            case SESSIONADMIN:
3811
                $sessionQuery = '';
3812
                if (api_get_setting('allow_session_admins_to_manage_all_sessions') != 'true') {
3813
                    $sqlInjectJoins .= " AND s.session_admin_id = $userId ";
3814
                }
3815
                break;
3816
            default:
3817
                $sessionQuery = "SELECT sru.session_id
3818
                                 FROM
3819
                                 $tbl_session_rel_user sru
3820
                                 WHERE
3821
                                    sru.user_id = $userId";
3822
                break;
3823
        }
3824
3825
        $keywordCondition = '';
3826
        if (!empty($keyword)) {
3827
            $keyword = Database::escape_string($keyword);
3828
            $keywordCondition = " AND (s.name LIKE '%$keyword%' ) ";
3829
3830
            if (!empty($description)) {
3831
                $description = Database::escape_string($description);
3832
                $keywordCondition = " AND (s.name LIKE '%$keyword%' OR s.description LIKE '%$description%' ) ";
3833
            }
3834
        }
3835
3836
        $whereConditions .= $keywordCondition;
3837
        $subQuery = $sessionQuery.$courseSessionQuery;
3838
3839
        if (!empty($subQuery)) {
3840
            $subQuery = " AND s.id IN ($subQuery)";
3841
        }
3842
3843
        $sql = " $select
3844
                FROM $tbl_session s
3845
                INNER JOIN $tbl_session_rel_access_url a
3846
                ON (s.id = a.session_id)
3847
                $sqlInjectJoins
3848
                WHERE
3849
                    access_url_id = ".api_get_current_access_url_id()."
3850
                    $subQuery
3851
                    $whereConditions
3852
                    $extraFieldsConditions
3853
                    $sqlInjectWhere
3854
                    $orderCondition
3855
                    $limitCondition";
3856
3857
        if ($getSql) {
3858
            return $sql;
3859
        }
3860
        $result = Database::query($sql);
3861
3862
        if ($getCount) {
3863
            $row = Database::fetch_array($result);
3864
            if ($row) {
3865
                return (int) $row['count'];
3866
            }
3867
3868
            return 0;
3869
        }
3870
3871
        $sessions = [];
3872
        if (Database::num_rows($result) > 0) {
3873
            $sysUploadPath = api_get_path(SYS_UPLOAD_PATH).'sessions/';
3874
            $webUploadPath = api_get_path(WEB_UPLOAD_PATH).'sessions/';
3875
            $imgPath = Display::return_icon(
3876
                'session_default_small.png',
3877
                null,
3878
                [],
3879
                ICON_SIZE_SMALL,
3880
                false,
3881
                true
3882
            );
3883
3884
            while ($row = Database::fetch_array($result)) {
3885
                if ($getOnlySessionId) {
3886
                    $sessions[$row['id']] = $row;
3887
                    continue;
3888
                }
3889
                $imageFilename = ExtraFieldModel::FIELD_TYPE_FILE_IMAGE.'_'.$row['id'].'.png';
3890
                $row['image'] = is_file($sysUploadPath.$imageFilename) ? $webUploadPath.$imageFilename : $imgPath;
3891
3892
                if ($row['display_start_date'] === '0000-00-00 00:00:00' || $row['display_start_date'] === '0000-00-00') {
3893
                    $row['display_start_date'] = null;
3894
                }
3895
3896
                if ($row['display_end_date'] === '0000-00-00 00:00:00' || $row['display_end_date'] === '0000-00-00') {
3897
                    $row['display_end_date'] = null;
3898
                }
3899
3900
                if ($row['access_start_date'] === '0000-00-00 00:00:00' || $row['access_start_date'] === '0000-00-00') {
3901
                    $row['access_start_date'] = null;
3902
                }
3903
3904
                if ($row['access_end_date'] === '0000-00-00 00:00:00' || $row['access_end_date'] === '0000-00-00') {
3905
                    $row['access_end_date'] = null;
3906
                }
3907
3908
                if ($row['coach_access_start_date'] === '0000-00-00 00:00:00' ||
3909
                    $row['coach_access_start_date'] === '0000-00-00'
3910
                ) {
3911
                    $row['coach_access_start_date'] = null;
3912
                }
3913
3914
                if ($row['coach_access_end_date'] === '0000-00-00 00:00:00' ||
3915
                    $row['coach_access_end_date'] === '0000-00-00'
3916
                ) {
3917
                    $row['coach_access_end_date'] = null;
3918
                }
3919
3920
                $sessions[$row['id']] = $row;
3921
            }
3922
        }
3923
3924
        return $sessions;
3925
    }
3926
3927
    /**
3928
     * Gets the list (or the count) of courses by session filtered by access_url.
3929
     *
3930
     * @param int    $session_id  The session id
3931
     * @param string $course_name The course code
3932
     * @param string $orderBy     Field to order the data
3933
     * @param bool   $getCount    Optional. Count the session courses
3934
     *
3935
     * @return array|int List of courses. Whether $getCount is true, return the count
3936
     */
3937
    public static function get_course_list_by_session_id(
3938
        $session_id,
3939
        $course_name = '',
3940
        $orderBy = null,
3941
        $getCount = false
3942
    ) {
3943
        $tbl_course = Database::get_main_table(TABLE_MAIN_COURSE);
3944
        $tbl_session_rel_course = Database::get_main_table(TABLE_MAIN_SESSION_COURSE);
3945
        $session_id = (int) $session_id;
3946
        $sqlSelect = '*, c.id, c.id as real_id, c.code as course_code';
3947
3948
        if ($getCount) {
3949
            $sqlSelect = 'COUNT(1) as count';
3950
        }
3951
3952
        // select the courses
3953
        $sql = "SELECT $sqlSelect
3954
                FROM $tbl_course c
3955
                INNER JOIN $tbl_session_rel_course src
3956
                ON (c.id = src.c_id)
3957
		        WHERE src.session_id = '$session_id' ";
3958
3959
        if (!empty($course_name)) {
3960
            $course_name = Database::escape_string($course_name);
3961
            $sql .= " AND c.title LIKE '%$course_name%' ";
3962
        }
3963
3964
        if (!empty($orderBy)) {
3965
            $orderBy = Database::escape_string($orderBy);
3966
            $orderBy = " ORDER BY $orderBy";
3967
        } else {
3968
            if (self::orderCourseIsEnabled()) {
3969
                $orderBy .= ' ORDER BY position ';
3970
            } else {
3971
                $orderBy .= ' ORDER BY title ';
3972
            }
3973
        }
3974
3975
        $sql .= Database::escape_string($orderBy);
3976
        $result = Database::query($sql);
3977
        $num_rows = Database::num_rows($result);
3978
        $courses = [];
3979
        if ($num_rows > 0) {
3980
            if ($getCount) {
3981
                $count = Database::fetch_assoc($result);
3982
3983
                return (int) $count['count'];
3984
            }
3985
3986
            while ($row = Database::fetch_array($result, 'ASSOC')) {
3987
                $courses[$row['real_id']] = $row;
3988
            }
3989
        }
3990
3991
        return $courses;
3992
    }
3993
3994
    /**
3995
     * Gets the list of courses by session filtered by access_url.
3996
     *
3997
     * @param $userId
3998
     * @param $sessionId
3999
     * @param null   $from
4000
     * @param null   $limit
0 ignored issues
show
Documentation Bug introduced by
Are you sure the doc-type for parameter $limit is correct as it would always require null to be passed?
Loading history...
4001
     * @param null   $column
0 ignored issues
show
Documentation Bug introduced by
Are you sure the doc-type for parameter $column is correct as it would always require null to be passed?
Loading history...
4002
     * @param null   $direction
0 ignored issues
show
Documentation Bug introduced by
Are you sure the doc-type for parameter $direction is correct as it would always require null to be passed?
Loading history...
4003
     * @param bool   $getCount
4004
     * @param string $keyword
4005
     *
4006
     * @return array
4007
     */
4008
    public static function getAllCoursesFollowedByUser(
4009
        $userId,
4010
        $sessionId,
4011
        $from = null,
4012
        $limit = null,
4013
        $column = null,
4014
        $direction = null,
4015
        $getCount = false,
4016
        $keyword = ''
4017
    ) {
4018
        if (empty($sessionId)) {
4019
            $sessionsSQL = self::get_sessions_followed_by_drh(
4020
                $userId,
4021
                null,
4022
                null,
4023
                null,
4024
                true,
4025
                true
4026
            );
4027
        } else {
4028
            $sessionsSQL = intval($sessionId);
4029
        }
4030
4031
        $tbl_course = Database::get_main_table(TABLE_MAIN_COURSE);
4032
        $tbl_session_rel_course = Database::get_main_table(TABLE_MAIN_SESSION_COURSE);
4033
4034
        if ($getCount) {
4035
            $select = "SELECT COUNT(DISTINCT(c.code)) as count ";
4036
        } else {
4037
            $select = "SELECT DISTINCT c.* ";
4038
        }
4039
4040
        $keywordCondition = null;
4041
        if (!empty($keyword)) {
4042
            $keyword = Database::escape_string($keyword);
4043
            $keywordCondition = " AND (c.code LIKE '%$keyword%' OR c.title LIKE '%$keyword%' ) ";
4044
        }
4045
4046
        // Select the courses
4047
        $sql = "$select
4048
                FROM $tbl_course c
4049
                INNER JOIN $tbl_session_rel_course src
4050
                ON c.id = src.c_id
4051
		        WHERE
4052
		            src.session_id IN ($sessionsSQL)
4053
		            $keywordCondition
4054
		        ";
4055
        if ($getCount) {
4056
            $result = Database::query($sql);
4057
            $row = Database::fetch_array($result, 'ASSOC');
4058
4059
            return $row['count'];
4060
        }
4061
4062
        if (isset($from) && isset($limit)) {
4063
            $from = intval($from);
4064
            $limit = intval($limit);
4065
            $sql .= " LIMIT $from, $limit";
4066
        }
4067
4068
        $result = Database::query($sql);
4069
        $num_rows = Database::num_rows($result);
4070
        $courses = [];
4071
4072
        if ($num_rows > 0) {
4073
            while ($row = Database::fetch_array($result, 'ASSOC')) {
4074
                $courses[$row['id']] = $row;
4075
            }
4076
        }
4077
4078
        return $courses;
4079
    }
4080
4081
    /**
4082
     * Gets the list of courses by session filtered by access_url.
4083
     *
4084
     * @param int    $session_id
4085
     * @param string $course_name
4086
     *
4087
     * @return array list of courses
4088
     */
4089
    public static function get_course_list_by_session_id_like($session_id, $course_name = '')
4090
    {
4091
        $tbl_course = Database::get_main_table(TABLE_MAIN_COURSE);
4092
        $tbl_session_rel_course = Database::get_main_table(TABLE_MAIN_SESSION_COURSE);
4093
4094
        $session_id = (int) $session_id;
4095
        $course_name = Database::escape_string($course_name);
4096
4097
        // select the courses
4098
        $sql = "SELECT c.id, c.title FROM $tbl_course c
4099
                INNER JOIN $tbl_session_rel_course src
4100
                ON c.id = src.c_id
4101
		        WHERE ";
4102
4103
        if (!empty($session_id)) {
4104
            $sql .= "src.session_id LIKE '$session_id' AND ";
4105
        }
4106
4107
        if (!empty($course_name)) {
4108
            $sql .= "UPPER(c.title) LIKE UPPER('%$course_name%') ";
4109
        }
4110
4111
        $sql .= "ORDER BY title;";
4112
        $result = Database::query($sql);
4113
        $num_rows = Database::num_rows($result);
4114
        $courses = [];
4115
        if ($num_rows > 0) {
4116
            while ($row = Database::fetch_array($result, 'ASSOC')) {
4117
                $courses[$row['id']] = $row;
4118
            }
4119
        }
4120
4121
        return $courses;
4122
    }
4123
4124
    /**
4125
     * Gets the count of courses by session filtered by access_url.
4126
     *
4127
     * @param int session id
4128
     * @param string $keyword
4129
     *
4130
     * @return array list of courses
4131
     */
4132
    public static function getCourseCountBySessionId($session_id, $keyword = '')
4133
    {
4134
        $tbl_course = Database::get_main_table(TABLE_MAIN_COURSE);
4135
        $tbl_session_rel_course = Database::get_main_table(TABLE_MAIN_SESSION_COURSE);
4136
        $session_id = (int) $session_id;
4137
4138
        // select the courses
4139
        $sql = "SELECT COUNT(c.code) count
4140
                FROM $tbl_course c
4141
                INNER JOIN $tbl_session_rel_course src
4142
                ON c.id = src.c_id
4143
		        WHERE src.session_id = '$session_id' ";
4144
4145
        $keywordCondition = null;
4146
        if (!empty($keyword)) {
4147
            $keyword = Database::escape_string($keyword);
4148
            $keywordCondition = " AND (c.code LIKE '%$keyword%' OR c.title LIKE '%$keyword%' ) ";
4149
        }
4150
        $sql .= $keywordCondition;
4151
4152
        $result = Database::query($sql);
4153
        $num_rows = Database::num_rows($result);
4154
        if ($num_rows > 0) {
4155
            $row = Database::fetch_array($result, 'ASSOC');
4156
4157
            return $row['count'];
4158
        }
4159
4160
        return null;
4161
    }
4162
4163
    /**
4164
     * Get the session id based on the original id and field name in the extra fields.
4165
     * Returns 0 if session was not found.
4166
     *
4167
     * @param string $value    Original session id
4168
     * @param string $variable Original field name
4169
     *
4170
     * @return int Session id
4171
     */
4172
    public static function getSessionIdFromOriginalId($value, $variable)
4173
    {
4174
        $extraFieldValue = new ExtraFieldValue('session');
4175
        $result = $extraFieldValue->get_item_id_from_field_variable_and_field_value(
4176
            $variable,
4177
            $value
4178
        );
4179
4180
        if (!empty($result)) {
4181
            return $result['item_id'];
4182
        }
4183
4184
        return 0;
4185
    }
4186
4187
    /**
4188
     * Get users by session.
4189
     *
4190
     * @param int  $id       session id
4191
     * @param int  $status   filter by status coach = 2
4192
     * @param bool $getCount Optional. Allow get the number of rows from the result
4193
     * @param int  $urlId
4194
     *
4195
     * @return array|int A list with an user list. If $getCount is true then return a the count of registers
4196
     */
4197
    public static function get_users_by_session(
4198
        $id,
4199
        $status = null,
4200
        $getCount = false,
4201
        $urlId = 0
4202
    ) {
4203
        if (empty($id)) {
4204
            return [];
4205
        }
4206
        $id = (int) $id;
4207
        $urlId = empty($urlId) ? api_get_current_access_url_id() : (int) $urlId;
4208
4209
        $tbl_user = Database::get_main_table(TABLE_MAIN_USER);
4210
        $tbl_session_rel_user = Database::get_main_table(TABLE_MAIN_SESSION_USER);
4211
        $table_access_url_user = Database::get_main_table(TABLE_MAIN_ACCESS_URL_REL_USER);
4212
4213
        $selectedField = '
4214
            u.user_id, u.lastname, u.firstname, u.username, su.relation_type, au.access_url_id,
4215
            su.moved_to, su.moved_status, su.moved_at, su.registered_at
4216
        ';
4217
4218
        if ($getCount) {
4219
            $selectedField = 'count(1) AS count';
4220
        }
4221
4222
        $sql = "SELECT $selectedField
4223
                FROM $tbl_user u
4224
                INNER JOIN $tbl_session_rel_user su
4225
                ON u.user_id = su.user_id AND
4226
                su.session_id = $id
4227
                LEFT OUTER JOIN $table_access_url_user au
4228
                ON (au.user_id = u.user_id)
4229
                ";
4230
4231
        if (is_numeric($status)) {
4232
            $status = (int) $status;
4233
            $sql .= " WHERE su.relation_type = $status AND (au.access_url_id = $urlId OR au.access_url_id is null)";
4234
        } else {
4235
            $sql .= " WHERE (au.access_url_id = $urlId OR au.access_url_id is null )";
4236
        }
4237
4238
        $sql .= ' ORDER BY su.relation_type, ';
4239
        $sql .= api_sort_by_first_name() ? ' u.firstname, u.lastname' : '  u.lastname, u.firstname';
4240
4241
        $result = Database::query($sql);
4242
        if ($getCount) {
4243
            $count = Database::fetch_assoc($result);
4244
            if ($count) {
4245
                return (int) $count['count'];
4246
            }
4247
4248
            return 0;
4249
        }
4250
4251
        $return = [];
4252
        while ($row = Database::fetch_array($result, 'ASSOC')) {
4253
            $return[] = $row;
4254
        }
4255
4256
        return $return;
4257
    }
4258
4259
    /**
4260
     * The general coach (field: session.id_coach).
4261
     *
4262
     * @param int  $user_id         user id
4263
     * @param bool $asPlatformAdmin The user is platform admin, return everything
4264
     *
4265
     * @return array
4266
     */
4267
    public static function get_sessions_by_general_coach($user_id, $asPlatformAdmin = false)
4268
    {
4269
        $session_table = Database::get_main_table(TABLE_MAIN_SESSION);
4270
        $user_id = (int) $user_id;
4271
4272
        // Session where we are general coach
4273
        $sql = "SELECT DISTINCT *
4274
                FROM $session_table";
4275
4276
        if (!$asPlatformAdmin) {
4277
            $sql .= " WHERE id_coach = $user_id";
4278
        }
4279
4280
        if (api_is_multiple_url_enabled()) {
4281
            $tbl_session_rel_access_url = Database::get_main_table(TABLE_MAIN_ACCESS_URL_REL_SESSION);
4282
            $access_url_id = api_get_current_access_url_id();
4283
4284
            $sqlCoach = '';
4285
            if (!$asPlatformAdmin) {
4286
                $sqlCoach = " id_coach = $user_id AND ";
4287
            }
4288
4289
            if ($access_url_id != -1) {
4290
                $sql = 'SELECT DISTINCT session.*
4291
                    FROM '.$session_table.' session INNER JOIN '.$tbl_session_rel_access_url.' session_rel_url
4292
                    ON (session.id = session_rel_url.session_id)
4293
                    WHERE '.$sqlCoach.' access_url_id = '.$access_url_id;
4294
            }
4295
        }
4296
        $sql .= ' ORDER by name';
4297
        $result = Database::query($sql);
4298
4299
        return Database::store_result($result, 'ASSOC');
4300
    }
4301
4302
    /**
4303
     * @param int $user_id
4304
     *
4305
     * @return array
4306
     *
4307
     * @deprecated use get_sessions_by_general_coach()
4308
     */
4309
    public static function get_sessions_by_coach($user_id)
4310
    {
4311
        $session_table = Database::get_main_table(TABLE_MAIN_SESSION);
4312
4313
        return Database::select(
4314
            '*',
4315
            $session_table,
4316
            ['where' => ['id_coach = ?' => $user_id]]
4317
        );
4318
    }
4319
4320
    /**
4321
     * @param int $user_id
4322
     * @param int $courseId
4323
     * @param int $session_id
4324
     *
4325
     * @return array|bool
4326
     */
4327
    public static function get_user_status_in_course_session($user_id, $courseId, $session_id)
4328
    {
4329
        $table = Database::get_main_table(TABLE_MAIN_SESSION_COURSE_USER);
4330
        $tbl_user = Database::get_main_table(TABLE_MAIN_USER);
4331
        $sql = "SELECT session_rcru.status
4332
                FROM $table session_rcru
4333
                INNER JOIN $tbl_user user
4334
                ON (session_rcru.user_id = user.user_id)
4335
                WHERE
4336
                    session_rcru.session_id = '".intval($session_id)."' AND
4337
                    session_rcru.c_id ='".intval($courseId)."' AND
4338
                    user.user_id = ".intval($user_id);
4339
4340
        $result = Database::query($sql);
4341
        $status = false;
4342
        if (Database::num_rows($result)) {
4343
            $status = Database::fetch_row($result);
4344
            $status = $status['0'];
4345
        }
4346
4347
        return $status;
4348
    }
4349
4350
    /**
4351
     * Gets user status within a session.
4352
     *
4353
     * @param int $userId
4354
     * @param int $sessionId
4355
     *
4356
     * @return SessionRelUser
4357
     */
4358
    public static function getUserStatusInSession($userId, $sessionId)
4359
    {
4360
        $em = Database::getManager();
4361
        $subscriptions = $em
4362
            ->getRepository('ChamiloCoreBundle:SessionRelUser')
4363
            ->findBy(['session' => $sessionId, 'user' => $userId]);
4364
4365
        /** @var SessionRelUser $subscription */
4366
        $subscription = current($subscriptions);
4367
4368
        return $subscription;
4369
    }
4370
4371
    /**
4372
     * @param int $id
4373
     *
4374
     * @return array
4375
     */
4376
    public static function get_all_sessions_by_promotion($id)
4377
    {
4378
        $table = Database::get_main_table(TABLE_MAIN_SESSION);
4379
4380
        return Database::select(
4381
            '*',
4382
            $table,
4383
            ['where' => ['promotion_id = ?' => $id]]
4384
        );
4385
    }
4386
4387
    /**
4388
     * @param int   $promotion_id
4389
     * @param array $list
4390
     */
4391
    public static function subscribe_sessions_to_promotion($promotion_id, $list)
4392
    {
4393
        $table = Database::get_main_table(TABLE_MAIN_SESSION);
4394
        $params = [];
4395
        $params['promotion_id'] = 0;
4396
        Database::update(
4397
            $table,
4398
            $params,
4399
            ['promotion_id = ?' => $promotion_id]
4400
        );
4401
4402
        $params['promotion_id'] = $promotion_id;
4403
        if (!empty($list)) {
4404
            foreach ($list as $session_id) {
4405
                $session_id = (int) $session_id;
4406
                Database::update($table, $params, ['id = ?' => $session_id]);
4407
            }
4408
        }
4409
    }
4410
4411
    /**
4412
     * Updates a session status.
4413
     *
4414
     * @param int session id
4415
     * @param int status
4416
     */
4417
    public static function set_session_status($session_id, $status)
4418
    {
4419
        $t = Database::get_main_table(TABLE_MAIN_SESSION);
4420
        $params['visibility'] = $status;
4421
        Database::update($t, $params, ['id = ?' => $session_id]);
4422
    }
4423
4424
    /**
4425
     * Copies a session with the same data to a new session.
4426
     * The new copy is not assigned to the same promotion.
4427
     *
4428
     * @param int  $id                         Session ID
4429
     * @param bool $copy_courses               Whether to copy the relationship with courses
4430
     * @param bool $copyTeachersAndDrh
4431
     * @param bool $create_new_courses         New courses will be created
4432
     * @param bool $set_exercises_lp_invisible Set exercises and LPs in the new session to invisible by default
4433
     * @param bool $copyWithSessionContent     Copy course session content into the courses
4434
     *
4435
     * @return int The new session ID on success, 0 otherwise
4436
     *
4437
     * @see subscribe_sessions_to_promotions() for that.
4438
     *
4439
     * @todo make sure the extra session fields are copied too
4440
     */
4441
    public static function copy(
4442
        $id,
4443
        $copy_courses = true,
4444
        $copyTeachersAndDrh = true,
4445
        $create_new_courses = false,
4446
        $set_exercises_lp_invisible = false,
4447
        $copyWithSessionContent = false
4448
    ) {
4449
        $id = (int) $id;
4450
        $s = self::fetch($id);
4451
4452
        if (empty($s)) {
4453
            return false;
4454
        }
4455
4456
        // Check all dates before copying
4457
        // Get timestamp for now in UTC - see http://php.net/manual/es/function.time.php#117251
4458
        $now = time() - date('Z');
4459
        // Timestamp in one month
4460
        $inOneMonth = $now + (30 * 24 * 3600);
4461
        $inOneMonth = api_get_local_time($inOneMonth);
4462
        if (api_strtotime($s['access_start_date']) < $now) {
4463
            $s['access_start_date'] = api_get_local_time($now);
4464
        } else {
4465
            $s['access_start_date'] = api_get_local_time($s['access_start_date']);
4466
        }
4467
        if (api_strtotime($s['display_start_date']) < $now) {
4468
            $s['display_start_date'] = api_get_local_time($now);
4469
        } else {
4470
            $s['display_start_date'] = api_get_local_time($s['display_start_date']);
4471
        }
4472
        if (api_strtotime($s['coach_access_start_date']) < $now) {
4473
            $s['coach_access_start_date'] = api_get_local_time($now);
4474
        } else {
4475
            $s['coach_access_start_date'] = api_get_local_time($s['coach_access_start_date']);
4476
        }
4477
        if (api_strtotime($s['access_end_date']) < $now) {
4478
            $s['access_end_date'] = $inOneMonth;
4479
        } else {
4480
            $s['access_end_date'] = api_get_local_time($s['access_end_date']);
4481
        }
4482
        if (api_strtotime($s['display_end_date']) < $now) {
4483
            $s['display_end_date'] = $inOneMonth;
4484
        } else {
4485
            $s['display_end_date'] = api_get_local_time($s['display_end_date']);
4486
        }
4487
        if (api_strtotime($s['coach_access_end_date']) < $now) {
4488
            $s['coach_access_end_date'] = $inOneMonth;
4489
        } else {
4490
            $s['coach_access_end_date'] = api_get_local_time($s['coach_access_end_date']);
4491
        }
4492
4493
        $extraFieldValue = new ExtraFieldValue('session');
4494
        $extraFieldsValues = $extraFieldValue->getAllValuesByItem($id);
4495
        $extraFieldsValuesToCopy = [];
4496
        if (!empty($extraFieldsValues)) {
4497
            foreach ($extraFieldsValues as $extraFieldValue) {
4498
                $extraFieldsValuesToCopy['extra_'.$extraFieldValue['variable']]['extra_'.$extraFieldValue['variable']] = $extraFieldValue['value'];
4499
            }
4500
        }
4501
4502
        if (isset($extraFieldsValuesToCopy['extra_image']) && isset($extraFieldsValuesToCopy['extra_image']['extra_image'])) {
4503
            $extraFieldsValuesToCopy['extra_image'] = [
4504
                'tmp_name' => api_get_path(SYS_UPLOAD_PATH).$extraFieldsValuesToCopy['extra_image']['extra_image'],
4505
                'error' => 0,
4506
            ];
4507
        }
4508
4509
        // Now try to create the session
4510
        $sid = self::create_session(
4511
            $s['name'].' '.get_lang('CopyLabelSuffix'),
4512
            $s['access_start_date'],
4513
            $s['access_end_date'],
4514
            $s['display_start_date'],
4515
            $s['display_end_date'],
4516
            $s['coach_access_start_date'],
4517
            $s['coach_access_end_date'],
4518
            (int) $s['id_coach'],
4519
            $s['session_category_id'],
4520
            (int) $s['visibility'],
4521
            true,
4522
            $s['duration'],
4523
            $s['description'],
4524
            $s['show_description'],
4525
            $extraFieldsValuesToCopy
4526
        );
4527
4528
        if (!is_numeric($sid) || empty($sid)) {
4529
            return false;
4530
        }
4531
4532
        if ($copy_courses) {
4533
            // Register courses from the original session to the new session
4534
            $courses = self::get_course_list_by_session_id($id);
4535
            $short_courses = $new_short_courses = [];
4536
            if (is_array($courses) && count($courses) > 0) {
4537
                foreach ($courses as $course) {
4538
                    $short_courses[] = $course;
4539
                }
4540
            }
4541
4542
            // We will copy the current courses of the session to new courses
4543
            if (!empty($short_courses)) {
4544
                if ($create_new_courses) {
4545
                    api_set_more_memory_and_time_limits();
4546
                    $params = [];
4547
                    $params['skip_lp_dates'] = true;
4548
4549
                    foreach ($short_courses as $course_data) {
4550
                        $course_info = CourseManager::copy_course_simple(
4551
                            $course_data['title'].' '.get_lang('CopyLabelSuffix'),
4552
                            $course_data['course_code'],
4553
                            $id,
4554
                            $sid,
4555
                            $params
4556
                        );
4557
4558
                        if ($course_info) {
4559
                            //By default new elements are invisible
4560
                            if ($set_exercises_lp_invisible) {
4561
                                $list = new LearnpathList('', $course_info, $sid);
4562
                                $flat_list = $list->get_flat_list();
4563
                                if (!empty($flat_list)) {
4564
                                    foreach ($flat_list as $lp_id => $data) {
4565
                                        api_item_property_update(
4566
                                            $course_info,
4567
                                            TOOL_LEARNPATH,
4568
                                            $lp_id,
4569
                                            'invisible',
4570
                                            api_get_user_id(),
4571
                                            0,
4572
                                            0,
4573
                                            0,
4574
                                            0,
4575
                                            $sid
4576
                                        );
4577
                                    }
4578
                                }
4579
                                $quiz_table = Database::get_course_table(TABLE_QUIZ_TEST);
4580
                                $course_id = $course_info['real_id'];
4581
                                //@todo check this query
4582
                                $sql = "UPDATE $quiz_table SET active = 0
4583
                                        WHERE c_id = $course_id AND session_id = $sid";
4584
                                Database::query($sql);
4585
                            }
4586
                            $new_short_courses[] = $course_info['real_id'];
4587
                        }
4588
                    }
4589
                } else {
4590
                    foreach ($short_courses as $course_data) {
4591
                        $new_short_courses[] = $course_data['id'];
4592
                    }
4593
                }
4594
4595
                $short_courses = $new_short_courses;
4596
                self::add_courses_to_session($sid, $short_courses, true);
4597
4598
                if ($copyWithSessionContent) {
4599
                    foreach ($courses as $course) {
4600
                        CourseManager::copy_course(
4601
                            $course['code'],
4602
                            $id,
4603
                            $course['code'],
4604
                            $sid,
4605
                            [],
4606
                            false
4607
                        );
4608
                    }
4609
                }
4610
4611
                if ($create_new_courses === false && $copyTeachersAndDrh) {
4612
                    foreach ($short_courses as $courseItemId) {
4613
                        $coachList = self::getCoachesByCourseSession($id, $courseItemId);
4614
                        foreach ($coachList as $userId) {
4615
                            self::set_coach_to_course_session($userId, $sid, $courseItemId);
4616
                        }
4617
                    }
4618
                }
4619
            }
4620
        }
4621
4622
        if ($copyTeachersAndDrh) {
4623
            // Register users from the original session to the new session
4624
            $users = self::get_users_by_session($id);
4625
            if (!empty($users)) {
4626
                $userListByStatus = [];
4627
                foreach ($users as $userData) {
4628
                    $userData['relation_type'] = (int) $userData['relation_type'];
4629
                    $userListByStatus[$userData['relation_type']][] = $userData;
4630
                }
4631
4632
                foreach ($userListByStatus as $status => $userList) {
4633
                    $userList = array_column($userList, 'user_id');
4634
                    switch ($status) {
4635
                        case 0:
4636
                            /*self::subscribeUsersToSession(
4637
                                $sid,
4638
                                $userList,
4639
                                SESSION_VISIBLE_READ_ONLY,
4640
                                false,
4641
                                true
4642
                            );*/
4643
                            break;
4644
                        case 1:
4645
                            // drh users
4646
                            foreach ($userList as $drhId) {
4647
                                $userInfo = api_get_user_info($drhId);
4648
                                self::subscribeSessionsToDrh($userInfo, [$sid], false, false);
4649
                            }
4650
                            break;
4651
                    }
4652
                }
4653
            }
4654
        }
4655
4656
        return $sid;
4657
    }
4658
4659
    /**
4660
     * @param int $user_id
4661
     * @param int $session_id
4662
     *
4663
     * @return bool
4664
     */
4665
    public static function user_is_general_coach($user_id, $session_id)
4666
    {
4667
        $session_id = (int) $session_id;
4668
        $user_id = (int) $user_id;
4669
        $table = Database::get_main_table(TABLE_MAIN_SESSION);
4670
        $sql = "SELECT DISTINCT id
4671
	         	FROM $table
4672
	         	WHERE session.id_coach = '".$user_id."' AND id = '$session_id'";
4673
        $result = Database::query($sql);
4674
        if ($result && Database::num_rows($result)) {
4675
            return true;
4676
        }
4677
4678
        return false;
4679
    }
4680
4681
    /**
4682
     * Get the number of sessions.
4683
     *
4684
     * @param int $access_url_id ID of the URL we want to filter on (optional)
4685
     *
4686
     * @return int Number of sessions
4687
     */
4688
    public static function count_sessions($access_url_id = 0)
4689
    {
4690
        $session_table = Database::get_main_table(TABLE_MAIN_SESSION);
4691
        $access_url_rel_session_table = Database::get_main_table(TABLE_MAIN_ACCESS_URL_REL_SESSION);
4692
        $access_url_id = (int) $access_url_id;
4693
        $sql = "SELECT count(s.id) FROM $session_table s";
4694
        if (!empty($access_url_id)) {
4695
            $sql .= ", $access_url_rel_session_table u ".
4696
                " WHERE s.id = u.session_id AND u.access_url_id = $access_url_id";
4697
        }
4698
        $res = Database::query($sql);
4699
        $row = Database::fetch_row($res);
4700
4701
        return $row[0];
4702
    }
4703
4704
    /**
4705
     * @param int  $id
4706
     * @param bool $checkSession
4707
     *
4708
     * @return bool
4709
     */
4710
    public static function cantEditSession($id, $checkSession = true)
4711
    {
4712
        if (!self::allowToManageSessions()) {
4713
            return false;
4714
        }
4715
4716
        if (api_is_platform_admin() && self::allowed($id)) {
4717
            return true;
4718
        }
4719
4720
        if ($checkSession) {
4721
            if (self::allowed($id)) {
4722
                return true;
4723
            }
4724
4725
            return false;
4726
        }
4727
4728
        return true;
4729
    }
4730
4731
    /**
4732
     * Protect a session to be edited.
4733
     *
4734
     * @param int  $id
4735
     * @param bool $checkSession
4736
     *
4737
     * @return mixed | bool true if pass the check, api_not_allowed otherwise
4738
     */
4739
    public static function protectSession($id, $checkSession = true)
4740
    {
4741
        if (!self::cantEditSession($id, $checkSession)) {
4742
            api_not_allowed(true);
4743
        }
4744
    }
4745
4746
    /**
4747
     * @return bool
4748
     */
4749
    public static function allowToManageSessions()
4750
    {
4751
        if (self::allowManageAllSessions()) {
4752
            return true;
4753
        }
4754
4755
        $setting = api_get_setting('allow_teachers_to_create_sessions');
4756
4757
        if (api_is_teacher() && $setting == 'true') {
4758
            return true;
4759
        }
4760
4761
        return false;
4762
    }
4763
4764
    /**
4765
     * @return bool
4766
     */
4767
    public static function allowOnlyMySessions()
4768
    {
4769
        if (self::allowToManageSessions() &&
4770
            !api_is_platform_admin() &&
4771
            api_is_teacher()
4772
        ) {
4773
            return true;
4774
        }
4775
4776
        return false;
4777
    }
4778
4779
    /**
4780
     * @return bool
4781
     */
4782
    public static function allowManageAllSessions()
4783
    {
4784
        if (api_is_platform_admin() || api_is_session_admin()) {
4785
            return true;
4786
        }
4787
4788
        return false;
4789
    }
4790
4791
    /**
4792
     * @param $id
4793
     *
4794
     * @return bool
4795
     */
4796
    public static function protect_teacher_session_edit($id)
4797
    {
4798
        if (!api_is_coach($id) && !api_is_platform_admin()) {
4799
            api_not_allowed(true);
4800
        } else {
4801
            return true;
4802
        }
4803
    }
4804
4805
    /**
4806
     * @param int $courseId
4807
     *
4808
     * @return array
4809
     *
4810
     * @todo Add param to get only active sessions (not expires ones)
4811
     */
4812
    public static function get_session_by_course($courseId)
4813
    {
4814
        $table_session_course = Database::get_main_table(TABLE_MAIN_SESSION_COURSE);
4815
        $table_session = Database::get_main_table(TABLE_MAIN_SESSION);
4816
        $url = Database::get_main_table(TABLE_MAIN_ACCESS_URL_REL_SESSION);
4817
        $courseId = (int) $courseId;
4818
        $urlId = api_get_current_access_url_id();
4819
4820
        if (empty($courseId)) {
4821
            return [];
4822
        }
4823
4824
        $sql = "SELECT name, s.id
4825
                FROM $table_session_course sc
4826
                INNER JOIN $table_session s
4827
                ON (sc.session_id = s.id)
4828
                INNER JOIN $url u
4829
                ON (u.session_id = s.id)
4830
                WHERE
4831
                    u.access_url_id = $urlId AND
4832
                    sc.c_id = '$courseId' ";
4833
        $result = Database::query($sql);
4834
4835
        return Database::store_result($result);
4836
    }
4837
4838
    /**
4839
     * @param int  $userId
4840
     * @param bool $ignoreVisibilityForAdmins
4841
     * @param bool $ignoreTimeLimit
4842
     *
4843
     * @return array
4844
     */
4845
    public static function get_sessions_by_user(
4846
        $userId,
4847
        $ignoreVisibilityForAdmins = false,
4848
        $ignoreTimeLimit = false
4849
    ) {
4850
        $sessionCategories = UserManager::get_sessions_by_category(
4851
            $userId,
4852
            false,
4853
            $ignoreVisibilityForAdmins,
4854
            $ignoreTimeLimit
4855
        );
4856
4857
        $sessionArray = [];
4858
        if (!empty($sessionCategories)) {
4859
            foreach ($sessionCategories as $category) {
4860
                if (isset($category['sessions'])) {
4861
                    foreach ($category['sessions'] as $session) {
4862
                        $sessionArray[] = $session;
4863
                    }
4864
                }
4865
            }
4866
        }
4867
4868
        return $sessionArray;
4869
    }
4870
4871
    /**
4872
     * @param string $file
4873
     * @param bool   $updateSession                                   true: if the session exists it will be updated.
4874
     *                                                                false: if session exists a new session will be created adding a counter session1, session2, etc
4875
     * @param int    $defaultUserId
4876
     * @param Logger $logger
4877
     * @param array  $extraFields                                     convert a file row to an extra field. Example in CSV file there's a SessionID
4878
     *                                                                then it will converted to extra_external_session_id if you set: array('SessionId' => 'extra_external_session_id')
4879
     * @param string $extraFieldId
4880
     * @param int    $daysCoachAccessBeforeBeginning
4881
     * @param int    $daysCoachAccessAfterBeginning
4882
     * @param int    $sessionVisibility
4883
     * @param array  $fieldsToAvoidUpdate
4884
     * @param bool   $deleteUsersNotInList
4885
     * @param bool   $updateCourseCoaches
4886
     * @param bool   $sessionWithCoursesModifier
4887
     * @param bool   $addOriginalCourseTeachersAsCourseSessionCoaches
4888
     * @param bool   $removeAllTeachersFromCourse
4889
     * @param int    $showDescription
4890
     * @param array  $teacherBackupList
4891
     * @param array  $groupBackup
4892
     *
4893
     * @return array
4894
     */
4895
    public static function importCSV(
4896
        $file,
4897
        $updateSession,
4898
        $defaultUserId = null,
4899
        $logger = null,
4900
        $extraFields = [],
4901
        $extraFieldId = null,
4902
        $daysCoachAccessBeforeBeginning = null,
4903
        $daysCoachAccessAfterBeginning = null,
4904
        $sessionVisibility = 1,
4905
        $fieldsToAvoidUpdate = [],
4906
        $deleteUsersNotInList = false,
4907
        $updateCourseCoaches = false,
4908
        $sessionWithCoursesModifier = false,
4909
        $addOriginalCourseTeachersAsCourseSessionCoaches = true,
4910
        $removeAllTeachersFromCourse = true,
4911
        $showDescription = null,
4912
        &$teacherBackupList = [],
4913
        &$groupBackup = []
4914
    ) {
4915
        $content = file($file);
4916
        $error_message = null;
4917
        $session_counter = 0;
4918
        $defaultUserId = empty($defaultUserId) ? api_get_user_id() : (int) $defaultUserId;
4919
4920
        $eol = PHP_EOL;
4921
        if (PHP_SAPI != 'cli') {
4922
            $eol = '<br />';
4923
        }
4924
4925
        $debug = false;
4926
        if (isset($logger)) {
4927
            $debug = true;
4928
        }
4929
4930
        $tbl_session = Database::get_main_table(TABLE_MAIN_SESSION);
4931
        $tbl_session_user = Database::get_main_table(TABLE_MAIN_SESSION_USER);
4932
        $tbl_session_course = Database::get_main_table(TABLE_MAIN_SESSION_COURSE);
4933
        $tbl_session_course_user = Database::get_main_table(TABLE_MAIN_SESSION_COURSE_USER);
4934
        $sessions = [];
4935
        if (!api_strstr($content[0], ';')) {
4936
            $error_message = get_lang('NotCSV');
4937
        } else {
4938
            $tag_names = [];
4939
            foreach ($content as $key => $enreg) {
4940
                $enreg = explode(';', trim($enreg));
4941
                if ($key) {
4942
                    foreach ($tag_names as $tag_key => $tag_name) {
4943
                        if (isset($enreg[$tag_key])) {
4944
                            $sessions[$key - 1][$tag_name] = $enreg[$tag_key];
4945
                        }
4946
                    }
4947
                } else {
4948
                    foreach ($enreg as $tag_name) {
4949
                        $tag_names[] = api_preg_replace('/[^a-zA-Z0-9_\-]/', '', $tag_name);
4950
                    }
4951
                    if (!in_array('SessionName', $tag_names) ||
4952
                        !in_array('DateStart', $tag_names) ||
4953
                        !in_array('DateEnd', $tag_names)
4954
                    ) {
4955
                        $error_message = get_lang('NoNeededData');
4956
                        break;
4957
                    }
4958
                }
4959
            }
4960
4961
            $sessionList = [];
4962
            $report = [];
4963
4964
            // Looping the sessions.
4965
            foreach ($sessions as $enreg) {
4966
                $user_counter = 0;
4967
                $course_counter = 0;
4968
4969
                if (isset($extraFields) && !empty($extraFields)) {
4970
                    foreach ($extraFields as $original => $to) {
4971
                        $enreg[$to] = isset($enreg[$original]) ? $enreg[$original] : null;
4972
                    }
4973
                }
4974
4975
                $session_name = $enreg['SessionName'];
4976
4977
                if ($debug) {
4978
                    $logger->addInfo('---------------------------------------');
4979
                    $logger->addInfo("Sessions - Start process of session: $session_name");
4980
                    $logger->addInfo('---------------------------------------');
4981
                }
4982
4983
                // Default visibility
4984
                $visibilityAfterExpirationPerSession = $sessionVisibility;
4985
4986
                if (isset($enreg['VisibilityAfterExpiration'])) {
4987
                    $visibility = $enreg['VisibilityAfterExpiration'];
4988
                    switch ($visibility) {
4989
                        case 'read_only':
4990
                            $visibilityAfterExpirationPerSession = SESSION_VISIBLE_READ_ONLY;
4991
                            break;
4992
                        case 'accessible':
4993
                            $visibilityAfterExpirationPerSession = SESSION_VISIBLE;
4994
                            break;
4995
                        case 'not_accessible':
4996
                            $visibilityAfterExpirationPerSession = SESSION_INVISIBLE;
4997
                            break;
4998
                    }
4999
                }
5000
5001
                if (empty($session_name)) {
5002
                    continue;
5003
                }
5004
5005
                $displayAccessStartDate = isset($enreg['DisplayStartDate']) ? $enreg['DisplayStartDate'] : $enreg['DateStart'];
5006
                $displayAccessEndDate = isset($enreg['DisplayEndDate']) ? $enreg['DisplayEndDate'] : $enreg['DateEnd'];
5007
                $coachAccessStartDate = isset($enreg['CoachStartDate']) ? $enreg['CoachStartDate'] : $enreg['DateStart'];
5008
                $coachAccessEndDate = isset($enreg['CoachEndDate']) ? $enreg['CoachEndDate'] : $enreg['DateEnd'];
5009
                // We assume the dates are already in UTC
5010
                $dateStart = explode('/', $enreg['DateStart']);
5011
                $dateEnd = explode('/', $enreg['DateEnd']);
5012
                $dateStart = $dateStart[0].'-'.$dateStart[1].'-'.$dateStart[2].' 00:00:00';
5013
                $dateEnd = $dateEnd[0].'-'.$dateEnd[1].'-'.$dateEnd[2].' 23:59:59';
5014
                $displayAccessStartDate = explode('/', $displayAccessStartDate);
5015
                $displayAccessStartDate = implode('-', $displayAccessStartDate).' 00:00:00';
5016
                $displayAccessEndDate = explode('/', $displayAccessEndDate);
5017
                $displayAccessEndDate = implode('-', $displayAccessEndDate).' 23:59:59';
5018
                $coachAccessStartDate = explode('/', $coachAccessStartDate);
5019
                $coachAccessStartDate = implode('-', $coachAccessStartDate).' 00:00:00';
5020
                $coachAccessEndDate = explode('/', $coachAccessEndDate);
5021
                $coachAccessEndDate = implode('-', $coachAccessEndDate).' 23:59:59';
5022
                $session_category_id = isset($enreg['SessionCategory']) ? $enreg['SessionCategory'] : null;
5023
                $sessionDescription = isset($enreg['SessionDescription']) ? $enreg['SessionDescription'] : null;
5024
                $classes = isset($enreg['Classes']) ? explode('|', $enreg['Classes']) : [];
5025
                $extraParams = [];
5026
                if (!is_null($showDescription)) {
5027
                    $extraParams['show_description'] = intval($showDescription);
5028
                }
5029
5030
                $coachBefore = '';
5031
                $coachAfter = '';
5032
                if (!empty($daysCoachAccessBeforeBeginning) && !empty($daysCoachAccessAfterBeginning)) {
5033
                    $date = new \DateTime($dateStart);
5034
                    $interval = new DateInterval('P'.$daysCoachAccessBeforeBeginning.'D');
5035
                    $date->sub($interval);
5036
                    $coachBefore = $date->format('Y-m-d h:i');
5037
                    $coachAccessStartDate = $coachBefore;
5038
                    $coachBefore = api_get_utc_datetime($coachBefore);
5039
5040
                    $date = new \DateTime($dateEnd);
5041
                    $interval = new DateInterval('P'.$daysCoachAccessAfterBeginning.'D');
5042
                    $date->add($interval);
5043
                    $coachAfter = $date->format('Y-m-d h:i');
5044
                    $coachAccessEndDate = $coachAfter;
5045
                    $coachAfter = api_get_utc_datetime($coachAfter);
5046
                }
5047
5048
                $dateStart = api_get_utc_datetime($dateStart);
5049
                $dateEnd = api_get_utc_datetime($dateEnd);
5050
                $displayAccessStartDate = api_get_utc_datetime($displayAccessStartDate);
5051
                $displayAccessEndDate = api_get_utc_datetime($displayAccessEndDate);
5052
                $coachAccessStartDate = api_get_utc_datetime($coachAccessStartDate);
5053
                $coachAccessEndDate = api_get_utc_datetime($coachAccessEndDate);
5054
5055
                if (!empty($sessionDescription)) {
5056
                    $extraParams['description'] = $sessionDescription;
5057
                }
5058
5059
                if (!empty($session_category_id)) {
5060
                    $extraParams['session_category_id'] = $session_category_id;
5061
                }
5062
5063
                // Searching a general coach.
5064
                if (!empty($enreg['Coach'])) {
5065
                    $coach_id = UserManager::get_user_id_from_username($enreg['Coach']);
5066
                    if ($coach_id === false) {
5067
                        // If the coach-user does not exist - I'm the coach.
5068
                        $coach_id = $defaultUserId;
5069
                    }
5070
                } else {
5071
                    $coach_id = $defaultUserId;
5072
                }
5073
5074
                $users = explode('|', $enreg['Users']);
5075
                $courses = explode('|', $enreg['Courses']);
5076
5077
                $deleteOnlyCourseCoaches = false;
5078
                if (count($courses) == 1) {
5079
                    if ($logger) {
5080
                        $logger->addInfo('Only one course delete old coach list');
5081
                    }
5082
                    $deleteOnlyCourseCoaches = true;
5083
                }
5084
5085
                if (!$updateSession) {
5086
                    // Create a session.
5087
                    $unique_name = false;
5088
                    $i = 0;
5089
                    // Change session name, verify that session doesn't exist.
5090
                    $suffix = null;
5091
                    while (!$unique_name) {
5092
                        if ($i > 1) {
5093
                            $suffix = ' - '.$i;
5094
                        }
5095
                        $sql = 'SELECT 1 FROM '.$tbl_session.'
5096
                                WHERE name="'.Database::escape_string($session_name).$suffix.'"';
5097
                        $rs = Database::query($sql);
5098
                        if (Database::result($rs, 0, 0)) {
5099
                            $i++;
5100
                        } else {
5101
                            $unique_name = true;
5102
                            $session_name .= $suffix;
5103
                        }
5104
                    }
5105
5106
                    $sessionParams = [
5107
                        'name' => $session_name,
5108
                        'id_coach' => $coach_id,
5109
                        'access_start_date' => $dateStart,
5110
                        'access_end_date' => $dateEnd,
5111
                        'display_start_date' => $displayAccessStartDate,
5112
                        'display_end_date' => $displayAccessEndDate,
5113
                        'coach_access_start_date' => $coachAccessStartDate,
5114
                        'coach_access_end_date' => $coachAccessEndDate,
5115
                        'visibility' => $visibilityAfterExpirationPerSession,
5116
                        'session_admin_id' => $defaultUserId,
5117
                    ];
5118
5119
                    if (!empty($extraParams)) {
5120
                        $sessionParams = array_merge($sessionParams, $extraParams);
5121
                    }
5122
                    // Creating the session.
5123
                    $session_id = Database::insert($tbl_session, $sessionParams);
5124
                    if ($debug) {
5125
                        if ($session_id) {
5126
                            foreach ($enreg as $key => $value) {
5127
                                if (substr($key, 0, 6) == 'extra_') { //an extra field
5128
                                    self::update_session_extra_field_value($session_id, substr($key, 6), $value);
5129
                                }
5130
                            }
5131
                            $logger->addInfo("Session created: #$session_id - $session_name");
5132
                        } else {
5133
                            $message = "Sessions - Session NOT created: $session_name";
5134
                            $logger->addError($message);
5135
                            $report[] = $message;
5136
                        }
5137
                    }
5138
                    $session_counter++;
5139
                } else {
5140
                    $sessionId = null;
5141
                    if (isset($extraFields) && !empty($extraFields) && !empty($enreg['extra_'.$extraFieldId])) {
5142
                        $sessionId = self::getSessionIdFromOriginalId($enreg['extra_'.$extraFieldId], $extraFieldId);
5143
                        if (empty($sessionId)) {
5144
                            $my_session_result = false;
5145
                        } else {
5146
                            $my_session_result = true;
5147
                        }
5148
                    } else {
5149
                        $my_session_result = self::get_session_by_name($enreg['SessionName']);
5150
                    }
5151
5152
                    if ($my_session_result === false) {
5153
                        // One more check
5154
                        $sessionExistsWithName = self::get_session_by_name($session_name);
5155
                        if ($sessionExistsWithName) {
5156
                            if ($debug) {
5157
                                $message = "Skip Session - Trying to update a session, but name already exists: $session_name";
5158
                                $logger->addError($message);
5159
                                $report[] = $message;
5160
                            }
5161
                            continue;
5162
                        }
5163
5164
                        $sessionParams = [
5165
                            'name' => $session_name,
5166
                            'id_coach' => $coach_id,
5167
                            'access_start_date' => $dateStart,
5168
                            'access_end_date' => $dateEnd,
5169
                            'display_start_date' => $displayAccessStartDate,
5170
                            'display_end_date' => $displayAccessEndDate,
5171
                            'coach_access_start_date' => $coachAccessStartDate,
5172
                            'coach_access_end_date' => $coachAccessEndDate,
5173
                            'visibility' => $visibilityAfterExpirationPerSession,
5174
                            'session_admin_id' => $defaultUserId,
5175
                        ];
5176
5177
                        if (!empty($extraParams)) {
5178
                            $sessionParams = array_merge($sessionParams, $extraParams);
5179
                        }
5180
                        Database::insert($tbl_session, $sessionParams);
5181
5182
                        // We get the last insert id.
5183
                        $my_session_result = self::get_session_by_name($session_name);
5184
                        $session_id = $my_session_result['id'];
5185
5186
                        if ($session_id) {
5187
                            foreach ($enreg as $key => $value) {
5188
                                if (substr($key, 0, 6) == 'extra_') { //an extra field
5189
                                    self::update_session_extra_field_value($session_id, substr($key, 6), $value);
5190
                                }
5191
                            }
5192
                            if ($debug) {
5193
                                $logger->addInfo("Sessions - #$session_id created: $session_name");
5194
                            }
5195
5196
                            // Delete session-user relation only for students
5197
                            $sql = "DELETE FROM $tbl_session_user
5198
                                    WHERE session_id = '$session_id' AND relation_type <> ".SESSION_RELATION_TYPE_RRHH;
5199
                            Database::query($sql);
5200
5201
                            $sql = "DELETE FROM $tbl_session_course WHERE session_id = '$session_id'";
5202
                            Database::query($sql);
5203
5204
                            // Delete session-course-user relationships students and coaches.
5205
                            if ($updateCourseCoaches) {
5206
                                $sql = "DELETE FROM $tbl_session_course_user
5207
                                        WHERE session_id = '$session_id' AND status in ('0', '2')";
5208
                                Database::query($sql);
5209
                            } else {
5210
                                // Delete session-course-user relation ships *only* for students.
5211
                                $sql = "DELETE FROM $tbl_session_course_user
5212
                                        WHERE session_id = '$session_id' AND status <> 2";
5213
                                Database::query($sql);
5214
                            }
5215
                            if ($deleteOnlyCourseCoaches) {
5216
                                $sql = "DELETE FROM $tbl_session_course_user
5217
                                        WHERE session_id = '$session_id' AND status in ('2')";
5218
                                Database::query($sql);
5219
                            }
5220
                        }
5221
                    } else {
5222
                        // Updating the session.
5223
                        $params = [
5224
                            'id_coach' => $coach_id,
5225
                            'access_start_date' => $dateStart,
5226
                            'access_end_date' => $dateEnd,
5227
                            'display_start_date' => $displayAccessStartDate,
5228
                            'display_end_date' => $displayAccessEndDate,
5229
                            'coach_access_start_date' => $coachAccessStartDate,
5230
                            'coach_access_end_date' => $coachAccessEndDate,
5231
                            'visibility' => $visibilityAfterExpirationPerSession,
5232
                            'session_category_id' => $session_category_id,
5233
                        ];
5234
5235
                        if (!empty($sessionDescription)) {
5236
                            $params['description'] = $sessionDescription;
5237
                        }
5238
5239
                        if (!empty($fieldsToAvoidUpdate)) {
5240
                            foreach ($fieldsToAvoidUpdate as $field) {
5241
                                unset($params[$field]);
5242
                            }
5243
                        }
5244
5245
                        if (isset($sessionId) && !empty($sessionId)) {
5246
                            $session_id = $sessionId;
5247
                            if (!empty($enreg['SessionName'])) {
5248
                                $sessionExistsWithName = self::get_session_by_name($session_name);
5249
                                if ($sessionExistsWithName === false) {
5250
                                    $sessionName = Database::escape_string($enreg['SessionName']);
5251
                                    $sql = "UPDATE $tbl_session SET name = '$sessionName' WHERE id = $session_id";
5252
                                    Database::query($sql);
5253
                                    $logger->addInfo(
5254
                                        "Session #$session_id name IS updated with: '$session_name' External id: ".$enreg['extra_'.$extraFieldId]
5255
                                    );
5256
                                } else {
5257
                                    $sessionExistsBesidesMe = self::sessionNameExistBesidesMySession(
5258
                                        $session_id,
5259
                                        $session_name
5260
                                    );
5261
                                    if ($sessionExistsBesidesMe === true) {
5262
                                        if ($debug) {
5263
                                            $message = "Skip Session. Error when update session Session #$session_id Name: '$session_name'. Other session has the same name. External id: ".$enreg['extra_'.$extraFieldId];
5264
                                            $logger->addError($message);
5265
                                            $report[] = $message;
5266
                                        }
5267
                                        continue;
5268
                                    } else {
5269
                                        if ($debug) {
5270
                                            $logger->addInfo(
5271
                                                "Session #$session_id name is not updated because it didn't change (but update of other session values will continue) Name: '$session_name' External id: ".$enreg['extra_'.$extraFieldId]
5272
                                            );
5273
                                        }
5274
                                    }
5275
                                }
5276
                            }
5277
                        } else {
5278
                            $my_session_result = self::get_session_by_name($session_name);
5279
                            $session_id = $my_session_result['id'];
5280
                        }
5281
5282
                        if ($debug) {
5283
                            $logger->addInfo("Session #$session_id to be updated: '$session_name'");
5284
                        }
5285
5286
                        if ($session_id) {
5287
                            $sessionInfo = api_get_session_info($session_id);
5288
                            $params['show_description'] = isset($sessionInfo['show_description']) ? $sessionInfo['show_description'] : intval($showDescription);
5289
5290
                            if (!empty($daysCoachAccessBeforeBeginning) && !empty($daysCoachAccessAfterBeginning)) {
5291
                                if (empty($sessionInfo['nb_days_access_before_beginning']) ||
5292
                                    (!empty($sessionInfo['nb_days_access_before_beginning']) &&
5293
                                        $sessionInfo['nb_days_access_before_beginning'] < $daysCoachAccessBeforeBeginning)
5294
                                ) {
5295
                                    $params['coach_access_start_date'] = $coachBefore;
5296
                                }
5297
5298
                                if (empty($sessionInfo['nb_days_access_after_end']) ||
5299
                                    (!empty($sessionInfo['nb_days_access_after_end']) &&
5300
                                        $sessionInfo['nb_days_access_after_end'] < $daysCoachAccessAfterBeginning)
5301
                                ) {
5302
                                    $params['coach_access_end_date'] = $coachAfter;
5303
                                }
5304
                            }
5305
5306
                            Database::update($tbl_session, $params, ['id = ?' => $session_id]);
5307
                            foreach ($enreg as $key => $value) {
5308
                                if (substr($key, 0, 6) == 'extra_') { //an extra field
5309
                                    self::update_session_extra_field_value($session_id, substr($key, 6), $value);
5310
                                }
5311
                            }
5312
5313
                            if ($debug) {
5314
                                $logger->addInfo("Session updated #$session_id");
5315
                            }
5316
5317
                            // Delete session-user relation only for students
5318
                            $sql = "DELETE FROM $tbl_session_user
5319
                                    WHERE session_id = '$session_id' AND relation_type <> ".SESSION_RELATION_TYPE_RRHH;
5320
                            Database::query($sql);
5321
5322
                            $sql = "DELETE FROM $tbl_session_course WHERE session_id = '$session_id'";
5323
                            Database::query($sql);
5324
5325
                            // Delete session-course-user relationships students and coaches.
5326
                            if ($updateCourseCoaches) {
5327
                                $sql = "DELETE FROM $tbl_session_course_user
5328
                                        WHERE session_id = '$session_id' AND status in ('0', '2')";
5329
                                Database::query($sql);
5330
                            } else {
5331
                                // Delete session-course-user relation ships *only* for students.
5332
                                $sql = "DELETE FROM $tbl_session_course_user
5333
                                        WHERE session_id = '$session_id' AND status <> 2";
5334
                                Database::query($sql);
5335
                            }
5336
5337
                            if ($deleteOnlyCourseCoaches) {
5338
                                $sql = "DELETE FROM $tbl_session_course_user
5339
                                        WHERE session_id = '$session_id' AND status in ('2')";
5340
                                Database::query($sql);
5341
                            }
5342
                        } else {
5343
                            if ($debug) {
5344
                                $logger->addError(
5345
                                    "Sessions - Session not found"
5346
                                );
5347
                            }
5348
                        }
5349
                    }
5350
                    $session_counter++;
5351
                }
5352
5353
                $sessionList[] = $session_id;
5354
5355
                // Adding the relationship "Session - User" for students
5356
                $userList = [];
5357
                if (is_array($users)) {
5358
                    $extraFieldValueCareer = new ExtraFieldValue('career');
5359
                    $careerList = isset($enreg['extra_careerid']) && !empty($enreg['extra_careerid']) ? $enreg['extra_careerid'] : [];
5360
                    $careerList = str_replace(['[', ']'], '', $careerList);
5361
                    $careerList = explode(',', $careerList);
5362
                    $finalCareerIdList = [];
5363
                    foreach ($careerList as $careerId) {
5364
                        $realCareerIdList = $extraFieldValueCareer->get_item_id_from_field_variable_and_field_value(
5365
                            'external_career_id',
5366
                            $careerId
5367
                        );
5368
                        if (isset($realCareerIdList['item_id'])) {
5369
                            $finalCareerIdList[] = $realCareerIdList['item_id'];
5370
                        }
5371
                    }
5372
5373
                    foreach ($users as $user) {
5374
                        $user_id = UserManager::get_user_id_from_username($user);
5375
                        if ($user_id !== false) {
5376
                            if (!empty($finalCareerIdList)) {
5377
                                foreach ($finalCareerIdList as $careerId) {
5378
                                    UserManager::addUserCareer($user_id, $careerId);
5379
                                }
5380
                            }
5381
5382
                            $userList[] = $user_id;
5383
                            // Insert new users.
5384
                            $sql = "INSERT IGNORE INTO $tbl_session_user SET
5385
                                    user_id = '$user_id',
5386
                                    session_id = '$session_id',
5387
                                    registered_at = '".api_get_utc_datetime()."'";
5388
                            Database::query($sql);
5389
                            if ($debug) {
5390
                                $logger->addInfo("Adding User #$user_id ($user) to session #$session_id");
5391
                            }
5392
                            $user_counter++;
5393
                        }
5394
                    }
5395
                }
5396
5397
                if ($deleteUsersNotInList) {
5398
                    // Getting user in DB in order to compare to the new list.
5399
                    $usersListInDatabase = self::get_users_by_session($session_id, 0);
5400
                    if (!empty($usersListInDatabase)) {
5401
                        if (empty($userList)) {
5402
                            foreach ($usersListInDatabase as $userInfo) {
5403
                                self::unsubscribe_user_from_session($session_id, $userInfo['user_id']);
5404
                            }
5405
                        } else {
5406
                            foreach ($usersListInDatabase as $userInfo) {
5407
                                if (!in_array($userInfo['user_id'], $userList)) {
5408
                                    self::unsubscribe_user_from_session($session_id, $userInfo['user_id']);
5409
                                }
5410
                            }
5411
                        }
5412
                    }
5413
                }
5414
5415
                // See BT#6449
5416
                $onlyAddFirstCoachOrTeacher = false;
5417
                if ($sessionWithCoursesModifier) {
5418
                    if (count($courses) >= 2) {
5419
                        // Only first teacher in course session;
5420
                        $onlyAddFirstCoachOrTeacher = true;
5421
                        // Remove all teachers from course.
5422
                        $removeAllTeachersFromCourse = false;
5423
                    }
5424
                }
5425
5426
                foreach ($courses as $course) {
5427
                    $courseArray = bracketsToArray($course);
5428
                    $course_code = $courseArray[0];
5429
5430
                    if (CourseManager::course_exists($course_code)) {
5431
                        $courseInfo = api_get_course_info($course_code);
5432
                        $courseId = $courseInfo['real_id'];
5433
5434
                        // Adding the course to a session.
5435
                        $sql = "INSERT IGNORE INTO $tbl_session_course
5436
                                SET c_id = '$courseId', session_id='$session_id'";
5437
                        Database::query($sql);
5438
5439
                        self::installCourse($session_id, $courseInfo['real_id']);
5440
5441
                        if ($debug) {
5442
                            $logger->addInfo("Adding course '$course_code' to session #$session_id");
5443
                        }
5444
5445
                        $course_counter++;
5446
                        $course_coaches = isset($courseArray[1]) ? $courseArray[1] : null;
5447
                        $course_users = isset($courseArray[2]) ? $courseArray[2] : null;
5448
                        $course_users = explode(',', $course_users);
5449
                        $course_coaches = explode(',', $course_coaches);
5450
5451
                        // Checking if the flag is set TeachersWillBeAddedAsCoachInAllCourseSessions (course_edit.php)
5452
                        $addTeachersToSession = true;
5453
5454
                        if (array_key_exists('add_teachers_to_sessions_courses', $courseInfo)) {
5455
                            $addTeachersToSession = $courseInfo['add_teachers_to_sessions_courses'];
5456
                        }
5457
5458
                        // If any user provided for a course, use the users array.
5459
                        if (empty($course_users)) {
5460
                            if (!empty($userList)) {
5461
                                self::subscribe_users_to_session_course(
5462
                                    $userList,
5463
                                    $session_id,
5464
                                    $course_code
5465
                                );
5466
                                if ($debug) {
5467
                                    $msg = "Adding student list ".implode(', #', $userList)." to course: '$course_code' and session #$session_id";
5468
                                    $logger->addInfo($msg);
5469
                                }
5470
                            }
5471
                        }
5472
5473
                        // Adding coaches to session course user.
5474
                        if (!empty($course_coaches)) {
5475
                            $savedCoaches = [];
5476
                            // only edit if add_teachers_to_sessions_courses is set.
5477
                            if ($addTeachersToSession) {
5478
                                if ($addOriginalCourseTeachersAsCourseSessionCoaches) {
5479
                                    // Adding course teachers as course session teachers.
5480
                                    $alreadyAddedTeachers = CourseManager::get_teacher_list_from_course_code(
5481
                                        $course_code
5482
                                    );
5483
5484
                                    if (!empty($alreadyAddedTeachers)) {
5485
                                        $teachersToAdd = [];
5486
                                        foreach ($alreadyAddedTeachers as $user) {
5487
                                            $teachersToAdd[] = $user['username'];
5488
                                        }
5489
                                        $course_coaches = array_merge(
5490
                                            $course_coaches,
5491
                                            $teachersToAdd
5492
                                        );
5493
                                    }
5494
                                }
5495
5496
                                foreach ($course_coaches as $course_coach) {
5497
                                    $coach_id = UserManager::get_user_id_from_username($course_coach);
5498
                                    if ($coach_id !== false) {
5499
                                        // Just insert new coaches
5500
                                        self::updateCoaches(
5501
                                            $session_id,
5502
                                            $courseId,
5503
                                            [$coach_id],
5504
                                            false
5505
                                        );
5506
5507
                                        if ($debug) {
5508
                                            $logger->addInfo("Adding course coach: user #$coach_id ($course_coach) to course: '$course_code' and session #$session_id");
5509
                                        }
5510
                                        $savedCoaches[] = $coach_id;
5511
                                    } else {
5512
                                        $error_message .= get_lang('UserDoesNotExist').' : '.$course_coach.$eol;
5513
                                    }
5514
                                }
5515
                            }
5516
5517
                            // Custom courses/session coaches
5518
                            $teacherToAdd = null;
5519
                            // Only one coach is added.
5520
                            if ($onlyAddFirstCoachOrTeacher == true) {
5521
                                if ($debug) {
5522
                                    $logger->addInfo("onlyAddFirstCoachOrTeacher : true");
5523
                                }
5524
5525
                                foreach ($course_coaches as $course_coach) {
5526
                                    $coach_id = UserManager::get_user_id_from_username($course_coach);
5527
                                    if ($coach_id !== false) {
5528
                                        $teacherToAdd = $coach_id;
5529
                                        break;
5530
                                    }
5531
                                }
5532
5533
                                // Un subscribe everyone that's not in the list.
5534
                                $teacherList = CourseManager::get_teacher_list_from_course_code($course_code);
5535
                                if (!empty($teacherList)) {
5536
                                    foreach ($teacherList as $teacher) {
5537
                                        if ($teacherToAdd != $teacher['user_id']) {
5538
                                            $sql = "SELECT * FROM ".Database::get_main_table(TABLE_MAIN_COURSE_USER)."
5539
                                                    WHERE
5540
                                                        user_id = ".$teacher['user_id']." AND
5541
                                                        c_id = '".$courseId."'
5542
                                                    ";
5543
5544
                                            $result = Database::query($sql);
5545
                                            $rows = Database::num_rows($result);
5546
                                            if ($rows > 0) {
5547
                                                $userCourseData = Database::fetch_array($result, 'ASSOC');
5548
                                                if (!empty($userCourseData)) {
5549
                                                    $teacherBackupList[$teacher['user_id']][$course_code] = $userCourseData;
5550
                                                }
5551
                                            }
5552
5553
                                            $sql = "SELECT * FROM ".Database::get_course_table(TABLE_GROUP_USER)."
5554
                                                    WHERE
5555
                                                        user_id = ".$teacher['user_id']." AND
5556
                                                        c_id = '".$courseInfo['real_id']."'
5557
                                                    ";
5558
5559
                                            $result = Database::query($sql);
5560
                                            while ($groupData = Database::fetch_array($result, 'ASSOC')) {
5561
                                                $groupBackup['user'][$teacher['user_id']][$course_code][$groupData['group_id']] = $groupData;
5562
                                            }
5563
5564
                                            $sql = "SELECT * FROM ".Database::get_course_table(TABLE_GROUP_TUTOR)."
5565
                                                    WHERE
5566
                                                        user_id = ".$teacher['user_id']." AND
5567
                                                        c_id = '".$courseInfo['real_id']."'
5568
                                                    ";
5569
5570
                                            $result = Database::query($sql);
5571
                                            while ($groupData = Database::fetch_array($result, 'ASSOC')) {
5572
                                                $groupBackup['tutor'][$teacher['user_id']][$course_code][$groupData['group_id']] = $groupData;
5573
                                            }
5574
5575
                                            CourseManager::unsubscribe_user(
5576
                                                $teacher['user_id'],
5577
                                                $course_code
5578
                                            );
5579
5580
                                            if ($debug) {
5581
                                                $logger->addInfo("Delete user #".$teacher['user_id']." from base course: $course_code");
5582
                                            }
5583
                                        }
5584
                                    }
5585
                                }
5586
5587
                                if (!empty($teacherToAdd)) {
5588
                                    self::updateCoaches(
5589
                                        $session_id,
5590
                                        $courseId,
5591
                                        [$teacherToAdd],
5592
                                        true
5593
                                    );
5594
5595
                                    if ($debug) {
5596
                                        $logger->addInfo("Add coach #$teacherToAdd to course $courseId and session $session_id");
5597
                                    }
5598
5599
                                    $userCourseCategory = '';
5600
                                    if (isset($teacherBackupList[$teacherToAdd]) &&
5601
                                        isset($teacherBackupList[$teacherToAdd][$course_code])
5602
                                    ) {
5603
                                        $courseUserData = $teacherBackupList[$teacherToAdd][$course_code];
5604
                                        $userCourseCategory = $courseUserData['user_course_cat'];
5605
                                    }
5606
5607
                                    CourseManager::subscribeUser(
5608
                                        $teacherToAdd,
5609
                                        $course_code,
5610
                                        COURSEMANAGER,
5611
                                        0,
5612
                                        $userCourseCategory
5613
                                    );
5614
5615
                                    if ($debug) {
5616
                                        $logger->addInfo("Subscribe user #$teacherToAdd as teacher in course $course_code with user userCourseCategory $userCourseCategory");
5617
                                    }
5618
5619
                                    if (isset($groupBackup['user'][$teacherToAdd]) &&
5620
                                        isset($groupBackup['user'][$teacherToAdd][$course_code]) &&
5621
                                        !empty($groupBackup['user'][$teacherToAdd][$course_code])
5622
                                    ) {
5623
                                        foreach ($groupBackup['user'][$teacherToAdd][$course_code] as $data) {
5624
                                            $groupInfo = GroupManager::get_group_properties($data['group_id']);
5625
                                            GroupManager::subscribe_users(
5626
                                                $teacherToAdd,
5627
                                                $groupInfo,
5628
                                                $data['c_id']
5629
                                            );
5630
                                        }
5631
                                    }
5632
5633
                                    if (isset($groupBackup['tutor'][$teacherToAdd]) &&
5634
                                        isset($groupBackup['tutor'][$teacherToAdd][$course_code]) &&
5635
                                        !empty($groupBackup['tutor'][$teacherToAdd][$course_code])
5636
                                    ) {
5637
                                        foreach ($groupBackup['tutor'][$teacherToAdd][$course_code] as $data) {
5638
                                            $groupInfo = GroupManager::get_group_properties($data['group_id']);
5639
                                            GroupManager::subscribe_tutors(
5640
                                                $teacherToAdd,
5641
                                                $groupInfo,
5642
                                                $data['c_id']
5643
                                            );
5644
                                        }
5645
                                    }
5646
                                }
5647
                            }
5648
5649
                            // See BT#6449#note-195
5650
                            // All coaches are added.
5651
                            if ($removeAllTeachersFromCourse) {
5652
                                if ($debug) {
5653
                                    $logger->addInfo("removeAllTeachersFromCourse true");
5654
                                }
5655
                                $teacherToAdd = null;
5656
                                foreach ($course_coaches as $course_coach) {
5657
                                    $coach_id = UserManager::get_user_id_from_username(
5658
                                        $course_coach
5659
                                    );
5660
                                    if ($coach_id !== false) {
5661
                                        $teacherToAdd[] = $coach_id;
5662
                                    }
5663
                                }
5664
5665
                                if (!empty($teacherToAdd)) {
5666
                                    // Deleting all course teachers and adding the only coach as teacher.
5667
                                    $teacherList = CourseManager::get_teacher_list_from_course_code($course_code);
5668
5669
                                    if (!empty($teacherList)) {
5670
                                        foreach ($teacherList as $teacher) {
5671
                                            if (!in_array($teacher['user_id'], $teacherToAdd)) {
5672
                                                $sql = "SELECT * FROM ".Database::get_main_table(TABLE_MAIN_COURSE_USER)."
5673
                                                        WHERE
5674
                                                            user_id = ".$teacher['user_id']." AND
5675
                                                            c_id = '".$courseId."'
5676
                                                        ";
5677
5678
                                                $result = Database::query($sql);
5679
                                                $rows = Database::num_rows($result);
5680
                                                if ($rows > 0) {
5681
                                                    $userCourseData = Database::fetch_array($result, 'ASSOC');
5682
                                                    if (!empty($userCourseData)) {
5683
                                                        $teacherBackupList[$teacher['user_id']][$course_code] = $userCourseData;
5684
                                                    }
5685
                                                }
5686
5687
                                                $sql = "SELECT * FROM ".Database::get_course_table(TABLE_GROUP_USER)."
5688
                                                        WHERE
5689
                                                            user_id = ".$teacher['user_id']." AND
5690
                                                            c_id = '".$courseInfo['real_id']."'
5691
                                                        ";
5692
5693
                                                $result = Database::query($sql);
5694
                                                while ($groupData = Database::fetch_array($result, 'ASSOC')) {
5695
                                                    $groupBackup['user'][$teacher['user_id']][$course_code][$groupData['group_id']] = $groupData;
5696
                                                }
5697
5698
                                                $sql = "SELECT * FROM ".Database::get_course_table(TABLE_GROUP_TUTOR)."
5699
                                                        WHERE
5700
                                                            user_id = ".$teacher['user_id']." AND
5701
                                                            c_id = '".$courseInfo['real_id']."'
5702
                                                        ";
5703
5704
                                                $result = Database::query($sql);
5705
                                                while ($groupData = Database::fetch_array($result, 'ASSOC')) {
5706
                                                    $groupBackup['tutor'][$teacher['user_id']][$course_code][$groupData['group_id']] = $groupData;
5707
                                                }
5708
5709
                                                CourseManager::unsubscribe_user(
5710
                                                    $teacher['user_id'],
5711
                                                    $course_code
5712
                                                );
5713
5714
                                                if ($debug) {
5715
                                                    $logger->addInfo("Delete user #".$teacher['user_id']." from base course: $course_code");
5716
                                                }
5717
                                            }
5718
                                        }
5719
                                    }
5720
5721
                                    foreach ($teacherToAdd as $teacherId) {
5722
                                        $userCourseCategory = '';
5723
                                        if (isset($teacherBackupList[$teacherId]) &&
5724
                                            isset($teacherBackupList[$teacherId][$course_code])
5725
                                        ) {
5726
                                            $courseUserData = $teacherBackupList[$teacherId][$course_code];
5727
                                            $userCourseCategory = $courseUserData['user_course_cat'];
5728
                                        }
5729
5730
                                        CourseManager::subscribeUser(
5731
                                            $teacherId,
5732
                                            $course_code,
5733
                                            COURSEMANAGER,
5734
                                            0,
5735
                                            $userCourseCategory
5736
                                        );
5737
5738
                                        if ($debug) {
5739
                                            $logger->addInfo("Add user as teacher #".$teacherId." in base course: $course_code with userCourseCategory: $userCourseCategory");
5740
                                        }
5741
5742
                                        if (isset($groupBackup['user'][$teacherId]) &&
5743
                                            isset($groupBackup['user'][$teacherId][$course_code]) &&
5744
                                            !empty($groupBackup['user'][$teacherId][$course_code])
5745
                                        ) {
5746
                                            foreach ($groupBackup['user'][$teacherId][$course_code] as $data) {
5747
                                                $groupInfo = GroupManager::get_group_properties($data['group_id']);
5748
                                                GroupManager::subscribe_users(
5749
                                                    $teacherId,
5750
                                                    $groupInfo,
5751
                                                    $data['c_id']
5752
                                                );
5753
                                            }
5754
                                        }
5755
5756
                                        if (isset($groupBackup['tutor'][$teacherId]) &&
5757
                                            isset($groupBackup['tutor'][$teacherId][$course_code]) &&
5758
                                            !empty($groupBackup['tutor'][$teacherId][$course_code])
5759
                                        ) {
5760
                                            foreach ($groupBackup['tutor'][$teacherId][$course_code] as $data) {
5761
                                                $groupInfo = GroupManager::get_group_properties($data['group_id']);
5762
                                                GroupManager::subscribe_tutors(
5763
                                                    $teacherId,
5764
                                                    $groupInfo,
5765
                                                    $data['c_id']
5766
                                                );
5767
                                            }
5768
                                        }
5769
                                    }
5770
                                }
5771
                            }
5772
5773
                            // Continue default behaviour.
5774
                            if ($onlyAddFirstCoachOrTeacher == false) {
5775
                                // Checking one more time see BT#6449#note-149
5776
                                $coaches = self::getCoachesByCourseSession($session_id, $courseId);
5777
                                // Update coaches if only there's 1 course see BT#6449#note-189
5778
                                if (empty($coaches) || count($courses) == 1) {
5779
                                    foreach ($course_coaches as $course_coach) {
5780
                                        $course_coach = trim($course_coach);
5781
                                        $coach_id = UserManager::get_user_id_from_username($course_coach);
5782
                                        if ($coach_id !== false) {
5783
                                            // Just insert new coaches
5784
                                            self::updateCoaches(
5785
                                                $session_id,
5786
                                                $courseId,
5787
                                                [$coach_id],
5788
                                                false
5789
                                            );
5790
5791
                                            if ($debug) {
5792
                                                $logger->addInfo("Sessions - Adding course coach: user #$coach_id ($course_coach) to course: '$course_code' and session #$session_id");
5793
                                            }
5794
                                            $savedCoaches[] = $coach_id;
5795
                                        } else {
5796
                                            $error_message .= get_lang('UserDoesNotExist').' : '.$course_coach.$eol;
5797
                                        }
5798
                                    }
5799
                                }
5800
                            }
5801
                        }
5802
5803
                        // Adding Students, updating relationship "Session - Course - User".
5804
                        $course_users = array_filter($course_users);
5805
                        if (!empty($course_users)) {
5806
                            foreach ($course_users as $user) {
5807
                                $user_id = UserManager::get_user_id_from_username($user);
5808
5809
                                if ($user_id !== false) {
5810
                                    self::subscribe_users_to_session_course(
5811
                                        [$user_id],
5812
                                        $session_id,
5813
                                        $course_code
5814
                                    );
5815
                                    if ($debug) {
5816
                                        $logger->addInfo("Adding student: user #$user_id ($user) to course: '$course_code' and session #$session_id");
5817
                                    }
5818
                                } else {
5819
                                    $error_message .= get_lang('UserDoesNotExist').': '.$user.$eol;
5820
                                }
5821
                            }
5822
                        }
5823
                        $inserted_in_course[$course_code] = $courseInfo['title'];
5824
                    }
5825
                }
5826
                $access_url_id = api_get_current_access_url_id();
5827
                UrlManager::add_session_to_url($session_id, $access_url_id);
5828
                $sql = "UPDATE $tbl_session SET nbr_users = '$user_counter', nbr_courses = '$course_counter'
5829
                        WHERE id = '$session_id'";
5830
                Database::query($sql);
5831
5832
                self::addClassesByName($session_id, $classes, false);
5833
5834
                if ($debug) {
5835
                    $logger->addInfo("End process session #$session_id -------------------- ");
5836
                }
5837
            }
5838
5839
            if (!empty($report)) {
5840
                if ($debug) {
5841
                    $logger->addInfo("--Summary--");
5842
                    foreach ($report as $line) {
5843
                        $logger->addInfo($line);
5844
                    }
5845
                }
5846
            }
5847
        }
5848
5849
        return [
5850
            'error_message' => $error_message,
5851
            'session_counter' => $session_counter,
5852
            'session_list' => $sessionList,
5853
        ];
5854
    }
5855
5856
    /**
5857
     * @param int $sessionId
5858
     * @param int $courseId
5859
     *
5860
     * @return array
5861
     */
5862
    public static function getCoachesByCourseSession($sessionId, $courseId)
5863
    {
5864
        $table = Database::get_main_table(TABLE_MAIN_SESSION_COURSE_USER);
5865
        $sessionId = (int) $sessionId;
5866
        $courseId = (int) $courseId;
5867
5868
        $sql = "SELECT user_id FROM $table
5869
                WHERE
5870
                    session_id = '$sessionId' AND
5871
                    c_id = '$courseId' AND
5872
                    status = 2";
5873
        $result = Database::query($sql);
5874
5875
        $coaches = [];
5876
        if (Database::num_rows($result) > 0) {
5877
            while ($row = Database::fetch_array($result)) {
5878
                $coaches[] = $row['user_id'];
5879
            }
5880
        }
5881
5882
        return $coaches;
5883
    }
5884
5885
    /**
5886
     * @param int    $sessionId
5887
     * @param int    $courseId
5888
     * @param string $separator
5889
     *
5890
     * @return string
5891
     */
5892
    public static function getCoachesByCourseSessionToString(
5893
        $sessionId,
5894
        $courseId,
5895
        $separator = ''
5896
    ) {
5897
        $coaches = self::getCoachesByCourseSession($sessionId, $courseId);
5898
        $list = [];
5899
        if (!empty($coaches)) {
5900
            foreach ($coaches as $coachId) {
5901
                $userInfo = api_get_user_info($coachId);
5902
                if ($userInfo) {
5903
                    $list[] = $userInfo['complete_name'];
5904
                }
5905
            }
5906
        }
5907
5908
        $separator = empty($separator) ? CourseManager::USER_SEPARATOR : $separator;
5909
5910
        return array_to_string($list, $separator);
5911
    }
5912
5913
    /**
5914
     * Get all coaches added in the session - course relationship.
5915
     *
5916
     * @param int $sessionId
5917
     *
5918
     * @return array
5919
     */
5920
    public static function getCoachesBySession($sessionId)
5921
    {
5922
        $table = Database::get_main_table(TABLE_MAIN_SESSION_COURSE_USER);
5923
        $sessionId = intval($sessionId);
5924
5925
        $sql = "SELECT DISTINCT user_id
5926
                FROM $table
5927
                WHERE session_id = '$sessionId' AND status = 2";
5928
        $result = Database::query($sql);
5929
5930
        $coaches = [];
5931
        if (Database::num_rows($result) > 0) {
5932
            while ($row = Database::fetch_array($result)) {
5933
                $coaches[] = $row['user_id'];
5934
            }
5935
        }
5936
5937
        return $coaches;
5938
    }
5939
5940
    /**
5941
     * @param int $userId
5942
     *
5943
     * @return array
5944
     */
5945
    public static function getAllCoursesFromAllSessionFromDrh($userId)
5946
    {
5947
        $sessions = self::get_sessions_followed_by_drh($userId);
5948
        $coursesFromSession = [];
5949
        if (!empty($sessions)) {
5950
            foreach ($sessions as $session) {
5951
                $courseList = self::get_course_list_by_session_id($session['id']);
5952
                foreach ($courseList as $course) {
5953
                    $coursesFromSession[] = $course['code'];
5954
                }
5955
            }
5956
        }
5957
5958
        return $coursesFromSession;
5959
    }
5960
5961
    /**
5962
     * getAllCoursesFromAllSessions.
5963
     *
5964
     * @return array
5965
     */
5966
    public static function getAllCoursesFromAllSessions()
5967
    {
5968
        $sessions = self::get_sessions_list();
5969
        $coursesFromSession = [];
5970
        if (!empty($sessions)) {
5971
            foreach ($sessions as $session) {
5972
                $courseList = self::get_course_list_by_session_id($session['id']);
5973
                foreach ($courseList as $course) {
5974
                    $coursesFromSession[$course['code'].':'.$session['id']] = $course['visual_code'].' - '.$course['title'].' ('.$session['name'].')';
5975
                }
5976
            }
5977
        }
5978
5979
        return $coursesFromSession;
5980
    }
5981
5982
    /**
5983
     * Return user id list or count of users depending of the $getCount parameter.
5984
     *
5985
     * @param string $status
5986
     * @param int    $userId
5987
     * @param bool   $getCount
5988
     * @param int    $from
5989
     * @param int    $numberItems
5990
     * @param int    $column
5991
     * @param string $direction
5992
     * @param string $keyword
5993
     * @param string $active
5994
     * @param string $lastConnectionDate
5995
     * @param array  $sessionIdList
5996
     * @param array  $studentIdList
5997
     * @param int    $filterByStatus
5998
     *
5999
     * @return array|int
6000
     */
6001
    public static function getAllUsersFromCoursesFromAllSessionFromStatus(
6002
        $status,
6003
        $userId,
6004
        $getCount = false,
6005
        $from = null,
6006
        $numberItems = null,
6007
        $column = '',
6008
        $direction = 'asc',
6009
        $keyword = null,
6010
        $active = null,
6011
        $lastConnectionDate = null,
6012
        $sessionIdList = [],
6013
        $studentIdList = [],
6014
        $filterByStatus = null
6015
    ) {
6016
        $filterByStatus = (int) $filterByStatus;
6017
        $userId = (int) $userId;
6018
6019
        if (empty($column)) {
6020
            $column = 'u.lastname';
6021
            if (api_is_western_name_order()) {
6022
                $column = 'u.firstname';
6023
            }
6024
        }
6025
6026
        $tbl_user = Database::get_main_table(TABLE_MAIN_USER);
6027
        $tbl_session = Database::get_main_table(TABLE_MAIN_SESSION);
6028
        $tbl_course = Database::get_main_table(TABLE_MAIN_COURSE);
6029
        $tbl_course_user = Database::get_main_table(TABLE_MAIN_COURSE_USER);
6030
        $tbl_user_rel_access_url = Database::get_main_table(TABLE_MAIN_ACCESS_URL_REL_USER);
6031
        $tbl_course_rel_access_url = Database::get_main_table(TABLE_MAIN_ACCESS_URL_REL_COURSE);
6032
        $tbl_session_rel_course_rel_user = Database::get_main_table(TABLE_MAIN_SESSION_COURSE_USER);
6033
        $tbl_session_rel_access_url = Database::get_main_table(TABLE_MAIN_ACCESS_URL_REL_SESSION);
6034
6035
        $direction = in_array(strtolower($direction), ['asc', 'desc']) ? $direction : 'asc';
6036
        $column = Database::escape_string($column);
6037
6038
        $urlId = api_get_current_access_url_id();
6039
6040
        $sessionConditions = '';
6041
        $courseConditions = '';
6042
        $userConditions = '';
6043
6044
        if (isset($active)) {
6045
            $active = (int) $active;
6046
            $userConditions .= " AND active = $active";
6047
        }
6048
6049
        $courseList = CourseManager::get_courses_followed_by_drh($userId, DRH);
6050
        if (!empty($courseList)) {
6051
            $courseIdList = array_column($courseList, 'id');
6052
            $courseConditions = ' AND c.id IN ("'.implode('","', $courseIdList).'")';
6053
        }
6054
6055
        $userConditionsFromDrh = '';
6056
6057
        // Classic DRH
6058
        if (empty($studentIdList)) {
6059
            $studentListSql = UserManager::get_users_followed_by_drh(
6060
                $userId,
6061
                $filterByStatus,
6062
                true,
6063
                false
6064
            );
6065
            if (!empty($studentListSql)) {
6066
                $studentIdList = array_keys($studentListSql);
6067
                $studentListSql = "'".implode("','", $studentIdList)."'";
6068
            }
6069
        } else {
6070
            $studentIdList = array_map('intval', $studentIdList);
6071
            $studentListSql = "'".implode("','", $studentIdList)."'";
6072
        }
6073
        if (!empty($studentListSql)) {
6074
            $userConditionsFromDrh = " AND u.user_id IN ($studentListSql) ";
6075
        }
6076
6077
        switch ($status) {
6078
            case 'admin':
6079
            case 'drh':
6080
                break;
6081
            case 'drh_all':
6082
                // Show all by DRH
6083
                if (empty($sessionIdList)) {
6084
                    $sessionListFollowed = self::get_sessions_followed_by_drh(
6085
                        $userId,
6086
                        null,
6087
                        null,
6088
                        false,
6089
                        true
6090
                    );
6091
6092
                    if (!empty($sessionListFollowed)) {
6093
                        $sessionIdList = array_column($sessionListFollowed, 'id');
6094
                    }
6095
                }
6096
6097
                if (!empty($sessionIdList)) {
6098
                    $sessionIdList = array_map('intval', $sessionIdList);
6099
                    $sessionsListSql = "'".implode("','", $sessionIdList)."'";
6100
                    $sessionConditions = " AND s.id IN ($sessionsListSql) ";
6101
                }
6102
6103
                break;
6104
            case 'teacher':
6105
            case 'session_admin':
6106
                $sessionConditions = " AND s.id_coach = $userId ";
6107
                $userConditionsFromDrh = '';
6108
                break;
6109
        }
6110
6111
        $select = 'SELECT DISTINCT u.* ';
6112
        $masterSelect = 'SELECT DISTINCT user_id FROM ';
6113
6114
        if ($getCount) {
6115
            $select = 'SELECT DISTINCT u.user_id ';
6116
            $masterSelect = 'SELECT COUNT(DISTINCT(user_id)) as count FROM ';
6117
        }
6118
6119
        if (!empty($filterByStatus)) {
6120
            $userConditions .= " AND u.status = $filterByStatus";
6121
        }
6122
6123
        if (!empty($lastConnectionDate)) {
6124
            $lastConnectionDate = Database::escape_string($lastConnectionDate);
6125
            $userConditions .= " AND u.last_login <= '$lastConnectionDate' ";
6126
        }
6127
6128
        if (!empty($keyword)) {
6129
            $keyword = trim(Database::escape_string($keyword));
6130
            $keywordParts = array_filter(explode(' ', $keyword));
6131
            $extraKeyword = '';
6132
            if (!empty($keywordParts)) {
6133
                $keywordPartsFixed = Database::escape_string(implode('%', $keywordParts));
6134
                if (!empty($keywordPartsFixed)) {
6135
                    $extraKeyword .= " OR
6136
                        CONCAT(u.firstname, ' ', u.lastname) LIKE '%$keywordPartsFixed%' OR
6137
                        CONCAT(u.lastname, ' ', u.firstname) LIKE '%$keywordPartsFixed%' ";
6138
                }
6139
            }
6140
6141
            $userConditions .= " AND (
6142
                u.username LIKE '%$keyword%' OR
6143
                u.firstname LIKE '%$keyword%' OR
6144
                u.lastname LIKE '%$keyword%' OR
6145
                u.official_code LIKE '%$keyword%' OR
6146
                u.email LIKE '%$keyword%' OR
6147
                CONCAT(u.firstname, ' ', u.lastname) LIKE '%$keyword%' OR
6148
                CONCAT(u.lastname, ' ', u.firstname) LIKE '%$keyword%'
6149
                $extraKeyword
6150
            )";
6151
        }
6152
6153
        $where = " WHERE
6154
                   access_url_id = $urlId
6155
                   $userConditions
6156
        ";
6157
6158
        $userUnion = '';
6159
        if (!empty($userConditionsFromDrh)) {
6160
            $userUnion = "
6161
            UNION (
6162
                $select
6163
                FROM $tbl_user u
6164
                INNER JOIN $tbl_user_rel_access_url url ON (url.user_id = u.id)
6165
                $where
6166
                $userConditionsFromDrh
6167
            )";
6168
        }
6169
6170
        $sql = "$masterSelect (
6171
                ($select
6172
                    FROM $tbl_session s
6173
                    INNER JOIN $tbl_session_rel_access_url url ON (url.session_id = s.id)
6174
                    INNER JOIN $tbl_session_rel_course_rel_user su ON (s.id = su.session_id)
6175
                    INNER JOIN $tbl_user u ON (u.user_id = su.user_id)
6176
                    $where
6177
                    $sessionConditions
6178
                    $userConditionsFromDrh
6179
                ) UNION (
6180
                    $select
6181
                    FROM $tbl_course c
6182
                    INNER JOIN $tbl_course_rel_access_url url ON (url.c_id = c.id)
6183
                    INNER JOIN $tbl_course_user cu ON (cu.c_id = c.id)
6184
                    INNER JOIN $tbl_user u ON (u.user_id = cu.user_id)
6185
                    $where
6186
                    $courseConditions
6187
                    $userConditionsFromDrh
6188
                ) $userUnion
6189
                ) as t1
6190
                ";
6191
6192
        if ($getCount) {
6193
            $result = Database::query($sql);
6194
6195
            $count = 0;
6196
            if (Database::num_rows($result)) {
6197
                $rows = Database::fetch_array($result);
6198
                $count = $rows['count'];
6199
            }
6200
6201
            return $count;
6202
        }
6203
6204
        if (!empty($column) && !empty($direction)) {
6205
            $column = str_replace('u.', '', $column);
6206
            $sql .= " ORDER BY `$column` $direction ";
6207
        }
6208
6209
        $limitCondition = '';
6210
        if (isset($from) && isset($numberItems)) {
6211
            $from = (int) $from;
6212
            $numberItems = (int) $numberItems;
6213
            $limitCondition = "LIMIT $from, $numberItems";
6214
        }
6215
6216
        $sql .= $limitCondition;
6217
6218
        $result = Database::query($sql);
6219
6220
        return Database::store_result($result);
6221
    }
6222
6223
    /**
6224
     * @param int   $sessionId
6225
     * @param int   $courseId
6226
     * @param array $coachList
6227
     * @param bool  $deleteCoachesNotInList
6228
     */
6229
    public static function updateCoaches(
6230
        $sessionId,
6231
        $courseId,
6232
        $coachList,
6233
        $deleteCoachesNotInList = false
6234
    ) {
6235
        $currentCoaches = self::getCoachesByCourseSession($sessionId, $courseId);
6236
6237
        if (!empty($coachList)) {
6238
            foreach ($coachList as $userId) {
6239
                self::set_coach_to_course_session($userId, $sessionId, $courseId);
6240
            }
6241
        }
6242
6243
        if ($deleteCoachesNotInList) {
6244
            if (!empty($coachList)) {
6245
                $coachesToDelete = array_diff($currentCoaches, $coachList);
6246
            } else {
6247
                $coachesToDelete = $currentCoaches;
6248
            }
6249
6250
            if (!empty($coachesToDelete)) {
6251
                foreach ($coachesToDelete as $userId) {
6252
                    self::set_coach_to_course_session(
6253
                        $userId,
6254
                        $sessionId,
6255
                        $courseId,
6256
                        true
6257
                    );
6258
                }
6259
            }
6260
        }
6261
    }
6262
6263
    /**
6264
     * @param array $sessions
6265
     * @param array $sessionsDestination
6266
     *
6267
     * @return array
6268
     */
6269
    public static function copyStudentsFromSession($sessions, $sessionsDestination)
6270
    {
6271
        $messages = [];
6272
        if (!empty($sessions)) {
6273
            foreach ($sessions as $sessionId) {
6274
                $sessionInfo = self::fetch($sessionId);
6275
                $userList = self::get_users_by_session($sessionId, 0);
6276
                if (!empty($userList)) {
6277
                    $newUserList = [];
6278
                    $userToString = null;
6279
                    foreach ($userList as $userInfo) {
6280
                        $newUserList[] = $userInfo['user_id'];
6281
                        $userToString .= $userInfo['firstname'].' '.$userInfo['lastname'].'<br />';
6282
                    }
6283
6284
                    if (!empty($sessionsDestination)) {
6285
                        foreach ($sessionsDestination as $sessionDestinationId) {
6286
                            $sessionDestinationInfo = self::fetch($sessionDestinationId);
6287
                            $messages[] = Display::return_message(
6288
                                sprintf(
6289
                                    get_lang(
6290
                                        'AddingStudentsFromSessionXToSessionY'
6291
                                    ),
6292
                                    $sessionInfo['name'],
6293
                                    $sessionDestinationInfo['name']
6294
                                ),
6295
                                'info',
6296
                                false
6297
                            );
6298
                            if ($sessionId == $sessionDestinationId) {
6299
                                $messages[] = Display::return_message(
6300
                                    sprintf(
6301
                                        get_lang('SessionXSkipped'),
6302
                                        $sessionDestinationId
6303
                                    ),
6304
                                    'warning',
6305
                                    false
6306
                                );
6307
                                continue;
6308
                            }
6309
                            $messages[] = Display::return_message(get_lang('StudentList').'<br />'.$userToString, 'info', false);
6310
                            self::subscribeUsersToSession(
6311
                                $sessionDestinationId,
6312
                                $newUserList,
6313
                                SESSION_VISIBLE_READ_ONLY,
6314
                                false
6315
                            );
6316
                        }
6317
                    } else {
6318
                        $messages[] = Display::return_message(get_lang('NoDestinationSessionProvided'), 'warning');
6319
                    }
6320
                } else {
6321
                    $messages[] = Display::return_message(
6322
                        get_lang('NoStudentsFoundForSession').' #'.$sessionInfo['name'],
6323
                        'warning'
6324
                    );
6325
                }
6326
            }
6327
        } else {
6328
            $messages[] = Display::return_message(get_lang('NoData'), 'warning');
6329
        }
6330
6331
        return $messages;
6332
    }
6333
6334
    /**
6335
     * Assign coaches of a session(s) as teachers to a given course (or courses).
6336
     *
6337
     * @param array A list of session IDs
6338
     * @param array A list of course IDs
6339
     *
6340
     * @return string
6341
     */
6342
    public static function copyCoachesFromSessionToCourse($sessions, $courses)
6343
    {
6344
        $coachesPerSession = [];
6345
        foreach ($sessions as $sessionId) {
6346
            $coaches = self::getCoachesBySession($sessionId);
6347
            $coachesPerSession[$sessionId] = $coaches;
6348
        }
6349
6350
        $result = [];
6351
6352
        if (!empty($courses)) {
6353
            foreach ($courses as $courseId) {
6354
                $courseInfo = api_get_course_info_by_id($courseId);
6355
                foreach ($coachesPerSession as $sessionId => $coachList) {
6356
                    CourseManager::updateTeachers(
6357
                        $courseInfo,
6358
                        $coachList,
6359
                        false,
6360
                        false,
6361
                        false
6362
                    );
6363
                    $result[$courseInfo['code']][$sessionId] = $coachList;
6364
                }
6365
            }
6366
        }
6367
        $sessionUrl = api_get_path(WEB_CODE_PATH).'session/resume_session.php?id_session=';
6368
        $htmlResult = null;
6369
6370
        if (!empty($result)) {
6371
            foreach ($result as $courseCode => $data) {
6372
                $url = api_get_course_url($courseCode);
6373
                $htmlResult .= sprintf(
6374
                    get_lang('CoachesSubscribedAsATeacherInCourseX'),
6375
                    Display::url($courseCode, $url, ['target' => '_blank'])
6376
                );
6377
                foreach ($data as $sessionId => $coachList) {
6378
                    $sessionInfo = self::fetch($sessionId);
6379
                    $htmlResult .= '<br />';
6380
                    $htmlResult .= Display::url(
6381
                        get_lang('Session').': '.$sessionInfo['name'].' <br />',
6382
                        $sessionUrl.$sessionId,
6383
                        ['target' => '_blank']
6384
                    );
6385
                    $teacherList = [];
6386
                    foreach ($coachList as $coachId) {
6387
                        $userInfo = api_get_user_info($coachId);
6388
                        $teacherList[] = $userInfo['complete_name'];
6389
                    }
6390
                    if (!empty($teacherList)) {
6391
                        $htmlResult .= implode(', ', $teacherList);
6392
                    } else {
6393
                        $htmlResult .= get_lang('NothingToAdd');
6394
                    }
6395
                }
6396
                $htmlResult .= '<br />';
6397
            }
6398
            $htmlResult = Display::return_message($htmlResult, 'normal', false);
6399
        }
6400
6401
        return $htmlResult;
6402
    }
6403
6404
    /**
6405
     * @param string $keyword
6406
     * @param string $active
6407
     * @param string $lastConnectionDate
6408
     * @param array  $sessionIdList
6409
     * @param array  $studentIdList
6410
     * @param int    $filterUserStatus   STUDENT|COURSEMANAGER constants
6411
     *
6412
     * @return array|int
6413
     */
6414
    public static function getCountUserTracking(
6415
        $keyword = null,
6416
        $active = null,
6417
        $lastConnectionDate = null,
6418
        $sessionIdList = [],
6419
        $studentIdList = [],
6420
        $filterUserStatus = null
6421
    ) {
6422
        $userId = api_get_user_id();
6423
        $drhLoaded = false;
6424
6425
        if (api_is_drh()) {
6426
            if (api_drh_can_access_all_session_content()) {
6427
                $count = self::getAllUsersFromCoursesFromAllSessionFromStatus(
6428
                    'drh_all',
6429
                    $userId,
6430
                    true,
6431
                    null,
6432
                    null,
6433
                    null,
6434
                    null,
6435
                    $keyword,
6436
                    $active,
6437
                    $lastConnectionDate,
6438
                    $sessionIdList,
6439
                    $studentIdList,
6440
                    $filterUserStatus
6441
                );
6442
                $drhLoaded = true;
6443
            }
6444
        }
6445
6446
        $checkSessionVisibility = api_get_configuration_value('show_users_in_active_sessions_in_tracking');
6447
6448
        if (false === $drhLoaded) {
6449
            $count = UserManager::getUsersFollowedByUser(
6450
                $userId,
6451
                $filterUserStatus,
6452
                false,
6453
                false,
6454
                true,
6455
                null,
6456
                null,
6457
                null,
6458
                null,
6459
                $active,
6460
                $lastConnectionDate,
6461
                api_is_student_boss() ? STUDENT_BOSS : COURSEMANAGER,
6462
                $keyword,
6463
                $checkSessionVisibility
6464
            );
6465
        }
6466
6467
        return $count;
6468
    }
6469
6470
    /**
6471
     * Get teachers followed by a user.
6472
     *
6473
     * @param int    $userId
6474
     * @param int    $active
6475
     * @param string $lastConnectionDate
6476
     * @param bool   $getCount
6477
     * @param array  $sessionIdList
6478
     *
6479
     * @return array|int
6480
     */
6481
    public static function getTeacherTracking(
6482
        $userId,
6483
        $active = 1,
6484
        $lastConnectionDate = null,
6485
        $getCount = false,
6486
        $sessionIdList = []
6487
    ) {
6488
        $teacherListId = [];
6489
        if (api_is_drh() || api_is_platform_admin()) {
6490
            // Followed teachers by drh
6491
            if (api_drh_can_access_all_session_content()) {
6492
                if (empty($sessionIdList)) {
6493
                    $sessions = self::get_sessions_followed_by_drh($userId);
6494
                    $sessionIdList = [];
6495
                    foreach ($sessions as $session) {
6496
                        $sessionIdList[] = $session['id'];
6497
                    }
6498
                }
6499
6500
                $sessionIdList = array_map('intval', $sessionIdList);
6501
                $sessionToString = implode("', '", $sessionIdList);
6502
6503
                $course = Database::get_main_table(TABLE_MAIN_COURSE);
6504
                $sessionCourse = Database::get_main_table(TABLE_MAIN_SESSION_COURSE);
6505
                $courseUser = Database::get_main_table(TABLE_MAIN_COURSE_USER);
6506
6507
                // Select the teachers.
6508
                $sql = "SELECT DISTINCT(cu.user_id)
6509
                        FROM $course c
6510
                        INNER JOIN $sessionCourse src
6511
                        ON c.id = src.c_id
6512
                        INNER JOIN $courseUser cu
6513
                        ON (cu.c_id = c.id)
6514
		                WHERE src.session_id IN ('$sessionToString') AND cu.status = 1";
6515
                $result = Database::query($sql);
6516
                while ($row = Database::fetch_array($result, 'ASSOC')) {
6517
                    $teacherListId[$row['user_id']] = $row['user_id'];
6518
                }
6519
            } else {
6520
                $teacherResult = UserManager::get_users_followed_by_drh($userId, COURSEMANAGER);
6521
                foreach ($teacherResult as $userInfo) {
6522
                    $teacherListId[] = $userInfo['user_id'];
6523
                }
6524
            }
6525
        }
6526
6527
        if (!empty($teacherListId)) {
6528
            $tableUser = Database::get_main_table(TABLE_MAIN_USER);
6529
6530
            $select = "SELECT DISTINCT u.* ";
6531
            if ($getCount) {
6532
                $select = "SELECT count(DISTINCT(u.user_id)) as count";
6533
            }
6534
6535
            $sql = "$select FROM $tableUser u";
6536
6537
            if (!empty($lastConnectionDate)) {
6538
                $tableLogin = Database::get_main_table(TABLE_STATISTIC_TRACK_E_LOGIN);
6539
                //$sql .= " INNER JOIN $tableLogin l ON (l.login_user_id = u.user_id) ";
6540
            }
6541
            $active = intval($active);
6542
            $teacherListId = implode("','", $teacherListId);
6543
            $where = " WHERE u.active = $active AND u.user_id IN ('$teacherListId') ";
6544
6545
            if (!empty($lastConnectionDate)) {
6546
                $lastConnectionDate = Database::escape_string($lastConnectionDate);
6547
                //$where .= " AND l.login_date <= '$lastConnectionDate' ";
6548
            }
6549
6550
            $sql .= $where;
6551
            $result = Database::query($sql);
6552
            if (Database::num_rows($result)) {
6553
                if ($getCount) {
6554
                    $row = Database::fetch_array($result);
6555
6556
                    return $row['count'];
6557
                } else {
6558
                    return Database::store_result($result, 'ASSOC');
6559
                }
6560
            }
6561
        }
6562
6563
        return 0;
6564
    }
6565
6566
    /**
6567
     * Get the list of course tools that have to be dealt with in case of
6568
     * registering any course to a session.
6569
     *
6570
     * @return array The list of tools to be dealt with (literal names)
6571
     */
6572
    public static function getCourseToolToBeManaged()
6573
    {
6574
        return [
6575
            'courseDescription',
6576
            'courseIntroduction',
6577
        ];
6578
    }
6579
6580
    /**
6581
     * Calls the methods bound to each tool when a course is registered into a session.
6582
     *
6583
     * @param int $sessionId
6584
     * @param int $courseId
6585
     *
6586
     * @return bool
6587
     */
6588
    public static function installCourse($sessionId, $courseId)
6589
    {
6590
        return true;
6591
        $toolList = self::getCourseToolToBeManaged();
6592
6593
        foreach ($toolList as $tool) {
6594
            $method = 'add'.$tool;
6595
            if (method_exists(get_class(), $method)) {
6596
                self::$method($sessionId, $courseId);
6597
            }
6598
        }
6599
    }
6600
6601
    /**
6602
     * Calls the methods bound to each tool when a course is unregistered from
6603
     * a session.
6604
     *
6605
     * @param int $sessionId
6606
     * @param int $courseId
6607
     */
6608
    public static function unInstallCourse($sessionId, $courseId)
6609
    {
6610
        return true;
6611
        $toolList = self::getCourseToolToBeManaged();
6612
6613
        foreach ($toolList as $tool) {
6614
            $method = 'remove'.$tool;
6615
            if (method_exists(get_class(), $method)) {
6616
                self::$method($sessionId, $courseId);
6617
            }
6618
        }
6619
    }
6620
6621
    /**
6622
     * @param array $userSessionList        format see self::importSessionDrhCSV()
6623
     * @param bool  $sendEmail
6624
     * @param bool  $removeOldRelationShips
6625
     */
6626
    public static function subscribeDrhToSessionList(
6627
        $userSessionList,
6628
        $sendEmail,
6629
        $removeOldRelationShips
6630
    ) {
6631
        if (!empty($userSessionList)) {
6632
            foreach ($userSessionList as $userId => $data) {
6633
                $sessionList = [];
6634
                foreach ($data['session_list'] as $sessionInfo) {
6635
                    $sessionList[] = $sessionInfo['session_id'];
6636
                }
6637
                $userInfo = $data['user_info'];
6638
                self::subscribeSessionsToDrh(
6639
                    $userInfo,
6640
                    $sessionList,
6641
                    $sendEmail,
6642
                    $removeOldRelationShips
6643
                );
6644
            }
6645
        }
6646
    }
6647
6648
    /**
6649
     * @param array $userSessionList format see self::importSessionDrhCSV()
6650
     *
6651
     * @return string
6652
     */
6653
    public static function checkSubscribeDrhToSessionList($userSessionList)
6654
    {
6655
        $message = null;
6656
        if (!empty($userSessionList)) {
6657
            if (!empty($userSessionList)) {
6658
                foreach ($userSessionList as $userId => $data) {
6659
                    $userInfo = $data['user_info'];
6660
6661
                    $sessionListSubscribed = self::get_sessions_followed_by_drh($userId);
6662
                    if (!empty($sessionListSubscribed)) {
6663
                        $sessionListSubscribed = array_keys($sessionListSubscribed);
6664
                    }
6665
6666
                    $sessionList = [];
6667
                    if (!empty($data['session_list'])) {
6668
                        foreach ($data['session_list'] as $sessionInfo) {
6669
                            if (in_array($sessionInfo['session_id'], $sessionListSubscribed)) {
6670
                                $sessionList[] = $sessionInfo['session_info']['name'];
6671
                            }
6672
                        }
6673
                    }
6674
6675
                    $message .= '<strong>'.get_lang('User').'</strong>: ';
6676
                    $message .= $userInfo['complete_name_with_username'].' <br />';
6677
6678
                    if (!in_array($userInfo['status'], [DRH]) && !api_is_platform_admin_by_id($userInfo['user_id'])) {
6679
                        $message .= get_lang('UserMustHaveTheDrhRole').'<br />';
6680
                        continue;
6681
                    }
6682
6683
                    if (!empty($sessionList)) {
6684
                        $message .= '<strong>'.get_lang('Sessions').':</strong> <br />';
6685
                        $message .= implode(', ', $sessionList).'<br /><br />';
6686
                    } else {
6687
                        $message .= get_lang('NoSessionProvided').' <br /><br />';
6688
                    }
6689
                }
6690
            }
6691
        }
6692
6693
        return $message;
6694
    }
6695
6696
    /**
6697
     * @param string $file
6698
     * @param bool   $sendEmail
6699
     * @param bool   $removeOldRelationShips
6700
     *
6701
     * @return string
6702
     */
6703
    public static function importSessionDrhCSV($file, $sendEmail, $removeOldRelationShips)
6704
    {
6705
        $list = Import::csv_reader($file);
6706
6707
        if (!empty($list)) {
6708
            $userSessionList = [];
6709
            foreach ($list as $data) {
6710
                $sessionInfo = [];
6711
                if (isset($data['SessionId'])) {
6712
                    $sessionInfo = api_get_session_info($data['SessionId']);
6713
                }
6714
6715
                if (isset($data['SessionName']) && empty($sessionInfo)) {
6716
                    $sessionInfo = self::get_session_by_name($data['SessionName']);
6717
                }
6718
6719
                if (empty($sessionInfo)) {
6720
                    $sessionData = isset($data['SessionName']) ? $data['SessionName'] : $data['SessionId'];
6721
                    Display::addFlash(
6722
                        Display::return_message(get_lang('SessionNotFound').' - '.$sessionData, 'warning')
6723
                    );
6724
                    continue;
6725
                }
6726
6727
                $userList = explode(',', $data['Username']);
6728
6729
                foreach ($userList as $username) {
6730
                    $userInfo = api_get_user_info_from_username($username);
6731
6732
                    if (empty($userInfo)) {
6733
                        Display::addFlash(
6734
                            Display::return_message(get_lang('UserDoesNotExist').' - '.$username, 'warning')
6735
                        );
6736
                        continue;
6737
                    }
6738
6739
                    if (!empty($userInfo) && !empty($sessionInfo)) {
6740
                        $userSessionList[$userInfo['user_id']]['session_list'][] = [
6741
                            'session_id' => $sessionInfo['id'],
6742
                            'session_info' => $sessionInfo,
6743
                        ];
6744
                        $userSessionList[$userInfo['user_id']]['user_info'] = $userInfo;
6745
                    }
6746
                }
6747
            }
6748
6749
            self::subscribeDrhToSessionList($userSessionList, $sendEmail, $removeOldRelationShips);
6750
6751
            return self::checkSubscribeDrhToSessionList($userSessionList);
6752
        }
6753
    }
6754
6755
    /**
6756
     * Courses re-ordering in resume_session.php flag see BT#8316.
6757
     */
6758
    public static function orderCourseIsEnabled()
6759
    {
6760
        $sessionCourseOrder = api_get_setting('session_course_ordering');
6761
        if ($sessionCourseOrder === 'true') {
6762
            return true;
6763
        }
6764
6765
        return false;
6766
    }
6767
6768
    /**
6769
     * @param string $direction (up/down)
6770
     * @param int    $sessionId
6771
     * @param int    $courseId
6772
     *
6773
     * @return bool
6774
     */
6775
    public static function move($direction, $sessionId, $courseId)
6776
    {
6777
        if (!self::orderCourseIsEnabled()) {
6778
            return false;
6779
        }
6780
6781
        $sessionId = intval($sessionId);
6782
        $courseId = intval($courseId);
6783
6784
        $table = Database::get_main_table(TABLE_MAIN_SESSION_COURSE);
6785
        $courseList = self::get_course_list_by_session_id($sessionId, null, 'position');
6786
6787
        $position = [];
6788
        $count = 0;
6789
        foreach ($courseList as $course) {
6790
            if ($course['position'] == '') {
6791
                $course['position'] = $count;
6792
            }
6793
            $position[$course['code']] = $course['position'];
6794
            // Saving current order.
6795
            $sql = "UPDATE $table SET position = $count
6796
                    WHERE session_id = $sessionId AND c_id = '".$course['real_id']."'";
6797
            Database::query($sql);
6798
            $count++;
6799
        }
6800
6801
        // Loading new positions.
6802
        $courseList = self::get_course_list_by_session_id($sessionId, null, 'position');
6803
6804
        $found = false;
6805
6806
        switch ($direction) {
6807
            case 'up':
6808
                $courseList = array_reverse($courseList);
6809
                break;
6810
            case 'down':
6811
                break;
6812
        }
6813
6814
        foreach ($courseList as $course) {
6815
            if ($found) {
6816
                $nextId = $course['real_id'];
6817
                $nextOrder = $course['position'];
6818
                break;
6819
            }
6820
6821
            if ($courseId == $course['real_id']) {
6822
                $thisCourseCode = $course['real_id'];
6823
                $thisOrder = $course['position'];
6824
                $found = true;
6825
            }
6826
        }
6827
6828
        $sql1 = "UPDATE $table SET position = '".intval($nextOrder)."'
6829
                 WHERE session_id = $sessionId AND c_id =  $thisCourseCode";
6830
        Database::query($sql1);
6831
6832
        $sql2 = "UPDATE $table SET position = '".intval($thisOrder)."'
6833
                 WHERE session_id = $sessionId AND c_id = $nextId";
6834
        Database::query($sql2);
6835
6836
        return true;
6837
    }
6838
6839
    /**
6840
     * @param int $sessionId
6841
     * @param int $courseId
6842
     *
6843
     * @return bool
6844
     */
6845
    public static function moveUp($sessionId, $courseId)
6846
    {
6847
        return self::move('up', $sessionId, $courseId);
6848
    }
6849
6850
    /**
6851
     * @param int    $sessionId
6852
     * @param string $courseCode
6853
     *
6854
     * @return bool
6855
     */
6856
    public static function moveDown($sessionId, $courseCode)
6857
    {
6858
        return self::move('down', $sessionId, $courseCode);
6859
    }
6860
6861
    /**
6862
     * Use the session duration to allow/block user access see BT#8317
6863
     * Needs these DB changes
6864
     * ALTER TABLE session ADD COLUMN duration int;
6865
     * ALTER TABLE session_rel_user ADD COLUMN duration int;.
6866
     */
6867
    public static function durationPerUserIsEnabled()
6868
    {
6869
        return api_get_configuration_value('session_duration_feature');
6870
    }
6871
6872
    /**
6873
     * Returns the number of days the student has left in a session when using
6874
     * sessions durations.
6875
     *
6876
     * @param int $userId
6877
     *
6878
     * @return int
6879
     */
6880
    public static function getDayLeftInSession(array $sessionInfo, $userId)
6881
    {
6882
        $sessionId = $sessionInfo['id'];
6883
        $subscription = self::getUserSession($userId, $sessionId);
6884
        $duration = empty($subscription['duration'])
6885
            ? $sessionInfo['duration']
6886
            : $sessionInfo['duration'] + $subscription['duration'];
6887
6888
        // Get an array with the details of the first access of the student to
6889
        // this session
6890
        $courseAccess = CourseManager::getFirstCourseAccessPerSessionAndUser(
6891
            $sessionId,
6892
            $userId
6893
        );
6894
6895
        $currentTime = time();
6896
6897
        // If no previous access, return false
6898
        if (count($courseAccess) == 0) {
6899
            return $duration;
6900
        }
6901
6902
        $firstAccess = api_strtotime($courseAccess['login_course_date'], 'UTC');
6903
        $endDateInSeconds = $firstAccess + $duration * 24 * 60 * 60;
6904
        $leftDays = round(($endDateInSeconds - $currentTime) / 60 / 60 / 24);
6905
6906
        return $leftDays;
6907
    }
6908
6909
    /**
6910
     * @param int $duration
6911
     * @param int $userId
6912
     * @param int $sessionId
6913
     *
6914
     * @return bool
6915
     */
6916
    public static function editUserSessionDuration($duration, $userId, $sessionId)
6917
    {
6918
        $duration = (int) $duration;
6919
        $userId = (int) $userId;
6920
        $sessionId = (int) $sessionId;
6921
6922
        if (empty($userId) || empty($sessionId)) {
6923
            return false;
6924
        }
6925
6926
        $table = Database::get_main_table(TABLE_MAIN_SESSION_USER);
6927
        $parameters = ['duration' => $duration];
6928
        $where = ['session_id = ? AND user_id = ? ' => [$sessionId, $userId]];
6929
        Database::update($table, $parameters, $where);
6930
6931
        return true;
6932
    }
6933
6934
    /**
6935
     * Gets one row from the session_rel_user table.
6936
     *
6937
     * @param int $userId
6938
     * @param int $sessionId
6939
     *
6940
     * @return array
6941
     */
6942
    public static function getUserSession($userId, $sessionId)
6943
    {
6944
        $userId = (int) $userId;
6945
        $sessionId = (int) $sessionId;
6946
6947
        if (empty($userId) || empty($sessionId)) {
6948
            return false;
6949
        }
6950
6951
        $table = Database::get_main_table(TABLE_MAIN_SESSION_USER);
6952
        $sql = "SELECT * FROM $table
6953
                WHERE session_id = $sessionId AND user_id = $userId";
6954
        $result = Database::query($sql);
6955
        $values = [];
6956
        if (Database::num_rows($result)) {
6957
            $values = Database::fetch_array($result, 'ASSOC');
6958
        }
6959
6960
        return $values;
6961
    }
6962
6963
    /**
6964
     * Check if user is subscribed inside a session as student.
6965
     *
6966
     * @param int $sessionId The session id
6967
     * @param int $userId    The user id
6968
     *
6969
     * @return bool Whether is subscribed
6970
     */
6971
    public static function isUserSubscribedAsStudent($sessionId, $userId)
6972
    {
6973
        $sessionRelUserTable = Database::get_main_table(TABLE_MAIN_SESSION_USER);
6974
        $sessionId = (int) $sessionId;
6975
        $userId = (int) $userId;
6976
6977
        // COUNT(1) actually returns the number of rows from the table (as if
6978
        // counting the results from the first column)
6979
        $sql = "SELECT COUNT(1) AS qty FROM $sessionRelUserTable
6980
                WHERE
6981
                    session_id = $sessionId AND
6982
                    user_id = $userId AND
6983
                    relation_type = 0";
6984
6985
        $result = Database::fetch_assoc(Database::query($sql));
6986
6987
        if (!empty($result) && $result['qty'] > 0) {
6988
            return true;
6989
        }
6990
6991
        return false;
6992
    }
6993
6994
    /**
6995
     * Check if user is subscribed inside a session as a HRM.
6996
     *
6997
     * @param int $sessionId The session id
6998
     * @param int $userId    The user id
6999
     *
7000
     * @return bool Whether is subscribed
7001
     */
7002
    public static function isUserSubscribedAsHRM($sessionId, $userId)
7003
    {
7004
        $sessionRelUserTable = Database::get_main_table(TABLE_MAIN_SESSION_USER);
7005
7006
        $sessionId = (int) $sessionId;
7007
        $userId = (int) $userId;
7008
7009
        // COUNT(1) actually returns the number of rows from the table (as if
7010
        // counting the results from the first column)
7011
        $sql = "SELECT COUNT(1) AS qty FROM $sessionRelUserTable
7012
                WHERE
7013
                    session_id = $sessionId AND
7014
                    user_id = $userId AND
7015
                    relation_type = ".SESSION_RELATION_TYPE_RRHH;
7016
7017
        $result = Database::fetch_assoc(Database::query($sql));
7018
7019
        if (!empty($result) && $result['qty'] > 0) {
7020
            return true;
7021
        }
7022
7023
        return false;
7024
    }
7025
7026
    /**
7027
     * Get the session coached by a user (general coach and course-session coach).
7028
     *
7029
     * @param int  $coachId                       The coach id
7030
     * @param bool $checkSessionRelUserVisibility Check the session visibility
7031
     * @param bool $asPlatformAdmin               The user is a platform admin and we want all sessions
7032
     *
7033
     * @return array The session list
7034
     */
7035
    public static function getSessionsCoachedByUser(
7036
        $coachId,
7037
        $checkSessionRelUserVisibility = false,
7038
        $asPlatformAdmin = false
7039
    ) {
7040
        // Get all sessions where $coachId is the general coach
7041
        $sessions = self::get_sessions_by_general_coach($coachId, $asPlatformAdmin);
7042
        // Get all sessions where $coachId is the course - session coach
7043
        $courseSessionList = self::getCoursesListByCourseCoach($coachId);
7044
        $sessionsByCoach = [];
7045
        if (!empty($courseSessionList)) {
7046
            foreach ($courseSessionList as $userCourseSubscription) {
7047
                $session = $userCourseSubscription->getSession();
7048
                $sessionsByCoach[$session->getId()] = api_get_session_info(
7049
                    $session->getId()
7050
                );
7051
            }
7052
        }
7053
7054
        if (!empty($sessionsByCoach)) {
7055
            $sessions = array_merge($sessions, $sessionsByCoach);
7056
        }
7057
7058
        // Remove repeated sessions
7059
        if (!empty($sessions)) {
7060
            $cleanSessions = [];
7061
            foreach ($sessions as $session) {
7062
                $cleanSessions[$session['id']] = $session;
7063
            }
7064
            $sessions = $cleanSessions;
7065
        }
7066
7067
        if ($checkSessionRelUserVisibility) {
7068
            if (!empty($sessions)) {
7069
                $newSessions = [];
7070
                foreach ($sessions as $session) {
7071
                    $visibility = api_get_session_visibility($session['id']);
7072
                    if ($visibility == SESSION_INVISIBLE) {
7073
                        continue;
7074
                    }
7075
                    $newSessions[] = $session;
7076
                }
7077
                $sessions = $newSessions;
7078
            }
7079
        }
7080
7081
        return $sessions;
7082
    }
7083
7084
    /**
7085
     * Check if the course belongs to the session.
7086
     *
7087
     * @param int    $sessionId  The session id
7088
     * @param string $courseCode The course code
7089
     *
7090
     * @return bool
7091
     */
7092
    public static function sessionHasCourse($sessionId, $courseCode)
7093
    {
7094
        $sessionId = (int) $sessionId;
7095
        $courseCode = Database::escape_string($courseCode);
7096
        $courseTable = Database::get_main_table(TABLE_MAIN_COURSE);
7097
        $sessionRelCourseTable = Database::get_main_table(TABLE_MAIN_SESSION_COURSE);
7098
7099
        $sql = "SELECT COUNT(1) AS qty
7100
                FROM $courseTable c
7101
                INNER JOIN $sessionRelCourseTable src
7102
                ON c.id = src.c_id
7103
                WHERE src.session_id = $sessionId
7104
                AND c.code = '$courseCode'  ";
7105
7106
        $result = Database::query($sql);
7107
7108
        if (false !== $result) {
7109
            $data = Database::fetch_assoc($result);
7110
7111
            if ($data['qty'] > 0) {
7112
                return true;
7113
            }
7114
        }
7115
7116
        return false;
7117
    }
7118
7119
    /**
7120
     * Calculate the total user time in the platform.
7121
     *
7122
     * @param int    $userId The user id
7123
     * @param string $from   Optional. From date
7124
     * @param string $until  Optional. Until date
7125
     *
7126
     * @return string The time (hh:mm:ss)
7127
     */
7128
    public static function getTotalUserTimeInPlatform($userId, $from = '', $until = '')
7129
    {
7130
        $userId = (int) $userId;
7131
        $trackLoginTable = Database::get_main_table(TABLE_STATISTIC_TRACK_E_LOGIN);
7132
        $whereConditions = [
7133
            'login_user_id = ? ' => $userId,
7134
        ];
7135
7136
        if (!empty($from) && !empty($until)) {
7137
            $whereConditions["AND (login_date >= '?' "] = $from;
7138
            $whereConditions["AND logout_date <= DATE_ADD('?', INTERVAL 1 DAY)) "] = $until;
7139
        }
7140
7141
        $trackResult = Database::select(
7142
            'SEC_TO_TIME(SUM(UNIX_TIMESTAMP(logout_date) - UNIX_TIMESTAMP(login_date))) as total_time',
7143
            $trackLoginTable,
7144
            [
7145
                'where' => $whereConditions,
7146
            ],
7147
            'first'
7148
        );
7149
7150
        if (false != $trackResult) {
7151
            return $trackResult['total_time'] ? $trackResult['total_time'] : '00:00:00';
7152
        }
7153
7154
        return '00:00:00';
7155
    }
7156
7157
    /**
7158
     * Get the courses list by a course coach.
7159
     *
7160
     * @param int $coachId The coach id
7161
     *
7162
     * @return array (id, user_id, session_id, c_id, visibility, status, legal_agreement)
7163
     */
7164
    public static function getCoursesListByCourseCoach($coachId)
7165
    {
7166
        $entityManager = Database::getManager();
7167
        $scuRepo = $entityManager->getRepository(
7168
            'ChamiloCoreBundle:SessionRelCourseRelUser'
7169
        );
7170
7171
        return $scuRepo->findBy([
7172
            'user' => $coachId,
7173
            'status' => SessionRelCourseRelUser::STATUS_COURSE_COACH,
7174
        ]);
7175
    }
7176
7177
    /**
7178
     * Get the count of user courses in session.
7179
     *
7180
     * @param int $sessionId
7181
     * @param int $courseId
7182
     *
7183
     * @return array
7184
     */
7185
    public static function getTotalUserCoursesInSession($sessionId, $courseId = 0)
7186
    {
7187
        $tableUser = Database::get_main_table(TABLE_MAIN_USER);
7188
        $table = Database::get_main_table(TABLE_MAIN_SESSION_COURSE_USER);
7189
7190
        $sessionId = (int) $sessionId;
7191
7192
        if (empty($sessionId)) {
7193
            return [];
7194
        }
7195
7196
        $courseCondition = '';
7197
        if (!empty($courseId)) {
7198
            $courseId = (int) $courseId;
7199
            $courseCondition = "  c_id = $courseId AND ";
7200
        }
7201
7202
        $sql = "SELECT
7203
                    COUNT(u.id) as count,
7204
                    u.id,
7205
                    scu.status status_in_session,
7206
                    u.status user_status
7207
                FROM $table scu
7208
                INNER JOIN $tableUser u
7209
                ON scu.user_id = u.id
7210
                WHERE
7211
                  $courseCondition
7212
                  scu.session_id = ".$sessionId."
7213
                GROUP BY u.id";
7214
7215
        $result = Database::query($sql);
7216
7217
        $list = [];
7218
        while ($data = Database::fetch_assoc($result)) {
7219
            $list[] = $data;
7220
        }
7221
7222
        return $list;
7223
    }
7224
7225
    /**
7226
     * Returns list of a few data from session (name, short description, start
7227
     * date, end date) and the given extra fields if defined based on a
7228
     * session category Id.
7229
     *
7230
     * @param int    $categoryId  The internal ID of the session category
7231
     * @param string $target      Value to search for in the session field values
7232
     * @param array  $extraFields A list of fields to be scanned and returned
7233
     *
7234
     * @return mixed
7235
     */
7236
    public static function getShortSessionListAndExtraByCategory(
7237
        $categoryId,
7238
        $target,
7239
        $extraFields = null,
7240
        $publicationDate = null
7241
    ) {
7242
        $categoryId = (int) $categoryId;
7243
        $sessionList = [];
7244
        // Check if categoryId is valid
7245
        if ($categoryId > 0) {
7246
            $target = Database::escape_string($target);
7247
            $sTable = Database::get_main_table(TABLE_MAIN_SESSION);
7248
            $sfTable = Database::get_main_table(TABLE_EXTRA_FIELD);
7249
            $sfvTable = Database::get_main_table(TABLE_EXTRA_FIELD_VALUES);
7250
            // Join session field and session field values tables
7251
            $joinTable = $sfTable.' sf INNER JOIN '.$sfvTable.' sfv ON sf.id = sfv.field_id';
7252
            $fieldsArray = [];
7253
            foreach ($extraFields as $field) {
7254
                $fieldsArray[] = Database::escape_string($field);
7255
            }
7256
            $extraFieldType = ExtraField::SESSION_FIELD_TYPE;
7257
            if (isset($publicationDate)) {
7258
                $publicationDateString = $publicationDate->format('Y-m-d H:i:s');
7259
                $wherePublication = " AND id NOT IN (
7260
                    SELECT sfv.item_id FROM $joinTable
7261
                    WHERE
7262
                        sf.extra_field_type = $extraFieldType AND
7263
                        ((sf.variable = 'publication_start_date' AND sfv.value > '$publicationDateString' and sfv.value != '') OR
7264
                        (sf.variable = 'publication_end_date' AND sfv.value < '$publicationDateString' and sfv.value != ''))
7265
                )";
7266
            }
7267
            // Get the session list from session category and target
7268
            $sessionList = Database::select(
7269
                'id, name, access_start_date, access_end_date',
7270
                $sTable,
7271
                [
7272
                    'where' => [
7273
                        "session_category_id = ? AND id IN (
7274
                            SELECT sfv.item_id FROM $joinTable
7275
                            WHERE
7276
                                sf.extra_field_type = $extraFieldType AND
7277
                                sfv.item_id = session.id AND
7278
                                sf.variable = 'target' AND
7279
                                sfv.value = ?
7280
                        ) $wherePublication" => [$categoryId, $target],
7281
                    ],
7282
                ]
7283
            );
7284
            $whereFieldVariables = [];
7285
            $whereFieldIds = [];
7286
            if (
7287
                is_array($fieldsArray) &&
7288
                count($fieldsArray) > 0
7289
            ) {
7290
                $whereParams = '?';
7291
                for ($i = 1; $i < count($fieldsArray); $i++) {
7292
                    $whereParams .= ', ?';
7293
                }
7294
                $whereFieldVariables = ' variable IN ( '.$whereParams.' )';
7295
                $whereFieldIds = 'field_id IN ( '.$whereParams.' )';
7296
            }
7297
            // Get session fields
7298
            $extraField = new ExtraFieldModel('session');
7299
            $questionMarks = substr(str_repeat('?, ', count($fieldsArray)), 0, -2);
7300
            $fieldsList = $extraField->get_all([
7301
                ' variable IN ( '.$questionMarks.' )' => $fieldsArray,
7302
            ]);
7303
            // Index session fields
7304
            foreach ($fieldsList as $field) {
7305
                $fields[$field['id']] = $field['variable'];
7306
            }
7307
            // Get session field values
7308
            $extra = new ExtraFieldValue('session');
7309
            $questionMarksFields = substr(str_repeat('?, ', count($fields)), 0, -2);
7310
            $sessionFieldValueList = $extra->get_all(['where' => ['field_id IN ( '.$questionMarksFields.' )' => array_keys($fields)]]);
7311
            // Add session fields values to session list
7312
            foreach ($sessionList as $id => &$session) {
7313
                foreach ($sessionFieldValueList as $sessionFieldValue) {
7314
                    // Match session field values to session
7315
                    if ($sessionFieldValue['item_id'] == $id) {
7316
                        // Check if session field value is set in session field list
7317
                        if (isset($fields[$sessionFieldValue['field_id']])) {
7318
                            // Avoid overwriting the session's ID field
7319
                            if ($fields[$sessionFieldValue['field_id']] != 'id') {
7320
                                $var = $fields[$sessionFieldValue['field_id']];
7321
                                $val = $sessionFieldValue['value'];
7322
                                // Assign session field value to session
7323
                                $session[$var] = $val;
7324
                            }
7325
                        }
7326
                    }
7327
                }
7328
            }
7329
        }
7330
7331
        return $sessionList;
7332
    }
7333
7334
    /**
7335
     * Return the Session Category id searched by name.
7336
     *
7337
     * @param string $categoryName Name attribute of session category used for search query
7338
     * @param bool   $force        boolean used to get even if something is wrong (e.g not unique name)
7339
     *
7340
     * @return int|array If success, return category id (int), else it will return an array
7341
     *                   with the next structure:
7342
     *                   array('error' => true, 'errorMessage' => ERROR_MESSAGE)
7343
     */
7344
    public static function getSessionCategoryIdByName($categoryName, $force = false)
7345
    {
7346
        // Start error result
7347
        $errorResult = ['error' => true, 'errorMessage' => get_lang('ThereWasAnError')];
7348
        $categoryName = Database::escape_string($categoryName);
7349
        // Check if is not empty category name
7350
        if (!empty($categoryName)) {
7351
            $sessionCategoryTable = Database::get_main_table(TABLE_MAIN_SESSION_CATEGORY);
7352
            // Get all session category with same name
7353
            $result = Database::select(
7354
                'id',
7355
                $sessionCategoryTable,
7356
                [
7357
                    'where' => [
7358
                        'name = ?' => $categoryName,
7359
                    ],
7360
                ]
7361
            );
7362
            // Check the result
7363
            if ($result < 1) {
7364
                // If not found any result, update error message
7365
                $errorResult['errorMessage'] = 'Not found any session category name '.$categoryName;
7366
            } elseif (count($result) > 1 && !$force) {
7367
                // If found more than one result and force is disabled, update error message
7368
                $errorResult['errorMessage'] = 'Found many session categories';
7369
            } elseif (count($result) == 1 || $force) {
7370
                // If found just one session category or force option is enabled
7371
7372
                return key($result);
7373
            }
7374
        } else {
7375
            // category name is empty, update error message
7376
            $errorResult['errorMessage'] = 'Not valid category name';
7377
        }
7378
7379
        return $errorResult;
7380
    }
7381
7382
    /**
7383
     * Return all data from sessions (plus extra field, course and coach data) by category id.
7384
     *
7385
     * @param int $sessionCategoryId session category id used to search sessions
7386
     *
7387
     * @return array If success, return session list and more session related data, else it will return an array
7388
     *               with the next structure:
7389
     *               array('error' => true, 'errorMessage' => ERROR_MESSAGE)
7390
     */
7391
    public static function getSessionListAndExtraByCategoryId($sessionCategoryId)
7392
    {
7393
        // Start error result
7394
        $errorResult = [
7395
            'error' => true,
7396
            'errorMessage' => get_lang('ThereWasAnError'),
7397
        ];
7398
7399
        $sessionCategoryId = intval($sessionCategoryId);
7400
        // Check if session category id is valid
7401
        if ($sessionCategoryId > 0) {
7402
            // Get table names
7403
            $sessionTable = Database::get_main_table(TABLE_MAIN_SESSION);
7404
            $sessionFieldTable = Database::get_main_table(TABLE_EXTRA_FIELD);
7405
            $sessionFieldValueTable = Database::get_main_table(TABLE_EXTRA_FIELD_VALUES);
7406
            $sessionCourseUserTable = Database::get_main_table(TABLE_MAIN_SESSION_COURSE_USER);
7407
            $userTable = Database::get_main_table(TABLE_MAIN_USER);
7408
            $courseTable = Database::get_main_table(TABLE_MAIN_COURSE);
7409
7410
            // Get all data from all sessions whit the session category specified
7411
            $sessionList = Database::select(
7412
                '*',
7413
                $sessionTable,
7414
                [
7415
                    'where' => [
7416
                        'session_category_id = ?' => $sessionCategoryId,
7417
                    ],
7418
                ]
7419
            );
7420
7421
            $extraFieldType = ExtraField::SESSION_FIELD_TYPE;
7422
7423
            // Check if session list query had result
7424
            if (!empty($sessionList)) {
7425
                // implode all session id
7426
                $sessionIdsString = '('.implode(', ', array_keys($sessionList)).')';
7427
                // Get all field variables
7428
                $sessionFieldList = Database::select(
7429
                    'id, variable',
7430
                    $sessionFieldTable,
7431
                    ['extra_field_type = ? ' => [$extraFieldType]]
7432
                );
7433
7434
                // Get all field values
7435
                $sql = "SELECT item_id, field_id, value FROM
7436
                        $sessionFieldValueTable v INNER JOIN $sessionFieldTable f
7437
                        ON (f.id = v.field_id)
7438
                        WHERE
7439
                            item_id IN $sessionIdsString AND
7440
                            extra_field_type = $extraFieldType
7441
                ";
7442
                $result = Database::query($sql);
7443
                $sessionFieldValueList = Database::store_result($result, 'ASSOC');
7444
7445
                // Check if session field values had result
7446
                if (!empty($sessionFieldValueList)) {
7447
                    $sessionFieldValueListBySession = [];
7448
                    foreach ($sessionFieldValueList as $key => $sessionFieldValue) {
7449
                        // Create an array to index ids to session id
7450
                        $sessionFieldValueListBySession[$sessionFieldValue['item_id']][] = $key;
7451
                    }
7452
                }
7453
                // Query used to find course-coaches from sessions
7454
                $sql = "SELECT
7455
                            scu.session_id,
7456
                            c.id AS course_id,
7457
                            c.code AS course_code,
7458
                            c.title AS course_title,
7459
                            u.username AS coach_username,
7460
                            u.firstname AS coach_firstname,
7461
                            u.lastname AS coach_lastname
7462
                        FROM $courseTable c
7463
                        INNER JOIN $sessionCourseUserTable scu ON c.id = scu.c_id
7464
                        INNER JOIN $userTable u ON scu.user_id = u.user_id
7465
                        WHERE scu.status = 2 AND scu.session_id IN $sessionIdsString
7466
                        ORDER BY scu.session_id ASC ";
7467
                $res = Database::query($sql);
7468
                $sessionCourseList = Database::store_result($res, 'ASSOC');
7469
                // Check if course list had result
7470
                if (!empty($sessionCourseList)) {
7471
                    foreach ($sessionCourseList as $key => $sessionCourse) {
7472
                        // Create an array to index ids to session_id
7473
                        $sessionCourseListBySession[$sessionCourse['session_id']][] = $key;
7474
                    }
7475
                }
7476
                // Join lists
7477
                if (is_array($sessionList)) {
7478
                    foreach ($sessionList as $id => &$row) {
7479
                        if (
7480
                            !empty($sessionFieldValueListBySession) &&
7481
                            is_array($sessionFieldValueListBySession[$id])
7482
                        ) {
7483
                            // If have an index array for session extra fields, use it to join arrays
7484
                            foreach ($sessionFieldValueListBySession[$id] as $key) {
7485
                                $row['extra'][$key] = [
7486
                                    'field_name' => $sessionFieldList[$sessionFieldValueList[$key]['field_id']]['variable'],
7487
                                    'value' => $sessionFieldValueList[$key]['value'],
7488
                                ];
7489
                            }
7490
                        }
7491
                        if (
7492
                            !empty($sessionCourseListBySession) &&
7493
                            is_array($sessionCourseListBySession[$id])
7494
                        ) {
7495
                            // If have an index array for session course coach, use it to join arrays
7496
                            foreach ($sessionCourseListBySession[$id] as $key) {
7497
                                $row['course'][$key] = [
7498
                                    'course_id' => $sessionCourseList[$key]['course_id'],
7499
                                    'course_code' => $sessionCourseList[$key]['course_code'],
7500
                                    'course_title' => $sessionCourseList[$key]['course_title'],
7501
                                    'coach_username' => $sessionCourseList[$key]['coach_username'],
7502
                                    'coach_firstname' => $sessionCourseList[$key]['coach_firstname'],
7503
                                    'coach_lastname' => $sessionCourseList[$key]['coach_lastname'],
7504
                                ];
7505
                            }
7506
                        }
7507
                    }
7508
                }
7509
7510
                return $sessionList;
7511
            } else {
7512
                // Not found result, update error message
7513
                $errorResult['errorMessage'] = 'Not found any session for session category id '.$sessionCategoryId;
7514
            }
7515
        }
7516
7517
        return $errorResult;
7518
    }
7519
7520
    /**
7521
     * Return session description from session id.
7522
     *
7523
     * @param int $sessionId
7524
     *
7525
     * @return string
7526
     */
7527
    public static function getDescriptionFromSessionId($sessionId)
7528
    {
7529
        // Init variables
7530
        $sessionId = (int) $sessionId;
7531
        $description = '';
7532
        // Check if session id is valid
7533
        if ($sessionId > 0) {
7534
            // Select query from session id
7535
            $rows = Database::select(
7536
                'description',
7537
                Database::get_main_table(TABLE_MAIN_SESSION),
7538
                [
7539
                    'where' => [
7540
                        'id = ?' => $sessionId,
7541
                    ],
7542
                ]
7543
            );
7544
7545
            // Check if select query result is not empty
7546
            if (!empty($rows)) {
7547
                // Get session description
7548
                $description = $rows[0]['description'];
7549
            }
7550
        }
7551
7552
        return $description;
7553
    }
7554
7555
    /**
7556
     * Get a session list filtered by name, description or any of the given extra fields.
7557
     *
7558
     * @param string $term                 The term to search
7559
     * @param array  $extraFieldsToInclude Extra fields to include in the session data
7560
     *
7561
     * @return array The list
7562
     */
7563
    public static function searchSession($term, $extraFieldsToInclude = [])
7564
    {
7565
        $sTable = Database::get_main_table(TABLE_MAIN_SESSION);
7566
        $extraFieldTable = Database::get_main_table(TABLE_EXTRA_FIELD);
7567
        $sfvTable = Database::get_main_table(TABLE_EXTRA_FIELD_VALUES);
7568
        $term = Database::escape_string($term);
7569
        $extraFieldType = ExtraField::SESSION_FIELD_TYPE;
7570
        if (is_array($extraFieldsToInclude) && count($extraFieldsToInclude) > 0) {
7571
            $resultData = Database::select('*', $sTable, [
7572
                'where' => [
7573
                    "name LIKE %?% " => $term,
7574
                    " OR description LIKE %?% " => $term,
7575
                    " OR id IN (
7576
                    SELECT item_id
7577
                    FROM $sfvTable v INNER JOIN $extraFieldTable e
7578
                    ON (v.field_id = e.id)
7579
                    WHERE value LIKE %?% AND extra_field_type = $extraFieldType
7580
                ) " => $term,
7581
                ],
7582
            ]);
7583
        } else {
7584
            $resultData = Database::select('*', $sTable, [
7585
                'where' => [
7586
                    "name LIKE %?% " => $term,
7587
                    "OR description LIKE %?% " => $term,
7588
                ],
7589
            ]);
7590
7591
            return $resultData;
7592
        }
7593
7594
        foreach ($resultData as $id => &$session) {
7595
            $session['extra'] = self::getFilteredExtraFields($id, $extraFieldsToInclude);
7596
        }
7597
7598
        return $resultData;
7599
    }
7600
7601
    /**
7602
     * @param int   $sessionId
7603
     * @param array $extraFieldsToInclude (empty means all)
7604
     *
7605
     * @return array
7606
     */
7607
    public static function getFilteredExtraFields($sessionId, $extraFieldsToInclude = [])
7608
    {
7609
        $extraData = [];
7610
        $variables = [];
7611
        $variablePlaceHolders = [];
7612
7613
        foreach ($extraFieldsToInclude as $sessionExtraField) {
7614
            $variablePlaceHolders[] = "?";
7615
            $variables[] = Database::escape_string($sessionExtraField);
7616
        }
7617
7618
        $sessionExtraField = new ExtraFieldModel('session');
7619
        $fieldList = $sessionExtraField->get_all(empty($extraFieldsToInclude) ? [] : [
7620
            "variable IN ( ".implode(", ", $variablePlaceHolders)." ) " => $variables,
7621
        ]);
7622
7623
        if (empty($fieldList)) {
7624
            return [];
7625
        }
7626
7627
        $fields = [];
7628
7629
        // Index session fields
7630
        foreach ($fieldList as $field) {
7631
            $fields[$field['id']] = $field['variable'];
7632
        }
7633
7634
        // Get session field values
7635
        $extra = new ExtraFieldValue('session');
7636
        $sessionFieldValueList = [];
7637
        foreach (array_keys($fields) as $fieldId) {
7638
            $sessionFieldValue = $extra->get_values_by_handler_and_field_id($sessionId, $fieldId);
7639
            if ($sessionFieldValue != false) {
7640
                $sessionFieldValueList[$fieldId] = $sessionFieldValue;
7641
            }
7642
        }
7643
7644
        foreach ($sessionFieldValueList as $sessionFieldValue) {
7645
            $extrafieldVariable = $fields[$sessionFieldValue['field_id']];
7646
            $extrafieldValue = $sessionFieldValue['value'];
7647
7648
            $extraData[] = [
7649
                'variable' => $extrafieldVariable,
7650
                'value' => $extrafieldValue,
7651
            ];
7652
        }
7653
7654
        return $extraData;
7655
    }
7656
7657
    /**
7658
     * @param int $sessionId
7659
     *
7660
     * @return bool
7661
     */
7662
    public static function isValidId($sessionId)
7663
    {
7664
        $sessionId = (int) $sessionId;
7665
        if ($sessionId > 0) {
7666
            $rows = Database::select(
7667
                'id',
7668
                Database::get_main_table(TABLE_MAIN_SESSION),
7669
                ['where' => ['id = ?' => $sessionId]]
7670
            );
7671
            if (!empty($rows)) {
7672
                return true;
7673
            }
7674
        }
7675
7676
        return false;
7677
    }
7678
7679
    /**
7680
     * Get list of sessions based on users of a group for a group admin.
7681
     *
7682
     * @param int $userId The user id
7683
     *
7684
     * @return array
7685
     */
7686
    public static function getSessionsFollowedForGroupAdmin($userId)
7687
    {
7688
        $sessionList = [];
7689
        $sessionTable = Database::get_main_table(TABLE_MAIN_SESSION);
7690
        $sessionUserTable = Database::get_main_table(TABLE_MAIN_SESSION_USER);
7691
        $userGroup = new UserGroup();
7692
        $userIdList = $userGroup->getGroupUsersByUser($userId);
7693
7694
        if (empty($userIdList)) {
7695
            return [];
7696
        }
7697
7698
        $sql = "SELECT DISTINCT s.*
7699
                FROM $sessionTable s
7700
                INNER JOIN $sessionUserTable sru
7701
                ON s.id = sru.id_session
7702
                WHERE
7703
                    (sru.id_user IN (".implode(', ', $userIdList).")
7704
                    AND sru.relation_type = 0
7705
                )";
7706
7707
        if (api_is_multiple_url_enabled()) {
7708
            $sessionAccessUrlTable = Database::get_main_table(TABLE_MAIN_ACCESS_URL_REL_SESSION);
7709
            $accessUrlId = api_get_current_access_url_id();
7710
7711
            if (-1 != $accessUrlId) {
7712
                $sql = "SELECT DISTINCT s.*
7713
                        FROM $sessionTable s
7714
                        INNER JOIN $sessionUserTable sru ON s.id = sru.id_session
7715
                        INNER JOIN $sessionAccessUrlTable srau ON s.id = srau.session_id
7716
                        WHERE
7717
                            srau.access_url_id = $accessUrlId
7718
                            AND (
7719
                                sru.id_user IN (".implode(', ', $userIdList).")
7720
                                AND sru.relation_type = 0
7721
                            )";
7722
            }
7723
        }
7724
7725
        $result = Database::query($sql);
7726
        while ($row = Database::fetch_assoc($result)) {
7727
            $sessionList[] = $row;
7728
        }
7729
7730
        return $sessionList;
7731
    }
7732
7733
    /**
7734
     * @param array $sessionInfo
7735
     *
7736
     * @return string
7737
     */
7738
    public static function getSessionVisibility($sessionInfo)
7739
    {
7740
        switch ($sessionInfo['visibility']) {
7741
            case 1:
7742
                return get_lang('ReadOnly');
7743
            case 2:
7744
                return get_lang('Visible');
7745
            case 3:
7746
                return api_ucfirst(get_lang('Invisible'));
7747
        }
7748
    }
7749
7750
    /**
7751
     * Returns a human readable string.
7752
     *
7753
     * @param array $sessionInfo An array with all the session dates
7754
     * @param bool  $showTime
7755
     *
7756
     * @return array
7757
     */
7758
    public static function parseSessionDates($sessionInfo, $showTime = false)
7759
    {
7760
        $displayDates = self::convertSessionDateToString(
7761
            $sessionInfo['display_start_date'],
7762
            $sessionInfo['display_end_date'],
7763
            $showTime,
7764
            true
7765
        );
7766
        $accessDates = self::convertSessionDateToString(
7767
            $sessionInfo['access_start_date'],
7768
            $sessionInfo['access_end_date'],
7769
            $showTime,
7770
            true
7771
        );
7772
7773
        $coachDates = self::convertSessionDateToString(
7774
            $sessionInfo['coach_access_start_date'],
7775
            $sessionInfo['coach_access_end_date'],
7776
            $showTime,
7777
            true
7778
        );
7779
7780
        $result = [
7781
            'access' => $accessDates,
7782
            'display' => $displayDates,
7783
            'coach' => $coachDates,
7784
        ];
7785
7786
        return $result;
7787
    }
7788
7789
    /**
7790
     * @param array $sessionInfo Optional
7791
     *
7792
     * @return array
7793
     */
7794
    public static function setForm(FormValidator $form, array $sessionInfo = [])
7795
    {
7796
        $sessionId = 0;
7797
        $coachInfo = [];
7798
7799
        if (!empty($sessionInfo)) {
7800
            $sessionId = (int) $sessionInfo['id'];
7801
            $coachInfo = api_get_user_info($sessionInfo['id_coach']);
7802
        }
7803
7804
        $categoriesList = self::get_all_session_category();
7805
        $userInfo = api_get_user_info();
7806
7807
        $categoriesOptions = [
7808
            '0' => get_lang('None'),
7809
        ];
7810
7811
        if ($categoriesList != false) {
7812
            foreach ($categoriesList as $categoryItem) {
7813
                $categoriesOptions[$categoryItem['id']] = $categoryItem['name'];
7814
            }
7815
        }
7816
7817
        // Database Table Definitions
7818
        $tbl_user = Database::get_main_table(TABLE_MAIN_USER);
7819
7820
        $form->addText(
7821
            'name',
7822
            get_lang('SessionName'),
7823
            true,
7824
            ['maxlength' => 150, 'aria-label' => get_lang('SessionName')]
7825
        );
7826
        $form->addRule('name', get_lang('SessionNameAlreadyExists'), 'callback', 'check_session_name');
7827
7828
        if (!api_is_platform_admin() && api_is_teacher()) {
7829
            $form->addElement(
7830
                'select',
7831
                'coach_username',
7832
                get_lang('CoachName'),
7833
                [api_get_user_id() => $userInfo['complete_name']],
7834
                [
7835
                    'id' => 'coach_username',
7836
                    'style' => 'width:370px;',
7837
                ]
7838
            );
7839
        } else {
7840
            $sql = "SELECT COUNT(1) FROM $tbl_user WHERE status = 1";
7841
            $rs = Database::query($sql);
7842
            $countUsers = (int) Database::result($rs, 0, 0);
7843
7844
            if ($countUsers < 50) {
7845
                $orderClause = 'ORDER BY ';
7846
                $orderClause .= api_sort_by_first_name() ? 'firstname, lastname, username' : 'lastname, firstname, username';
7847
7848
                $sql = "SELECT user_id, lastname, firstname, username
7849
                        FROM $tbl_user
7850
                        WHERE status = '1' ".
7851
                        $orderClause;
7852
7853
                if (api_is_multiple_url_enabled()) {
7854
                    $userRelAccessUrlTable = Database::get_main_table(
7855
                        TABLE_MAIN_ACCESS_URL_REL_USER
7856
                    );
7857
                    $accessUrlId = api_get_current_access_url_id();
7858
                    if ($accessUrlId != -1) {
7859
                        $sql = "SELECT user.user_id, username, lastname, firstname
7860
                        FROM $tbl_user user
7861
                        INNER JOIN $userRelAccessUrlTable url_user
7862
                        ON (url_user.user_id = user.user_id)
7863
                        WHERE
7864
                            access_url_id = $accessUrlId AND
7865
                            status = 1 "
7866
                            .$orderClause;
7867
                    }
7868
                }
7869
7870
                $result = Database::query($sql);
7871
                $coachesList = Database::store_result($result);
7872
                $coachesOptions = [];
7873
                foreach ($coachesList as $coachItem) {
7874
                    $coachesOptions[$coachItem['user_id']] =
7875
                        api_get_person_name($coachItem['firstname'], $coachItem['lastname']).' ('.$coachItem['username'].')';
7876
                }
7877
7878
                $form->addElement(
7879
                    'select',
7880
                    'coach_username',
7881
                    get_lang('CoachName'),
7882
                    $coachesOptions,
7883
                    [
7884
                        'id' => 'coach_username',
7885
                        'style' => 'width:370px;',
7886
                    ]
7887
                );
7888
            } else {
7889
                $form->addElement(
7890
                    'select_ajax',
7891
                    'coach_username',
7892
                    get_lang('CoachName'),
7893
                    $coachInfo ? [$coachInfo['id'] => $coachInfo['complete_name_with_username']] : [],
7894
                    [
7895
                        'url' => api_get_path(WEB_AJAX_PATH).'session.ajax.php?a=search_general_coach',
7896
                        'width' => '100%',
7897
                        'id' => 'coach_username',
7898
                    ]
7899
                );
7900
            }
7901
        }
7902
7903
        $form->addRule('coach_username', get_lang('ThisFieldIsRequired'), 'required');
7904
        $form->addHtml('<div id="ajax_list_coachs"></div>');
7905
7906
        $form->addButtonAdvancedSettings('advanced_params');
7907
        $form->addElement('html', '<div id="advanced_params_options" style="display:none">');
7908
7909
        if (empty($sessionId)) {
7910
            $form->addSelectAjax(
7911
                'session_template',
7912
                get_lang('SessionTemplate'),
7913
                [],
7914
                ['url' => api_get_path(WEB_AJAX_PATH).'session.ajax.php?a=search_template_session', 'id' => 'system_template']
7915
            );
7916
        }
7917
7918
        $form->addSelect(
7919
            'session_category',
7920
            get_lang('SessionCategory'),
7921
            $categoriesOptions,
7922
            [
7923
                'id' => 'session_category',
7924
            ]
7925
        );
7926
7927
        if (api_get_configuration_value('allow_session_status')) {
7928
            $statusList = self::getStatusList();
7929
            $form->addSelect(
7930
                'status',
7931
                get_lang('SessionStatus'),
7932
                $statusList,
7933
                [
7934
                    'id' => 'status',
7935
                ]
7936
            );
7937
        }
7938
7939
        $form->addHtmlEditor(
7940
            'description',
7941
            get_lang('Description'),
7942
            false,
7943
            false,
7944
            [
7945
                'ToolbarSet' => 'Minimal',
7946
            ]
7947
        );
7948
7949
        $form->addElement('checkbox', 'show_description', null, get_lang('ShowDescription'));
7950
7951
        $visibilityGroup = [];
7952
        $visibilityGroup[] = $form->createElement(
7953
            'select',
7954
            'session_visibility',
7955
            null,
7956
            [
7957
                SESSION_VISIBLE_READ_ONLY => get_lang('SessionReadOnly'),
7958
                SESSION_VISIBLE => get_lang('SessionAccessible'),
7959
                SESSION_INVISIBLE => api_ucfirst(get_lang('SessionNotAccessible')),
7960
            ]
7961
        );
7962
        $form->addGroup(
7963
            $visibilityGroup,
7964
            'visibility_group',
7965
            get_lang('SessionVisibility'),
7966
            null,
7967
            false
7968
        );
7969
7970
        $options = [
7971
            0 => get_lang('ByDuration'),
7972
            1 => get_lang('ByDates'),
7973
        ];
7974
7975
        $form->addSelect('access', get_lang('Access'), $options, [
7976
            'onchange' => 'accessSwitcher()',
7977
            'id' => 'access',
7978
        ]);
7979
7980
        $form->addHtml('<div id="duration_div" style="display:none">');
7981
        $form->addElement(
7982
            'number',
7983
            'duration',
7984
            [
7985
                get_lang('SessionDurationTitle'),
7986
                get_lang('SessionDurationDescription'),
7987
            ],
7988
            [
7989
                'maxlength' => 50,
7990
            ]
7991
        );
7992
7993
        $form->addHtml('</div>');
7994
        $form->addHtml('<div id="date_fields" style="display:none">');
7995
7996
        // Dates
7997
        $form->addDateTimePicker(
7998
            'access_start_date',
7999
            [get_lang('SessionStartDate'), get_lang('SessionStartDateComment')],
8000
            ['id' => 'access_start_date']
8001
        );
8002
8003
        $form->addDateTimePicker(
8004
            'access_end_date',
8005
            [get_lang('SessionEndDate'), get_lang('SessionEndDateComment')],
8006
            ['id' => 'access_end_date']
8007
        );
8008
8009
        $form->addRule(
8010
            ['access_start_date', 'access_end_date'],
8011
            get_lang('StartDateMustBeBeforeTheEndDate'),
8012
            'compare_datetime_text',
8013
            '< allow_empty'
8014
        );
8015
8016
        $form->addDateTimePicker(
8017
            'display_start_date',
8018
            [
8019
                get_lang('SessionDisplayStartDate'),
8020
                get_lang('SessionDisplayStartDateComment'),
8021
            ],
8022
            ['id' => 'display_start_date']
8023
        );
8024
8025
        $form->addDateTimePicker(
8026
            'display_end_date',
8027
            [
8028
                get_lang('SessionDisplayEndDate'),
8029
                get_lang('SessionDisplayEndDateComment'),
8030
            ],
8031
            ['id' => 'display_end_date']
8032
        );
8033
8034
        $form->addRule(
8035
            ['display_start_date', 'display_end_date'],
8036
            get_lang('StartDateMustBeBeforeTheEndDate'),
8037
            'compare_datetime_text',
8038
            '< allow_empty'
8039
        );
8040
8041
        $form->addDateTimePicker(
8042
            'coach_access_start_date',
8043
            [
8044
                get_lang('SessionCoachStartDate'),
8045
                get_lang('SessionCoachStartDateComment'),
8046
            ],
8047
            ['id' => 'coach_access_start_date']
8048
        );
8049
8050
        $form->addDateTimePicker(
8051
            'coach_access_end_date',
8052
            [
8053
                get_lang('SessionCoachEndDate'),
8054
                get_lang('SessionCoachEndDateComment'),
8055
            ],
8056
            ['id' => 'coach_access_end_date']
8057
        );
8058
8059
        $form->addRule(
8060
            ['coach_access_start_date', 'coach_access_end_date'],
8061
            get_lang('StartDateMustBeBeforeTheEndDate'),
8062
            'compare_datetime_text',
8063
            '< allow_empty'
8064
        );
8065
8066
        $form->addElement('html', '</div>');
8067
8068
        $form->addCheckBox(
8069
            'send_subscription_notification',
8070
            [
8071
                get_lang('SendSubscriptionNotification'),
8072
                get_lang('SendAnEmailWhenAUserBeingSubscribed'),
8073
            ]
8074
        );
8075
8076
        // Extra fields
8077
        $extra_field = new ExtraFieldModel('session');
8078
        $extra = $extra_field->addElements($form, $sessionId);
8079
8080
        $form->addElement('html', '</div>');
8081
8082
        $js = $extra['jquery_ready_content'];
8083
8084
        return ['js' => $js];
8085
    }
8086
8087
    /**
8088
     * Gets the number of rows in the session table filtered through the given
8089
     * array of parameters.
8090
     *
8091
     * @param array Array of options/filters/keys
8092
     *
8093
     * @return int The number of rows, or false on wrong param
8094
     * @assert ('a') === false
8095
     */
8096
    public static function get_count_admin_complete($options = [])
8097
    {
8098
        if (!is_array($options)) {
8099
            return false;
8100
        }
8101
        $tbl_session = Database::get_main_table(TABLE_MAIN_SESSION);
8102
        $tbl_session_category = Database::get_main_table(TABLE_MAIN_SESSION_CATEGORY);
8103
        $tbl_user = Database::get_main_table(TABLE_MAIN_USER);
8104
        $sessionCourseUserTable = Database::get_main_table(TABLE_MAIN_SESSION_COURSE_USER);
8105
        $courseTable = Database::get_main_table(TABLE_MAIN_COURSE);
8106
        $tbl_session_field_values = Database::get_main_table(TABLE_EXTRA_FIELD_VALUES);
8107
        $tbl_session_field_options = Database::get_main_table(TABLE_EXTRA_FIELD_OPTIONS);
8108
8109
        $where = 'WHERE 1 = 1 ';
8110
        $user_id = api_get_user_id();
8111
8112
        if (api_is_session_admin() &&
8113
            'false' == api_get_setting('allow_session_admins_to_see_all_sessions')
8114
        ) {
8115
            $where .= " WHERE s.session_admin_id = $user_id ";
8116
        }
8117
8118
        $extraFieldTables = '';
8119
        if (!empty($options['where'])) {
8120
            $options['where'] = str_replace('course_title', 'c.title', $options['where']);
8121
            $options['where'] = str_replace("( session_active = '0' )", '1=1', $options['where']);
8122
8123
            $options['where'] = str_replace(
8124
                ["AND session_active = '1'  )", " AND (  session_active = '1'  )"],
8125
                [') GROUP BY s.name HAVING session_active = 1 ', " GROUP BY s.name HAVING session_active = 1 "],
8126
                $options['where']
8127
            );
8128
8129
            $options['where'] = str_replace(
8130
                ["AND session_active = '0'  )", " AND (  session_active = '0'  )"],
8131
                [') GROUP BY s.name HAVING session_active = 0 ', " GROUP BY s.name HAVING session_active = '0' "],
8132
                $options['where']
8133
            );
8134
8135
            if (!empty($options['extra'])) {
8136
                $options['where'] = str_replace(' 1 = 1  AND', '', $options['where']);
8137
                $options['where'] = str_replace('AND', 'OR', $options['where']);
8138
8139
                foreach ($options['extra'] as $extra) {
8140
                    $options['where'] = str_replace(
8141
                        $extra['field'],
8142
                        'fv.field_id = '.$extra['id'].' AND fvo.option_value',
8143
                        $options['where']
8144
                    );
8145
                    $extraFieldTables = "$tbl_session_field_values fv, $tbl_session_field_options fvo, ";
8146
                }
8147
            }
8148
            $where .= ' AND '.$options['where'];
8149
        }
8150
8151
        $today = api_get_utc_datetime();
8152
        $query_rows = "SELECT count(*) as total_rows, c.title as course_title, s.name,
8153
                        IF (
8154
                            (s.access_start_date <= '$today' AND '$today' < s.access_end_date) OR
8155
                            (s.access_start_date = '0000-00-00 00:00:00' AND s.access_end_date = '0000-00-00 00:00:00' ) OR
8156
                            (s.access_start_date IS NULL AND s.access_end_date IS NULL) OR
8157
                            (s.access_start_date <= '$today' AND ('0000-00-00 00:00:00' = s.access_end_date OR s.access_end_date IS NULL )) OR
8158
                            ('$today' < s.access_end_date AND ('0000-00-00 00:00:00' = s.access_start_date OR s.access_start_date IS NULL) )
8159
                        , 1, 0) as session_active
8160
                       FROM $extraFieldTables $tbl_session s
8161
                       LEFT JOIN  $tbl_session_category sc
8162
                       ON s.session_category_id = sc.id
8163
                       INNER JOIN $tbl_user u
8164
                       ON s.id_coach = u.id
8165
                       INNER JOIN $sessionCourseUserTable scu
8166
                       ON s.id = scu.session_id
8167
                       INNER JOIN $courseTable c
8168
                       ON c.id = scu.c_id
8169
                       $where ";
8170
8171
        if (api_is_multiple_url_enabled()) {
8172
            $table_access_url_rel_session = Database::get_main_table(TABLE_MAIN_ACCESS_URL_REL_SESSION);
8173
            $access_url_id = api_get_current_access_url_id();
8174
            if (-1 != $access_url_id) {
8175
                $where .= " AND ar.access_url_id = $access_url_id ";
8176
                $query_rows = "SELECT count(*) as total_rows
8177
                               FROM $tbl_session s
8178
                               LEFT JOIN  $tbl_session_category sc
8179
                               ON s.session_category_id = sc.id
8180
                               INNER JOIN $tbl_user u
8181
                               ON s.id_coach = u.id
8182
                               INNER JOIN $table_access_url_rel_session ar
8183
                               ON ar.session_id = s.id $where ";
8184
            }
8185
        }
8186
8187
        $result = Database::query($query_rows);
8188
        $num = 0;
8189
        if (Database::num_rows($result)) {
8190
            $rows = Database::fetch_array($result);
8191
            $num = $rows['total_rows'];
8192
        }
8193
8194
        return $num;
8195
    }
8196
8197
    /**
8198
     * @param string $listType
8199
     * @param array  $extraFields
8200
     *
8201
     * @return array
8202
     */
8203
    public static function getGridColumns(
8204
        $listType = 'all',
8205
        $extraFields = [],
8206
        $addExtraFields = true
8207
    ) {
8208
        $showCount = api_get_configuration_value('session_list_show_count_users');
8209
        // Column config
8210
        $operators = ['cn', 'nc'];
8211
        $date_operators = ['gt', 'ge', 'lt', 'le'];
8212
8213
        switch ($listType) {
8214
            case 'my_space':
8215
                $columns = [
8216
                    get_lang('Title'),
8217
                    get_lang('Date'),
8218
                    get_lang('NbCoursesPerSession'),
8219
                    get_lang('NbStudentPerSession'),
8220
                    get_lang('Details'),
8221
                ];
8222
8223
                $columnModel = [
8224
                    ['name' => 'name', 'index' => 'name', 'width' => '255', 'align' => 'left'],
8225
                    ['name' => 'date', 'index' => 'access_start_date', 'width' => '150', 'align' => 'left'],
8226
                    [
8227
                        'name' => 'course_per_session',
8228
                        'index' => 'course_per_session',
8229
                        'width' => '150',
8230
                        'sortable' => 'false',
8231
                        'search' => 'false',
8232
                    ],
8233
                    [
8234
                        'name' => 'student_per_session',
8235
                        'index' => 'student_per_session',
8236
                        'width' => '100',
8237
                        'sortable' => 'false',
8238
                        'search' => 'false',
8239
                    ],
8240
                    [
8241
                        'name' => 'actions',
8242
                        'index' => 'actions',
8243
                        'width' => '100',
8244
                        'sortable' => 'false',
8245
                        'search' => 'false',
8246
                    ],
8247
                ];
8248
                break;
8249
            case 'all':
8250
            case 'active':
8251
            case 'close':
8252
                $columns = [
8253
                    '#',
8254
                    get_lang('Name'),
8255
                    get_lang('Category'),
8256
                    get_lang('SessionDisplayStartDate'),
8257
                    get_lang('SessionDisplayEndDate'),
8258
                    get_lang('Visibility'),
8259
                ];
8260
8261
                $columnModel = [
8262
                    [
8263
                        'name' => 'id',
8264
                        'index' => 's.id',
8265
                        'width' => '160',
8266
                        'hidden' => 'true',
8267
                    ],
8268
                    [
8269
                        'name' => 'name',
8270
                        'index' => 's.name',
8271
                        'width' => '160',
8272
                        'align' => 'left',
8273
                        'search' => 'true',
8274
                        'searchoptions' => ['sopt' => $operators],
8275
                    ],
8276
                    [
8277
                        'name' => 'category_name',
8278
                        'index' => 'category_name',
8279
                        'width' => '40',
8280
                        'align' => 'left',
8281
                        'search' => 'true',
8282
                        'searchoptions' => ['sopt' => $operators],
8283
                    ],
8284
                    [
8285
                        'name' => 'display_start_date',
8286
                        'index' => 'display_start_date',
8287
                        'width' => '50',
8288
                        'align' => 'left',
8289
                        'search' => 'true',
8290
                        'searchoptions' => [
8291
                            'dataInit' => 'date_pick_today',
8292
                            'sopt' => $date_operators,
8293
                        ],
8294
                    ],
8295
                    [
8296
                        'name' => 'display_end_date',
8297
                        'index' => 'display_end_date',
8298
                        'width' => '50',
8299
                        'align' => 'left',
8300
                        'search' => 'true',
8301
                        'searchoptions' => [
8302
                            'dataInit' => 'date_pick_one_month',
8303
                            'sopt' => $date_operators,
8304
                        ],
8305
                    ],
8306
                    [
8307
                        'name' => 'visibility',
8308
                        'index' => 'visibility',
8309
                        'width' => '40',
8310
                        'align' => 'left',
8311
                        'search' => 'false',
8312
                    ],
8313
                ];
8314
8315
                if ($showCount) {
8316
                    $columns[] = get_lang('Users');
8317
                    $columnModel[] = [
8318
                        'name' => 'users',
8319
                        'index' => 'users',
8320
                        'width' => '20',
8321
                        'align' => 'left',
8322
                        'search' => 'false',
8323
                    ];
8324
8325
                    // ofaj
8326
                    $columns[] = get_lang('Teachers');
8327
                    $columnModel[] = [
8328
                        'name' => 'teachers',
8329
                        'index' => 'teachers',
8330
                        'width' => '20',
8331
                        'align' => 'left',
8332
                        'search' => 'false',
8333
                    ];
8334
                }
8335
8336
                if (api_get_configuration_value('allow_session_status')) {
8337
                    $columns[] = get_lang('SessionStatus');
8338
                    $list = self::getStatusList();
8339
                    $listToString = '';
8340
                    foreach ($list as $statusId => $status) {
8341
                        $listToString .= $statusId.':'.$status.';';
8342
                    }
8343
8344
                    $columnModel[] = [
8345
                        'name' => 'status',
8346
                        'index' => 'status',
8347
                        'width' => '25',
8348
                        'align' => 'left',
8349
                        'search' => 'true',
8350
                        'stype' => 'select',
8351
                        // for the bottom bar
8352
                        'searchoptions' => [
8353
                            'defaultValue' => '1',
8354
                            'value' => $listToString,
8355
                        ],
8356
                    ];
8357
                }
8358
                break;
8359
            case 'complete':
8360
                $columns = [
8361
                    get_lang('Name'),
8362
                    get_lang('SessionDisplayStartDate'),
8363
                    get_lang('SessionDisplayEndDate'),
8364
                    get_lang('Coach'),
8365
                    get_lang('Status'),
8366
                    get_lang('Visibility'),
8367
                    get_lang('CourseTitle'),
8368
                ];
8369
                $columnModel = [
8370
                    [
8371
                        'name' => 'name',
8372
                        'index' => 's.name',
8373
                        'width' => '200',
8374
                        'align' => 'left',
8375
                        'search' => 'true',
8376
                        'searchoptions' => ['sopt' => $operators],
8377
                    ],
8378
                    [
8379
                        'name' => 'display_start_date',
8380
                        'index' => 'display_start_date',
8381
                        'width' => '70',
8382
                        'align' => 'left',
8383
                        'search' => 'true',
8384
                        'searchoptions' => ['dataInit' => 'date_pick_today', 'sopt' => $date_operators],
8385
                    ],
8386
                    [
8387
                        'name' => 'display_end_date',
8388
                        'index' => 'display_end_date',
8389
                        'width' => '70',
8390
                        'align' => 'left',
8391
                        'search' => 'true',
8392
                        'searchoptions' => ['dataInit' => 'date_pick_one_month', 'sopt' => $date_operators],
8393
                    ],
8394
                    [
8395
                        'name' => 'coach_name',
8396
                        'index' => 'coach_name',
8397
                        'width' => '70',
8398
                        'align' => 'left',
8399
                        'search' => 'false',
8400
                        'searchoptions' => ['sopt' => $operators],
8401
                    ],
8402
                    [
8403
                        'name' => 'session_active',
8404
                        'index' => 'session_active',
8405
                        'width' => '25',
8406
                        'align' => 'left',
8407
                        'search' => 'true',
8408
                        'stype' => 'select',
8409
                        // for the bottom bar
8410
                        'searchoptions' => [
8411
                            'defaultValue' => '1',
8412
                            'value' => '1:'.get_lang('Active').';0:'.get_lang('Inactive'),
8413
                        ],
8414
                        // for the top bar
8415
                        'editoptions' => [
8416
                            'value' => '" ":'.get_lang('All').';1:'.get_lang('Active').';0:'.get_lang(
8417
                                    'Inactive'
8418
                                ),
8419
                        ],
8420
                    ],
8421
                    [
8422
                        'name' => 'visibility',
8423
                        'index' => 'visibility',
8424
                        'width' => '40',
8425
                        'align' => 'left',
8426
                        'search' => 'false',
8427
                    ],
8428
                    [
8429
                        'name' => 'course_title',
8430
                        'index' => 'course_title',
8431
                        'width' => '50',
8432
                        'hidden' => 'true',
8433
                        'search' => 'true',
8434
                        'searchoptions' => ['searchhidden' => 'true', 'sopt' => $operators],
8435
                    ],
8436
                ];
8437
8438
                break;
8439
8440
            case 'custom':
8441
                $columns = [
8442
                    '#',
8443
                    get_lang('Name'),
8444
                    get_lang('Category'),
8445
                    get_lang('SessionDisplayStartDate'),
8446
                    get_lang('SessionDisplayEndDate'),
8447
                    get_lang('Visibility'),
8448
                ];
8449
                $columnModel = [
8450
                    [
8451
                        'name' => 'id',
8452
                        'index' => 's.id',
8453
                        'width' => '160',
8454
                        'hidden' => 'true',
8455
                    ],
8456
                    [
8457
                        'name' => 'name',
8458
                        'index' => 's.name',
8459
                        'width' => '160',
8460
                        'align' => 'left',
8461
                        'search' => 'true',
8462
                        'searchoptions' => ['sopt' => $operators],
8463
                    ],
8464
                    [
8465
                        'name' => 'category_name',
8466
                        'index' => 'category_name',
8467
                        'width' => '40',
8468
                        'align' => 'left',
8469
                        'search' => 'true',
8470
                        'searchoptions' => ['sopt' => $operators],
8471
                    ],
8472
                    [
8473
                        'name' => 'display_start_date',
8474
                        'index' => 'display_start_date',
8475
                        'width' => '50',
8476
                        'align' => 'left',
8477
                        'search' => 'true',
8478
                        'searchoptions' => [
8479
                            'dataInit' => 'date_pick_today',
8480
                            'sopt' => $date_operators,
8481
                        ],
8482
                    ],
8483
                    [
8484
                        'name' => 'display_end_date',
8485
                        'index' => 'display_end_date',
8486
                        'width' => '50',
8487
                        'align' => 'left',
8488
                        'search' => 'true',
8489
                        'searchoptions' => [
8490
                            'dataInit' => 'date_pick_one_month',
8491
                            'sopt' => $date_operators,
8492
                        ],
8493
                    ],
8494
                    [
8495
                        'name' => 'visibility',
8496
                        'index' => 'visibility',
8497
                        'width' => '40',
8498
                        'align' => 'left',
8499
                        'search' => 'false',
8500
                    ],
8501
                ];
8502
8503
                if ($showCount) {
8504
                    $columns[] = get_lang('Users');
8505
                    $columnModel[] = [
8506
                        'name' => 'users',
8507
                        'index' => 'users',
8508
                        'width' => '20',
8509
                        'align' => 'left',
8510
                        'search' => 'false',
8511
                    ];
8512
8513
                    // ofaj
8514
                    $columns[] = get_lang('Teachers');
8515
                    $columnModel[] = [
8516
                        'name' => 'teachers',
8517
                        'index' => 'teachers',
8518
                        'width' => '20',
8519
                        'align' => 'left',
8520
                        'search' => 'false',
8521
                    ];
8522
                }
8523
8524
                if (api_get_configuration_value('allow_session_status')) {
8525
                    $columns[] = get_lang('SessionStatus');
8526
                    $list = self::getStatusList();
8527
                    $listToString = '';
8528
                    foreach ($list as $statusId => $status) {
8529
                        $listToString .= $statusId.':'.$status.';';
8530
                    }
8531
8532
                    $columnModel[] = [
8533
                        'name' => 'status',
8534
                        'index' => 'status',
8535
                        'width' => '25',
8536
                        'align' => 'left',
8537
                        'search' => 'true',
8538
                        'stype' => 'select',
8539
                        // for the bottom bar
8540
                        'searchoptions' => [
8541
                            'defaultValue' => '1',
8542
                            'value' => $listToString,
8543
                        ],
8544
                    ];
8545
                }
8546
8547
                break;
8548
        }
8549
8550
        if (!empty($extraFields)) {
8551
            foreach ($extraFields as $field) {
8552
                $columns[] = $field['display_text'];
8553
                $columnModel[] = [
8554
                    'name' => $field['variable'],
8555
                    'index' => $field['variable'],
8556
                    'width' => '80',
8557
                    'align' => 'center',
8558
                    'search' => 'false',
8559
                ];
8560
            }
8561
        }
8562
8563
        // Inject extra session fields
8564
        $rules = [];
8565
        if ($addExtraFields) {
8566
            $sessionField = new ExtraFieldModel('session');
8567
            $rules = $sessionField->getRules($columns, $columnModel);
8568
        }
8569
8570
        if (!in_array('actions', array_column($columnModel, 'name'))) {
8571
            $columnModel[] = [
8572
                'name' => 'actions',
8573
                'index' => 'actions',
8574
                'width' => '80',
8575
                'align' => 'left',
8576
                'formatter' => 'action_formatter',
8577
                'sortable' => 'false',
8578
                'search' => 'false',
8579
            ];
8580
            $columns[] = get_lang('Actions');
8581
        }
8582
8583
        $columnName = [];
8584
        foreach ($columnModel as $col) {
8585
            $columnName[] = $col['name'];
8586
        }
8587
8588
        $return = [
8589
            'columns' => $columns,
8590
            'column_model' => $columnModel,
8591
            'rules' => $rules,
8592
            'simple_column_name' => $columnName,
8593
        ];
8594
8595
        return $return;
8596
    }
8597
8598
    /**
8599
     * Converts all dates sent through the param array (given form) to correct dates with timezones.
8600
     *
8601
     * @param array The dates The same array, with times converted
8602
     * @param bool $applyFormat Whether apply the DATE_TIME_FORMAT_SHORT format for sessions
8603
     *
8604
     * @return array The same array, with times converted
8605
     */
8606
    public static function convert_dates_to_local($params, $applyFormat = false)
8607
    {
8608
        if (!is_array($params)) {
8609
            return false;
8610
        }
8611
        $params['display_start_date'] = api_get_local_time($params['display_start_date'], null, null, true);
8612
        $params['display_end_date'] = api_get_local_time($params['display_end_date'], null, null, true);
8613
8614
        $params['access_start_date'] = api_get_local_time($params['access_start_date'], null, null, true);
8615
        $params['access_end_date'] = api_get_local_time($params['access_end_date'], null, null, true);
8616
8617
        $params['coach_access_start_date'] = isset($params['coach_access_start_date']) ? api_get_local_time($params['coach_access_start_date'], null, null, true) : null;
8618
        $params['coach_access_end_date'] = isset($params['coach_access_end_date']) ? api_get_local_time($params['coach_access_end_date'], null, null, true) : null;
8619
8620
        if ($applyFormat) {
8621
            if (isset($params['display_start_date'])) {
8622
                $params['display_start_date'] = api_format_date($params['display_start_date'], DATE_TIME_FORMAT_SHORT);
8623
            }
8624
8625
            if (isset($params['display_end_date'])) {
8626
                $params['display_end_date'] = api_format_date($params['display_end_date'], DATE_TIME_FORMAT_SHORT);
8627
            }
8628
8629
            if (isset($params['access_start_date'])) {
8630
                $params['access_start_date'] = api_format_date($params['access_start_date'], DATE_TIME_FORMAT_SHORT);
8631
            }
8632
8633
            if (isset($params['access_end_date'])) {
8634
                $params['access_end_date'] = api_format_date($params['access_end_date'], DATE_TIME_FORMAT_SHORT);
8635
            }
8636
8637
            if (isset($params['coach_access_start_date'])) {
8638
                $params['coach_access_start_date'] = api_format_date($params['coach_access_start_date'], DATE_TIME_FORMAT_SHORT);
8639
            }
8640
8641
            if (isset($params['coach_access_end_date'])) {
8642
                $params['coach_access_end_date'] = api_format_date($params['coach_access_end_date'], DATE_TIME_FORMAT_SHORT);
8643
            }
8644
        }
8645
8646
        return $params;
8647
    }
8648
8649
    /**
8650
     * Gets the admin session list callback of the session/session_list.php
8651
     * page with all user/details in the right fomat.
8652
     *
8653
     * @param array $options
8654
     *
8655
     * @return array Array of rows results
8656
     * @asset ('a') === false
8657
     */
8658
    public static function get_sessions_admin_complete($options = [])
8659
    {
8660
        if (!is_array($options)) {
8661
            return false;
8662
        }
8663
8664
        $tbl_session = Database::get_main_table(TABLE_MAIN_SESSION);
8665
        $tbl_session_category = Database::get_main_table(TABLE_MAIN_SESSION_CATEGORY);
8666
        $tbl_user = Database::get_main_table(TABLE_MAIN_USER);
8667
        $tbl_session_rel_course = Database::get_main_table(TABLE_MAIN_SESSION_COURSE);
8668
        $tbl_course = Database::get_main_table(TABLE_MAIN_COURSE);
8669
8670
        $extraFieldTable = Database::get_main_table(TABLE_EXTRA_FIELD);
8671
        $tbl_session_field_values = Database::get_main_table(TABLE_EXTRA_FIELD_VALUES);
8672
        $tbl_session_field_options = Database::get_main_table(TABLE_EXTRA_FIELD_OPTIONS);
8673
8674
        $where = 'WHERE 1 = 1 ';
8675
        $user_id = api_get_user_id();
8676
8677
        if (!api_is_platform_admin()) {
8678
            if (api_is_session_admin() &&
8679
                'false' == api_get_setting('allow_session_admins_to_manage_all_sessions')
8680
            ) {
8681
                $where .= " AND s.session_admin_id = $user_id ";
8682
            }
8683
        }
8684
8685
        $coach_name = " CONCAT(u.lastname , ' ', u.firstname) as coach_name ";
8686
        if (api_is_western_name_order()) {
8687
            $coach_name = " CONCAT(u.firstname, ' ', u.lastname) as coach_name ";
8688
        }
8689
8690
        $today = api_get_utc_datetime();
8691
        $injectExtraFields = null;
8692
        $extra_fields_info = [];
8693
8694
        //for now only sessions
8695
        $extra_field = new ExtraFieldModel('session');
8696
        $double_fields = [];
8697
        $extra_field_option = new ExtraFieldOption('session');
8698
8699
        if (isset($options['extra'])) {
8700
            $extra_fields = $options['extra'];
8701
            if (!empty($extra_fields)) {
8702
                foreach ($extra_fields as $extra) {
8703
                    $injectExtraFields .= " IF (fv.field_id = {$extra['id']}, fvo.option_display_text, NULL ) as {$extra['field']} , ";
8704
                    if (isset($extra_fields_info[$extra['id']])) {
8705
                        $info = $extra_fields_info[$extra['id']];
8706
                    } else {
8707
                        $info = $extra_field->get($extra['id']);
8708
                        $extra_fields_info[$extra['id']] = $info;
8709
                    }
8710
8711
                    if (ExtraFieldModel::FIELD_TYPE_DOUBLE_SELECT == $info['field_type']) {
8712
                        $double_fields[$info['id']] = $info;
8713
                    }
8714
                }
8715
            }
8716
        }
8717
8718
        $options_by_double = [];
8719
        foreach ($double_fields as $double) {
8720
            $my_options = $extra_field_option->get_field_options_by_field(
8721
                $double['id'],
8722
                true
8723
            );
8724
            $options_by_double['extra_'.$double['field_variable']] = $my_options;
8725
        }
8726
8727
        //sc.name as category_name,
8728
        $select = "
8729
                SELECT * FROM (
8730
                    SELECT DISTINCT
8731
                        IF (
8732
                            (s.access_start_date <= '$today' AND '$today' < s.access_end_date) OR
8733
                            (s.access_start_date = '0000-00-00 00:00:00' AND s.access_end_date = '0000-00-00 00:00:00' ) OR
8734
                            (s.access_start_date IS NULL AND s.access_end_date IS NULL) OR
8735
                            (s.access_start_date <= '$today' AND ('0000-00-00 00:00:00' = s.access_end_date OR s.access_end_date IS NULL )) OR
8736
                            ('$today' < s.access_end_date AND ('0000-00-00 00:00:00' = s.access_start_date OR s.access_start_date IS NULL) )
8737
                        , 1, 0) as session_active,
8738
                s.name,
8739
                s.nbr_courses,
8740
                s.nbr_users,
8741
                s.display_start_date,
8742
                s.display_end_date,
8743
                $coach_name,
8744
                access_start_date,
8745
                access_end_date,
8746
                s.visibility,
8747
                u.id as user_id,
8748
                $injectExtraFields
8749
                c.title as course_title,
8750
                s.id ";
8751
8752
        if (!empty($options['where'])) {
8753
            if (!empty($options['extra'])) {
8754
                $options['where'] = str_replace(' 1 = 1  AND', '', $options['where']);
8755
                $options['where'] = str_replace('AND', 'OR', $options['where']);
8756
                foreach ($options['extra'] as $extra) {
8757
                    $options['where'] = str_replace($extra['field'], 'fv.field_id = '.$extra['id'].' AND fvo.option_value', $options['where']);
8758
                }
8759
            }
8760
            $options['where'] = str_replace('course_title', 'c.title', $options['where']);
8761
            $options['where'] = str_replace("( session_active = '0' )", '1=1', $options['where']);
8762
            $options['where'] = str_replace(
8763
                ["AND session_active = '1'  )", " AND (  session_active = '1'  )"],
8764
                [') GROUP BY s.name HAVING session_active = 1 ', " GROUP BY s.name HAVING session_active = 1 "],
8765
                $options['where']
8766
            );
8767
8768
            $options['where'] = str_replace(
8769
                ["AND session_active = '0'  )", " AND (  session_active = '0'  )"],
8770
                [') GROUP BY s.name HAVING session_active = 0 ', " GROUP BY s.name HAVING session_active = '0' "],
8771
                $options['where']
8772
            );
8773
8774
            $where .= ' AND '.$options['where'];
8775
        }
8776
8777
        $limit = '';
8778
        if (!empty($options['limit'])) {
8779
            $limit = ' LIMIT '.$options['limit'];
8780
        }
8781
8782
        $query = "$select FROM $tbl_session s
8783
                    LEFT JOIN $tbl_session_field_values fv
8784
                    ON (fv.item_id = s.id)
8785
                    LEFT JOIN $extraFieldTable f
8786
                    ON f.id = fv.field_id
8787
                    LEFT JOIN $tbl_session_field_options fvo
8788
                    ON (fv.field_id = fvo.field_id)
8789
                    LEFT JOIN $tbl_session_rel_course src
8790
                    ON (src.session_id = s.id)
8791
                    LEFT JOIN $tbl_course c
8792
                    ON (src.c_id = c.id)
8793
                    LEFT JOIN $tbl_session_category sc
8794
                    ON (s.session_category_id = sc.id)
8795
                    INNER JOIN $tbl_user u
8796
                    ON (s.id_coach = u.id)
8797
                    $where
8798
                    $limit
8799
        ";
8800
8801
        if (api_is_multiple_url_enabled()) {
8802
            $table_access_url_rel_session = Database::get_main_table(TABLE_MAIN_ACCESS_URL_REL_SESSION);
8803
            $access_url_id = api_get_current_access_url_id();
8804
            if (-1 != $access_url_id) {
8805
                $query = "$select
8806
                    FROM $tbl_session s
8807
                    LEFT JOIN $tbl_session_field_values fv
8808
                    ON (fv.item_id = s.id)
8809
                    LEFT JOIN $tbl_session_field_options fvo
8810
                    ON (fv.field_id = fvo.field_id)
8811
                    LEFT JOIN $tbl_session_rel_course src
8812
                    ON (src.session_id = s.id)
8813
                    LEFT JOIN $tbl_course c
8814
                    ON (src.c_id = c.id)
8815
                    LEFT JOIN $tbl_session_category sc
8816
                    ON (s.session_category_id = sc.id)
8817
                    INNER JOIN $tbl_user u
8818
                    ON (s.id_coach = u.id)
8819
                    INNER JOIN $table_access_url_rel_session ar
8820
                    ON (ar.session_id = s.id AND ar.access_url_id = $access_url_id)
8821
                    $where
8822
                    $limit
8823
                ";
8824
            }
8825
        }
8826
8827
        $query .= ') AS s';
8828
8829
        if (!empty($options['order'])) {
8830
            $query .= ' ORDER BY '.$options['order'];
8831
        }
8832
8833
        $result = Database::query($query);
8834
8835
        $acceptIcon = Display::return_icon(
8836
            'accept.png',
8837
            get_lang('Active'),
8838
            [],
8839
            ICON_SIZE_SMALL
8840
        );
8841
8842
        $errorIcon = Display::return_icon(
8843
            'error.png',
8844
            get_lang('Inactive'),
8845
            [],
8846
            ICON_SIZE_SMALL
8847
        );
8848
8849
        $formatted_sessions = [];
8850
        if (Database::num_rows($result)) {
8851
            $sessions = Database::store_result($result, 'ASSOC');
8852
            foreach ($sessions as $session) {
8853
                $session_id = $session['id'];
8854
                $session['name'] = Display::url($session['name'], "resume_session.php?id_session=".$session['id']);
8855
                $session['coach_name'] = Display::url($session['coach_name'], "user_information.php?user_id=".$session['user_id']);
8856
                if (1 == $session['session_active']) {
8857
                    $session['session_active'] = $acceptIcon;
8858
                } else {
8859
                    $session['session_active'] = $errorIcon;
8860
                }
8861
8862
                $session = self::convert_dates_to_local($session);
8863
8864
                switch ($session['visibility']) {
8865
                    case SESSION_VISIBLE_READ_ONLY: //1
8866
                        $session['visibility'] = get_lang('ReadOnly');
8867
                        break;
8868
                    case SESSION_VISIBLE:           //2
8869
                    case SESSION_AVAILABLE:         //4
8870
                        $session['visibility'] = get_lang('Visible');
8871
                        break;
8872
                    case SESSION_INVISIBLE:         //3
8873
                        $session['visibility'] = api_ucfirst(get_lang('Invisible'));
8874
                        break;
8875
                }
8876
8877
                // Cleaning double selects
8878
                foreach ($session as $key => &$value) {
8879
                    if (isset($options_by_double[$key]) || isset($options_by_double[$key.'_second'])) {
8880
                        $options = explode('::', $value);
8881
                    }
8882
                    $original_key = $key;
8883
8884
                    if (strpos($key, '_second') === false) {
8885
                    } else {
8886
                        $key = str_replace('_second', '', $key);
8887
                    }
8888
8889
                    if (isset($options_by_double[$key])) {
8890
                        if (isset($options[0])) {
8891
                            if (isset($options_by_double[$key][$options[0]])) {
8892
                                if (strpos($original_key, '_second') === false) {
8893
                                    $value = $options_by_double[$key][$options[0]]['option_display_text'];
8894
                                } else {
8895
                                    $value = $options_by_double[$key][$options[1]]['option_display_text'];
8896
                                }
8897
                            }
8898
                        }
8899
                    }
8900
                }
8901
8902
                // Magic filter
8903
                if (isset($formatted_sessions[$session_id])) {
8904
                    $formatted_sessions[$session_id] = self::compareArraysToMerge(
8905
                        $formatted_sessions[$session_id],
8906
                        $session
8907
                    );
8908
                } else {
8909
                    $formatted_sessions[$session_id] = $session;
8910
                }
8911
            }
8912
        }
8913
8914
        return $formatted_sessions;
8915
    }
8916
8917
    /**
8918
     * Compare two arrays.
8919
     *
8920
     * @param array $array1
8921
     * @param array $array2
8922
     *
8923
     * @return array
8924
     */
8925
    public static function compareArraysToMerge($array1, $array2)
8926
    {
8927
        if (empty($array2)) {
8928
            return $array1;
8929
        }
8930
        foreach ($array1 as $key => $item) {
8931
            if (!isset($array1[$key])) {
8932
                //My string is empty try the other one
8933
                if (isset($array2[$key]) && !empty($array2[$key])) {
8934
                    $array1[$key] = $array2[$key];
8935
                }
8936
            }
8937
        }
8938
8939
        return $array1;
8940
    }
8941
8942
    /**
8943
     * Get link to the admin page for this session.
8944
     *
8945
     * @param int $id Session ID
8946
     *
8947
     * @return mixed URL to the admin page to manage the session, or false on error
8948
     */
8949
    public static function getAdminPath($id)
8950
    {
8951
        $id = (int) $id;
8952
        $session = self::fetch($id);
8953
        if (empty($session)) {
8954
            return false;
8955
        }
8956
8957
        return api_get_path(WEB_CODE_PATH).'session/resume_session.php?id_session='.$id;
8958
    }
8959
8960
    /**
8961
     * Get link to the user page for this session.
8962
     * If a course is provided, build the link to the course.
8963
     *
8964
     * @param int $id       Session ID
8965
     * @param int $courseId Course ID (optional) in case the link has to send straight to the course
8966
     *
8967
     * @return mixed URL to the page to use the session, or false on error
8968
     */
8969
    public static function getPath($id, $courseId = 0)
8970
    {
8971
        $id = (int) $id;
8972
        $session = self::fetch($id);
8973
        if (empty($session)) {
8974
            return false;
8975
        }
8976
        if (empty($courseId)) {
8977
            return api_get_path(WEB_CODE_PATH).'session/index.php?session_id='.$id;
8978
        } else {
8979
            $courseInfo = api_get_course_info_by_id($courseId);
8980
            if ($courseInfo) {
8981
                return $courseInfo['course_public_url'].'?id_session='.$id;
8982
            }
8983
        }
8984
8985
        return false;
8986
    }
8987
8988
    /**
8989
     * Return an associative array 'id_course' => [id_session1, id_session2...]
8990
     * where course id_course is in sessions id_session1, id_session2
8991
     * for course where user is coach
8992
     * i.e. coach for the course or
8993
     * main coach for a session the course is in
8994
     * for a session category (or woth no session category if empty).
8995
     *
8996
     * @param int $userId
8997
     *
8998
     * @return array
8999
     */
9000
    public static function getSessionCourseForUser($userId)
9001
    {
9002
        // list of COURSES where user is COURSE session coach
9003
        $listCourseCourseCoachSession = self::getCoursesForCourseSessionCoach($userId);
9004
        // list of courses where user is MAIN session coach
9005
        $listCourseMainCoachSession = self::getCoursesForMainSessionCoach($userId);
9006
        // merge these 2 array
9007
        $listResCourseSession = $listCourseCourseCoachSession;
9008
        foreach ($listCourseMainCoachSession as $courseId2 => $listSessionId2) {
9009
            if (isset($listResCourseSession[$courseId2])) {
9010
                // if sessionId array exists for this course
9011
                // same courseId, merge the list of session
9012
                foreach ($listCourseMainCoachSession[$courseId2] as $i => $sessionId2) {
9013
                    if (!in_array($sessionId2, $listResCourseSession[$courseId2])) {
9014
                        $listResCourseSession[$courseId2][] = $sessionId2;
9015
                    }
9016
                }
9017
            } else {
9018
                $listResCourseSession[$courseId2] = $listSessionId2;
9019
            }
9020
        }
9021
9022
        return $listResCourseSession;
9023
    }
9024
9025
    /**
9026
     * Return an associative array 'id_course' => [id_session1, id_session2...]
9027
     * where course id_course is in sessions id_session1, id_session2.
9028
     *
9029
     * @param int $userId
9030
     *
9031
     * @return array
9032
     */
9033
    public static function getCoursesForCourseSessionCoach($userId)
9034
    {
9035
        $userId = (int) $userId;
9036
        $listResCourseSession = [];
9037
        $tblCourse = Database::get_main_table(TABLE_MAIN_COURSE);
9038
        $tblSessionRelCourseRelUser = Database::get_main_table(TABLE_MAIN_SESSION_COURSE_USER);
9039
9040
        $sql = "SELECT session_id, c_id, c.id
9041
                FROM $tblSessionRelCourseRelUser srcru
9042
                LEFT JOIN $tblCourse c
9043
                ON c.id = srcru.c_id
9044
                WHERE
9045
                    srcru.user_id = $userId AND
9046
                    srcru.status = 2";
9047
9048
        $res = Database::query($sql);
9049
9050
        while ($data = Database::fetch_assoc($res)) {
9051
            if (api_get_session_visibility($data['session_id'])) {
9052
                if (!isset($listResCourseSession[$data['id']])) {
9053
                    $listResCourseSession[$data['id']] = [];
9054
                }
9055
                $listResCourseSession[$data['id']][] = $data['session_id'];
9056
            }
9057
        }
9058
9059
        return $listResCourseSession;
9060
    }
9061
9062
    /**
9063
     * Return an associative array 'id_course' => [id_session1, id_session2...]
9064
     * where course id_course is in sessions id_session1, id_session2.
9065
     *
9066
     * @param $userId
9067
     *
9068
     * @return array
9069
     */
9070
    public static function getCoursesForMainSessionCoach($userId)
9071
    {
9072
        $userId = (int) $userId;
9073
        $listResCourseSession = [];
9074
        $tblSession = Database::get_main_table(TABLE_MAIN_SESSION);
9075
9076
        // list of SESSION where user is session coach
9077
        $sql = "SELECT id FROM $tblSession
9078
                WHERE id_coach = ".$userId;
9079
        $res = Database::query($sql);
9080
9081
        while ($data = Database::fetch_assoc($res)) {
9082
            $sessionId = $data['id'];
9083
            $listCoursesInSession = self::getCoursesInSession($sessionId);
9084
            foreach ($listCoursesInSession as $i => $courseId) {
9085
                if (api_get_session_visibility($sessionId)) {
9086
                    if (!isset($listResCourseSession[$courseId])) {
9087
                        $listResCourseSession[$courseId] = [];
9088
                    }
9089
                    $listResCourseSession[$courseId][] = $sessionId;
9090
                }
9091
            }
9092
        }
9093
9094
        return $listResCourseSession;
9095
    }
9096
9097
    /**
9098
     * Return an array of course_id used in session $sessionId.
9099
     *
9100
     * @param $sessionId
9101
     *
9102
     * @return array
9103
     */
9104
    public static function getCoursesInSession($sessionId)
9105
    {
9106
        if (empty($sessionId)) {
9107
            return [];
9108
        }
9109
9110
        $tblSessionRelCourse = Database::get_main_table(TABLE_MAIN_SESSION_COURSE);
9111
        $tblCourse = Database::get_main_table(TABLE_MAIN_COURSE);
9112
9113
        // list of course in this session
9114
        $sql = "SELECT session_id, c.id
9115
                FROM $tblSessionRelCourse src
9116
                LEFT JOIN $tblCourse c
9117
                ON c.id = src.c_id
9118
                WHERE session_id = ".intval($sessionId);
9119
        $res = Database::query($sql);
9120
9121
        $listResultsCourseId = [];
9122
        while ($data = Database::fetch_assoc($res)) {
9123
            $listResultsCourseId[] = $data['id'];
9124
        }
9125
9126
        return $listResultsCourseId;
9127
    }
9128
9129
    /**
9130
     * Return an array of courses in session for user
9131
     * and for each courses the list of session that use this course for user.
9132
     *
9133
     * [0] => array
9134
     *      userCatId
9135
     *      userCatTitle
9136
     *      courseInUserCatList
9137
     *          [0] => array
9138
     *              courseId
9139
     *              title
9140
     *              courseCode
9141
     *              sessionCatList
9142
     *                  [0] => array
9143
     *                      catSessionId
9144
     *                      catSessionName
9145
     *                      sessionList
9146
     *                          [0] => array
9147
     *                              sessionId
9148
     *                              sessionName
9149
     *
9150
     * @param int $userId
9151
     *
9152
     * @return array
9153
     */
9154
    public static function getNamedSessionCourseForCoach($userId)
9155
    {
9156
        $listResults = [];
9157
        $listCourseSession = self::getSessionCourseForUser($userId);
9158
        foreach ($listCourseSession as $courseId => $listSessionId) {
9159
            // Course info
9160
            $courseInfo = api_get_course_info_by_id($courseId);
9161
            $listOneCourse = [];
9162
            $listOneCourse['courseId'] = $courseId;
9163
            $listOneCourse['title'] = $courseInfo['title'];
9164
            //$listOneCourse['courseCode'] = $courseInfo['code'];
9165
            $listOneCourse['course'] = $courseInfo;
9166
            $listOneCourse['sessionCatList'] = [];
9167
            $listCat = [];
9168
            foreach ($listSessionId as $i => $sessionId) {
9169
                // here we got all session for this course
9170
                // lets check there session categories
9171
                $sessionInfo = self::fetch($sessionId);
9172
                $catId = $sessionInfo['session_category_id'];
9173
                if (!isset($listCat[$catId])) {
9174
                    $listCatInfo = self::get_session_category($catId);
9175
                    if ($listCatInfo) {
9176
                        $listCat[$catId] = [];
9177
                        $listCat[$catId]['catSessionId'] = $catId;
9178
                        $listCat[$catId]['catSessionName'] = $listCatInfo['name'];
9179
                        $listCat[$catId]['sessionList'] = [];
9180
                    }
9181
                }
9182
                $listSessionInfo = self::fetch($sessionId);
9183
                $listSessionIdName = [
9184
                    'sessionId' => $sessionId,
9185
                    'sessionName' => $listSessionInfo['name'],
9186
                ];
9187
                $listCat[$catId]['sessionList'][] = $listSessionIdName;
9188
            }
9189
            // sort $listCat by catSessionName
9190
            usort($listCat, 'self::compareBySessionName');
9191
            // in each catSession sort sessionList by sessionName
9192
            foreach ($listCat as $i => $listCatSessionInfo) {
9193
                $listSessionList = $listCatSessionInfo['sessionList'];
9194
                usort($listSessionList, 'self::compareCatSessionInfo');
9195
                $listCat[$i]['sessionList'] = $listSessionList;
9196
            }
9197
9198
            $listOneCourse['sessionCatList'] = $listCat;
9199
9200
            // user course category
9201
            $courseCategory = CourseManager::getUserCourseCategoryForCourse(
9202
                $userId,
9203
                $courseId
9204
            );
9205
9206
            $userCatTitle = '';
9207
            $userCatId = 0;
9208
            if ($courseCategory) {
9209
                $userCatId = $courseCategory['user_course_cat'];
9210
                $userCatTitle = $courseCategory['title'];
9211
            }
9212
9213
            $listResults[$userCatId]['courseInUserCategoryId'] = $userCatId;
9214
            $listResults[$userCatId]['courseInUserCategoryTitle'] = $userCatTitle;
9215
            $listResults[$userCatId]['courseInUserCatList'][] = $listOneCourse;
9216
        }
9217
9218
        // sort by user course cat
9219
        uasort($listResults, 'self::compareByUserCourseCat');
9220
9221
        // sort by course title
9222
        foreach ($listResults as $userCourseCatId => $tabCoursesInCat) {
9223
            $courseInUserCatList = $tabCoursesInCat['courseInUserCatList'];
9224
            uasort($courseInUserCatList, 'self::compareByCourse');
9225
            $listResults[$userCourseCatId]['courseInUserCatList'] = $courseInUserCatList;
9226
        }
9227
9228
        return $listResults;
9229
    }
9230
9231
    /**
9232
     * @param int $userId
9233
     * @param int $courseId
9234
     *
9235
     * @return array
9236
     */
9237
    public static function searchCourseInSessionsFromUser($userId, $courseId)
9238
    {
9239
        $table = Database::get_main_table(TABLE_MAIN_SESSION_COURSE_USER);
9240
        $userId = (int) $userId;
9241
        $courseId = (int) $courseId;
9242
        if (empty($userId) || empty($courseId)) {
9243
            return [];
9244
        }
9245
9246
        $sql = "SELECT * FROM $table
9247
                WHERE c_id = $courseId AND user_id = $userId";
9248
        $result = Database::query($sql);
9249
9250
        return Database::store_result($result, 'ASSOC');
9251
    }
9252
9253
    /**
9254
     * Subscribe and redirect to session after inscription.
9255
     */
9256
    public static function redirectToSession()
9257
    {
9258
        $sessionId = (int) ChamiloSession::read('session_redirect');
9259
        $onlyOneCourseSessionToRedirect = ChamiloSession::read('only_one_course_session_redirect');
9260
        if ($sessionId) {
9261
            $sessionInfo = api_get_session_info($sessionId);
9262
            if (!empty($sessionInfo)) {
9263
                $userId = api_get_user_id();
9264
                $response = self::isUserSubscribedAsStudent($sessionId, $userId);
9265
                if ($response) {
9266
                    $urlToRedirect = api_get_path(WEB_CODE_PATH).'session/index.php?session_id='.$sessionId;
9267
                    if (!empty($onlyOneCourseSessionToRedirect)) {
9268
                        $urlToRedirect = api_get_path(WEB_PATH).
9269
                            'courses/'.$onlyOneCourseSessionToRedirect.'/index.php?id_session='.$sessionId;
9270
                    }
9271
9272
                    header('Location: '.$urlToRedirect);
9273
                    exit;
9274
                }
9275
            }
9276
        }
9277
    }
9278
9279
    /**
9280
     * @return int
9281
     */
9282
    public static function getCountUsersInCourseSession(Course $course, Session $session)
9283
    {
9284
        $urlId = api_get_current_access_url_id();
9285
9286
        return Database::getManager()
9287
            ->createQuery("
9288
                SELECT COUNT(scu)
9289
                FROM ChamiloCoreBundle:SessionRelCourseRelUser scu
9290
                INNER JOIN ChamiloCoreBundle:SessionRelUser su
9291
                    WITH scu.user = su.user
9292
                    AND scu.session = su.session
9293
                INNER JOIN ChamiloCoreBundle:AccessUrlRelUser a
9294
                    WITH a.user = su.user
9295
                WHERE
9296
                    scu.course = :course AND
9297
                    su.relationType <> :relationType AND
9298
                    scu.session = :session AND
9299
                    a.portal = :url
9300
            ")
9301
            ->setParameters([
9302
                'course' => $course->getId(),
9303
                'relationType' => SESSION_RELATION_TYPE_RRHH,
9304
                'session' => $session->getId(),
9305
                'url' => $urlId,
9306
            ])
9307
            ->getSingleScalarResult();
9308
    }
9309
9310
    /**
9311
     * Get course IDs where user in not subscribed in session.
9312
     *
9313
     * @return array
9314
     */
9315
    public static function getAvoidedCoursesInSession(User $user, Session $session)
9316
    {
9317
        $courseIds = [];
9318
9319
        /** @var SessionRelCourse $sessionCourse */
9320
        foreach ($session->getCourses() as $sessionCourse) {
9321
            /** @var Course $course */
9322
            $course = $sessionCourse->getCourse();
9323
9324
            if ($session->getUserInCourse($user, $course)->count()) {
9325
                continue;
9326
            }
9327
9328
            $courseIds[] = $course->getId();
9329
        }
9330
9331
        return $courseIds;
9332
    }
9333
9334
    /**
9335
     * @param int             $userId
9336
     * @param int             $sessionId
9337
     * @param ExtraFieldValue $extraFieldValue
9338
     * @param string          $collapsableLink
9339
     *
9340
     * @return array
9341
     */
9342
    public static function getCollapsableData($userId, $sessionId, $extraFieldValue, $collapsableLink)
9343
    {
9344
        $collapsed = 0;
9345
9346
        // Get default collapsed value in extra field
9347
        $value = $extraFieldValue->get_values_by_handler_and_field_variable($sessionId, 'collapsed');
9348
        if (!empty($value) && isset($value['value'])) {
9349
            $collapsed = $value['value'];
9350
        }
9351
9352
        $userRelSession = self::getUserSession($userId, $sessionId);
9353
9354
        if ($userRelSession) {
9355
            if (isset($userRelSession['collapsed']) && '' != $userRelSession['collapsed']) {
9356
                $collapsed = $userRelSession['collapsed'];
9357
            }
9358
        } else {
9359
            return ['collapsed' => $collapsed, 'collapsable_link' => '&nbsp;'];
9360
        }
9361
9362
        $link = $collapsableLink.'&session_id='.$sessionId.'&value=1';
9363
        $image = '<i class="fa fa-folder-open"></i>';
9364
        if (1 == $collapsed) {
9365
            $link = $collapsableLink.'&session_id='.$sessionId.'&value=0';
9366
            $image = '<i class="fa fa-folder"></i>';
9367
        }
9368
9369
        $link = Display::url(
9370
            $image,
9371
            $link
9372
        );
9373
9374
        return ['collapsed' => $collapsed, 'collapsable_link' => $link];
9375
    }
9376
9377
    /**
9378
     * Converts "start date" and "end date" to "From start date to end date" string.
9379
     *
9380
     * @param string $startDate
9381
     * @param string $endDate
9382
     * @param bool   $showTime
9383
     * @param bool   $dateHuman
9384
     *
9385
     * @return string
9386
     */
9387
    public static function convertSessionDateToString($startDate, $endDate, $showTime, $dateHuman)
9388
    {
9389
        // api_get_local_time returns empty if date is invalid like 0000-00-00 00:00:00
9390
        $startDateToLocal = api_get_local_time(
9391
            $startDate,
9392
            null,
9393
            null,
9394
            true,
9395
            $showTime,
9396
            $dateHuman
9397
        );
9398
        $endDateToLocal = api_get_local_time(
9399
            $endDate,
9400
            null,
9401
            null,
9402
            true,
9403
            $showTime,
9404
            $dateHuman
9405
        );
9406
9407
        $format = $showTime ? DATE_TIME_FORMAT_LONG_24H : DATE_FORMAT_LONG_NO_DAY;
9408
9409
        $result = '';
9410
        if (!empty($startDateToLocal) && !empty($endDateToLocal)) {
9411
            $result = sprintf(
9412
                get_lang('FromDateXToDateY'),
9413
                api_format_date($startDateToLocal, $format),
9414
                api_format_date($endDateToLocal, $format)
9415
            );
9416
        } else {
9417
            if (!empty($startDateToLocal)) {
9418
                $result = get_lang('From').' '.api_format_date($startDateToLocal, $format);
9419
            }
9420
            if (!empty($endDateToLocal)) {
9421
                $result = get_lang('Until').' '.api_format_date($endDateToLocal, $format);
9422
            }
9423
        }
9424
        if (empty($result)) {
9425
            $result = get_lang('NoTimeLimits');
9426
        }
9427
9428
        return $result;
9429
    }
9430
9431
    public static function getStatusList()
9432
    {
9433
        return [
9434
            self::STATUS_PLANNED => get_lang('Planned'),
9435
            self::STATUS_PROGRESS => get_lang('InProgress'),
9436
            self::STATUS_FINISHED => get_lang('Finished'),
9437
            self::STATUS_CANCELLED => get_lang('Cancelled'),
9438
        ];
9439
    }
9440
9441
    public static function getStatusLabel($status)
9442
    {
9443
        $list = self::getStatusList();
9444
9445
        if (!isset($list[$status])) {
9446
            return get_lang('NoStatus');
9447
        }
9448
9449
        return $list[$status];
9450
    }
9451
9452
    public static function getDefaultSessionTab()
9453
    {
9454
        $default = 'all';
9455
        $view = api_get_configuration_value('default_session_list_view');
9456
9457
        if (!empty($view)) {
9458
            $default = $view;
9459
        }
9460
9461
        return $default;
9462
    }
9463
9464
    /**
9465
     * @return string
9466
     */
9467
    public static function getSessionListTabs($listType)
9468
    {
9469
        $tabs = [
9470
            [
9471
                'content' => get_lang('AllSessionsShort'),
9472
                'url' => api_get_path(WEB_CODE_PATH).'session/session_list.php?list_type=all',
9473
            ],
9474
            [
9475
                'content' => get_lang('ActiveSessionsShort'),
9476
                'url' => api_get_path(WEB_CODE_PATH).'session/session_list.php?list_type=active',
9477
            ],
9478
            [
9479
                'content' => get_lang('ClosedSessionsShort'),
9480
                'url' => api_get_path(WEB_CODE_PATH).'session/session_list.php?list_type=close',
9481
            ],
9482
            [
9483
                'content' => get_lang('SessionListCustom'),
9484
                'url' => api_get_path(WEB_CODE_PATH).'session/session_list.php?list_type=custom',
9485
            ],
9486
            /*[
9487
                'content' => get_lang('Complete'),
9488
                'url' => api_get_path(WEB_CODE_PATH).'session/session_list_simple.php?list_type=complete',
9489
            ],*/
9490
        ];
9491
9492
        switch ($listType) {
9493
            case 'all':
9494
                $default = 1;
9495
                break;
9496
            case 'active':
9497
                $default = 2;
9498
                break;
9499
            case 'close':
9500
                $default = 3;
9501
                break;
9502
            case 'custom':
9503
                $default = 4;
9504
                break;
9505
        }
9506
9507
        return Display::tabsOnlyLink($tabs, $default);
9508
    }
9509
9510
    /**
9511
     * Check if a session is followed by human resources manager.
9512
     *
9513
     * @param int $sessionId
9514
     * @param int $userId
9515
     *
9516
     * @return bool
9517
     */
9518
    public static function isSessionFollowedByDrh($sessionId, $userId)
9519
    {
9520
        $userId = (int) $userId;
9521
        $sessionId = (int) $sessionId;
9522
9523
        $tblSession = Database::get_main_table(TABLE_MAIN_SESSION);
9524
        $tblSessionRelUser = Database::get_main_table(TABLE_MAIN_SESSION_USER);
9525
9526
        if (api_is_multiple_url_enabled()) {
9527
            $tblSessionRelAccessUrl = Database::get_main_table(TABLE_MAIN_ACCESS_URL_REL_SESSION);
9528
9529
            $sql = "SELECT s.id FROM $tblSession s
9530
                INNER JOIN $tblSessionRelUser sru ON (sru.session_id = s.id)
9531
                LEFT JOIN $tblSessionRelAccessUrl a ON (s.id = a.session_id)
9532
                WHERE
9533
                    sru.user_id = '$userId' AND
9534
                    sru.session_id = '$sessionId' AND
9535
                    sru.relation_type = '".SESSION_RELATION_TYPE_RRHH."' AND
9536
                    access_url_id = ".api_get_current_access_url_id();
9537
        } else {
9538
            $sql = "SELECT s.id FROM $tblSession s
9539
                INNER JOIN $tblSessionRelUser sru ON sru.session_id = s.id
9540
                WHERE
9541
                    sru.user_id = '$userId' AND
9542
                    sru.session_id = '$sessionId' AND
9543
                    sru.relation_type = '".SESSION_RELATION_TYPE_RRHH."'";
9544
        }
9545
9546
        $result = Database::query($sql);
9547
9548
        return Database::num_rows($result) > 0;
9549
    }
9550
9551
    /**
9552
     * Add a warning message when session is read-only mode.
9553
     */
9554
    public static function addFlashSessionReadOnly()
9555
    {
9556
        if (api_get_session_id() && !api_is_allowed_to_session_edit()) {
9557
            Display::addFlash(
9558
                Display::return_message(get_lang('SessionIsReadOnly'), 'warning')
9559
            );
9560
        }
9561
    }
9562
9563
    public static function insertUsersInCourses(array $studentIds, array $courseIds, int $sessionId)
9564
    {
9565
        $tblSessionUser = Database::get_main_table(TABLE_MAIN_SESSION_USER);
9566
        $tblSession = Database::get_main_table(TABLE_MAIN_SESSION);
9567
9568
        foreach ($courseIds as $courseId) {
9569
            self::insertUsersInCourse($studentIds, $courseId, $sessionId, [], false);
9570
        }
9571
9572
        foreach ($studentIds as $studentId) {
9573
            Database::query(
9574
                "INSERT IGNORE INTO $tblSessionUser (session_id, user_id, registered_at)
9575
                VALUES ($sessionId, $studentId, '".api_get_utc_datetime()."')"
9576
            );
9577
        }
9578
9579
        Database::query(
9580
            "UPDATE $tblSession s
9581
            SET s.nbr_users = (
9582
                SELECT COUNT(1) FROM session_rel_user sru
9583
                WHERE sru.session_id = $sessionId AND sru.relation_type <> ".Session::DRH."
9584
            )
9585
            WHERE s.id = $sessionId"
9586
        );
9587
    }
9588
9589
    public static function insertUsersInCourse(
9590
        array $studentIds,
9591
        int $courseId,
9592
        int $sessionId,
9593
        array $relationInfo = [],
9594
        bool $updateSession = true
9595
    ) {
9596
        $tblSessionCourseUser = Database::get_main_table(TABLE_MAIN_SESSION_COURSE_USER);
9597
        $tblSessionCourse = Database::get_main_table(TABLE_MAIN_SESSION_COURSE);
9598
        $tblSessionUser = Database::get_main_table(TABLE_MAIN_SESSION_USER);
9599
        $tblSession = Database::get_main_table(TABLE_MAIN_SESSION);
9600
9601
        $relationInfo = array_merge(['visibility' => 0, 'status' => Session::STUDENT], $relationInfo);
9602
9603
        $sessionCourseUser = [
9604
            'session_id' => $sessionId,
9605
            'c_id' => $courseId,
9606
            'visibility' => $relationInfo['visibility'],
9607
            'status' => $relationInfo['status'],
9608
        ];
9609
        $sessionUser = [
9610
            'session_id' => $sessionId,
9611
            'registered_at' => api_get_utc_datetime(),
9612
        ];
9613
9614
        foreach ($studentIds as $studentId) {
9615
            $sessionCourseUser['user_id'] = $studentId;
9616
9617
            $count = Database::select(
9618
                'COUNT(1) as nbr',
9619
                $tblSessionCourseUser,
9620
                ['where' => ['session_id = ? AND c_id = ? AND user_id = ?' => [$sessionId, $courseId, $studentId]]],
9621
                'first'
9622
            );
9623
9624
            if (empty($count['nbr'])) {
9625
                Database::insert($tblSessionCourseUser, $sessionCourseUser);
9626
9627
                Event::logUserSubscribedInCourseSession($studentId, $courseId, $sessionId);
9628
            }
9629
9630
            if ($updateSession) {
9631
                $sessionUser['user_id'] = $studentId;
9632
9633
                $count = Database::select(
9634
                    'COUNT(1) as nbr',
9635
                    $tblSessionUser,
9636
                    ['where' => ['session_id = ? AND user_id = ?' => [$sessionId, $studentId]]],
9637
                    'first'
9638
                );
9639
9640
                if (empty($count['nbr'])) {
9641
                    Database::insert($tblSessionUser, $sessionUser);
9642
                }
9643
            }
9644
        }
9645
9646
        Database::query(
9647
            "UPDATE $tblSessionCourse src
9648
            SET src.nbr_users = (
9649
                SELECT COUNT(1) FROM $tblSessionCourseUser srcru
9650
                WHERE
9651
                    srcru.session_id = $sessionId AND srcru.c_id = $courseId AND srcru.status <> ".Session::COACH."
9652
            )
9653
            WHERE src.session_id = $sessionId AND src.c_id = $courseId"
9654
        );
9655
9656
        if ($updateSession) {
9657
            Database::query(
9658
                "UPDATE $tblSession s
9659
                SET s.nbr_users = (
9660
                    SELECT COUNT(1) FROM session_rel_user sru
9661
                    WHERE sru.session_id = $sessionId AND sru.relation_type <> ".Session::DRH."
9662
                )
9663
                WHERE s.id = $sessionId"
9664
            );
9665
        }
9666
    }
9667
9668
    public static function getCareersFromSession(int $sessionId): array
9669
    {
9670
        $extraFieldValueSession = new ExtraFieldValue('session');
9671
        $extraFieldValueCareer = new ExtraFieldValue('career');
9672
9673
        $value = $extraFieldValueSession->get_values_by_handler_and_field_variable($sessionId, 'careerid');
9674
        $careers = [];
9675
        if (isset($value['value']) && !empty($value['value'])) {
9676
            $careerList = str_replace(['[', ']'], '', $value['value']);
9677
            $careerList = explode(',', $careerList);
9678
            $careerManager = new Career();
9679
            foreach ($careerList as $career) {
9680
                $careerIdValue = $extraFieldValueCareer->get_item_id_from_field_variable_and_field_value(
9681
                    'external_career_id',
9682
                    $career
9683
                );
9684
                if (isset($careerIdValue['item_id']) && !empty($careerIdValue['item_id'])) {
9685
                    $finalCareerId = $careerIdValue['item_id'];
9686
                    $careerInfo = $careerManager->get($finalCareerId);
9687
                    if (!empty($careerInfo)) {
9688
                        $careers[] = $careerInfo;
9689
                    }
9690
                }
9691
            }
9692
        }
9693
9694
        return $careers;
9695
    }
9696
9697
    public static function getCareerDiagramPerSessionList($sessionList, $userId)
9698
    {
9699
        if (empty($sessionList) || empty($userId)) {
9700
            return '';
9701
        }
9702
9703
        $userId = (int) $userId;
9704
        $careersAdded = [];
9705
        $careerModel = new Career();
9706
        $frames = '';
9707
        foreach ($sessionList as $sessionId) {
9708
            $visibility = api_get_session_visibility($sessionId, null, false, $userId);
9709
            if (SESSION_AVAILABLE === $visibility) {
9710
                $careerList = self::getCareersFromSession($sessionId);
9711
                if (empty($careerList)) {
9712
                    continue;
9713
                }
9714
                foreach ($careerList as $career) {
9715
                    $careerId = $careerIdToShow = $career['id'];
9716
                    if (api_get_configuration_value('use_career_external_id_as_identifier_in_diagrams')) {
9717
                        $careerIdToShow = $careerModel->getCareerIdFromInternalToExternal($careerId);
9718
                    }
9719
9720
                    if (!in_array($careerId, $careersAdded)) {
9721
                        $careersAdded[] = $careerId;
9722
                        $careerUrl = api_get_path(WEB_CODE_PATH).'user/career_diagram.php?iframe=1&career_id='.$careerIdToShow.'&user_id='.$userId;
9723
                        $frames .= '
9724
                            <iframe
9725
                                onload="resizeIframe(this)"
9726
                                style="width:100%;"
9727
                                border="0"
9728
                                frameborder="0"
9729
                                scrolling="no"
9730
                                src="'.$careerUrl.'"
9731
                            ></iframe>';
9732
                    }
9733
                }
9734
            }
9735
        }
9736
9737
        $content = '';
9738
        if (!empty($frames)) {
9739
            $content = Display::page_subheader(get_lang('OngoingTraining'));
9740
            $content .= '
9741
               <script>
9742
                resizeIframe = function(iFrame) {
9743
                    iFrame.height = iFrame.contentWindow.document.body.scrollHeight + 20;
9744
                }
9745
                </script>
9746
            ';
9747
            $content .= $frames;
9748
            $content .= Career::renderDiagramFooter();
9749
        }
9750
9751
        return $content;
9752
    }
9753
9754
    /**
9755
     * @param int $id
9756
     *
9757
     * @return bool
9758
     */
9759
    private static function allowed($id)
9760
    {
9761
        $sessionInfo = self::fetch($id);
9762
9763
        if (empty($sessionInfo)) {
9764
            return false;
9765
        }
9766
9767
        if (api_is_platform_admin()) {
9768
            return true;
9769
        }
9770
9771
        $userId = api_get_user_id();
9772
9773
        if (api_is_session_admin() &&
9774
            api_get_setting('allow_session_admins_to_manage_all_sessions') != 'true'
9775
        ) {
9776
            if ($sessionInfo['session_admin_id'] != $userId) {
9777
                return false;
9778
            }
9779
        }
9780
9781
        if (api_is_teacher() &&
9782
            api_get_setting('allow_teachers_to_create_sessions') == 'true'
9783
        ) {
9784
            if ($sessionInfo['id_coach'] != $userId) {
9785
                return false;
9786
            }
9787
        }
9788
9789
        return true;
9790
    }
9791
9792
    /**
9793
     * Add classes (by their names) to a session.
9794
     *
9795
     * @param int   $sessionId
9796
     * @param array $classesNames
9797
     * @param bool  $deleteClassSessions Optional. Empty the session list for the usergroup (class)
9798
     */
9799
    private static function addClassesByName($sessionId, $classesNames, $deleteClassSessions = true)
9800
    {
9801
        if (!$classesNames) {
9802
            return;
9803
        }
9804
9805
        $usergroup = new UserGroup();
9806
9807
        foreach ($classesNames as $className) {
9808
            if (empty($className)) {
9809
                continue;
9810
            }
9811
9812
            $usergroup->subscribe_sessions_to_usergroup(
9813
                $usergroup->getIdByName($className),
9814
                [$sessionId],
9815
                $deleteClassSessions
9816
            );
9817
        }
9818
    }
9819
9820
    /**
9821
     * @param array $listA
9822
     * @param array $listB
9823
     *
9824
     * @return int
9825
     */
9826
    private static function compareCatSessionInfo($listA, $listB)
9827
    {
9828
        if ($listA['sessionName'] == $listB['sessionName']) {
9829
            return 0;
9830
        } elseif ($listA['sessionName'] > $listB['sessionName']) {
9831
            return 1;
9832
        } else {
9833
            return -1;
9834
        }
9835
    }
9836
9837
    /**
9838
     * @param array $listA
9839
     * @param array $listB
9840
     *
9841
     * @return int
9842
     */
9843
    private static function compareBySessionName($listA, $listB)
9844
    {
9845
        if ('' == $listB['catSessionName']) {
9846
            return -1;
9847
        } elseif ('' == $listA['catSessionName']) {
9848
            return 1;
9849
        } elseif ($listA['catSessionName'] == $listB['catSessionName']) {
9850
            return 0;
9851
        } elseif ($listA['catSessionName'] > $listB['catSessionName']) {
9852
            return 1;
9853
        } else {
9854
            return -1;
9855
        }
9856
    }
9857
9858
    /**
9859
     * @param array $listA
9860
     * @param array $listB
9861
     *
9862
     * @return int
9863
     */
9864
    private static function compareByUserCourseCat($listA, $listB)
9865
    {
9866
        if ($listA['courseInUserCategoryTitle'] == $listB['courseInUserCategoryTitle']) {
9867
            return 0;
9868
        } elseif ($listA['courseInUserCategoryTitle'] > $listB['courseInUserCategoryTitle']) {
9869
            return 1;
9870
        } else {
9871
            return -1;
9872
        }
9873
    }
9874
9875
    /**
9876
     * @param array $listA
9877
     * @param array $listB
9878
     *
9879
     * @return int
9880
     */
9881
    private static function compareByCourse($listA, $listB)
9882
    {
9883
        if ($listA['title'] == $listB['title']) {
9884
            return 0;
9885
        } elseif ($listA['title'] > $listB['title']) {
9886
            return 1;
9887
        } else {
9888
            return -1;
9889
        }
9890
    }
9891
}
9892