SessionManager::getUserSession()   A
last analyzed

Complexity

Conditions 4
Paths 3

Size

Total Lines 19
Code Lines 12

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 4
eloc 12
nc 3
nop 2
dl 0
loc 19
rs 9.8666
c 0
b 0
f 0
1
<?php
2
3
/* For licensing terms, see /license.txt */
4
5
use Chamilo\CoreBundle\Component\HTMLPurifier\Filter\RemoveOnAttributes;
6
use Chamilo\CoreBundle\Entity\Course;
7
use Chamilo\CoreBundle\Entity\ExtraField;
8
use Chamilo\CoreBundle\Entity\Repository\SequenceResourceRepository;
9
use Chamilo\CoreBundle\Entity\SequenceResource;
10
use Chamilo\CoreBundle\Entity\Session;
11
use Chamilo\CoreBundle\Entity\SessionRelCourse;
12
use Chamilo\CoreBundle\Entity\SessionRelCourseRelUser;
13
use Chamilo\CoreBundle\Entity\SessionRelUser;
14
use Chamilo\UserBundle\Entity\User;
15
use ExtraField as ExtraFieldModel;
16
use Monolog\Logger;
17
18
/**
19
 * Class SessionManager.
20
 *
21
 * This is the session library for Chamilo
22
 * (as in courses>session, not as in PHP session)
23
 * All main sessions functions should be placed here.
24
 * This class provides methods for sessions management.
25
 * Include/require it in your code to use its features.
26
 */
27
class SessionManager
28
{
29
    public const STATUS_PLANNED = 1;
30
    public const STATUS_PROGRESS = 2;
31
    public const STATUS_FINISHED = 3;
32
    public const STATUS_CANCELLED = 4;
33
34
    public static $_debug = false;
35
36
    /**
37
     * Constructor.
38
     */
39
    public function __construct()
40
    {
41
    }
42
43
    /**
44
     * Fetches a session from the database.
45
     *
46
     * @param int $id Session Id
47
     *
48
     * @return array Session details
49
     */
50
    public static function fetch($id)
51
    {
52
        $em = Database::getManager();
53
54
        if (empty($id)) {
55
            return [];
56
        }
57
58
        /** @var Session $session */
59
        $session = $em->find('ChamiloCoreBundle:Session', $id);
60
61
        if (!$session) {
0 ignored issues
show
introduced by
$session is of type Chamilo\CoreBundle\Entity\Session, thus it always evaluated to true.
Loading history...
62
            return [];
63
        }
64
65
        $result = [
66
            'id' => $session->getId(),
67
            'id_coach' => $session->getGeneralCoach() ? $session->getGeneralCoach()->getId() : null,
68
            'session_category_id' => $session->getCategory() ? $session->getCategory()->getId() : null,
69
            'name' => $session->getName(),
70
            'description' => $session->getDescription(),
71
            'show_description' => $session->getShowDescription(),
72
            'duration' => $session->getDuration(),
73
            'nbr_courses' => $session->getNbrCourses(),
74
            'nbr_users' => $session->getNbrUsers(),
75
            'nbr_classes' => $session->getNbrClasses(),
76
            'session_admin_id' => $session->getSessionAdminId(),
77
            'visibility' => $session->getVisibility(),
78
            'promotion_id' => $session->getPromotionId(),
79
            'display_start_date' => $session->getDisplayStartDate()
80
                ? $session->getDisplayStartDate()->format('Y-m-d H:i:s')
81
                : null,
82
            'display_end_date' => $session->getDisplayEndDate()
83
                ? $session->getDisplayEndDate()->format('Y-m-d H:i:s')
84
                : null,
85
            'access_start_date' => $session->getAccessStartDate()
86
                ? $session->getAccessStartDate()->format('Y-m-d H:i:s')
87
                : null,
88
            'access_end_date' => $session->getAccessEndDate()
89
                ? $session->getAccessEndDate()->format('Y-m-d H:i:s')
90
                : null,
91
            'coach_access_start_date' => $session->getCoachAccessStartDate()
92
                ? $session->getCoachAccessStartDate()->format('Y-m-d H:i:s')
93
                : null,
94
            'coach_access_end_date' => $session->getCoachAccessEndDate()
95
                ? $session->getCoachAccessEndDate()->format('Y-m-d H:i:s')
96
                : null,
97
            'send_subscription_notification' => $session->getSendSubscriptionNotification(),
98
        ];
99
100
        if (api_get_configuration_value('allow_session_status')) {
101
            $table = Database::get_main_table(TABLE_MAIN_SESSION);
102
            $sql = "SELECT status FROM $table WHERE id = $id";
103
            $resultQuery = Database::query($sql);
104
            $row = Database::fetch_array($resultQuery);
105
            $result['status'] = $row['status'];
106
            $result['status_label'] = self::getStatusLabel($row['status']);
107
        }
108
109
        // Converted to local values
110
        $variables = [
111
            'display_start_date',
112
            'display_end_date',
113
            'access_start_date',
114
            'access_end_date',
115
            'coach_access_start_date',
116
            'coach_access_end_date',
117
        ];
118
119
        foreach ($variables as $value) {
120
            $result[$value.'_to_local_time'] = null;
121
            if (!empty($result[$value])) {
122
                $result[$value.'_to_local_time'] = api_get_local_time($result[$value]);
123
            }
124
        }
125
126
        return $result;
127
    }
128
129
    /**
130
     * Create a session.
131
     *
132
     * @author Carlos Vargas <[email protected]>, from existing code
133
     *
134
     * @param string $name
135
     * @param string $startDate                    (YYYY-MM-DD hh:mm:ss)
136
     * @param string $endDate                      (YYYY-MM-DD hh:mm:ss)
137
     * @param string $displayStartDate             (YYYY-MM-DD hh:mm:ss)
138
     * @param string $displayEndDate               (YYYY-MM-DD hh:mm:ss)
139
     * @param string $coachStartDate               (YYYY-MM-DD hh:mm:ss)
140
     * @param string $coachEndDate                 (YYYY-MM-DD hh:mm:ss)
141
     * @param mixed  $coachId                      If int, this is the session coach id,
142
     *                                             if string, the coach ID will be looked for from the user table
143
     * @param int    $sessionCategoryId            ID of the session category in which this session is registered
144
     * @param int    $visibility                   Visibility after end date (0 = read-only, 1 = invisible, 2 =
145
     *                                             accessible)
146
     * @param bool   $fixSessionNameIfExists
147
     * @param string $duration
148
     * @param string $description                  Optional. The session description
149
     * @param int    $showDescription              Optional. Whether show the session description
150
     * @param array  $extraFields
151
     * @param int    $sessionAdminId               Optional. If this sessions was created by a session admin, assign it
152
     *                                             to him
153
     * @param bool   $sendSubscriptionNotification Optional.
154
     *                                             Whether send a mail notification to users being subscribed
155
     * @param int    $accessUrlId                  Optional.
156
     * @param int    $status
157
     *
158
     * @return mixed Session ID on success, error message otherwise
159
     *
160
     * @todo   use an array to replace all this parameters or use the model.lib.php ...
161
     */
162
    public static function create_session(
163
        $name,
164
        $startDate,
165
        $endDate,
166
        $displayStartDate,
167
        $displayEndDate,
168
        $coachStartDate,
169
        $coachEndDate,
170
        $coachId,
171
        $sessionCategoryId,
172
        $visibility = 1,
173
        $fixSessionNameIfExists = false,
174
        $duration = null,
175
        $description = null,
176
        $showDescription = 0,
177
        $extraFields = [],
178
        $sessionAdminId = 0,
179
        $sendSubscriptionNotification = false,
180
        $accessUrlId = 0,
181
        $status = 0
182
    ) {
183
        global $_configuration;
184
185
        // Check portal limits
186
        $accessUrlId = api_is_multiple_url_enabled()
187
            ? (empty($accessUrlId) ? api_get_current_access_url_id() : (int) $accessUrlId)
188
            : 1;
189
190
        if (isset($_configuration[$accessUrlId]) &&
191
            is_array($_configuration[$accessUrlId]) &&
192
            isset($_configuration[$accessUrlId]['hosting_limit_sessions']) &&
193
            $_configuration[$accessUrlId]['hosting_limit_sessions'] > 0
194
        ) {
195
            $num = self::count_sessions();
196
            if ($num >= $_configuration[$accessUrlId]['hosting_limit_sessions']) {
197
                api_warn_hosting_contact('hosting_limit_sessions');
198
199
                return get_lang('PortalSessionsLimitReached');
200
            }
201
        }
202
203
        $name = Database::escape_string(trim($name));
204
        $sessionCategoryId = (int) $sessionCategoryId;
205
        $visibility = (int) $visibility;
206
        $tbl_session = Database::get_main_table(TABLE_MAIN_SESSION);
207
208
        $startDate = Database::escape_string($startDate);
209
        $endDate = Database::escape_string($endDate);
210
211
        if (empty($name)) {
212
            $msg = get_lang('SessionNameIsRequired');
213
214
            return $msg;
215
        } elseif (!empty($startDate) && !api_is_valid_date($startDate, 'Y-m-d H:i') &&
216
            !api_is_valid_date($startDate, 'Y-m-d H:i:s')
217
        ) {
218
            $msg = get_lang('InvalidStartDate');
219
220
            return $msg;
221
        } elseif (!empty($endDate) && !api_is_valid_date($endDate, 'Y-m-d H:i') &&
222
            !api_is_valid_date($endDate, 'Y-m-d H:i:s')
223
        ) {
224
            $msg = get_lang('InvalidEndDate');
225
226
            return $msg;
227
        } elseif (!empty($startDate) && !empty($endDate) && $startDate >= $endDate) {
228
            $msg = get_lang('StartDateShouldBeBeforeEndDate');
229
230
            return $msg;
231
        } else {
232
            $ready_to_create = false;
233
            if ($fixSessionNameIfExists) {
234
                $name = self::generateNextSessionName($name);
235
                if ($name) {
236
                    $ready_to_create = true;
237
                } else {
238
                    $msg = get_lang('SessionNameAlreadyExists');
239
240
                    return $msg;
241
                }
242
            } else {
243
                $rs = Database::query("SELECT 1 FROM $tbl_session WHERE name='".$name."'");
244
                if (Database::num_rows($rs)) {
245
                    $msg = get_lang('SessionNameAlreadyExists');
246
247
                    return $msg;
248
                }
249
                $ready_to_create = true;
250
            }
251
252
            if ($ready_to_create) {
253
                $sessionAdminId = !empty($sessionAdminId) ? $sessionAdminId : api_get_user_id();
254
                $values = [
255
                    'name' => $name,
256
                    'id_coach' => $coachId,
257
                    'session_admin_id' => $sessionAdminId,
258
                    'visibility' => $visibility,
259
                    'description' => $description,
260
                    'show_description' => $showDescription,
261
                    'send_subscription_notification' => (int) $sendSubscriptionNotification,
262
                ];
263
264
                if (!empty($startDate)) {
265
                    $values['access_start_date'] = api_get_utc_datetime($startDate);
266
                }
267
268
                if (!empty($endDate)) {
269
                    $values['access_end_date'] = api_get_utc_datetime($endDate);
270
                }
271
272
                if (!empty($displayStartDate)) {
273
                    $values['display_start_date'] = api_get_utc_datetime($displayStartDate);
274
                }
275
276
                if (!empty($displayEndDate)) {
277
                    $values['display_end_date'] = api_get_utc_datetime($displayEndDate);
278
                }
279
280
                if (!empty($coachStartDate)) {
281
                    $values['coach_access_start_date'] = api_get_utc_datetime($coachStartDate);
282
                }
283
                if (!empty($coachEndDate)) {
284
                    $values['coach_access_end_date'] = api_get_utc_datetime($coachEndDate);
285
                }
286
287
                if (!empty($sessionCategoryId)) {
288
                    $values['session_category_id'] = $sessionCategoryId;
289
                }
290
291
                if (api_get_configuration_value('allow_session_status')) {
292
                    $values['status'] = $status;
293
                }
294
295
                $session_id = Database::insert($tbl_session, $values);
296
                $duration = (int) $duration;
297
298
                if (!empty($duration)) {
299
                    $sql = "UPDATE $tbl_session SET
300
                        access_start_date = NULL,
301
                        access_end_date = NULL,
302
                        display_start_date = NULL,
303
                        display_end_date = NULL,
304
                        coach_access_start_date = NULL,
305
                        coach_access_end_date = NULL,
306
                        duration = $duration
307
                    WHERE id = $session_id";
308
                    Database::query($sql);
309
                } else {
310
                    $sql = "UPDATE $tbl_session
311
                        SET duration = 0
312
                        WHERE id = $session_id";
313
                    Database::query($sql);
314
                }
315
316
                if (!empty($session_id)) {
317
                    $extraFields['item_id'] = $session_id;
318
                    $sessionFieldValue = new ExtraFieldValue('session');
319
                    $sessionFieldValue->saveFieldValues($extraFields);
320
321
                    // Adding to the correct URL
322
                    UrlManager::add_session_to_url($session_id, $accessUrlId);
323
324
                    // add event to system log
325
                    Event::addEvent(
326
                        LOG_SESSION_CREATE,
327
                        LOG_SESSION_ID,
328
                        $session_id,
329
                        api_get_utc_datetime(),
330
                        api_get_user_id()
331
                    );
332
                }
333
334
                return $session_id;
335
            }
336
        }
337
    }
338
339
    /**
340
     * @param string $name
341
     *
342
     * @return bool
343
     */
344
    public static function sessionNameExists($name)
345
    {
346
        $name = Database::escape_string($name);
347
        $sql = "SELECT COUNT(*) as count FROM ".Database::get_main_table(TABLE_MAIN_SESSION)."
348
                WHERE name = '$name'";
349
        $result = Database::fetch_array(Database::query($sql));
350
351
        return $result['count'] > 0;
352
    }
353
354
    /**
355
     * @param string $where_condition
356
     *
357
     * @return mixed
358
     */
359
    public static function get_count_admin($where_condition = '')
360
    {
361
        $tbl_session = Database::get_main_table(TABLE_MAIN_SESSION);
362
        $tbl_session_category = Database::get_main_table(TABLE_MAIN_SESSION_CATEGORY);
363
        $tbl_user = Database::get_main_table(TABLE_MAIN_USER);
364
        $table_access_url_rel_session = Database::get_main_table(TABLE_MAIN_ACCESS_URL_REL_SESSION);
365
        $tbl_session_rel_user = Database::get_main_table(TABLE_MAIN_SESSION_USER);
366
367
        $where = 'WHERE 1=1 ';
368
        $user_id = api_get_user_id();
369
        $extraJoin = '';
370
371
        if (api_is_session_admin() &&
372
            api_get_setting('allow_session_admins_to_manage_all_sessions') == 'false'
373
        ) {
374
            $where .= " AND (
375
                            s.session_admin_id = $user_id  OR
376
                            sru.user_id = '$user_id' AND
377
                            sru.relation_type = '".SESSION_RELATION_TYPE_RRHH."'
378
                            )
379
                      ";
380
381
            $extraJoin = " INNER JOIN $tbl_session_rel_user sru
382
                           ON sru.session_id = s.id ";
383
        }
384
385
        $today = api_get_utc_datetime();
386
        $today = api_strtotime($today, 'UTC');
387
        $today = date('Y-m-d', $today);
388
389
        if (!empty($where_condition)) {
390
            $where_condition = str_replace("(  session_active = ':'  )", '1=1', $where_condition);
391
392
            $where_condition = str_replace('category_name', 'sc.name', $where_condition);
393
            $where_condition = str_replace(
394
                ["AND session_active = '1'  )", " AND (  session_active = '1'  )"],
395
                [') GROUP BY s.name HAVING session_active = 1 ', " GROUP BY s.name HAVING session_active = 1 "],
396
                $where_condition
397
            );
398
            $where_condition = str_replace(
399
                ["AND session_active = '0'  )", " AND (  session_active = '0'  )"],
400
                [') GROUP BY s.name HAVING session_active = 0 ', " GROUP BY s.name HAVING session_active = '0' "],
401
                $where_condition
402
            );
403
        } else {
404
            $where_condition = " AND 1 = 1";
405
        }
406
407
        $courseCondition = null;
408
        if (strpos($where_condition, 'c.id')) {
409
            $table = Database::get_main_table(TABLE_MAIN_SESSION_COURSE);
410
            $tableCourse = Database::get_main_table(TABLE_MAIN_COURSE);
411
            $courseCondition = " INNER JOIN $table course_rel_session
412
                                 ON (s.id = course_rel_session.session_id)
413
                                 INNER JOIN $tableCourse c
414
                                 ON (course_rel_session.c_id = c.id)
415
                                ";
416
        }
417
418
        $sql = "SELECT COUNT(id) as total_rows FROM (
419
                SELECT DISTINCT
420
                 IF (
421
					(s.access_start_date <= '$today' AND '$today' <= s.access_end_date) OR
422
                    (s.access_start_date IS NULL AND s.access_end_date IS NULL ) OR
423
					(s.access_start_date <= '$today' AND s.access_end_date IS NULL) OR
424
					('$today' <= s.access_end_date AND s.access_start_date IS NULL)
425
				, 1, 0) as session_active,
426
                s.id
427
                FROM $tbl_session s
428
                LEFT JOIN $tbl_session_category sc
429
                ON s.session_category_id = sc.id
430
                INNER JOIN $tbl_user u
431
                ON s.id_coach = u.id
432
                $courseCondition
433
                $extraJoin
434
                $where $where_condition ) as session_table";
435
436
        if (api_is_multiple_url_enabled()) {
437
            $access_url_id = api_get_current_access_url_id();
438
            if ($access_url_id != -1) {
439
                $where .= " AND ar.access_url_id = $access_url_id ";
440
441
                $sql = "SELECT count(id) as total_rows FROM (
442
                SELECT DISTINCT
443
                  IF (
444
					(s.access_start_date <= '$today' AND '$today' <= s.access_end_date) OR
445
                    (s.access_start_date IS NULL AND s.access_end_date IS NULL) OR
446
					(s.access_start_date <= '$today' AND s.access_end_date IS NULL) OR
447
					('$today' <= s.access_end_date AND s.access_start_date IS NULL)
448
				, 1, 0)
449
				as session_active,
450
				s.id
451
                FROM $tbl_session s
452
                    LEFT JOIN  $tbl_session_category sc
453
                    ON s.session_category_id = sc.id
454
                    INNER JOIN $tbl_user u ON s.id_coach = u.user_id
455
                    INNER JOIN $table_access_url_rel_session ar
456
                    ON ar.session_id = s.id
457
                    $courseCondition
458
                    $extraJoin
459
                $where $where_condition) as session_table";
460
            }
461
        }
462
463
        $result_rows = Database::query($sql);
464
        $row = Database::fetch_array($result_rows);
465
        $num = $row['total_rows'];
466
467
        return $num;
468
    }
469
470
    /**
471
     * Get session list for a session admin or platform admin.
472
     *
473
     * @param int    $userId   User Id for the session admin.
474
     * @param array  $options  Order and limit keys.
475
     * @param bool   $getCount Whether to get all the results or only the count.
476
     * @param array  $columns  Columns from jqGrid.
477
     * @param string $listType
478
     *
479
     * @return array
480
     */
481
    public static function getSessionsForAdmin(
482
        $userId,
483
        $options = [],
484
        $getCount = false,
485
        $columns = [],
486
        $listType = 'all'
487
    ) {
488
        $tblSession = Database::get_main_table(TABLE_MAIN_SESSION);
489
        $sessionCategoryTable = Database::get_main_table(TABLE_MAIN_SESSION_CATEGORY);
490
491
        $where = 'WHERE 1 = 1 ';
492
493
        $userId = (int) $userId;
494
495
        if (!api_is_platform_admin() && !api_is_session_admin() && !api_is_teacher()) {
496
            api_not_allowed(true);
497
        }
498
499
        if (!api_is_platform_admin()) {
500
            if (api_is_session_admin() &&
501
                'false' === api_get_setting('allow_session_admins_to_manage_all_sessions')
502
            ) {
503
                $where .= " AND s.session_admin_id = $userId ";
504
            }
505
        }
506
507
        if (!api_is_platform_admin() &&
508
            api_is_teacher() &&
509
            'true' === api_get_setting('allow_teachers_to_create_sessions')
510
        ) {
511
            $where .= " AND s.id_coach = $userId ";
512
        }
513
514
        $extraFieldModel = new ExtraFieldModel('session');
515
        $conditions = $extraFieldModel->parseConditions($options);
516
517
        $sqlInjectJoins = $conditions['inject_joins'];
518
        $where .= $conditions['where'];
519
        $sqlInjectWhere = $conditions['inject_where'];
520
        $injectExtraFields = $conditions['inject_extra_fields'];
521
        $order = $conditions['order'];
522
        $limit = $conditions['limit'];
523
524
        $isMakingOrder = false;
525
        $showCountUsers = false;
526
527
        if (true === $getCount) {
528
            $select = ' SELECT count(DISTINCT s.id) as total_rows ';
529
        } else {
530
            if (!empty($columns['column_model'])) {
531
                foreach ($columns['column_model'] as $column) {
532
                    if ('users' == $column['name']) {
533
                        $showCountUsers = true;
534
                    }
535
                }
536
            }
537
538
            $select =
539
                "SELECT DISTINCT
540
                     s.name,
541
                     s.display_start_date,
542
                     s.display_end_date,
543
                     access_start_date,
544
                     access_end_date,
545
                     s.visibility,
546
                     s.session_category_id,
547
                     $injectExtraFields
548
                     s.id
549
             ";
550
551
            if ($showCountUsers) {
552
                $select .= ', count(su.user_id) users';
553
            }
554
555
            if (api_get_configuration_value('allow_session_status')) {
556
                $select .= ', status';
557
            }
558
559
            if (isset($options['order'])) {
560
                $isMakingOrder = 0 === strpos($options['order'], 'category_name');
561
            }
562
        }
563
564
        $isFilteringSessionCategory = strpos($where, 'category_name') !== false;
565
        $isFilteringSessionCategoryWithName = strpos($where, 'sc.name') !== false;
566
567
        if ($isMakingOrder || $isFilteringSessionCategory || $isFilteringSessionCategoryWithName) {
568
            $sqlInjectJoins .= " LEFT JOIN $sessionCategoryTable sc ON s.session_category_id = sc.id ";
569
570
            if ($isFilteringSessionCategory) {
571
                $where = str_replace('category_name', 'sc.name', $where);
572
            }
573
574
            if ($isMakingOrder) {
575
                $order = str_replace('category_name', 'sc.name', $order);
576
            }
577
        }
578
579
        if ($showCountUsers) {
580
            $tblSessionRelUser = Database::get_main_table(TABLE_MAIN_SESSION_USER);
581
            $sqlInjectJoins .= " LEFT JOIN $tblSessionRelUser su ON (su.session_id = s.id)";
582
        }
583
584
        $query = "$select FROM $tblSession s $sqlInjectJoins $where $sqlInjectWhere";
585
586
        if (api_is_multiple_url_enabled()) {
587
            $tblAccessUrlRelSession = Database::get_main_table(TABLE_MAIN_ACCESS_URL_REL_SESSION);
588
            $accessUrlId = api_get_current_access_url_id();
589
590
            if ($accessUrlId != -1) {
591
                $where .= " AND ar.access_url_id = $accessUrlId ";
592
                $query = "$select
593
                    FROM $tblSession s $sqlInjectJoins
594
                    INNER JOIN $tblAccessUrlRelSession ar
595
                    ON (ar.session_id = s.id) $where";
596
            }
597
        }
598
599
        $date = api_get_utc_datetime();
600
601
        switch ($listType) {
602
            case 'all':
603
                break;
604
            case 'active':
605
                $query .= "AND (
606
                    (s.access_end_date IS NULL)
607
                    OR
608
                    (
609
                    s.access_start_date IS NOT NULL AND
610
                    s.access_end_date IS NOT NULL AND
611
                    s.access_start_date <= '$date' AND s.access_end_date >= '$date')
612
                    OR
613
                    (
614
                        s.access_start_date IS NULL AND
615
                        s.access_end_date IS NOT NULL AND
616
                        s.access_end_date >= '$date'
617
                    )
618
                )";
619
                break;
620
            case 'close':
621
                $query .= "AND (
622
                    (
623
                    s.access_start_date IS NOT NULL AND
624
                    s.access_end_date IS NOT NULL AND
625
                    s.access_start_date <= '$date' AND s.access_end_date <= '$date')
626
                    OR
627
                    (
628
                        s.access_start_date IS NULL AND
629
                        s.access_end_date IS NOT NULL AND
630
                        s.access_end_date <= '$date'
631
                    )
632
                )";
633
                break;
634
        }
635
636
        if ($showCountUsers) {
637
            $query .= ' GROUP by s.id';
638
        }
639
640
        $allowOrder = api_get_configuration_value('session_list_order');
641
642
        if ($allowOrder) {
643
            $order = ' ORDER BY position ASC';
644
        }
645
646
        $query .= $order;
647
        $query .= $limit;
648
        $result = Database::query($query);
649
650
        $sessions = Database::store_result($result, 'ASSOC');
651
652
        if ('all' === $listType) {
653
            if ($getCount) {
654
                return $sessions[0]['total_rows'];
655
            }
656
657
            return $sessions;
658
        }
659
660
        return $sessions;
661
    }
662
663
    /**
664
     * Gets the admin session list callback of the session/session_list.php page.
665
     *
666
     * @param array  $options           order and limit keys
667
     * @param bool   $getCount          Whether to get all the results or only the count
668
     * @param array  $columns
669
     * @param array  $extraFieldsToLoad
670
     * @param string $listType
671
     *
672
     * @return mixed Integer for number of rows, or array of results
673
     * @assert ([],true) !== false
674
     */
675
    public static function formatSessionsAdminForGrid(
676
        $options = [],
677
        $getCount = false,
678
        $columns = [],
679
        $extraFieldsToLoad = [],
680
        $listType = 'all'
681
    ) {
682
        $showCountUsers = false;
683
        if (!$getCount && !empty($columns['column_model'])) {
684
            foreach ($columns['column_model'] as $column) {
685
                if ('users' === $column['name']) {
686
                    $showCountUsers = true;
687
                }
688
            }
689
        }
690
691
        $userId = api_get_user_id();
692
        $sessions = self::getSessionsForAdmin($userId, $options, $getCount, $columns, $listType);
693
        if ($getCount) {
694
            return (int) $sessions;
695
        }
696
697
        $formattedSessions = [];
698
        $categories = self::get_all_session_category();
699
        $orderedCategories = [];
700
        if (!empty($categories)) {
701
            foreach ($categories as $category) {
702
                $orderedCategories[$category['id']] = $category['name'];
703
            }
704
        }
705
706
        $activeIcon = Display::return_icon('accept.png', get_lang('Active'));
707
        $inactiveIcon = Display::return_icon('error.png', get_lang('Inactive'));
708
        $webPath = api_get_path(WEB_PATH);
709
710
        foreach ($sessions as $session) {
711
            if ($showCountUsers) {
712
                $session['users'] = self::get_users_by_session($session['id'], 0, true);
713
            }
714
            $url = $webPath.'main/session/resume_session.php?id_session='.$session['id'];
715
            if ($extraFieldsToLoad || api_is_drh()) {
716
                $url = $webPath.'session/'.$session['id'].'/about/';
717
            }
718
719
            $session['name'] = Display::url($session['name'], $url);
720
721
            if (!empty($extraFieldsToLoad)) {
722
                foreach ($extraFieldsToLoad as $field) {
723
                    $extraFieldValue = new ExtraFieldValue('session');
724
                    $fieldData = $extraFieldValue->getAllValuesByItemAndField(
725
                        $session['id'],
726
                        $field['id']
727
                    );
728
                    $fieldDataArray = [];
729
                    $fieldDataToString = '';
730
                    if (!empty($fieldData)) {
731
                        foreach ($fieldData as $data) {
732
                            $fieldDataArray[] = $data['value'];
733
                        }
734
                        $fieldDataToString = implode(', ', $fieldDataArray);
735
                    }
736
                    $session[$field['variable']] = $fieldDataToString;
737
                }
738
            }
739
            if (isset($session['session_active']) && $session['session_active'] == 1) {
740
                $session['session_active'] = $activeIcon;
741
            } else {
742
                $session['session_active'] = $inactiveIcon;
743
            }
744
745
            $session = self::convert_dates_to_local($session, true);
746
747
            switch ($session['visibility']) {
748
                case SESSION_VISIBLE_READ_ONLY: //1
749
                    $session['visibility'] = get_lang('ReadOnly');
750
                    break;
751
                case SESSION_VISIBLE:           //2
752
                case SESSION_AVAILABLE:         //4
753
                    $session['visibility'] = get_lang('Visible');
754
                    break;
755
                case SESSION_INVISIBLE:         //3
756
                    $session['visibility'] = api_ucfirst(get_lang('Invisible'));
757
                    break;
758
            }
759
760
            // Cleaning double selects.
761
            foreach ($session as $key => &$value) {
762
                if (isset($optionsByDouble[$key]) || isset($optionsByDouble[$key.'_second'])) {
763
                    $options = explode('::', $value);
764
                }
765
                $original_key = $key;
766
                if (strpos($key, '_second') !== false) {
767
                    $key = str_replace('_second', '', $key);
768
                }
769
770
                if (isset($optionsByDouble[$key]) &&
771
                    isset($options[0]) &&
772
                    isset($optionsByDouble[$key][$options[0]])
773
                ) {
774
                    if (strpos($original_key, '_second') === false) {
775
                        $value = $optionsByDouble[$key][$options[0]]['option_display_text'];
776
                    } else {
777
                        $value = $optionsByDouble[$key][$options[1]]['option_display_text'];
778
                    }
779
                }
780
            }
781
782
            $categoryName = isset($orderedCategories[$session['session_category_id']]) ? $orderedCategories[$session['session_category_id']] : '';
783
            $session['category_name'] = $categoryName;
784
            if (isset($session['status'])) {
785
                $session['status'] = self::getStatusLabel($session['status']);
786
            }
787
788
            $formattedSessions[] = $session;
789
        }
790
791
        return $formattedSessions;
792
    }
793
794
    /**
795
     * Gets the progress of learning paths in the given session.
796
     *
797
     * @param int    $sessionId
798
     * @param int    $courseId
799
     * @param string $date_from
800
     * @param string $date_to
801
     * @param array options order and limit keys
802
     *
803
     * @return array table with user name, lp name, progress
804
     */
805
    public static function get_session_lp_progress(
806
        $sessionId,
807
        $courseId,
808
        $date_from,
809
        $date_to,
810
        $options
811
    ) {
812
        //escaping vars
813
        $sessionId = $sessionId === 'T' ? 'T' : intval($sessionId);
814
        $courseId = intval($courseId);
815
816
        //tables
817
        $session_course_user = Database::get_main_table(TABLE_MAIN_SESSION_COURSE_USER);
818
        $user = Database::get_main_table(TABLE_MAIN_USER);
819
        $tbl_course_lp_view = Database::get_course_table(TABLE_LP_VIEW);
820
821
        $course = api_get_course_info_by_id($courseId);
822
        $sessionCond = 'and session_id = %s';
823
        if ($sessionId === 'T') {
824
            $sessionCond = '';
825
        }
826
827
        $where = " WHERE c_id = '%s' AND s.status <> 2 $sessionCond";
828
829
        $limit = null;
830
        if (!empty($options['limit'])) {
831
            $limit = " LIMIT ".$options['limit'];
832
        }
833
834
        if (!empty($options['where'])) {
835
            $where .= ' '.$options['where'];
836
        }
837
838
        $order = null;
839
        if (!empty($options['order'])) {
840
            $order = " ORDER BY ".$options['order']." ";
841
        }
842
843
        $sql = "SELECT u.id as user_id, u.lastname, u.firstname, u.username, u.email, s.c_id
844
                FROM $session_course_user s
845
                INNER JOIN $user u ON u.id = s.user_id
846
                $where
847
                $order
848
                $limit";
849
850
        $sql_query = sprintf($sql, Database::escape_string($course['real_id']), $sessionId);
851
852
        $rs = Database::query($sql_query);
853
        while ($user = Database::fetch_array($rs)) {
854
            $users[$user['user_id']] = $user;
855
        }
856
857
        // Get lessons
858
        $lessons = LearnpathList::get_course_lessons($course['code'], $sessionId);
859
860
        $table = [];
861
        foreach ($users as $user) {
862
            $data = [
863
                'lastname' => $user[1],
864
                'firstname' => $user[2],
865
                'username' => $user[3],
866
            ];
867
868
            $sessionCond = 'AND v.session_id = %d';
869
            if ($sessionId == 'T') {
870
                $sessionCond = "";
871
            }
872
873
            //Get lessons progress by user
874
            $sql = "SELECT v.lp_id as id, v.progress
875
                    FROM  $tbl_course_lp_view v
876
                    WHERE v.c_id = %d
877
                    AND v.user_id = %d
878
            $sessionCond";
879
880
            $sql_query = sprintf(
881
                $sql,
882
                intval($courseId),
883
                intval($user['user_id']),
884
                $sessionId
885
            );
886
887
            $result = Database::query($sql_query);
888
889
            $user_lessons = [];
890
            while ($row = Database::fetch_array($result)) {
891
                $user_lessons[$row['id']] = $row;
892
            }
893
894
            //Match course lessons with user progress
895
            $progress = 0;
896
            $count = 0;
897
            foreach ($lessons as $lesson) {
898
                $data[$lesson['id']] = (!empty($user_lessons[$lesson['id']]['progress'])) ? $user_lessons[$lesson['id']]['progress'] : 0;
899
                $progress += $data[$lesson['id']];
900
                $data[$lesson['id']] = $data[$lesson['id']].'%';
901
                $count++;
902
            }
903
            if ($count == 0) {
904
                $data['total'] = 0;
905
            } else {
906
                $data['total'] = round($progress / $count, 2).'%';
907
            }
908
            $table[] = $data;
909
        }
910
911
        return $table;
912
    }
913
914
    /**
915
     * Gets the survey answers.
916
     *
917
     * @param int $sessionId
918
     * @param int $courseId
919
     * @param int $surveyId
920
     * @param array options order and limit keys
921
     *
922
     * @todo fix the query
923
     *
924
     * @return array table with user name, lp name, progress
925
     */
926
    public static function get_survey_overview(
927
        $sessionId,
928
        $courseId,
929
        $surveyId,
930
        $date_from,
931
        $date_to,
932
        $options
933
    ) {
934
        //escaping vars
935
        $sessionId = intval($sessionId);
936
        $courseId = intval($courseId);
937
        $surveyId = intval($surveyId);
938
939
        //tables
940
        $session_course_user = Database::get_main_table(TABLE_MAIN_SESSION_COURSE_USER);
941
        $user = Database::get_main_table(TABLE_MAIN_USER);
942
        $c_survey = Database::get_course_table(TABLE_SURVEY);
943
        $c_survey_answer = Database::get_course_table(TABLE_SURVEY_ANSWER);
944
        $c_survey_question = Database::get_course_table(TABLE_SURVEY_QUESTION);
945
        $c_survey_question_option = Database::get_course_table(TABLE_SURVEY_QUESTION_OPTION);
946
947
        $course = api_get_course_info_by_id($courseId);
948
949
        $where = " WHERE c_id = '%s' AND s.status <> 2 AND session_id = %s";
950
951
        $limit = null;
952
        if (!empty($options['limit'])) {
953
            $limit = " LIMIT ".$options['limit'];
954
        }
955
956
        if (!empty($options['where'])) {
957
            $where .= ' '.$options['where'];
958
        }
959
960
        $order = null;
961
        if (!empty($options['order'])) {
962
            $order = " ORDER BY ".$options['order'];
963
        }
964
965
        $sql = "SELECT u.user_id, u.lastname, u.firstname, u.username, u.email, s.c_id
966
                FROM $session_course_user s
967
                INNER JOIN $user u ON u.user_id = s.user_id
968
                $where $order $limit";
969
970
        $sql_query = sprintf($sql, intval($course['real_id']), $sessionId);
971
        $rs = Database::query($sql_query);
972
        while ($user = Database::fetch_array($rs)) {
973
            $users[$user['user_id']] = $user;
974
        }
975
976
        //Get survey questions
977
        $questions = SurveyManager::get_questions($surveyId, $courseId);
978
979
        //Survey is anonymous?
980
        $result = Database::query(sprintf("SELECT anonymous FROM $c_survey WHERE survey_id = %d", $surveyId));
981
        $row = Database::fetch_array($result);
982
        $anonymous = ($row['anonymous'] == 1) ? true : false;
983
984
        $table = [];
985
        foreach ($users as $user) {
986
            $data = [
987
                'lastname' => ($anonymous ? '***' : $user[1]),
988
                'firstname' => ($anonymous ? '***' : $user[2]),
989
                'username' => ($anonymous ? '***' : $user[3]),
990
            ];
991
992
            //Get questions by user
993
            $sql = "SELECT sa.question_id, sa.option_id, sqo.option_text, sq.type
994
                    FROM $c_survey_answer sa
995
                    INNER JOIN $c_survey_question sq
996
                    ON sq.question_id = sa.question_id
997
                    LEFT JOIN $c_survey_question_option sqo
998
                    ON
999
                      sqo.c_id = sa.c_id AND
1000
                      sqo.question_id = sq.question_id AND
1001
                      sqo.question_option_id = sa.option_id AND
1002
                      sqo.survey_id = sq.survey_id
1003
                    WHERE
1004
                      sa.survey_id = %d AND
1005
                      sa.c_id = %d AND
1006
                      sa.user = %d
1007
            "; //. $where_survey;
1008
            $sql_query = sprintf($sql, $surveyId, $courseId, $user['user_id']);
1009
1010
            $result = Database::query($sql_query);
1011
1012
            $user_questions = [];
1013
            while ($row = Database::fetch_array($result)) {
1014
                $user_questions[$row['question_id']] = $row;
1015
            }
1016
1017
            //Match course lessons with user progress
1018
            foreach ($questions as $question_id => $question) {
1019
                $option_text = 'option_text';
1020
                if ($user_questions[$question_id]['type'] == 'open') {
1021
                    $option_text = 'option_id';
1022
                }
1023
                $data[$question_id] = $user_questions[$question_id][$option_text];
1024
            }
1025
1026
            $table[] = $data;
1027
        }
1028
1029
        return $table;
1030
    }
1031
1032
    /**
1033
     * Gets the progress of the given session.
1034
     *
1035
     * @param int $sessionId
1036
     * @param int $courseId
1037
     * @param array options order and limit keys
1038
     *
1039
     * @return array table with user name, lp name, progress
1040
     */
1041
    public static function get_session_progress(
1042
        $sessionId,
1043
        $courseId,
1044
        $date_from,
1045
        $date_to,
1046
        $options
1047
    ) {
1048
        $sessionId = (int) $sessionId;
1049
1050
        $getAllSessions = false;
1051
        if (empty($sessionId)) {
1052
            $sessionId = 0;
1053
            $getAllSessions = true;
1054
        }
1055
1056
        //tables
1057
        $session_course_user = Database::get_main_table(TABLE_MAIN_SESSION_COURSE_USER);
1058
        $user = Database::get_main_table(TABLE_MAIN_USER);
1059
        $workTable = Database::get_course_table(TABLE_STUDENT_PUBLICATION);
1060
        $workTableAssignment = Database::get_course_table(TABLE_STUDENT_PUBLICATION_ASSIGNMENT);
1061
        $tbl_course_lp = Database::get_course_table(TABLE_LP_MAIN);
1062
        $wiki = Database::get_course_table(TABLE_WIKI);
1063
        $table_stats_default = Database::get_main_table(TABLE_STATISTIC_TRACK_E_DEFAULT);
1064
        $table_stats_access = Database::get_main_table(TABLE_STATISTIC_TRACK_E_ACCESS);
1065
1066
        $course = api_get_course_info_by_id($courseId);
1067
        $where = " WHERE c_id = '%s' AND s.status <> 2 ";
1068
1069
        $limit = null;
1070
        if (!empty($options['limit'])) {
1071
            $limit = " LIMIT ".$options['limit'];
1072
        }
1073
1074
        if (!empty($options['where'])) {
1075
            $where .= ' '.$options['where'];
1076
        }
1077
1078
        $order = null;
1079
        if (!empty($options['order'])) {
1080
            $order = " ORDER BY ".$options['order'];
1081
        }
1082
1083
        //TODO, fix create report without session
1084
        $queryVariables = [$course['real_id']];
1085
        if (!empty($sessionId)) {
1086
            $where .= ' AND session_id = %s';
1087
            $queryVariables[] = $sessionId;
1088
            $sql = "SELECT
1089
                        u.user_id, u.lastname, u.firstname, u.username,
1090
                        u.email, s.c_id, s.session_id
1091
                    FROM $session_course_user s
1092
                    INNER JOIN $user u
1093
                    ON u.user_id = s.user_id
1094
                    $where $order $limit";
1095
        } else {
1096
            $sql = "SELECT
1097
                        u.user_id, u.lastname, u.firstname, u.username,
1098
                        u.email, s.c_id, s.session_id
1099
                    FROM $session_course_user s
1100
                    INNER JOIN $user u ON u.user_id = s.user_id
1101
                    $where $order $limit";
1102
        }
1103
1104
        $sql_query = vsprintf($sql, $queryVariables);
1105
        $rs = Database::query($sql_query);
1106
        while ($user = Database::fetch_array($rs)) {
1107
            $users[$user['user_id']] = $user;
1108
        }
1109
1110
        /**
1111
         *  Lessons.
1112
         */
1113
        $sql = "SELECT * FROM $tbl_course_lp WHERE c_id = %s "; //AND session_id = %s
1114
        $sql_query = sprintf($sql, $course['real_id']);
1115
        $result = Database::query($sql_query);
1116
        $arrLesson = [[]];
1117
        while ($row = Database::fetch_array($result)) {
1118
            if (empty($arrLesson[$row['session_id']]['lessons_total'])) {
1119
                $arrLesson[$row['session_id']]['lessons_total'] = 1;
1120
            } else {
1121
                $arrLesson[$row['session_id']]['lessons_total']++;
1122
            }
1123
        }
1124
1125
        /**
1126
         *  Exercises.
1127
         */
1128
        $exercises = ExerciseLib::get_all_exercises(
1129
            $course,
1130
            $sessionId,
1131
            false,
1132
            '',
1133
            $getAllSessions
1134
        );
1135
        $exercises_total = count($exercises);
1136
1137
        /**
1138
         *  Assignments.
1139
         */
1140
        //total
1141
        $params = [$course['real_id']];
1142
        if ($getAllSessions) {
1143
            $sql = "SELECT count(w.id) as count
1144
                    FROM $workTable w
1145
                    LEFT JOIN $workTableAssignment a
1146
                    ON (a.publication_id = w.id AND a.c_id = w.c_id)
1147
                    WHERE
1148
                        w.c_id = %s AND
1149
                        parent_id = 0 AND
1150
                        active IN (1, 0)";
1151
        } else {
1152
            $sql = "SELECT count(w.id) as count
1153
                    FROM $workTable w
1154
                    LEFT JOIN $workTableAssignment a
1155
                    ON (a.publication_id = w.id AND a.c_id = w.c_id)
1156
                    WHERE
1157
                        w.c_id = %s AND
1158
                        parent_id = 0 AND
1159
                        active IN (1, 0)";
1160
1161
            if (empty($sessionId)) {
1162
                $sql .= ' AND w.session_id = NULL ';
1163
            } else {
1164
                $sql .= ' AND w.session_id = %s ';
1165
                $params[] = $sessionId;
1166
            }
1167
        }
1168
1169
        $sql_query = vsprintf($sql, $params);
1170
        $result = Database::query($sql_query);
1171
        $row = Database::fetch_array($result);
1172
        $assignments_total = $row['count'];
1173
1174
        /**
1175
         * Wiki.
1176
         */
1177
        if ($getAllSessions) {
1178
            $sql = "SELECT count(distinct page_id)  as count FROM $wiki
1179
                    WHERE c_id = %s";
1180
        } else {
1181
            $sql = "SELECT count(distinct page_id)  as count FROM $wiki
1182
                    WHERE c_id = %s and session_id = %s";
1183
        }
1184
        $sql_query = sprintf($sql, $course['real_id'], $sessionId);
1185
        $result = Database::query($sql_query);
1186
        $row = Database::fetch_array($result);
1187
        $wiki_total = $row['count'];
1188
1189
        /**
1190
         * Surveys.
1191
         */
1192
        $survey_user_list = [];
1193
        $survey_list = SurveyManager::get_surveys($course['code'], $sessionId);
1194
1195
        $surveys_total = count($survey_list);
1196
        foreach ($survey_list as $survey) {
1197
            $user_list = SurveyManager::get_people_who_filled_survey(
1198
                $survey['survey_id'],
1199
                false,
1200
                $course['real_id']
1201
            );
1202
            foreach ($user_list as $user_id) {
1203
                isset($survey_user_list[$user_id]) ? $survey_user_list[$user_id]++ : $survey_user_list[$user_id] = 1;
1204
            }
1205
        }
1206
1207
        /**
1208
         * Forums.
1209
         */
1210
        $forums_total = CourseManager::getCountForum(
1211
            $course['real_id'],
1212
            $sessionId,
1213
            $getAllSessions
1214
        );
1215
1216
        //process table info
1217
        foreach ($users as $user) {
1218
            //Course description
1219
            $sql = "SELECT count(*) as count
1220
                    FROM $table_stats_access
1221
                    WHERE access_tool = 'course_description'
1222
                    AND c_id = '%s'
1223
                    AND access_session_id = %s
1224
                    AND access_user_id = %s ";
1225
            $sql_query = sprintf($sql, $course['real_id'], $user['id_session'], $user['user_id']);
1226
1227
            $result = Database::query($sql_query);
1228
            $row = Database::fetch_array($result);
1229
            $course_description_progress = ($row['count'] > 0) ? 100 : 0;
1230
1231
            if (!empty($arrLesson[$user['id_session']]['lessons_total'])) {
1232
                $lessons_total = $arrLesson[$user['id_session']]['lessons_total'];
1233
            } else {
1234
                $lessons_total = !empty($arrLesson[0]['lessons_total']) ? $arrLesson[0]['lessons_total'] : 0;
1235
            }
1236
1237
            //Lessons
1238
            //TODO: Lessons done and left is calculated by progress per item in lesson, maybe we should calculate it only per completed lesson?
1239
            $lessons_progress = Tracking::get_avg_student_progress(
1240
                $user['user_id'],
1241
                $course['code'],
1242
                [],
1243
                $user['id_session']
1244
            );
1245
            $lessons_done = ($lessons_progress * $lessons_total) / 100;
1246
            $lessons_left = $lessons_total - $lessons_done;
1247
1248
            // Exercises
1249
            $exercises_progress = str_replace(
1250
                '%',
1251
                '',
1252
                Tracking::get_exercise_student_progress(
1253
                    $exercises,
1254
                    $user['user_id'],
1255
                    $course['real_id'],
1256
                    $user['id_session']
1257
                )
1258
            );
1259
            $exercises_done = round(($exercises_progress * $exercises_total) / 100);
1260
            $exercises_left = $exercises_total - $exercises_done;
1261
1262
            //Assignments
1263
            $assignments_done = Tracking::count_student_assignments($user['user_id'], $course['code'], $user['id_session']);
1264
            $assignments_left = $assignments_total - $assignments_done;
1265
            if (!empty($assignments_total)) {
1266
                $assignments_progress = round((($assignments_done * 100) / $assignments_total), 2);
1267
            } else {
1268
                $assignments_progress = 0;
1269
            }
1270
1271
            // Wiki
1272
            // total revisions per user
1273
            $sql = "SELECT count(*) as count
1274
                    FROM $wiki
1275
                    WHERE c_id = %s and session_id = %s and user_id = %s";
1276
            $sql_query = sprintf($sql, $course['real_id'], $user['id_session'], $user['user_id']);
1277
            $result = Database::query($sql_query);
1278
            $row = Database::fetch_array($result);
1279
            $wiki_revisions = $row['count'];
1280
            //count visited wiki pages
1281
            $sql = "SELECT count(distinct default_value) as count
1282
                    FROM $table_stats_default
1283
                    WHERE
1284
                        default_user_id = %s AND
1285
                        default_event_type = 'wiki_page_view' AND
1286
                        default_value_type = 'wiki_page_id' AND
1287
                        c_id = %s
1288
                    ";
1289
            $sql_query = sprintf($sql, $user['user_id'], $course['real_id']);
1290
            $result = Database::query($sql_query);
1291
            $row = Database::fetch_array($result);
1292
1293
            $wiki_read = $row['count'];
1294
            $wiki_unread = $wiki_total - $wiki_read;
1295
            if (!empty($wiki_total)) {
1296
                $wiki_progress = round((($wiki_read * 100) / $wiki_total), 2);
1297
            } else {
1298
                $wiki_progress = 0;
1299
            }
1300
1301
            //Surveys
1302
            $surveys_done = (isset($survey_user_list[$user['user_id']]) ? $survey_user_list[$user['user_id']] : 0);
1303
            $surveys_left = $surveys_total - $surveys_done;
1304
            if (!empty($surveys_total)) {
1305
                $surveys_progress = round((($surveys_done * 100) / $surveys_total), 2);
1306
            } else {
1307
                $surveys_progress = 0;
1308
            }
1309
1310
            //Forums
1311
            $forums_done = CourseManager::getCountForumPerUser(
1312
                $user['user_id'],
1313
                $course['real_id'],
1314
                $user['id_session']
1315
            );
1316
            $forums_left = $forums_total - $forums_done;
1317
            if (!empty($forums_total)) {
1318
                $forums_progress = round((($forums_done * 100) / $forums_total), 2);
1319
            } else {
1320
                $forums_progress = 0;
1321
            }
1322
1323
            // Overall Total
1324
            $overall_total = ($course_description_progress + $exercises_progress + $forums_progress + $assignments_progress + $wiki_progress + $surveys_progress) / 6;
1325
1326
            $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>';
1327
            $linkForum = '<a href="'.api_get_path(WEB_CODE_PATH).'forum/index.php?cidReq='.$course['code'].'&id_session='.$user['id_session'].'"> %s </a>';
1328
            $linkWork = '<a href="'.api_get_path(WEB_CODE_PATH).'work/work.php?cidReq='.$course['code'].'&id_session='.$user['id_session'].'"> %s </a>';
1329
            $linkWiki = '<a href="'.api_get_path(WEB_CODE_PATH).'wiki/index.php?cidReq='.$course['code'].'&session_id='.$user['id_session'].'&action=statistics"> %s </a>';
1330
            $linkSurvey = '<a href="'.api_get_path(WEB_CODE_PATH).'survey/survey_list.php?cidReq='.$course['code'].'&id_session='.$user['id_session'].'"> %s </a>';
1331
1332
            $table[] = [
1333
                'lastname' => $user[1],
1334
                'firstname' => $user[2],
1335
                'username' => $user[3],
1336
                //'profile'   => '',
1337
                'total' => round($overall_total, 2).'%',
1338
                'courses' => sprintf($link, $course_description_progress.'%'),
1339
                'lessons' => sprintf($link, $lessons_progress.'%'),
1340
                'exercises' => sprintf($link, $exercises_progress.'%'),
1341
                'forums' => sprintf($link, $forums_progress.'%'),
1342
                'homeworks' => sprintf($link, $assignments_progress.'%'),
1343
                'wikis' => sprintf($link, $wiki_progress.'%'),
1344
                'surveys' => sprintf($link, $surveys_progress.'%'),
1345
                //course description
1346
                'course_description_progress' => $course_description_progress.'%',
1347
                //lessons
1348
                'lessons_total' => sprintf($link, $lessons_total),
1349
                'lessons_done' => sprintf($link, $lessons_done),
1350
                'lessons_left' => sprintf($link, $lessons_left),
1351
                'lessons_progress' => sprintf($link, $lessons_progress.'%'),
1352
                //exercises
1353
                'exercises_total' => sprintf($link, $exercises_total),
1354
                'exercises_done' => sprintf($link, $exercises_done),
1355
                'exercises_left' => sprintf($link, $exercises_left),
1356
                'exercises_progress' => sprintf($link, $exercises_progress.'%'),
1357
                //forums
1358
                'forums_total' => sprintf($linkForum, $forums_total),
1359
                'forums_done' => sprintf($linkForum, $forums_done),
1360
                'forums_left' => sprintf($linkForum, $forums_left),
1361
                'forums_progress' => sprintf($linkForum, $forums_progress.'%'),
1362
                //assignments
1363
                'assignments_total' => sprintf($linkWork, $assignments_total),
1364
                'assignments_done' => sprintf($linkWork, $assignments_done),
1365
                'assignments_left' => sprintf($linkWork, $assignments_left),
1366
                'assignments_progress' => sprintf($linkWork, $assignments_progress.'%'),
1367
                //wiki
1368
                'wiki_total' => sprintf($linkWiki, $wiki_total),
1369
                'wiki_revisions' => sprintf($linkWiki, $wiki_revisions),
1370
                'wiki_read' => sprintf($linkWiki, $wiki_read),
1371
                'wiki_unread' => sprintf($linkWiki, $wiki_unread),
1372
                'wiki_progress' => sprintf($linkWiki, $wiki_progress.'%'),
1373
                //survey
1374
                'surveys_total' => sprintf($linkSurvey, $surveys_total),
1375
                'surveys_done' => sprintf($linkSurvey, $surveys_done),
1376
                'surveys_left' => sprintf($linkSurvey, $surveys_left),
1377
                'surveys_progress' => sprintf($linkSurvey, $surveys_progress.'%'),
1378
            ];
1379
        }
1380
1381
        return $table;
1382
    }
1383
1384
    /**
1385
     * Get the ip, total of clicks, login date and time logged in for all user, in one session.
1386
     *
1387
     * @todo track_e_course_access table should have ip so we dont have to look for it in track_e_login
1388
     *
1389
     * @author César Perales <[email protected]>, Beeznest Team
1390
     *
1391
     * @version 1.9.6
1392
     */
1393
    public static function get_user_data_access_tracking_overview(
1394
        $sessionId,
1395
        $courseId = 0,
1396
        $studentId = 0,
1397
        $profile = '',
1398
        $date_from = '',
1399
        $date_to = '',
1400
        $options = []
1401
    ) {
1402
        $sessionId = intval($sessionId);
1403
        $courseId = intval($courseId);
1404
        $studentId = intval($studentId);
1405
        $profile = intval($profile);
1406
        $date_from = Database::escape_string($date_from);
1407
        $date_to = Database::escape_string($date_to);
1408
1409
        // database table definition
1410
        $user = Database::get_main_table(TABLE_MAIN_USER);
1411
        $course = Database::get_main_table(TABLE_MAIN_COURSE);
1412
        $track_e_login = Database::get_main_table(TABLE_STATISTIC_TRACK_E_LOGIN);
1413
        $track_e_course_access = Database::get_main_table(TABLE_STATISTIC_TRACK_E_COURSE_ACCESS);
1414
        $sessionTable = Database::get_main_table(TABLE_MAIN_SESSION);
1415
1416
        global $export_csv;
1417
        if ($export_csv) {
1418
            $is_western_name_order = api_is_western_name_order(PERSON_NAME_DATA_EXPORT);
1419
        } else {
1420
            $is_western_name_order = api_is_western_name_order();
1421
        }
1422
1423
        $where = null;
1424
        if (isset($sessionId) && !empty($sessionId)) {
1425
            $where = sprintf(" WHERE a.session_id = %d", $sessionId);
1426
        }
1427
        if (isset($courseId) && !empty($courseId)) {
1428
            $where .= sprintf(" AND c.id = %d", $courseId);
1429
        }
1430
        if (isset($studentId) && !empty($studentId)) {
1431
            $where .= sprintf(" AND u.user_id = %d", $studentId);
1432
        }
1433
        if (isset($profile) && !empty($profile)) {
1434
            $where .= sprintf(" AND u.status = %d", $profile);
1435
        }
1436
        if (!empty($date_to) && !empty($date_from)) {
1437
            $where .= sprintf(
1438
                " AND a.login_course_date >= '%s 00:00:00'
1439
                 AND a.login_course_date <= '%s 23:59:59'",
1440
                $date_from,
1441
                $date_to
1442
            );
1443
        }
1444
1445
        $limit = null;
1446
        if (!empty($options['limit'])) {
1447
            $limit = " LIMIT ".$options['limit'];
1448
        }
1449
1450
        if (!empty($options['where'])) {
1451
            $where .= ' '.$options['where'];
1452
        }
1453
1454
        $order = null;
1455
        if (!empty($options['order'])) {
1456
            $order = " ORDER BY ".$options['order'];
1457
        }
1458
1459
        //TODO add course name
1460
        $sql = "SELECT
1461
                a.login_course_date ,
1462
                u.username ,
1463
                ".($is_western_name_order ? "
1464
                    u.firstname,
1465
                    u.lastname,
1466
                    " : "
1467
                    u.lastname,
1468
                    u.firstname,
1469
                ")."
1470
                a.logout_course_date,
1471
                a.counter,
1472
                c.title,
1473
                c.code,
1474
                u.user_id,
1475
                a.session_id
1476
            FROM $track_e_course_access a
1477
            INNER JOIN $user u ON a.user_id = u.user_id
1478
            INNER JOIN $course c ON a.c_id = c.id
1479
            $where $order $limit";
1480
        $result = Database::query(sprintf($sql, $sessionId, $courseId));
1481
1482
        $data = [];
1483
        while ($user = Database::fetch_assoc($result)) {
1484
            $data[] = $user;
1485
        }
1486
1487
        foreach ($data as $key => $info) {
1488
            $sql = "SELECT
1489
                    name
1490
                    FROM $sessionTable
1491
                    WHERE
1492
                    id = {$info['session_id']}";
1493
            $result = Database::query($sql);
1494
            $session = Database::fetch_assoc($result);
1495
1496
            // building array to display
1497
            $return[] = [
1498
                'user_id' => $info['user_id'],
1499
                'logindate' => $info['login_course_date'],
1500
                'username' => $info['username'],
1501
                'firstname' => $info['firstname'],
1502
                'lastname' => $info['lastname'],
1503
                'clicks' => $info['counter'], //+ $clicks[$info['user_id']],
1504
                'ip' => '',
1505
                'timeLoggedIn' => gmdate("H:i:s", strtotime($info['logout_course_date']) - strtotime($info['login_course_date'])),
1506
                'session' => $session['name'],
1507
            ];
1508
        }
1509
1510
        foreach ($return as $key => $info) {
1511
            //Search for ip, we do less querys if we iterate the final array
1512
            $sql = sprintf(
1513
                "SELECT user_ip FROM $track_e_login WHERE login_user_id = %d AND login_date < '%s' ORDER BY login_date DESC LIMIT 1",
1514
                $info['user_id'],
1515
                $info['logindate']
1516
            ); //TODO add select by user too
1517
            $result = Database::query($sql);
1518
            $ip = Database::fetch_assoc($result);
1519
            //if no ip founded, we search the closest higher ip
1520
            if (empty($ip['user_ip'])) {
1521
                $sql = sprintf(
1522
                    "SELECT user_ip FROM $track_e_login WHERE login_user_id = %d AND login_date > '%s'  ORDER BY login_date ASC LIMIT 1",
1523
                    $info['user_id'],
1524
                    $info['logindate']
1525
                ); //TODO add select by user too
1526
                $result = Database::query($sql);
1527
                $ip = Database::fetch_assoc($result);
1528
            }
1529
            //add ip to final array
1530
            $return[$key]['ip'] = $ip['user_ip'];
1531
        }
1532
1533
        return $return;
1534
    }
1535
1536
    /**
1537
     * Creates a new course code based in given code.
1538
     *
1539
     * @param string $session_name
1540
     *                             <code>
1541
     *                             $wanted_code = 'curse' if there are in the DB codes like curse1 curse2 the function
1542
     *                             will return: course3 if the course code doest not exist in the DB the same course
1543
     *                             code will be returned
1544
     *                             </code>
1545
     *
1546
     * @return string wanted unused code
1547
     */
1548
    public static function generateNextSessionName($session_name)
1549
    {
1550
        $session_name_ok = !self::sessionNameExists($session_name);
1551
        if (!$session_name_ok) {
1552
            $table = Database::get_main_table(TABLE_MAIN_SESSION);
1553
            $session_name = Database::escape_string($session_name);
1554
            $sql = "SELECT count(*) as count FROM $table
1555
                    WHERE name LIKE '$session_name%'";
1556
            $result = Database::query($sql);
1557
            if (Database::num_rows($result) > 0) {
1558
                $row = Database::fetch_array($result);
1559
                $count = $row['count'] + 1;
1560
                $session_name = $session_name.'_'.$count;
1561
                $result = self::sessionNameExists($session_name);
1562
                if (!$result) {
1563
                    return $session_name;
1564
                }
1565
            }
1566
1567
            return false;
1568
        }
1569
1570
        return $session_name;
1571
    }
1572
1573
    /**
1574
     * Edit a session.
1575
     *
1576
     * @author Carlos Vargas from existing code
1577
     *
1578
     * @param int    $id                           Session primary key
1579
     * @param string $name
1580
     * @param string $startDate
1581
     * @param string $endDate
1582
     * @param string $displayStartDate
1583
     * @param string $displayEndDate
1584
     * @param string $coachStartDate
1585
     * @param string $coachEndDate
1586
     * @param int    $coachId
1587
     * @param int    $sessionCategoryId
1588
     * @param int    $visibility
1589
     * @param string $description
1590
     * @param int    $showDescription
1591
     * @param int    $duration
1592
     * @param array  $extraFields
1593
     * @param int    $sessionAdminId
1594
     * @param bool   $sendSubscriptionNotification Optional. Whether send a mail notification to users being subscribed
1595
     * @param int    $status
1596
     *
1597
     * @return mixed
1598
     */
1599
    public static function edit_session(
1600
        $id,
1601
        $name,
1602
        $startDate,
1603
        $endDate,
1604
        $displayStartDate,
1605
        $displayEndDate,
1606
        $coachStartDate,
1607
        $coachEndDate,
1608
        $coachId,
1609
        $sessionCategoryId,
1610
        $visibility,
1611
        $description = null,
1612
        $showDescription = 0,
1613
        $duration = null,
1614
        $extraFields = [],
1615
        $sessionAdminId = 0,
1616
        $sendSubscriptionNotification = false,
1617
        $status = 0
1618
    ) {
1619
        $status = (int) $status;
1620
        $coachId = (int) $coachId;
1621
        $sessionCategoryId = (int) $sessionCategoryId;
1622
        $visibility = (int) $visibility;
1623
        $tbl_session = Database::get_main_table(TABLE_MAIN_SESSION);
1624
1625
        if (empty($name)) {
1626
            Display::addFlash(
1627
                Display::return_message(get_lang('SessionNameIsRequired'), 'warning')
1628
            );
1629
1630
            return false;
1631
        } elseif (empty($coachId)) {
1632
            Display::addFlash(
1633
                Display::return_message(get_lang('CoachIsRequired'), 'warning')
1634
            );
1635
1636
            return false;
1637
        } elseif (!empty($startDate) &&
1638
            !api_is_valid_date($startDate, 'Y-m-d H:i') &&
1639
            !api_is_valid_date($startDate, 'Y-m-d H:i:s')
1640
        ) {
1641
            Display::addFlash(
1642
                Display::return_message(get_lang('InvalidStartDate'), 'warning')
1643
            );
1644
1645
            return false;
1646
        } elseif (!empty($endDate) &&
1647
            !api_is_valid_date($endDate, 'Y-m-d H:i') &&
1648
            !api_is_valid_date($endDate, 'Y-m-d H:i:s')
1649
        ) {
1650
            Display::addFlash(
1651
                Display::return_message(get_lang('InvalidEndDate'), 'warning')
1652
            );
1653
1654
            return false;
1655
        } elseif (!empty($startDate) && !empty($endDate) && $startDate >= $endDate) {
1656
            Display::addFlash(
1657
                Display::return_message(get_lang('StartDateShouldBeBeforeEndDate'), 'warning')
1658
            );
1659
1660
            return false;
1661
        } else {
1662
            $sessionInfo = self::get_session_by_name($name);
1663
            $exists = false;
1664
1665
            if (!empty($sessionInfo)) {
1666
                if ($sessionInfo['id'] != $id) {
1667
                    $exists = true;
1668
                }
1669
            }
1670
1671
            if ($exists) {
1672
                Display::addFlash(
1673
                    Display::return_message(get_lang('SessionNameAlreadyExists'), 'warning')
1674
                );
1675
1676
                return false;
1677
            } else {
1678
                $values = [
1679
                    'name' => $name,
1680
                    'duration' => $duration,
1681
                    'id_coach' => $coachId,
1682
                    'description' => $description,
1683
                    'show_description' => intval($showDescription),
1684
                    'visibility' => $visibility,
1685
                    'send_subscription_notification' => $sendSubscriptionNotification,
1686
                    'access_start_date' => null,
1687
                    'access_end_date' => null,
1688
                    'display_start_date' => null,
1689
                    'display_end_date' => null,
1690
                    'coach_access_start_date' => null,
1691
                    'coach_access_end_date' => null,
1692
                ];
1693
1694
                if (!empty($sessionAdminId)) {
1695
                    $values['session_admin_id'] = $sessionAdminId;
1696
                }
1697
1698
                if (!empty($startDate)) {
1699
                    $values['access_start_date'] = api_get_utc_datetime($startDate);
1700
                }
1701
1702
                if (!empty($endDate)) {
1703
                    $values['access_end_date'] = api_get_utc_datetime($endDate);
1704
                }
1705
1706
                if (!empty($displayStartDate)) {
1707
                    $values['display_start_date'] = api_get_utc_datetime($displayStartDate);
1708
                }
1709
1710
                if (!empty($displayEndDate)) {
1711
                    $values['display_end_date'] = api_get_utc_datetime($displayEndDate);
1712
                }
1713
1714
                if (!empty($coachStartDate)) {
1715
                    $values['coach_access_start_date'] = api_get_utc_datetime($coachStartDate);
1716
                }
1717
                if (!empty($coachEndDate)) {
1718
                    $values['coach_access_end_date'] = api_get_utc_datetime($coachEndDate);
1719
                }
1720
1721
                $values['session_category_id'] = null;
1722
                if (!empty($sessionCategoryId)) {
1723
                    $values['session_category_id'] = $sessionCategoryId;
1724
                }
1725
1726
                if (api_get_configuration_value('allow_session_status')) {
1727
                    $values['status'] = $status;
1728
                }
1729
1730
                Database::update(
1731
                    $tbl_session,
1732
                    $values,
1733
                    ['id = ?' => $id]
1734
                );
1735
1736
                if (!empty($extraFields)) {
1737
                    $extraFields['item_id'] = $id;
1738
                    $sessionFieldValue = new ExtraFieldValue('session');
1739
                    $sessionFieldValue->saveFieldValues($extraFields);
1740
                }
1741
1742
                return $id;
1743
            }
1744
        }
1745
    }
1746
1747
    /**
1748
     * Delete session.
1749
     *
1750
     * @author Carlos Vargas  from existing code
1751
     *
1752
     * @param array $id_checked an array to delete sessions
1753
     * @param bool  $from_ws    optional, true if the function is called
1754
     *                          by a webservice, false otherwise
1755
     *
1756
     * @return bool
1757
     * */
1758
    public static function delete($id_checked, $from_ws = false)
1759
    {
1760
        $tbl_session = Database::get_main_table(TABLE_MAIN_SESSION);
1761
        $tbl_session_rel_course = Database::get_main_table(TABLE_MAIN_SESSION_COURSE);
1762
        $tbl_session_rel_course_rel_user = Database::get_main_table(TABLE_MAIN_SESSION_COURSE_USER);
1763
        $tbl_session_rel_user = Database::get_main_table(TABLE_MAIN_SESSION_USER);
1764
        $tbl_url_session = Database::get_main_table(TABLE_MAIN_ACCESS_URL_REL_SESSION);
1765
        $tbl_item_properties = Database::get_course_table(TABLE_ITEM_PROPERTY);
1766
        $tbl_student_publication = Database::get_course_table(TABLE_STUDENT_PUBLICATION);
1767
        $tbl_student_publication_assignment = Database::get_course_table(TABLE_STUDENT_PUBLICATION_ASSIGNMENT);
1768
        $userGroupSessionTable = Database::get_main_table(TABLE_USERGROUP_REL_SESSION);
1769
        $trackCourseAccess = Database::get_main_table(TABLE_STATISTIC_TRACK_E_COURSE_ACCESS);
1770
        $trackAccess = Database::get_main_table(TABLE_STATISTIC_TRACK_E_ACCESS);
1771
        $tbl_learnpath = Database::get_course_table(TABLE_LP_MAIN);
1772
        $tbl_dropbox = Database::get_course_table(TABLE_DROPBOX_FILE);
1773
        $trackEExercises = Database::get_main_table(TABLE_STATISTIC_TRACK_E_EXERCISES);
1774
        $trackEAttempt = Database::get_main_table(TABLE_STATISTIC_TRACK_E_ATTEMPT);
1775
1776
        $ticket = Database::get_main_table(TABLE_TICKET_TICKET);
1777
        $em = Database::getManager();
1778
        $userId = api_get_user_id();
1779
1780
        // If this session is involved in any sequence, cancel deletion and ask
1781
        // for the sequence update before deleting.
1782
        /** @var SequenceResourceRepository $repo */
1783
        $repo = Database::getManager()->getRepository('ChamiloCoreBundle:SequenceResource');
1784
        $sequenceResource = $repo->findRequirementForResource(
1785
            $id_checked,
1786
            SequenceResource::SESSION_TYPE
1787
        );
1788
1789
        if ($sequenceResource) {
1790
            Display::addFlash(
1791
                Display::return_message(
1792
                    get_lang('ThereIsASequenceResourceLinkedToThisSessionYouNeedToDeleteItFirst'),
1793
                    'error'
1794
                )
1795
            );
1796
1797
            return false;
1798
        }
1799
1800
        // If the $id_checked param is an array, split it into individual
1801
        // sessions deletion.
1802
        if (is_array($id_checked)) {
1803
            foreach ($id_checked as $sessionId) {
1804
                self::delete($sessionId);
1805
            }
1806
        } else {
1807
            $id_checked = intval($id_checked);
1808
        }
1809
1810
        // Check permissions from the person launching the deletion.
1811
        // If the call is issued from a web service or automated process,
1812
        // we assume the caller checks for permissions ($from_ws).
1813
        if (self::allowed($id_checked) && !$from_ws) {
1814
            $qb = $em
1815
                ->createQuery('
1816
                    SELECT s.sessionAdminId FROM ChamiloCoreBundle:Session s
1817
                    WHERE s.id = ?1
1818
                ')
1819
                ->setParameter(1, $id_checked);
1820
1821
            $res = $qb->getSingleScalarResult();
1822
1823
            if ($res != $userId && !api_is_platform_admin()) {
1824
                api_not_allowed(true);
1825
            }
1826
        }
1827
1828
        $sessionInfo = api_get_session_info($id_checked);
1829
1830
        // Delete documents and assignments inside a session
1831
        $courses = self::getCoursesInSession($id_checked);
1832
        foreach ($courses as $courseId) {
1833
            $courseInfo = api_get_course_info_by_id($courseId);
1834
            // Delete documents
1835
            DocumentManager::deleteDocumentsFromSession($courseInfo, $id_checked);
1836
1837
            // Delete assignments
1838
            $works = Database::select(
1839
                '*',
1840
                $tbl_student_publication,
1841
                [
1842
                    'where' => ['session_id = ? AND c_id = ?' => [$id_checked, $courseId]],
1843
                ]
1844
            );
1845
            $currentCourseRepositorySys = api_get_path(SYS_COURSE_PATH).$courseInfo['path'].'/';
1846
            foreach ($works as $index => $work) {
1847
                if ($work['filetype'] = 'folder') {
1848
                    Database::query("DELETE FROM $tbl_student_publication_assignment WHERE publication_id = $index");
1849
                }
1850
                my_delete($currentCourseRepositorySys.'/'.$work['url']);
1851
            }
1852
1853
            // Delete learning paths
1854
            $learnpaths = Database::select(
1855
                'iid',
1856
                $tbl_learnpath,
1857
                [
1858
                    'where' => ['session_id = ? AND c_id = ?' => [$id_checked, $courseId]],
1859
                ]
1860
            );
1861
            $courseInfo = api_get_course_info_by_id($courseId);
1862
            foreach ($learnpaths as $lpData) {
1863
                $lp = new learnpath($courseInfo['code'], $lpData['iid'], $userId);
1864
                $lp->delete($courseInfo, $lpData['iid'], true);
1865
                unset($lp);
1866
            }
1867
1868
            // Delete dropbox documents
1869
            $dropboxes = Database::select(
1870
                'iid',
1871
                $tbl_dropbox,
1872
                [
1873
                    'where' => ['session_id = ? AND c_id = ?' => [$id_checked, $courseId]],
1874
                ]
1875
            );
1876
            require_once __DIR__.'/../../dropbox/dropbox_functions.inc.php';
1877
            foreach ($dropboxes as $dropbox) {
1878
                $dropboxPerson = new Dropbox_Person(
1879
                    $userId,
1880
                    true,
1881
                    false,
1882
                    $courseId,
1883
                    $id_checked
1884
                );
1885
                $dropboxPerson->deleteReceivedWork($dropbox['iid'], $courseId, $id_checked);
1886
                $dropboxPerson->deleteSentWork($dropbox['iid'], $courseId, $id_checked);
1887
            }
1888
1889
            // TODO: Delete audio files from test answers
1890
            $attempts = Database::select(
1891
                ['id', 'user_id', 'exe_id'],
1892
                $trackEAttempt,
1893
                [
1894
                    'where' => [
1895
                        'session_id = ? AND c_id = ? AND (filename IS NOT NULL AND filename != \'\')' => [
1896
                            $id_checked,
1897
                            $courseId,
1898
                        ],
1899
                    ],
1900
                ]
1901
            );
1902
            foreach ($attempts as $attempt) {
1903
                $oral = new OralExpression();
1904
                $oral->initFile($id_checked, $attempt['user_id'], 0, $attempt['exe_id'], $courseId);
1905
                $filename = $oral->getAbsoluteFilePath(true);
1906
                my_delete($filename);
1907
            }
1908
        }
1909
1910
        // Class
1911
        $sql = "DELETE FROM $userGroupSessionTable
1912
                WHERE session_id IN($id_checked)";
1913
        Database::query($sql);
1914
1915
        Database::query("DELETE FROM $tbl_student_publication WHERE session_id IN($id_checked)");
1916
        Database::query("DELETE FROM $tbl_session_rel_course WHERE session_id IN($id_checked)");
1917
        Database::query("DELETE FROM $tbl_session_rel_course_rel_user WHERE session_id IN($id_checked)");
1918
        Database::query("DELETE FROM $tbl_session_rel_user WHERE session_id IN($id_checked)");
1919
        Database::query("DELETE FROM $tbl_item_properties WHERE session_id IN ($id_checked)");
1920
        Database::query("DELETE FROM $tbl_url_session WHERE session_id IN($id_checked)");
1921
1922
        Database::query("DELETE FROM $trackCourseAccess WHERE session_id IN($id_checked)");
1923
        Database::query("DELETE FROM $trackAccess WHERE access_session_id IN($id_checked)");
1924
1925
        if (api_get_configuration_value('allow_lp_subscription_to_usergroups')) {
1926
            $tableGroup = Database::get_course_table(TABLE_LP_REL_USERGROUP);
1927
            Database::query("DELETE FROM $tableGroup WHERE session_id IN($id_checked)");
1928
            $tableGroup = Database::get_course_table(TABLE_LP_CATEGORY_REL_USERGROUP);
1929
            Database::query("DELETE FROM $tableGroup WHERE session_id IN($id_checked)");
1930
        }
1931
1932
        $sql = "UPDATE $ticket SET session_id = NULL WHERE session_id IN ($id_checked)";
1933
        Database::query($sql);
1934
1935
        $app_plugin = new AppPlugin();
1936
        $app_plugin->performActionsWhenDeletingItem('session', $id_checked);
1937
1938
        $sql = "DELETE FROM $tbl_session WHERE id IN ($id_checked)";
1939
        Database::query($sql);
1940
1941
        $extraFieldValue = new ExtraFieldValue('session');
1942
        $extraFieldValue->deleteValuesByItem($id_checked);
1943
1944
        $repo->deleteResource(
1945
            $id_checked,
1946
            SequenceResource::SESSION_TYPE
1947
        );
1948
1949
        // Add event to system log
1950
        Event::addEvent(
1951
            LOG_SESSION_DELETE,
1952
            LOG_SESSION_ID,
1953
            $sessionInfo['name'].' - id:'.$id_checked,
1954
            api_get_utc_datetime(),
1955
            $userId
1956
        );
1957
1958
        return true;
1959
    }
1960
1961
    /**
1962
     * @param int $id promotion id
1963
     *
1964
     * @return bool
1965
     */
1966
    public static function clear_session_ref_promotion($id)
1967
    {
1968
        $tbl_session = Database::get_main_table(TABLE_MAIN_SESSION);
1969
        $id = intval($id);
1970
        $sql = "UPDATE $tbl_session
1971
                SET promotion_id = 0
1972
                WHERE promotion_id = $id";
1973
        if (Database::query($sql)) {
1974
            return true;
1975
        } else {
1976
            return false;
1977
        }
1978
    }
1979
1980
    /**
1981
     * Subscribes students to the given session and optionally (default)
1982
     * unsubscribes previous users.
1983
     *
1984
     * @author Carlos Vargas from existing code
1985
     * @author Julio Montoya. Cleaning code.
1986
     *
1987
     * @param int   $sessionId
1988
     * @param array $userList
1989
     * @param int   $session_visibility
1990
     * @param bool  $empty_users
1991
     * @param bool  $registerUsersToAllCourses
1992
     *
1993
     * @return bool
1994
     */
1995
    public static function subscribeUsersToSession(
1996
        $sessionId,
1997
        $userList,
1998
        $session_visibility = SESSION_VISIBLE_READ_ONLY,
1999
        $empty_users = true,
2000
        $registerUsersToAllCourses = true
2001
    ) {
2002
        $sessionId = (int) $sessionId;
2003
2004
        if (empty($sessionId)) {
2005
            return false;
2006
        }
2007
2008
        foreach ($userList as $intUser) {
2009
            if ($intUser != strval(intval($intUser))) {
2010
                return false;
2011
            }
2012
        }
2013
2014
        $tbl_session_rel_course = Database::get_main_table(TABLE_MAIN_SESSION_COURSE);
2015
        $tbl_session_rel_course_rel_user = Database::get_main_table(TABLE_MAIN_SESSION_COURSE_USER);
2016
        $tbl_session_rel_user = Database::get_main_table(TABLE_MAIN_SESSION_USER);
2017
        $tbl_session = Database::get_main_table(TABLE_MAIN_SESSION);
2018
2019
        if (!self::isValidId($sessionId)) {
2020
            return false;
2021
        }
2022
2023
        $session = api_get_session_entity($sessionId);
2024
2025
        // from function parameter
2026
        if (empty($session_visibility)) {
2027
            $session_visibility = $session->getVisibility();
2028
            //default status loaded if empty
2029
            // by default readonly 1
2030
            if (empty($session_visibility)) {
2031
                $session_visibility = SESSION_VISIBLE_READ_ONLY;
2032
            }
2033
        } else {
2034
            if (!in_array($session_visibility, [SESSION_VISIBLE_READ_ONLY, SESSION_VISIBLE, SESSION_INVISIBLE])) {
2035
                $session_visibility = SESSION_VISIBLE_READ_ONLY;
2036
            }
2037
        }
2038
2039
        $sql = "SELECT user_id FROM $tbl_session_rel_course_rel_user
2040
                WHERE session_id = $sessionId AND status = 0";
2041
        $result = Database::query($sql);
2042
        $existingUsers = [];
2043
        while ($row = Database::fetch_array($result)) {
2044
            $existingUsers[] = $row['user_id'];
2045
        }
2046
2047
        $sql = "SELECT c_id FROM $tbl_session_rel_course
2048
                WHERE session_id = $sessionId";
2049
        $result = Database::query($sql);
2050
        $course_list = [];
2051
        while ($row = Database::fetch_array($result)) {
2052
            $course_list[] = $row['c_id'];
2053
        }
2054
2055
        // Build list of users already subscribed to the session as students.
2056
        // This allows us to avoid re-enrolling them into all courses again
2057
        // when they are already part of the session (preserves manual
2058
        // unsubscriptions at the course level).
2059
        $usersAlreadyInSession = [];
2060
        if (!empty($userList)) {
2061
            $userIdsStr = "'".implode("','", $userList)."'";
2062
            $sql = "SELECT user_id FROM $tbl_session_rel_user
2063
                    WHERE session_id = $sessionId AND relation_type = 0
2064
                    AND user_id IN ($userIdsStr)";
2065
            $resUsersInSession = Database::query($sql);
2066
            while ($row = Database::fetch_array($resUsersInSession)) {
2067
                $usersAlreadyInSession[] = (int) $row['user_id'];
2068
            }
2069
        }
2070
2071
        if ($session->getSendSubscriptionNotification() &&
2072
            is_array($userList)
2073
        ) {
2074
            // Sending emails only
2075
            foreach ($userList as $user_id) {
2076
                if (in_array($user_id, $existingUsers)) {
2077
                    continue;
2078
                }
2079
2080
                $tplSubject = new Template(
2081
                    null,
2082
                    false,
2083
                    false,
2084
                    false,
2085
                    false,
2086
                    false
2087
                );
2088
                $layoutSubject = $tplSubject->get_template(
2089
                    'mail/subject_subscription_to_session_confirmation.tpl'
2090
                );
2091
                $subject = $tplSubject->fetch($layoutSubject);
2092
                $user_info = api_get_user_info($user_id);
2093
2094
                $tplContent = new Template(
2095
                    null,
2096
                    false,
2097
                    false,
2098
                    false,
2099
                    false,
2100
                    false
2101
                );
2102
                // Variables for default template
2103
                $tplContent->assign('complete_name', stripslashes($user_info['complete_name']));
2104
                $tplContent->assign('session_name', $session->getName());
2105
                $tplContent->assign('session_coach', $session->getGeneralCoach()->getCompleteName());
2106
                $layoutContent = $tplContent->get_template(
2107
                    'mail/content_subscription_to_session_confirmation.tpl'
2108
                );
2109
2110
                if (api_get_configuration_value('email_template_subscription_to_session_confirmation_username')) {
2111
                    $username = sprintf(
2112
                        get_lang('YourUsernameToAccessIsX'),
2113
                        stripslashes($user_info['username']));
2114
2115
                    $tplContent->assign('username', $username);
2116
                }
2117
2118
                if (api_get_configuration_value('email_template_subscription_to_session_confirmation_lost_password')) {
2119
                    $urlLostPw = api_get_path(WEB_CODE_PATH).'auth/lostPassword.php';
2120
2121
                    $forgotPassword = sprintf(
2122
                        get_lang('InstructionsLostPasswordWithLinkX'),
2123
                        $urlLostPw);
2124
2125
                    $tplContent->assign('lostPassword', $forgotPassword);
2126
                }
2127
2128
                $content = $tplContent->fetch($layoutContent);
2129
2130
                api_mail_html(
2131
                    $user_info['complete_name'],
2132
                    $user_info['mail'],
2133
                    $subject,
2134
                    $content,
2135
                    api_get_person_name(
2136
                        api_get_setting('administratorName'),
2137
                        api_get_setting('administratorSurname')
2138
                    ),
2139
                    api_get_setting('emailAdministrator')
2140
                );
2141
            }
2142
        }
2143
2144
        if ($registerUsersToAllCourses) {
2145
            foreach ($course_list as $courseId) {
2146
                // for each course in the session
2147
                $courseId = (int) $courseId;
2148
2149
                $sql = "SELECT DISTINCT user_id
2150
                        FROM $tbl_session_rel_course_rel_user
2151
                        WHERE
2152
                            session_id = $sessionId AND
2153
                            c_id = $courseId AND
2154
                            status = 0
2155
                        ";
2156
                $result = Database::query($sql);
2157
                $existingUsers = [];
2158
                while ($row = Database::fetch_array($result)) {
2159
                    $existingUsers[] = $row['user_id'];
2160
                }
2161
2162
                // Delete existing users
2163
                if ($empty_users) {
2164
                    foreach ($existingUsers as $existing_user) {
2165
                        if (!in_array($existing_user, $userList)) {
2166
                            self::unSubscribeUserFromCourseSession($existing_user, $courseId, $sessionId);
2167
                        }
2168
                    }
2169
                }
2170
2171
                $usersToSubscribeInCourse = array_filter(
2172
                    $userList,
2173
                    function ($userId) use ($existingUsers, $usersAlreadyInSession) {
2174
                        return !in_array($userId, $existingUsers) && !in_array($userId, $usersAlreadyInSession);
2175
                    }
2176
                );
2177
2178
                self::insertUsersInCourse(
2179
                    $usersToSubscribeInCourse,
2180
                    $courseId,
2181
                    $sessionId,
2182
                    ['visibility' => $session_visibility],
2183
                    false
2184
                );
2185
            }
2186
        }
2187
2188
        // Delete users from the session
2189
        if (true === $empty_users) {
2190
            $sql = "DELETE FROM $tbl_session_rel_user
2191
                    WHERE
2192
                      session_id = $sessionId AND
2193
                      relation_type <> ".SESSION_RELATION_TYPE_RRHH;
2194
            // Don't reset session_rel_user.registered_at of users that will be registered later anyways.
2195
            if (!empty($userList)) {
2196
                $avoidDeleteThisUsers = " AND user_id NOT IN ('".implode("','", $userList)."')";
2197
                $sql .= $avoidDeleteThisUsers;
2198
            }
2199
            Event::addEvent(
2200
                LOG_SESSION_DELETE_USER,
2201
                LOG_USER_ID,
2202
                'all',
2203
                api_get_utc_datetime(),
2204
                api_get_user_id(),
2205
                null,
2206
                $sessionId
2207
            );
2208
            Database::query($sql);
2209
        }
2210
2211
        // Insert missing users into session
2212
        foreach ($userList as $enreg_user) {
2213
            $isUserSubscribed = self::isUserSubscribedAsStudent($sessionId, $enreg_user);
2214
            if ($isUserSubscribed === false) {
2215
                $enreg_user = (int) $enreg_user;
2216
                $sql = "INSERT IGNORE INTO $tbl_session_rel_user (relation_type, session_id, user_id, registered_at)
2217
                        VALUES (0, $sessionId, $enreg_user, '".api_get_utc_datetime()."')";
2218
                Database::query($sql);
2219
                Event::addEvent(
2220
                    LOG_SESSION_ADD_USER,
2221
                    LOG_USER_ID,
2222
                    $enreg_user,
2223
                    api_get_utc_datetime(),
2224
                    api_get_user_id(),
2225
                    null,
2226
                    $sessionId
2227
                );
2228
            }
2229
        }
2230
2231
        // update number of users in the session
2232
        $sql = "UPDATE $tbl_session
2233
                SET nbr_users = (SELECT count(user_id) FROM $tbl_session_rel_user WHERE session_id = $sessionId)
2234
                WHERE id = $sessionId";
2235
        Database::query($sql);
2236
2237
        return true;
2238
    }
2239
2240
    /**
2241
     * Returns user list of the current users subscribed in the course-session.
2242
     *
2243
     * @param int   $sessionId
2244
     * @param array $courseInfo
2245
     * @param int   $status
2246
     *
2247
     * @return array
2248
     */
2249
    public static function getUsersByCourseSession(
2250
        $sessionId,
2251
        $courseInfo,
2252
        $status = null
2253
    ) {
2254
        $sessionId = (int) $sessionId;
2255
        $courseId = $courseInfo['real_id'];
2256
2257
        if (empty($sessionId) || empty($courseId)) {
2258
            return [];
2259
        }
2260
2261
        $statusCondition = null;
2262
        if (isset($status) && !is_null($status)) {
2263
            $status = (int) $status;
2264
            $statusCondition = " AND status = $status";
2265
        }
2266
2267
        $table = Database::get_main_table(TABLE_MAIN_SESSION_COURSE_USER);
2268
2269
        $sql = "SELECT DISTINCT user_id
2270
                FROM $table
2271
                WHERE
2272
                    session_id = $sessionId AND
2273
                    c_id = $courseId
2274
                    $statusCondition
2275
                ";
2276
2277
        $result = Database::query($sql);
2278
        $existingUsers = [];
2279
        while ($row = Database::fetch_array($result)) {
2280
            $existingUsers[] = $row['user_id'];
2281
        }
2282
2283
        return $existingUsers;
2284
    }
2285
2286
    /**
2287
     * Returns user list of the current users subscribed in the course-session.
2288
     *
2289
     * @param array $sessionList
2290
     * @param array $courseList
2291
     * @param int   $status
2292
     * @param int   $start
2293
     * @param int   $limit
2294
     *
2295
     * @return array
2296
     */
2297
    public static function getUsersByCourseAndSessionList(
2298
        $sessionList,
2299
        $courseList,
2300
        $status = null,
2301
        $start = null,
2302
        $limit = null
2303
    ) {
2304
        if (empty($sessionList) || empty($courseList)) {
2305
            return [];
2306
        }
2307
        $sessionListToString = implode("','", $sessionList);
2308
        $courseListToString = implode("','", $courseList);
2309
2310
        $statusCondition = null;
2311
        if (isset($status) && !is_null($status)) {
2312
            $status = (int) $status;
2313
            $statusCondition = " AND status = $status";
2314
        }
2315
2316
        $table = Database::get_main_table(TABLE_MAIN_SESSION_COURSE_USER);
2317
2318
        $sql = "SELECT DISTINCT user_id
2319
                FROM $table
2320
                WHERE
2321
                    session_id IN ('$sessionListToString') AND
2322
                    c_id IN ('$courseListToString')
2323
                    $statusCondition
2324
                ";
2325
        if (!is_null($start) && !is_null($limit)) {
2326
            $start = (int) $start;
2327
            $limit = (int) $limit;
2328
            $sql .= "LIMIT $start, $limit";
2329
        }
2330
        $result = Database::query($sql);
2331
        $existingUsers = [];
2332
        while ($row = Database::fetch_array($result)) {
2333
            $existingUsers[] = $row['user_id'];
2334
        }
2335
2336
        return $existingUsers;
2337
    }
2338
2339
    /**
2340
     * Remove a list of users from a course-session.
2341
     *
2342
     * @param array $userList
2343
     * @param int   $sessionId
2344
     * @param array $courseInfo
2345
     * @param int   $status
2346
     * @param bool  $updateTotal
2347
     *
2348
     * @return bool
2349
     */
2350
    public static function removeUsersFromCourseSession(
2351
        $userList,
2352
        $sessionId,
2353
        $courseInfo,
2354
        $status = null,
2355
        $updateTotal = true
2356
    ) {
2357
        $table = Database::get_main_table(TABLE_MAIN_SESSION_COURSE_USER);
2358
        $tableSessionCourse = Database::get_main_table(TABLE_MAIN_SESSION_COURSE);
2359
        $sessionId = (int) $sessionId;
2360
2361
        if (empty($sessionId) || empty($userList) || empty($courseInfo)) {
2362
            return false;
2363
        }
2364
2365
        is_array($courseInfo) ? $courseId = $courseInfo['real_id'] : $courseId = $courseInfo;
2366
2367
        $statusCondition = null;
2368
        if (isset($status) && !is_null($status)) {
2369
            $status = (int) $status;
2370
            $statusCondition = " AND status = $status";
2371
        }
2372
2373
        foreach ($userList as $userId) {
2374
            $userId = (int) $userId;
2375
            $sql = "DELETE FROM $table
2376
                    WHERE
2377
                        session_id = $sessionId AND
2378
                        c_id = $courseId AND
2379
                        user_id = $userId
2380
                        $statusCondition
2381
                    ";
2382
            Database::query($sql);
2383
2384
            Event::addEvent(
2385
                LOG_SESSION_DELETE_USER_COURSE,
2386
                LOG_USER_ID,
2387
                $userId,
2388
                api_get_utc_datetime(),
2389
                api_get_user_id(),
2390
                $courseId,
2391
                $sessionId
2392
            );
2393
        }
2394
2395
        if ($updateTotal) {
2396
            // Count users in this session-course relation
2397
            $sql = "SELECT COUNT(user_id) as nbUsers
2398
                    FROM $table
2399
                    WHERE
2400
                        session_id = $sessionId AND
2401
                        c_id = $courseId AND
2402
                        status <> 2";
2403
            $result = Database::query($sql);
2404
            [$userCount] = Database::fetch_array($result);
2405
2406
            // update the session-course relation to add the users total
2407
            $sql = "UPDATE $tableSessionCourse
2408
                    SET nbr_users = $userCount
2409
                    WHERE
2410
                        session_id = $sessionId AND
2411
                        c_id = $courseId";
2412
            Database::query($sql);
2413
        }
2414
    }
2415
2416
    /**
2417
     * Subscribe a user to an specific course inside a session.
2418
     *
2419
     * @param array  $user_list
2420
     * @param int    $session_id
2421
     * @param string $course_code
2422
     * @param int    $session_visibility
2423
     * @param bool   $removeUsersNotInList
2424
     *
2425
     * @return bool
2426
     */
2427
    public static function subscribe_users_to_session_course(
2428
        $user_list,
2429
        $session_id,
2430
        $course_code,
2431
        $session_visibility = SESSION_VISIBLE_READ_ONLY,
2432
        $removeUsersNotInList = false
2433
    ) {
2434
        if (empty($session_id) || empty($course_code)) {
2435
            return false;
2436
        }
2437
2438
        $session_id = (int) $session_id;
2439
        $session_visibility = (int) $session_visibility;
2440
        $course_code = Database::escape_string($course_code);
2441
        $courseInfo = api_get_course_info($course_code);
2442
        $courseId = $courseInfo['real_id'];
2443
2444
        if ($removeUsersNotInList) {
2445
            $currentUsers = self::getUsersByCourseSession($session_id, $courseInfo, 0);
2446
2447
            if (!empty($user_list)) {
2448
                $userToDelete = array_diff($currentUsers, $user_list);
2449
            } else {
2450
                $userToDelete = $currentUsers;
2451
            }
2452
2453
            if (!empty($userToDelete)) {
2454
                self::removeUsersFromCourseSession(
2455
                    $userToDelete,
2456
                    $session_id,
2457
                    $courseInfo,
2458
                    0,
2459
                    true
2460
                );
2461
            }
2462
        }
2463
2464
        self::insertUsersInCourse(
2465
            $user_list,
2466
            $courseId,
2467
            $session_id,
2468
            ['visibility' => $session_visibility]
2469
        );
2470
    }
2471
2472
    /**
2473
     * Unsubscribe user from session.
2474
     *
2475
     * @param int Session id
2476
     * @param int User id
2477
     *
2478
     * @return bool True in case of success, false in case of error
2479
     */
2480
    public static function unsubscribe_user_from_session($session_id, $user_id)
2481
    {
2482
        $session_id = (int) $session_id;
2483
        $user_id = (int) $user_id;
2484
2485
        $tbl_session_rel_user = Database::get_main_table(TABLE_MAIN_SESSION_USER);
2486
        $tbl_session = Database::get_main_table(TABLE_MAIN_SESSION);
2487
2488
        if (!self::isValidId($session_id)) {
2489
            return false;
2490
        }
2491
2492
        $sql = "DELETE FROM $tbl_session_rel_user
2493
                WHERE
2494
                    session_id = $session_id AND
2495
                    user_id = $user_id AND
2496
                    relation_type <> ".SESSION_RELATION_TYPE_RRHH;
2497
        $result = Database::query($sql);
2498
        $return = Database::affected_rows($result);
2499
2500
        // Update number of users
2501
        $sql = "UPDATE $tbl_session
2502
                SET nbr_users = nbr_users - $return
2503
                WHERE id = $session_id ";
2504
        Database::query($sql);
2505
2506
        Event::addEvent(
2507
            LOG_SESSION_DELETE_USER,
2508
            LOG_USER_ID,
2509
            $user_id,
2510
            api_get_utc_datetime(),
2511
            api_get_user_id(),
2512
            null,
2513
            $session_id
2514
        );
2515
2516
        // Get the list of courses related to this session
2517
        $course_list = self::get_course_list_by_session_id($session_id);
2518
        if (!empty($course_list)) {
2519
            foreach ($course_list as $course) {
2520
                self::unSubscribeUserFromCourseSession($user_id, $course['id'], $session_id);
2521
            }
2522
        }
2523
2524
        return true;
2525
    }
2526
2527
    /**
2528
     * @param int $user_id
2529
     * @param int $courseId
2530
     * @param int $session_id
2531
     */
2532
    public static function unSubscribeUserFromCourseSession($user_id, $courseId, $session_id)
2533
    {
2534
        $user_id = (int) $user_id;
2535
        $courseId = (int) $courseId;
2536
        $session_id = (int) $session_id;
2537
2538
        $tbl_session_rel_course_rel_user = Database::get_main_table(TABLE_MAIN_SESSION_COURSE_USER);
2539
        $tbl_session_rel_course = Database::get_main_table(TABLE_MAIN_SESSION_COURSE);
2540
2541
        // Delete user from course
2542
        $sql = "DELETE FROM $tbl_session_rel_course_rel_user
2543
                WHERE session_id = $session_id AND c_id = $courseId AND user_id = $user_id";
2544
        $result = Database::query($sql);
2545
2546
        if (Database::affected_rows($result)) {
2547
            // Update number of users in this relation
2548
            $sql = "UPDATE $tbl_session_rel_course SET
2549
                    nbr_users = nbr_users - 1
2550
                    WHERE session_id = $session_id AND c_id = $courseId";
2551
            Database::query($sql);
2552
        }
2553
2554
        Event::addEvent(
2555
            LOG_SESSION_DELETE_USER_COURSE,
2556
            LOG_USER_ID,
2557
            $user_id,
2558
            api_get_utc_datetime(),
2559
            api_get_user_id(),
2560
            $courseId,
2561
            $session_id
2562
        );
2563
    }
2564
2565
    /**
2566
     * Subscribes courses to the given session and optionally (default)
2567
     * unsubscribe previous users.
2568
     *
2569
     * @author Carlos Vargas from existing code
2570
     *
2571
     * @param int   $sessionId
2572
     * @param array $courseList                     List of courses int ids
2573
     * @param bool  $removeExistingCoursesWithUsers Whether to unsubscribe
2574
     *                                              existing courses and users (true, default) or not (false)
2575
     * @param bool  $copyEvaluation                 from base course to session course
2576
     * @param bool  $copyCourseTeachersAsCoach
2577
     * @param bool  $importAssignments
2578
     *
2579
     * @throws Exception
2580
     *
2581
     * @return bool False on failure, true otherwise
2582
     * */
2583
    public static function add_courses_to_session(
2584
        $sessionId,
2585
        $courseList,
2586
        $removeExistingCoursesWithUsers = true,
2587
        $copyEvaluation = false,
2588
        $copyCourseTeachersAsCoach = false,
2589
        $importAssignments = false
2590
    ) {
2591
        $sessionId = (int) $sessionId;
2592
2593
        if (empty($sessionId) || empty($courseList)) {
2594
            return false;
2595
        }
2596
2597
        if ($importAssignments) {
2598
            require_once api_get_path(SYS_CODE_PATH).'work/work.lib.php';
2599
        }
2600
2601
        $session = api_get_session_entity($sessionId);
2602
2603
        if (!$session) {
2604
            return false;
2605
        }
2606
        $sessionVisibility = $session->getVisibility();
2607
2608
        $tbl_session_rel_course_rel_user = Database::get_main_table(TABLE_MAIN_SESSION_COURSE_USER);
2609
        $tbl_session = Database::get_main_table(TABLE_MAIN_SESSION);
2610
        $tbl_session_rel_user = Database::get_main_table(TABLE_MAIN_SESSION_USER);
2611
        $tbl_session_rel_course = Database::get_main_table(TABLE_MAIN_SESSION_COURSE);
2612
2613
        // Get list of courses subscribed to this session
2614
        $sql = "SELECT c_id
2615
                FROM $tbl_session_rel_course
2616
                WHERE session_id = $sessionId";
2617
        $rs = Database::query($sql);
2618
        $existingCourses = Database::store_result($rs);
2619
        $nbr_courses = count($existingCourses);
2620
2621
        // Get list of users subscribed to this session
2622
        $sql = "SELECT user_id
2623
                FROM $tbl_session_rel_user
2624
                WHERE
2625
                    session_id = $sessionId AND
2626
                    relation_type<>".SESSION_RELATION_TYPE_RRHH;
2627
        $result = Database::query($sql);
2628
        $user_list = Database::store_result($result);
2629
2630
        // Remove existing courses from the session.
2631
        if ($removeExistingCoursesWithUsers === true && !empty($existingCourses)) {
2632
            foreach ($existingCourses as $existingCourse) {
2633
                if (!in_array($existingCourse['c_id'], $courseList)) {
2634
                    $sql = "DELETE FROM $tbl_session_rel_course
2635
                            WHERE
2636
                                c_id = ".$existingCourse['c_id']." AND
2637
                                session_id = $sessionId";
2638
                    Database::query($sql);
2639
2640
                    $sql = "DELETE FROM $tbl_session_rel_course_rel_user
2641
                            WHERE
2642
                                c_id = ".$existingCourse['c_id']." AND
2643
                                session_id = $sessionId";
2644
                    Database::query($sql);
2645
2646
                    Event::addEvent(
2647
                        LOG_SESSION_DELETE_COURSE,
2648
                        LOG_COURSE_ID,
2649
                        $existingCourse['c_id'],
2650
                        api_get_utc_datetime(),
2651
                        api_get_user_id(),
2652
                        $existingCourse['c_id'],
2653
                        $sessionId
2654
                    );
2655
2656
                    CourseManager::remove_course_ranking(
2657
                        $existingCourse['c_id'],
2658
                        $sessionId
2659
                    );
2660
                    $nbr_courses--;
2661
                }
2662
            }
2663
        }
2664
2665
        $em = Database::getManager();
2666
2667
        // Pass through the courses list we want to add to the session
2668
        foreach ($courseList as $courseId) {
2669
            $courseInfo = api_get_course_info_by_id($courseId);
2670
2671
            // If course doesn't exists continue!
2672
            if (empty($courseInfo)) {
2673
                continue;
2674
            }
2675
2676
            $exists = false;
2677
            // check if the course we want to add is already subscribed
2678
            foreach ($existingCourses as $existingCourse) {
2679
                if ($courseId == $existingCourse['c_id']) {
2680
                    $exists = true;
2681
                }
2682
            }
2683
2684
            if (!$exists) {
2685
                // Copy gradebook categories and links (from base course)
2686
                // to the new course session
2687
                if ($copyEvaluation) {
2688
                    // it gets the main categories ordered by parent
2689
                    $cats = Category::load(null, null, $courseInfo['code'], null, null, null, 'ORDER BY parent_id ASC');
2690
                    if (!empty($cats)) {
2691
                        $sessionCategory = Category::load(
2692
                            null,
2693
                            null,
2694
                            $courseInfo['code'],
2695
                            null,
2696
                            null,
2697
                            $sessionId,
2698
                            false
2699
                        );
2700
2701
                        $sessionCategoriesId = [];
2702
                        if (empty($sessionCategory)) {
2703
                            // It sets the values from the main categories to be copied
2704
                            foreach ($cats as $origCat) {
2705
                                $cat = new Category();
2706
                                $sessionName = $session->getName();
2707
                                $cat->set_name($origCat->get_name().' - '.get_lang('Session').' '.$sessionName);
2708
                                $cat->set_session_id($sessionId);
2709
                                $cat->set_course_code($origCat->get_course_code());
2710
                                $cat->set_description($origCat->get_description());
2711
                                $cat->set_parent_id($origCat->get_parent_id());
2712
                                $cat->set_weight($origCat->get_weight());
2713
                                $cat->set_visible(0);
2714
                                $cat->set_certificate_min_score($origCat->getCertificateMinScore());
2715
                                $cat->setGenerateCertificates($origCat->getGenerateCertificates());
2716
                                $cat->setIsRequirement($origCat->getIsRequirement());
2717
                                $cat->add();
2718
                                $sessionGradeBookCategoryId = $cat->get_id();
2719
                                $sessionCategoriesId[$origCat->get_id()] = $sessionGradeBookCategoryId;
2720
2721
                                // it updates the new parent id
2722
                                if ($origCat->get_parent_id() > 0) {
2723
                                    $cat->updateParentId($sessionCategoriesId[$origCat->get_parent_id()], $sessionGradeBookCategoryId);
2724
                                }
2725
                            }
2726
                        } else {
2727
                            if (!empty($sessionCategory[0])) {
2728
                                $sessionCategoriesId[0] = $sessionCategory[0]->get_id();
2729
                            }
2730
                        }
2731
2732
                        $categoryIdList = [];
2733
                        /** @var Category $cat */
2734
                        foreach ($cats as $cat) {
2735
                            $categoryIdList[$cat->get_id()] = $cat->get_id();
2736
                        }
2737
2738
                        $newCategoryIdList = [];
2739
                        foreach ($cats as $cat) {
2740
                            $links = $cat->get_links(
2741
                                null,
2742
                                false,
2743
                                $courseInfo['code'],
2744
                                0
2745
                            );
2746
2747
                            if (!empty($links)) {
2748
                                /** @var AbstractLink $link */
2749
                                foreach ($links as $link) {
2750
                                    $newCategoryId = isset($sessionCategoriesId[$link->getCategory()->get_id()]) ? $sessionCategoriesId[$link->getCategory()->get_id()] : $sessionCategoriesId[0];
2751
                                    $link->set_category_id($newCategoryId);
2752
                                    $link->add();
2753
                                }
2754
                            }
2755
2756
                            $evaluationList = $cat->get_evaluations(
2757
                                null,
2758
                                false,
2759
                                $courseInfo['code'],
2760
                                0
2761
                            );
2762
2763
                            if (!empty($evaluationList)) {
2764
                                /** @var Evaluation $evaluation */
2765
                                foreach ($evaluationList as $evaluation) {
2766
                                    $newCategoryId = isset($sessionCategoriesId[$evaluation->getCategory()->get_id()]) ? $sessionCategoriesId[$evaluation->getCategory()->get_id()] : $sessionCategoriesId[0];
2767
                                    $evaluation->set_category_id($newCategoryId);
2768
                                    $evaluation->add();
2769
                                }
2770
                            }
2771
                        }
2772
2773
                        // Create
2774
                        DocumentManager::generateDefaultCertificate(
2775
                            $courseInfo,
2776
                            true,
2777
                            $sessionId
2778
                        );
2779
                    }
2780
                }
2781
2782
                if ($importAssignments) {
2783
                    $workTable = Database::get_course_table(TABLE_STUDENT_PUBLICATION);
2784
                    $sql = " SELECT * FROM $workTable
2785
                             WHERE active = 1 AND
2786
                                   c_id = $courseId AND
2787
                                   parent_id = 0 AND
2788
                                   (session_id IS NULL OR session_id = 0)";
2789
                    $result = Database::query($sql);
2790
                    $workList = Database::store_result($result, 'ASSOC');
2791
2792
                    foreach ($workList as $work) {
2793
                        $values = [
2794
                            'work_title' => $work['title'],
2795
                            'new_dir' => $work['url'].'_session_'.$sessionId,
2796
                            'description' => $work['description'],
2797
                            'qualification' => $work['qualification'],
2798
                            'allow_text_assignment' => $work['allow_text_assignment'],
2799
                        ];
2800
2801
                        addDir(
2802
                            $values,
2803
                            api_get_user_id(),
2804
                            $courseInfo,
2805
                            0,
2806
                            $sessionId
2807
                        );
2808
                    }
2809
                }
2810
2811
                // If the course isn't subscribed yet
2812
                $sql = "INSERT INTO $tbl_session_rel_course (session_id, c_id, nbr_users, position)
2813
                        VALUES ($sessionId, $courseId, 0, 0)";
2814
                Database::query($sql);
2815
2816
                if (api_get_configuration_value('allow_skill_rel_items')) {
2817
                    $skillRelCourseRepo = $em->getRepository('ChamiloSkillBundle:SkillRelCourse');
2818
                    $items = $skillRelCourseRepo->findBy(['course' => $courseId, 'session' => null]);
2819
                    /** @var \Chamilo\SkillBundle\Entity\SkillRelCourse $item */
2820
                    foreach ($items as $item) {
2821
                        $exists = $skillRelCourseRepo->findOneBy(['course' => $courseId, 'session' => $session]);
2822
                        if (null === $exists) {
2823
                            $skillRelCourse = clone $item;
2824
                            $skillRelCourse->setSession($session);
2825
                            $em->persist($skillRelCourse);
2826
                        }
2827
                    }
2828
                    $em->flush();
2829
                }
2830
2831
                Event::addEvent(
2832
                    LOG_SESSION_ADD_COURSE,
2833
                    LOG_COURSE_ID,
2834
                    $courseId,
2835
                    api_get_utc_datetime(),
2836
                    api_get_user_id(),
2837
                    $courseId,
2838
                    $sessionId
2839
                );
2840
2841
                // We add the current course in the existing courses array,
2842
                // to avoid adding another time the current course
2843
                $existingCourses[] = ['c_id' => $courseId];
2844
                $nbr_courses++;
2845
2846
                // Subscribe all the users from the session to this course inside the session
2847
                self::insertUsersInCourse(
2848
                    array_column($user_list, 'user_id'),
2849
                    $courseId,
2850
                    $sessionId,
2851
                    ['visibility' => $sessionVisibility]
2852
                );
2853
            }
2854
2855
            if ($copyCourseTeachersAsCoach) {
2856
                $teachers = CourseManager::get_teacher_list_from_course_code($courseInfo['code']);
2857
                if (!empty($teachers)) {
2858
                    foreach ($teachers as $teacher) {
2859
                        self::updateCoaches(
2860
                            $sessionId,
2861
                            $courseId,
2862
                            [$teacher['user_id']],
2863
                            false
2864
                        );
2865
                    }
2866
                }
2867
            }
2868
        }
2869
2870
        $sql = "UPDATE $tbl_session SET nbr_courses = $nbr_courses WHERE id = $sessionId";
2871
        Database::query($sql);
2872
2873
        return true;
2874
    }
2875
2876
    /**
2877
     * Unsubscribe course from a session.
2878
     *
2879
     * @param int $session_id
2880
     * @param int $course_id
2881
     *
2882
     * @return bool True in case of success, false otherwise
2883
     */
2884
    public static function unsubscribe_course_from_session($session_id, $course_id)
2885
    {
2886
        $session_id = (int) $session_id;
2887
        $course_id = (int) $course_id;
2888
2889
        $tbl_session_rel_course = Database::get_main_table(TABLE_MAIN_SESSION_COURSE);
2890
        $tbl_session_rel_course_rel_user = Database::get_main_table(TABLE_MAIN_SESSION_COURSE_USER);
2891
        $tbl_session = Database::get_main_table(TABLE_MAIN_SESSION);
2892
2893
        // Get course code
2894
        $course_code = CourseManager::get_course_code_from_course_id($course_id);
2895
2896
        if (empty($course_code)) {
2897
            return false;
2898
        }
2899
2900
        // Unsubscribe course
2901
        $sql = "DELETE FROM $tbl_session_rel_course
2902
                WHERE c_id = $course_id AND session_id = $session_id";
2903
        $result = Database::query($sql);
2904
        $nb_affected = Database::affected_rows($result);
2905
2906
        $sql = "DELETE FROM $tbl_session_rel_course_rel_user
2907
                WHERE c_id = $course_id AND session_id = $session_id";
2908
        Database::query($sql);
2909
2910
        Event::addEvent(
2911
            LOG_SESSION_DELETE_COURSE,
2912
            LOG_COURSE_ID,
2913
            $course_id,
2914
            api_get_utc_datetime(),
2915
            api_get_user_id(),
2916
            $course_id,
2917
            $session_id
2918
        );
2919
2920
        if ($nb_affected > 0) {
2921
            // Update number of courses in the session
2922
            $sql = "UPDATE $tbl_session SET nbr_courses= nbr_courses - $nb_affected
2923
                    WHERE id = $session_id";
2924
            Database::query($sql);
2925
2926
            return true;
2927
        }
2928
2929
        return false;
2930
    }
2931
2932
    /**
2933
     * Creates a new extra field for a given session.
2934
     *
2935
     * @param string $variable    Field's internal variable name
2936
     * @param int    $fieldType   Field's type
2937
     * @param string $displayText Field's language var name
2938
     * @param string $default     Field's default value
2939
     *
2940
     * @return int new extra field id
2941
     */
2942
    public static function create_session_extra_field(
2943
        $variable,
2944
        $fieldType,
2945
        $displayText,
2946
        $default = ''
2947
    ) {
2948
        $extraField = new ExtraFieldModel('session');
2949
        $params = [
2950
            'variable' => $variable,
2951
            'field_type' => $fieldType,
2952
            'display_text' => $displayText,
2953
            'default_value' => $default,
2954
        ];
2955
2956
        return $extraField->save($params);
2957
    }
2958
2959
    /**
2960
     * Update an extra field value for a given session.
2961
     *
2962
     * @param int    $sessionId Session ID
2963
     * @param string $variable  Field variable name
2964
     * @param string $value     Optional. Default field value
2965
     *
2966
     * @return bool|int An integer when register a new extra field. And boolean when update the extrafield
2967
     */
2968
    public static function update_session_extra_field_value($sessionId, $variable, $value = '')
2969
    {
2970
        $extraFieldValue = new ExtraFieldValue('session');
2971
        $params = [
2972
            'item_id' => $sessionId,
2973
            'variable' => $variable,
2974
            'value' => $value,
2975
        ];
2976
2977
        return $extraFieldValue->save($params);
2978
    }
2979
2980
    /**
2981
     * Checks the relationship between a session and a course.
2982
     *
2983
     * @param int $session_id
2984
     * @param int $courseId
2985
     *
2986
     * @return bool returns TRUE if the session and the course are related, FALSE otherwise
2987
     * */
2988
    public static function relation_session_course_exist($session_id, $courseId)
2989
    {
2990
        $tbl_session_course = Database::get_main_table(TABLE_MAIN_SESSION_COURSE);
2991
        $return_value = false;
2992
        $sql = "SELECT c_id FROM $tbl_session_course
2993
                WHERE
2994
                  session_id = ".intval($session_id)." AND
2995
                  c_id = ".intval($courseId);
2996
        $result = Database::query($sql);
2997
        $num = Database::num_rows($result);
2998
        if ($num > 0) {
2999
            $return_value = true;
3000
        }
3001
3002
        return $return_value;
3003
    }
3004
3005
    /**
3006
     * Get the session information by name.
3007
     *
3008
     * @param string $name
3009
     *
3010
     * @return mixed false if the session does not exist, array if the session exist
3011
     */
3012
    public static function get_session_by_name($name)
3013
    {
3014
        $tbl_session = Database::get_main_table(TABLE_MAIN_SESSION);
3015
        $name = Database::escape_string(trim($name));
3016
        if (empty($name)) {
3017
            return false;
3018
        }
3019
3020
        $sql = 'SELECT *
3021
		        FROM '.$tbl_session.'
3022
		        WHERE name = "'.$name.'"';
3023
        $result = Database::query($sql);
3024
        $num = Database::num_rows($result);
3025
        if ($num > 0) {
3026
            return Database::fetch_array($result);
3027
        } else {
3028
            return false;
3029
        }
3030
    }
3031
3032
    /**
3033
     * @param int $sessionId
3034
     * @param int $name
3035
     *
3036
     * @return bool
3037
     */
3038
    public static function sessionNameExistBesidesMySession($sessionId, $name)
3039
    {
3040
        $table = Database::get_main_table(TABLE_MAIN_SESSION);
3041
        $name = Database::escape_string(trim($name));
3042
        $sessionId = (int) $sessionId;
3043
3044
        if (empty($name)) {
3045
            return false;
3046
        }
3047
3048
        $sql = "SELECT *
3049
		        FROM $table
3050
		        WHERE name = '$name' AND id <> $sessionId ";
3051
        $result = Database::query($sql);
3052
        $num = Database::num_rows($result);
3053
        if ($num > 0) {
3054
            return true;
3055
        }
3056
3057
        return false;
3058
    }
3059
3060
    /**
3061
     * Create a session category.
3062
     *
3063
     * @author Jhon Hinojosa <[email protected]>, from existing code
3064
     *
3065
     * @param string        name
3066
     * @param int        year_start
3067
     * @param int        month_start
3068
     * @param int        day_start
3069
     * @param int        year_end
3070
     * @param int        month_end
3071
     * @param int        day_end
3072
     *
3073
     * @return int session ID
3074
     * */
3075
    public static function create_category_session(
3076
        $sname,
3077
        $syear_start,
3078
        $smonth_start,
3079
        $sday_start,
3080
        $syear_end,
3081
        $smonth_end,
3082
        $sday_end
3083
    ) {
3084
        $tbl_session_category = Database::get_main_table(TABLE_MAIN_SESSION_CATEGORY);
3085
3086
        $name = trim($sname);
3087
        $name = html_filter($name);
3088
        $name = RemoveOnAttributes::filter($name);
3089
        $name = Database::escape_string($name);
3090
3091
        $year_start = intval($syear_start);
3092
        $month_start = intval($smonth_start);
3093
        $day_start = intval($sday_start);
3094
        $year_end = intval($syear_end);
3095
        $month_end = intval($smonth_end);
3096
        $day_end = intval($sday_end);
3097
        $date_start = "$year_start-".(($month_start < 10) ? "0$month_start" : $month_start)."-".(($day_start < 10) ? "0$day_start" : $day_start);
3098
        $date_end = "$year_end-".(($month_end < 10) ? "0$month_end" : $month_end)."-".(($day_end < 10) ? "0$day_end" : $day_end);
3099
        if (empty($name)) {
3100
            $msg = get_lang('SessionCategoryNameIsRequired');
3101
3102
            return $msg;
3103
        } elseif (!$month_start || !$day_start || !$year_start || !checkdate($month_start, $day_start, $year_start)) {
3104
            $msg = get_lang('InvalidStartDate');
3105
3106
            return $msg;
3107
        } elseif (!$month_end && !$day_end && !$year_end) {
3108
            $date_end = '';
3109
        } elseif (!$month_end || !$day_end || !$year_end || !checkdate($month_end, $day_end, $year_end)) {
3110
            $msg = get_lang('InvalidEndDate');
3111
3112
            return $msg;
3113
        } elseif ($date_start >= $date_end) {
3114
            $msg = get_lang('StartDateShouldBeBeforeEndDate');
3115
3116
            return $msg;
3117
        }
3118
        $access_url_id = api_get_current_access_url_id();
3119
3120
        $params = [
3121
            'name' => $name,
3122
            'date_start' => $date_start,
3123
            'access_url_id' => $access_url_id,
3124
        ];
3125
3126
        if (!empty($date_end)) {
3127
            $params['date_end'] = $date_end;
3128
        }
3129
3130
        $id = Database::insert($tbl_session_category, $params);
3131
3132
        // Add event to system log
3133
        $user_id = api_get_user_id();
3134
        Event::addEvent(
3135
            LOG_SESSION_CATEGORY_CREATE,
3136
            LOG_SESSION_CATEGORY_ID,
3137
            $id,
3138
            api_get_utc_datetime(),
3139
            $user_id
3140
        );
3141
3142
        return $id;
3143
    }
3144
3145
    /**
3146
     * Edit a sessions category.
3147
     *
3148
     * @author Jhon Hinojosa <[email protected]>,from existing code
3149
     *
3150
     * @param int        id
3151
     * @param string        name
3152
     * @param int        year_start
3153
     * @param int        month_start
3154
     * @param int        day_start
3155
     * @param int        year_end
3156
     * @param int        month_end
3157
     * @param int        day_end
3158
     *
3159
     * @return bool
3160
     *              The parameter id is a primary key
3161
     * */
3162
    public static function edit_category_session(
3163
        $id,
3164
        $sname,
3165
        $syear_start,
3166
        $smonth_start,
3167
        $sday_start,
3168
        $syear_end,
3169
        $smonth_end,
3170
        $sday_end
3171
    ) {
3172
        $tbl_session_category = Database::get_main_table(TABLE_MAIN_SESSION_CATEGORY);
3173
        $name = trim($sname);
3174
        $name = html_filter($name);
3175
        $name = RemoveOnAttributes::filter($name);
3176
        $year_start = intval($syear_start);
3177
        $month_start = intval($smonth_start);
3178
        $day_start = intval($sday_start);
3179
        $year_end = intval($syear_end);
3180
        $month_end = intval($smonth_end);
3181
        $day_end = intval($sday_end);
3182
        $id = intval($id);
3183
        $date_start = "$year_start-".(($month_start < 10) ? "0$month_start" : $month_start)."-".(($day_start < 10) ? "0$day_start" : $day_start);
3184
        $date_end = "$year_end-".(($month_end < 10) ? "0$month_end" : $month_end)."-".(($day_end < 10) ? "0$day_end" : $day_end);
3185
3186
        if (empty($name)) {
3187
            $msg = get_lang('SessionCategoryNameIsRequired');
3188
3189
            return $msg;
3190
        } elseif (!$month_start || !$day_start || !$year_start || !checkdate($month_start, $day_start, $year_start)) {
3191
            $msg = get_lang('InvalidStartDate');
3192
3193
            return $msg;
3194
        } elseif (!$month_end && !$day_end && !$year_end) {
3195
            $date_end = null;
3196
        } elseif (!$month_end || !$day_end || !$year_end || !checkdate($month_end, $day_end, $year_end)) {
3197
            $msg = get_lang('InvalidEndDate');
3198
3199
            return $msg;
3200
        } elseif ($date_start >= $date_end) {
3201
            $msg = get_lang('StartDateShouldBeBeforeEndDate');
3202
3203
            return $msg;
3204
        }
3205
        if ($date_end != null) {
3206
            $sql = "UPDATE $tbl_session_category
3207
                    SET
3208
                        name = '".Database::escape_string($name)."',
3209
                        date_start = '$date_start' ,
3210
                        date_end = '$date_end'
3211
                    WHERE id= $id";
3212
        } else {
3213
            $sql = "UPDATE $tbl_session_category SET
3214
                        name = '".Database::escape_string($name)."',
3215
                        date_start = '$date_start',
3216
                        date_end = NULL
3217
                    WHERE id= $id";
3218
        }
3219
        $result = Database::query($sql);
3220
3221
        return $result ? true : false;
3222
    }
3223
3224
    /**
3225
     * Delete sessions categories.
3226
     *
3227
     * @param array|int $categoryId
3228
     * @param bool      $deleteSessions Optional. Include delete session.
3229
     * @param bool      $fromWs         Optional. True if the function is called by a webservice, false otherwise.
3230
     *
3231
     * @return bool Nothing, or false on error
3232
     *              The parameters is a array to delete sessions
3233
     *
3234
     * @author Jhon Hinojosa <[email protected]>, from existing code
3235
     */
3236
    public static function delete_session_category($categoryId, $deleteSessions = false, $fromWs = false)
3237
    {
3238
        $tblSessionCategory = Database::get_main_table(TABLE_MAIN_SESSION_CATEGORY);
3239
        $tblSession = Database::get_main_table(TABLE_MAIN_SESSION);
3240
3241
        if (is_array($categoryId)) {
3242
            $categoryId = array_map('intval', $categoryId);
3243
        } else {
3244
            $categoryId = [(int) $categoryId];
3245
        }
3246
3247
        $categoryId = implode(', ', $categoryId);
3248
3249
        if ($deleteSessions) {
3250
            $sql = "SELECT id FROM $tblSession WHERE session_category_id IN ($categoryId)";
3251
            $result = Database::query($sql);
3252
            while ($rows = Database::fetch_array($result)) {
3253
                $sessionId = $rows['id'];
3254
                self::delete($sessionId, $fromWs);
3255
            }
3256
        } else {
3257
            $sql = "UPDATE $tblSession SET session_category_id = NULL WHERE session_category_id IN ($categoryId)";
3258
            Database::query($sql);
3259
        }
3260
3261
        $sql = "DELETE FROM $tblSessionCategory WHERE id IN ($categoryId)";
3262
        Database::query($sql);
3263
3264
        // Add event to system log
3265
        Event::addEvent(
3266
            LOG_SESSION_CATEGORY_DELETE,
3267
            LOG_SESSION_CATEGORY_ID,
3268
            $categoryId,
3269
            api_get_utc_datetime(),
3270
            api_get_user_id()
3271
        );
3272
3273
        return true;
3274
    }
3275
3276
    /**
3277
     * Get a list of sessions of which the given conditions match with an = 'cond'.
3278
     *
3279
     * @param array $conditions          a list of condition example :
3280
     *                                   array('status' => STUDENT) or
3281
     *                                   array('s.name' => array('operator' => 'LIKE', value = '%$needle%'))
3282
     * @param array $order_by            a list of fields on which sort
3283
     * @param int   $urlId
3284
     * @param array $onlyThisSessionList
3285
     *
3286
     * @return array an array with all sessions of the platform
3287
     *
3288
     * @todo   optional course code parameter, optional sorting parameters...
3289
     */
3290
    public static function get_sessions_list(
3291
        $conditions = [],
3292
        $order_by = [],
3293
        $from = null,
3294
        $to = null,
3295
        $urlId = 0,
3296
        $onlyThisSessionList = [],
3297
        $includeSessionWithNoCourse = false
3298
    ) {
3299
        $session_table = Database::get_main_table(TABLE_MAIN_SESSION);
3300
        $session_category_table = Database::get_main_table(TABLE_MAIN_SESSION_CATEGORY);
3301
        $user_table = Database::get_main_table(TABLE_MAIN_USER);
3302
        $table_access_url_rel_session = Database::get_main_table(TABLE_MAIN_ACCESS_URL_REL_SESSION);
3303
        $session_course_table = Database::get_main_table(TABLE_MAIN_SESSION_COURSE);
3304
        $course_table = Database::get_main_table(TABLE_MAIN_COURSE);
3305
        $urlId = empty($urlId) ? api_get_current_access_url_id() : (int) $urlId;
3306
        $return_array = [];
3307
        $courseFrom ="LEFT JOIN " . $session_course_table . " sco ON (sco.session_id = s.id)
3308
				INNER JOIN " . $course_table . " c ON sco.c_id = c.id";
3309
3310
        if ($includeSessionWithNoCourse) {
3311
            $courseFrom = "";
3312
        }
3313
3314
        $sql_query = " SELECT
3315
                    DISTINCT(s.id),
3316
                    s.name,
3317
                    s.nbr_courses,
3318
                    s.access_start_date,
3319
                    s.access_end_date,
3320
                    u.firstname,
3321
                    u.lastname,
3322
                    sc.name as category_name,
3323
                    s.promotion_id
3324
				FROM $session_table s
3325
				INNER JOIN $user_table u ON s.id_coach = u.user_id
3326
				INNER JOIN $table_access_url_rel_session ar ON ar.session_id = s.id
3327
				LEFT JOIN  $session_category_table sc ON s.session_category_id = sc.id
3328
				$courseFrom
3329
				WHERE ar.access_url_id = $urlId ";
3330
3331
        $availableFields = [
3332
            's.id',
3333
            's.name',
3334
            'c.id',
3335
        ];
3336
3337
        $availableOperator = [
3338
            'like',
3339
            '>=',
3340
            '<=',
3341
            '=',
3342
        ];
3343
3344
        if (count($conditions) > 0) {
3345
            foreach ($conditions as $field => $options) {
3346
                $operator = strtolower($options['operator']);
3347
                $value = Database::escape_string($options['value']);
3348
                if (in_array($field, $availableFields) && in_array($operator, $availableOperator)) {
3349
                    $sql_query .= ' AND '.$field." $operator '".$value."'";
3350
                }
3351
            }
3352
        }
3353
3354
        if (!empty($onlyThisSessionList)) {
3355
            $onlyThisSessionList = array_map('intval', $onlyThisSessionList);
3356
            $onlyThisSessionList = implode("','", $onlyThisSessionList);
3357
            $sql_query .= " AND s.id IN ('$onlyThisSessionList') ";
3358
        }
3359
3360
        $orderAvailableList = ['name'];
3361
        if (count($order_by) > 0) {
3362
            $order = null;
3363
            $direction = null;
3364
            if (isset($order_by[0]) && in_array($order_by[0], $orderAvailableList)) {
3365
                $order = $order_by[0];
3366
            }
3367
            if (isset($order_by[1]) && in_array(strtolower($order_by[1]), ['desc', 'asc'])) {
3368
                $direction = $order_by[1];
3369
            }
3370
3371
            if (!empty($order)) {
3372
                $sql_query .= " ORDER BY `$order` $direction ";
3373
            }
3374
        }
3375
3376
        if (!is_null($from) && !is_null($to)) {
3377
            $to = (int) $to;
3378
            $from = (int) $from;
3379
            $sql_query .= "LIMIT $from, $to";
3380
        }
3381
3382
        $sql_result = Database::query($sql_query);
3383
        if (Database::num_rows($sql_result) > 0) {
3384
            while ($result = Database::fetch_array($sql_result)) {
3385
                $return_array[$result['id']] = $result;
3386
            }
3387
        }
3388
3389
        return $return_array;
3390
    }
3391
3392
    /**
3393
     * Get the session category information by id.
3394
     *
3395
     * @param string session category ID
3396
     *
3397
     * @return mixed false if the session category does not exist, array if the session category exists
3398
     */
3399
    public static function get_session_category($id)
3400
    {
3401
        $table = Database::get_main_table(TABLE_MAIN_SESSION_CATEGORY);
3402
        $id = (int) $id;
3403
        $sql = "SELECT id, name, date_start, date_end
3404
                FROM $table
3405
                WHERE id= $id";
3406
        $result = Database::query($sql);
3407
        $num = Database::num_rows($result);
3408
        if ($num > 0) {
3409
            return Database::fetch_array($result);
3410
        } else {
3411
            return false;
3412
        }
3413
    }
3414
3415
    /**
3416
     * Get Hot Sessions (limit 8).
3417
     *
3418
     * @return array with sessions
3419
     */
3420
    public static function getHotSessions()
3421
    {
3422
        $tbl_session = Database::get_main_table(TABLE_MAIN_SESSION);
3423
        $tbl_session_category = Database::get_main_table(TABLE_MAIN_SESSION_CATEGORY);
3424
        $tbl_users = Database::get_main_table(TABLE_MAIN_USER);
3425
        $tbl_extra_fields = Database::get_main_table(TABLE_EXTRA_FIELD_VALUES);
3426
        $tbl_session_user = Database::get_main_table(TABLE_MAIN_SESSION_USER);
3427
        $tbl_lp = Database::get_course_table(TABLE_LP_MAIN);
3428
3429
        $extraField = new ExtraFieldModel('session');
3430
        $field = $extraField->get_handler_field_info_by_field_variable('image');
3431
3432
        $sql = "SELECT
3433
                s.id,
3434
                s.name,
3435
                s.id_coach,
3436
                u.firstname,
3437
                u.lastname,
3438
                s.session_category_id,
3439
                c.name as category_name,
3440
                s.description,
3441
                (SELECT COUNT(*) FROM $tbl_session_user WHERE session_id = s.id) as users,
3442
				(SELECT COUNT(*) FROM $tbl_lp WHERE session_id = s.id) as lessons ";
3443
        if ($field !== false) {
3444
            $fieldId = $field['id'];
3445
            $sql .= ",(SELECT value FROM $tbl_extra_fields WHERE field_id = $fieldId AND item_id = s.id) as image ";
3446
        }
3447
        $sql .= " FROM $tbl_session s
3448
                LEFT JOIN $tbl_session_category c
3449
                    ON s.session_category_id = c.id
3450
                INNER JOIN $tbl_users u
3451
                    ON s.id_coach = u.id
3452
                ORDER BY 9 DESC
3453
                LIMIT 8";
3454
        $result = Database::query($sql);
3455
3456
        if (Database::num_rows($result) > 0) {
3457
            $plugin = BuyCoursesPlugin::create();
3458
            $checker = $plugin->isEnabled();
3459
            $sessions = [];
3460
            while ($row = Database::fetch_array($result, 'ASSOC')) {
3461
                if (!isset($row['image'])) {
3462
                    $row['image'] = '';
3463
                }
3464
                $row['on_sale'] = '';
3465
                if ($checker) {
3466
                    $row['on_sale'] = $plugin->getItemByProduct(
3467
                        $row['id'],
3468
                        BuyCoursesPlugin::PRODUCT_TYPE_SESSION
3469
                    );
3470
                }
3471
                $sessions[] = $row;
3472
            }
3473
3474
            return $sessions;
3475
        }
3476
3477
        return false;
3478
    }
3479
3480
    /**
3481
     * Get all session categories (filter by access_url_id).
3482
     *
3483
     * @return mixed false if the session category does not exist, array if the session category exists
3484
     */
3485
    public static function get_all_session_category()
3486
    {
3487
        $table = Database::get_main_table(TABLE_MAIN_SESSION_CATEGORY);
3488
        $id = api_get_current_access_url_id();
3489
        $sql = 'SELECT * FROM '.$table.'
3490
                WHERE access_url_id = '.$id.'
3491
                ORDER BY name ASC';
3492
        $result = Database::query($sql);
3493
        if (Database::num_rows($result) > 0) {
3494
            $data = [];
3495
3496
            while ($category = Database::fetch_assoc($result)) {
3497
                $category['name'] = Security::remove_XSS($category['name']);
3498
                $data[] = $category;
3499
            }
3500
3501
            return $data;
3502
        }
3503
3504
        return false;
3505
    }
3506
3507
    /**
3508
     * Assign a coach to course in session with status = 2.
3509
     *
3510
     * @param int  $userId
3511
     * @param int  $sessionId
3512
     * @param int  $courseId
3513
     * @param bool $noCoach   optional, if is true the user don't be a coach now,
3514
     *                        otherwise it'll assign a coach
3515
     *
3516
     * @return bool true if there are affected rows, otherwise false
3517
     */
3518
    public static function set_coach_to_course_session(
3519
        $userId,
3520
        $sessionId = 0,
3521
        $courseId = 0,
3522
        $noCoach = false
3523
    ) {
3524
        // Definition of variables
3525
        $userId = (int) $userId;
3526
3527
        $sessionId = !empty($sessionId) ? (int) $sessionId : api_get_session_id();
3528
        $courseId = !empty($courseId) ? (int) $courseId : api_get_course_id();
3529
3530
        if (empty($sessionId) || empty($courseId) || empty($userId)) {
3531
            return false;
3532
        }
3533
3534
        // Table definition
3535
        $tblSessionRelCourseRelUser = Database::get_main_table(TABLE_MAIN_SESSION_COURSE_USER);
3536
        $tblSessionRelUser = Database::get_main_table(TABLE_MAIN_SESSION_USER);
3537
        $tblUser = Database::get_main_table(TABLE_MAIN_USER);
3538
3539
        $allowedTeachers = implode(',', UserManager::getAllowedRolesAsTeacher());
3540
3541
        // check if user is a teacher
3542
        $sql = "SELECT * FROM $tblUser WHERE status IN ($allowedTeachers) AND user_id = $userId";
3543
3544
        $rsCheckUser = Database::query($sql);
3545
3546
        if (Database::num_rows($rsCheckUser) <= 0) {
3547
            return false;
3548
        }
3549
3550
        if ($noCoach) {
3551
            // check if user_id exists in session_rel_user (if the user is
3552
            // subscribed to the session in any manner)
3553
            $sql = "SELECT user_id FROM $tblSessionRelUser
3554
                    WHERE
3555
                        session_id = $sessionId AND
3556
                        user_id = $userId";
3557
            $res = Database::query($sql);
3558
3559
            if (Database::num_rows($res) > 0) {
3560
                // The user is already subscribed to the session. Change the
3561
                // record so the user is NOT a coach for this course anymore
3562
                // and then exit
3563
                $sql = "UPDATE $tblSessionRelCourseRelUser
3564
                        SET status = 0
3565
                        WHERE
3566
                            session_id = $sessionId AND
3567
                            c_id = $courseId AND
3568
                            user_id = $userId ";
3569
                $result = Database::query($sql);
3570
3571
                return Database::affected_rows($result) > 0;
3572
            }
3573
3574
            // The user is not subscribed to the session, so make sure
3575
            // he isn't subscribed to a course in this session either
3576
            // and then exit
3577
            $sql = "DELETE FROM $tblSessionRelCourseRelUser
3578
                    WHERE
3579
                        session_id = $sessionId AND
3580
                        c_id = $courseId AND
3581
                        user_id = $userId ";
3582
            $result = Database::query($sql);
3583
3584
            return Database::affected_rows($result) > 0;
3585
        }
3586
3587
        // Assign user as a coach to course
3588
        // First check if the user is registered to the course
3589
        $sql = "SELECT user_id FROM $tblSessionRelCourseRelUser
3590
                WHERE
3591
                    session_id = $sessionId AND
3592
                    c_id = $courseId AND
3593
                    user_id = $userId";
3594
        $rs_check = Database::query($sql);
3595
3596
        // Then update or insert.
3597
        if (Database::num_rows($rs_check) > 0) {
3598
            $sql = "UPDATE $tblSessionRelCourseRelUser SET status = 2
3599
                    WHERE
3600
                        session_id = $sessionId AND
3601
                        c_id = $courseId AND
3602
                        user_id = $userId ";
3603
            $result = Database::query($sql);
3604
3605
            return Database::affected_rows($result) > 0;
3606
        }
3607
3608
        $sql = "INSERT INTO $tblSessionRelCourseRelUser(session_id, c_id, user_id, status)
3609
                VALUES($sessionId, $courseId, $userId, 2)";
3610
        $result = Database::query($sql);
3611
3612
        return Database::affected_rows($result) > 0;
3613
    }
3614
3615
    /**
3616
     * @param int $sessionId
3617
     *
3618
     * @return bool
3619
     */
3620
    public static function removeAllDrhFromSession($sessionId)
3621
    {
3622
        $tbl_session_rel_user = Database::get_main_table(TABLE_MAIN_SESSION_USER);
3623
        $sessionId = (int) $sessionId;
3624
3625
        if (empty($sessionId)) {
3626
            return false;
3627
        }
3628
3629
        $sql = "DELETE FROM $tbl_session_rel_user
3630
                WHERE
3631
                    session_id = $sessionId AND
3632
                    relation_type =".SESSION_RELATION_TYPE_RRHH;
3633
        Database::query($sql);
3634
3635
        return true;
3636
    }
3637
3638
    /**
3639
     * Subscribes sessions to human resource manager (Dashboard feature).
3640
     *
3641
     * @param array $userInfo               Human Resource Manager info
3642
     * @param array $sessions_list          Sessions id
3643
     * @param bool  $sendEmail
3644
     * @param bool  $removeSessionsFromUser
3645
     *
3646
     * @return int
3647
     * */
3648
    public static function subscribeSessionsToDrh(
3649
        $userInfo,
3650
        $sessions_list,
3651
        $sendEmail = false,
3652
        $removeSessionsFromUser = true
3653
    ) {
3654
        // Database Table Definitions
3655
        $tbl_session_rel_user = Database::get_main_table(TABLE_MAIN_SESSION_USER);
3656
        $tbl_session_rel_access_url = Database::get_main_table(TABLE_MAIN_ACCESS_URL_REL_SESSION);
3657
3658
        if (empty($userInfo)) {
3659
            return 0;
3660
        }
3661
3662
        $userId = $userInfo['user_id'];
3663
3664
        // Only subscribe DRH users.
3665
        $rolesAllowed = [
3666
            DRH,
3667
            SESSIONADMIN,
3668
            PLATFORM_ADMIN,
3669
            COURSE_TUTOR,
3670
        ];
3671
        $isAdmin = api_is_platform_admin_by_id($userInfo['user_id']);
3672
        if (!$isAdmin && !in_array($userInfo['status'], $rolesAllowed)) {
3673
            return 0;
3674
        }
3675
3676
        $affected_rows = 0;
3677
        // Deleting assigned sessions to hrm_id.
3678
        if ($removeSessionsFromUser) {
3679
            if (api_is_multiple_url_enabled()) {
3680
                $sql = "SELECT s.session_id
3681
                        FROM $tbl_session_rel_user s
3682
                        INNER JOIN $tbl_session_rel_access_url a
3683
                        ON (a.session_id = s.session_id)
3684
                        WHERE
3685
                            s.user_id = $userId AND
3686
                            relation_type = ".SESSION_RELATION_TYPE_RRHH." AND
3687
                            access_url_id = ".api_get_current_access_url_id();
3688
            } else {
3689
                $sql = "SELECT s.session_id
3690
                        FROM $tbl_session_rel_user s
3691
                        WHERE user_id = $userId AND relation_type=".SESSION_RELATION_TYPE_RRHH;
3692
            }
3693
            $result = Database::query($sql);
3694
3695
            if (Database::num_rows($result) > 0) {
3696
                while ($row = Database::fetch_array($result)) {
3697
                    $sql = "DELETE FROM $tbl_session_rel_user
3698
                            WHERE
3699
                                session_id = {$row['session_id']} AND
3700
                                user_id = $userId AND
3701
                                relation_type =".SESSION_RELATION_TYPE_RRHH;
3702
                    Database::query($sql);
3703
3704
                    Event::addEvent(
3705
                        LOG_SESSION_DELETE_USER,
3706
                        LOG_USER_ID,
3707
                        $userId,
3708
                        api_get_utc_datetime(),
3709
                        api_get_user_id(),
3710
                        null,
3711
                        $row['session_id']
3712
                    );
3713
                }
3714
            }
3715
        }
3716
3717
        // Inserting new sessions list.
3718
        if (!empty($sessions_list) && is_array($sessions_list)) {
3719
            foreach ($sessions_list as $session_id) {
3720
                $session_id = (int) $session_id;
3721
                $sql = "SELECT session_id
3722
                        FROM $tbl_session_rel_user
3723
                        WHERE
3724
                            session_id = $session_id AND
3725
                            user_id = $userId AND
3726
                            relation_type = '".SESSION_RELATION_TYPE_RRHH."'";
3727
                $result = Database::query($sql);
3728
                if (Database::num_rows($result) == 0) {
3729
                    $sql = "INSERT IGNORE INTO $tbl_session_rel_user (session_id, user_id, relation_type, registered_at)
3730
                            VALUES (
3731
                                $session_id,
3732
                                $userId,
3733
                                '".SESSION_RELATION_TYPE_RRHH."',
3734
                                '".api_get_utc_datetime()."'
3735
                            )";
3736
                    Database::query($sql);
3737
3738
                    Event::addEvent(
3739
                        LOG_SESSION_ADD_USER,
3740
                        LOG_USER_ID,
3741
                        $userId,
3742
                        api_get_utc_datetime(),
3743
                        api_get_user_id(),
3744
                        null,
3745
                        $session_id
3746
                    );
3747
3748
                    $affected_rows++;
3749
                }
3750
            }
3751
        }
3752
3753
        return $affected_rows;
3754
    }
3755
3756
    /**
3757
     * @param int $sessionId
3758
     *
3759
     * @return array
3760
     */
3761
    public static function getDrhUsersInSession($sessionId)
3762
    {
3763
        return self::get_users_by_session($sessionId, SESSION_RELATION_TYPE_RRHH);
3764
    }
3765
3766
    /**
3767
     * @param int $userId
3768
     * @param int $sessionId
3769
     *
3770
     * @return array
3771
     */
3772
    public static function getSessionFollowedByDrh($userId, $sessionId)
3773
    {
3774
        $tbl_session = Database::get_main_table(TABLE_MAIN_SESSION);
3775
        $tbl_session_rel_user = Database::get_main_table(TABLE_MAIN_SESSION_USER);
3776
        $tbl_session_rel_access_url = Database::get_main_table(TABLE_MAIN_ACCESS_URL_REL_SESSION);
3777
3778
        $userId = (int) $userId;
3779
        $sessionId = (int) $sessionId;
3780
3781
        $select = " SELECT * ";
3782
        if (api_is_multiple_url_enabled()) {
3783
            $sql = " $select FROM $tbl_session s
3784
                    INNER JOIN $tbl_session_rel_user sru ON (sru.session_id = s.id)
3785
                    LEFT JOIN $tbl_session_rel_access_url a ON (s.id = a.session_id)
3786
                    WHERE
3787
                        sru.user_id = '$userId' AND
3788
                        sru.session_id = '$sessionId' AND
3789
                        sru.relation_type = '".SESSION_RELATION_TYPE_RRHH."' AND
3790
                        access_url_id = ".api_get_current_access_url_id()."
3791
                    ";
3792
        } else {
3793
            $sql = "$select FROM $tbl_session s
3794
                     INNER JOIN $tbl_session_rel_user sru
3795
                     ON
3796
                        sru.session_id = s.id AND
3797
                        sru.user_id = '$userId' AND
3798
                        sru.session_id = '$sessionId' AND
3799
                        sru.relation_type = '".SESSION_RELATION_TYPE_RRHH."'
3800
                    ";
3801
        }
3802
3803
        $result = Database::query($sql);
3804
        if (Database::num_rows($result)) {
3805
            $row = Database::fetch_array($result, 'ASSOC');
3806
            $row['course_list'] = self::get_course_list_by_session_id($sessionId);
3807
3808
            return $row;
3809
        }
3810
3811
        return [];
3812
    }
3813
3814
    /**
3815
     * Get sessions followed by human resources manager.
3816
     *
3817
     * @param int    $userId
3818
     * @param int    $start
3819
     * @param int    $limit
3820
     * @param bool   $getCount
3821
     * @param bool   $getOnlySessionId
3822
     * @param bool   $getSql
3823
     * @param string $orderCondition
3824
     * @param string $keyword
3825
     * @param string $description
3826
     * @param array  $options
3827
     *
3828
     * @return array sessions
3829
     */
3830
    public static function get_sessions_followed_by_drh(
3831
        $userId,
3832
        $start = null,
3833
        $limit = null,
3834
        $getCount = false,
3835
        $getOnlySessionId = false,
3836
        $getSql = false,
3837
        $orderCondition = null,
3838
        $keyword = '',
3839
        $description = '',
3840
        $options = []
3841
    ) {
3842
        return self::getSessionsFollowedByUser(
3843
            $userId,
3844
            DRH,
3845
            $start,
3846
            $limit,
3847
            $getCount,
3848
            $getOnlySessionId,
3849
            $getSql,
3850
            $orderCondition,
3851
            $keyword,
3852
            $description,
3853
            $options
3854
        );
3855
    }
3856
3857
    /**
3858
     * Get sessions followed by human resources manager.
3859
     *
3860
     * @param int    $userId
3861
     * @param int    $status           DRH Optional
3862
     * @param int    $start
3863
     * @param int    $limit
3864
     * @param bool   $getCount
3865
     * @param bool   $getOnlySessionId
3866
     * @param bool   $getSql
3867
     * @param string $orderCondition
3868
     * @param string $keyword
3869
     * @param string $description
3870
     * @param array  $options
3871
     *
3872
     * @return array sessions
3873
     */
3874
    public static function getSessionsFollowedByUser(
3875
        $userId,
3876
        $status = null,
3877
        $start = null,
3878
        $limit = null,
3879
        $getCount = false,
3880
        $getOnlySessionId = false,
3881
        $getSql = false,
3882
        $orderCondition = null,
3883
        $keyword = '',
3884
        $description = '',
3885
        $options = []
3886
    ) {
3887
        // Database Table Definitions
3888
        $tbl_session = Database::get_main_table(TABLE_MAIN_SESSION);
3889
        $tbl_session_rel_user = Database::get_main_table(TABLE_MAIN_SESSION_USER);
3890
        $tbl_session_rel_course_rel_user = Database::get_main_table(TABLE_MAIN_SESSION_COURSE_USER);
3891
        $tbl_session_rel_access_url = Database::get_main_table(TABLE_MAIN_ACCESS_URL_REL_SESSION);
3892
3893
        $extraFieldModel = new ExtraFieldModel('session');
3894
        $conditions = $extraFieldModel->parseConditions($options);
3895
        $sqlInjectJoins = $conditions['inject_joins'];
3896
        $extraFieldsConditions = $conditions['where'];
3897
        $sqlInjectWhere = $conditions['inject_where'];
3898
        $injectExtraFields = $conditions['inject_extra_fields'];
3899
3900
        if (!empty($injectExtraFields)) {
3901
            $injectExtraFields = ' , '.$injectExtraFields.' s.id';
3902
        }
3903
3904
        $userId = (int) $userId;
3905
3906
        $select = ' SELECT DISTINCT * '.$injectExtraFields;
3907
        if ($getCount) {
3908
            $select = ' SELECT count(DISTINCT(s.id)) as count ';
3909
        }
3910
3911
        if ($getOnlySessionId) {
3912
            $select = ' SELECT DISTINCT(s.id) ';
3913
        }
3914
3915
        $limitCondition = null;
3916
        if (!is_null($start) && !is_null($limit)) {
3917
            $limitCondition = " LIMIT ".intval($start).", ".intval($limit);
3918
        }
3919
3920
        if (empty($orderCondition)) {
3921
            $orderCondition = ' ORDER BY s.name ';
3922
        }
3923
3924
        $whereConditions = null;
3925
        $sessionCourseConditions = null;
3926
        $sessionConditions = null;
3927
        $sessionQuery = '';
3928
        $courseSessionQuery = null;
3929
        switch ($status) {
3930
            case DRH:
3931
                $sessionQuery = "SELECT sru.session_id
3932
                                 FROM
3933
                                 $tbl_session_rel_user sru
3934
                                 WHERE
3935
                                    sru.relation_type = '".SESSION_RELATION_TYPE_RRHH."' AND
3936
                                    sru.user_id = $userId";
3937
                break;
3938
            case COURSEMANAGER:
3939
                $courseSessionQuery = "
3940
                    SELECT scu.session_id as id
3941
                    FROM $tbl_session_rel_course_rel_user scu
3942
                    WHERE (scu.status = 2 AND scu.user_id = $userId)";
3943
3944
                $whereConditions = " OR (s.id_coach = $userId) ";
3945
                break;
3946
            case SESSIONADMIN:
3947
                $sessionQuery = '';
3948
                if (api_get_setting('allow_session_admins_to_manage_all_sessions') != 'true') {
3949
                    $sqlInjectJoins .= " AND s.session_admin_id = $userId ";
3950
                }
3951
                break;
3952
            default:
3953
                $sessionQuery = "SELECT sru.session_id
3954
                                 FROM
3955
                                 $tbl_session_rel_user sru
3956
                                 WHERE
3957
                                    sru.user_id = $userId";
3958
                break;
3959
        }
3960
3961
        $keywordCondition = '';
3962
        if (!empty($keyword)) {
3963
            $keyword = Database::escape_string($keyword);
3964
            $keywordCondition = " AND (s.name LIKE '%$keyword%' ) ";
3965
3966
            if (!empty($description)) {
3967
                $description = Database::escape_string($description);
3968
                $keywordCondition = " AND (s.name LIKE '%$keyword%' OR s.description LIKE '%$description%' ) ";
3969
            }
3970
        }
3971
3972
        $whereConditions .= $keywordCondition;
3973
        $subQuery = $sessionQuery.$courseSessionQuery;
3974
3975
        if (!empty($subQuery)) {
3976
            $subQuery = " AND s.id IN ($subQuery)";
3977
        }
3978
3979
        $sql = " $select
3980
                FROM $tbl_session s
3981
                INNER JOIN $tbl_session_rel_access_url a
3982
                ON (s.id = a.session_id)
3983
                $sqlInjectJoins
3984
                WHERE
3985
                    access_url_id = ".api_get_current_access_url_id()."
3986
                    $subQuery
3987
                    $whereConditions
3988
                    $extraFieldsConditions
3989
                    $sqlInjectWhere
3990
                    $orderCondition
3991
                    $limitCondition";
3992
3993
        if ($getSql) {
3994
            return $sql;
3995
        }
3996
        $result = Database::query($sql);
3997
3998
        if ($getCount) {
3999
            $row = Database::fetch_array($result);
4000
            if ($row) {
4001
                return (int) $row['count'];
4002
            }
4003
4004
            return 0;
4005
        }
4006
4007
        $sessions = [];
4008
        if (Database::num_rows($result) > 0) {
4009
            $sysUploadPath = api_get_path(SYS_UPLOAD_PATH).'sessions/';
4010
            $webUploadPath = api_get_path(WEB_UPLOAD_PATH).'sessions/';
4011
            $imgPath = Display::return_icon(
4012
                'session_default_small.png',
4013
                null,
4014
                [],
4015
                ICON_SIZE_SMALL,
4016
                false,
4017
                true
4018
            );
4019
4020
            while ($row = Database::fetch_array($result)) {
4021
                if ($getOnlySessionId) {
4022
                    $sessions[$row['id']] = $row;
4023
                    continue;
4024
                }
4025
                $imageFilename = ExtraFieldModel::FIELD_TYPE_FILE_IMAGE.'_'.$row['id'].'.png';
4026
                $row['image'] = is_file($sysUploadPath.$imageFilename) ? $webUploadPath.$imageFilename : $imgPath;
4027
4028
                if ($row['display_start_date'] === '0000-00-00 00:00:00' || $row['display_start_date'] === '0000-00-00') {
4029
                    $row['display_start_date'] = null;
4030
                }
4031
4032
                if ($row['display_end_date'] === '0000-00-00 00:00:00' || $row['display_end_date'] === '0000-00-00') {
4033
                    $row['display_end_date'] = null;
4034
                }
4035
4036
                if ($row['access_start_date'] === '0000-00-00 00:00:00' || $row['access_start_date'] === '0000-00-00') {
4037
                    $row['access_start_date'] = null;
4038
                }
4039
4040
                if ($row['access_end_date'] === '0000-00-00 00:00:00' || $row['access_end_date'] === '0000-00-00') {
4041
                    $row['access_end_date'] = null;
4042
                }
4043
4044
                if ($row['coach_access_start_date'] === '0000-00-00 00:00:00' ||
4045
                    $row['coach_access_start_date'] === '0000-00-00'
4046
                ) {
4047
                    $row['coach_access_start_date'] = null;
4048
                }
4049
4050
                if ($row['coach_access_end_date'] === '0000-00-00 00:00:00' ||
4051
                    $row['coach_access_end_date'] === '0000-00-00'
4052
                ) {
4053
                    $row['coach_access_end_date'] = null;
4054
                }
4055
4056
                $sessions[$row['id']] = $row;
4057
            }
4058
        }
4059
4060
        return $sessions;
4061
    }
4062
4063
    /**
4064
     * Gets the list (or the count) of courses by session filtered by access_url.
4065
     *
4066
     * @param int    $session_id  The session id
4067
     * @param string $course_name The course code
4068
     * @param string $orderBy     Field to order the data
4069
     * @param bool   $getCount    Optional. Count the session courses
4070
     *
4071
     * @return array|int List of courses. Whether $getCount is true, return the count
4072
     */
4073
    public static function get_course_list_by_session_id(
4074
        $session_id,
4075
        $course_name = '',
4076
        $orderBy = null,
4077
        $getCount = false
4078
    ) {
4079
        $tbl_course = Database::get_main_table(TABLE_MAIN_COURSE);
4080
        $tbl_session_rel_course = Database::get_main_table(TABLE_MAIN_SESSION_COURSE);
4081
        $session_id = (int) $session_id;
4082
        $sqlSelect = '*, c.id, c.id as real_id, c.code as course_code';
4083
4084
        if ($getCount) {
4085
            $sqlSelect = 'COUNT(1) as count';
4086
        }
4087
4088
        // select the courses
4089
        $sql = "SELECT $sqlSelect
4090
                FROM $tbl_course c
4091
                INNER JOIN $tbl_session_rel_course src
4092
                ON (c.id = src.c_id)
4093
		        WHERE src.session_id = '$session_id' ";
4094
4095
        if (!empty($course_name)) {
4096
            $course_name = Database::escape_string($course_name);
4097
            $sql .= " AND c.title LIKE '%$course_name%' ";
4098
        }
4099
4100
        if (!empty($orderBy)) {
4101
            $orderBy = Database::escape_string($orderBy);
4102
            $orderBy = " ORDER BY $orderBy";
4103
        } else {
4104
            if (self::orderCourseIsEnabled()) {
4105
                $orderBy .= ' ORDER BY position ';
4106
            } else {
4107
                $orderBy .= ' ORDER BY title ';
4108
            }
4109
        }
4110
4111
        $sql .= Database::escape_string($orderBy);
4112
        $result = Database::query($sql);
4113
        $num_rows = Database::num_rows($result);
4114
        $courses = [];
4115
        if ($num_rows > 0) {
4116
            if ($getCount) {
4117
                $count = Database::fetch_assoc($result);
4118
4119
                return (int) $count['count'];
4120
            }
4121
4122
            while ($row = Database::fetch_array($result, 'ASSOC')) {
4123
                $courses[$row['real_id']] = $row;
4124
            }
4125
        }
4126
4127
        return $courses;
4128
    }
4129
4130
    /**
4131
     * Gets the list of courses by session filtered by access_url.
4132
     *
4133
     * @param $userId
4134
     * @param $sessionId
4135
     * @param null   $from
0 ignored issues
show
Documentation Bug introduced by
Are you sure the doc-type for parameter $from is correct as it would always require null to be passed?
Loading history...
4136
     * @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...
4137
     * @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...
4138
     * @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...
4139
     * @param bool   $getCount
4140
     * @param string $keyword
4141
     *
4142
     * @return array
4143
     */
4144
    public static function getAllCoursesFollowedByUser(
4145
        $userId,
4146
        $sessionId,
4147
        $from = null,
4148
        $limit = null,
4149
        $column = null,
4150
        $direction = null,
4151
        $getCount = false,
4152
        $keyword = ''
4153
    ) {
4154
        if (empty($sessionId)) {
4155
            $sessionsSQL = self::get_sessions_followed_by_drh(
4156
                $userId,
4157
                null,
4158
                null,
4159
                null,
4160
                true,
4161
                true
4162
            );
4163
        } else {
4164
            $sessionsSQL = intval($sessionId);
4165
        }
4166
4167
        $tbl_course = Database::get_main_table(TABLE_MAIN_COURSE);
4168
        $tbl_session_rel_course = Database::get_main_table(TABLE_MAIN_SESSION_COURSE);
4169
4170
        if ($getCount) {
4171
            $select = "SELECT COUNT(DISTINCT(c.code)) as count ";
4172
        } else {
4173
            $select = "SELECT DISTINCT c.* ";
4174
        }
4175
4176
        $keywordCondition = null;
4177
        if (!empty($keyword)) {
4178
            $keyword = Database::escape_string($keyword);
4179
            $keywordCondition = " AND (c.code LIKE '%$keyword%' OR c.title LIKE '%$keyword%' ) ";
4180
        }
4181
4182
        // Select the courses
4183
        $sql = "$select
4184
                FROM $tbl_course c
4185
                INNER JOIN $tbl_session_rel_course src
4186
                ON c.id = src.c_id
4187
		        WHERE
4188
		            src.session_id IN ($sessionsSQL)
4189
		            $keywordCondition
4190
		        ";
4191
        if ($getCount) {
4192
            $result = Database::query($sql);
4193
            $row = Database::fetch_array($result, 'ASSOC');
4194
4195
            return $row['count'];
4196
        }
4197
4198
        if (isset($from) && isset($limit)) {
4199
            $from = intval($from);
4200
            $limit = intval($limit);
4201
            $sql .= " LIMIT $from, $limit";
4202
        }
4203
4204
        $result = Database::query($sql);
4205
        $num_rows = Database::num_rows($result);
4206
        $courses = [];
4207
4208
        if ($num_rows > 0) {
4209
            while ($row = Database::fetch_array($result, 'ASSOC')) {
4210
                $courses[$row['id']] = $row;
4211
            }
4212
        }
4213
4214
        return $courses;
4215
    }
4216
4217
    /**
4218
     * Gets the list of courses by session filtered by access_url.
4219
     *
4220
     * @param int    $session_id
4221
     * @param string $course_name
4222
     *
4223
     * @return array list of courses
4224
     */
4225
    public static function get_course_list_by_session_id_like($session_id, $course_name = '')
4226
    {
4227
        $tbl_course = Database::get_main_table(TABLE_MAIN_COURSE);
4228
        $tbl_session_rel_course = Database::get_main_table(TABLE_MAIN_SESSION_COURSE);
4229
4230
        $session_id = (int) $session_id;
4231
        $course_name = Database::escape_string($course_name);
4232
4233
        // select the courses
4234
        $sql = "SELECT c.id, c.title FROM $tbl_course c
4235
                INNER JOIN $tbl_session_rel_course src
4236
                ON c.id = src.c_id
4237
		        WHERE ";
4238
4239
        if (!empty($session_id)) {
4240
            $sql .= "src.session_id LIKE '$session_id' AND ";
4241
        }
4242
4243
        if (!empty($course_name)) {
4244
            $sql .= "UPPER(c.title) LIKE UPPER('%$course_name%') ";
4245
        }
4246
4247
        $sql .= "ORDER BY title;";
4248
        $result = Database::query($sql);
4249
        $num_rows = Database::num_rows($result);
4250
        $courses = [];
4251
        if ($num_rows > 0) {
4252
            while ($row = Database::fetch_array($result, 'ASSOC')) {
4253
                $courses[$row['id']] = $row;
4254
            }
4255
        }
4256
4257
        return $courses;
4258
    }
4259
4260
    /**
4261
     * Gets the count of courses by session filtered by access_url.
4262
     *
4263
     * @param int session id
4264
     * @param string $keyword
4265
     *
4266
     * @return array list of courses
4267
     */
4268
    public static function getCourseCountBySessionId($session_id, $keyword = '')
4269
    {
4270
        $tbl_course = Database::get_main_table(TABLE_MAIN_COURSE);
4271
        $tbl_session_rel_course = Database::get_main_table(TABLE_MAIN_SESSION_COURSE);
4272
        $session_id = (int) $session_id;
4273
4274
        // select the courses
4275
        $sql = "SELECT COUNT(c.code) count
4276
                FROM $tbl_course c
4277
                INNER JOIN $tbl_session_rel_course src
4278
                ON c.id = src.c_id
4279
		        WHERE src.session_id = '$session_id' ";
4280
4281
        $keywordCondition = null;
4282
        if (!empty($keyword)) {
4283
            $keyword = Database::escape_string($keyword);
4284
            $keywordCondition = " AND (c.code LIKE '%$keyword%' OR c.title LIKE '%$keyword%' ) ";
4285
        }
4286
        $sql .= $keywordCondition;
4287
4288
        $result = Database::query($sql);
4289
        $num_rows = Database::num_rows($result);
4290
        if ($num_rows > 0) {
4291
            $row = Database::fetch_array($result, 'ASSOC');
4292
4293
            return $row['count'];
4294
        }
4295
4296
        return null;
4297
    }
4298
4299
    /**
4300
     * Get the session id based on the original id and field name in the extra fields.
4301
     * Returns 0 if session was not found.
4302
     *
4303
     * @param string $value    Original session id
4304
     * @param string $variable Original field name
4305
     *
4306
     * @return int Session id
4307
     */
4308
    public static function getSessionIdFromOriginalId($value, $variable)
4309
    {
4310
        $extraFieldValue = new ExtraFieldValue('session');
4311
        $result = $extraFieldValue->get_item_id_from_field_variable_and_field_value(
4312
            $variable,
4313
            $value
4314
        );
4315
4316
        if (!empty($result)) {
4317
            return $result['item_id'];
4318
        }
4319
4320
        return 0;
4321
    }
4322
4323
    /**
4324
     * Get users by session.
4325
     *
4326
     * @param int  $id       session id
4327
     * @param int  $status   filter by status coach = 2
4328
     * @param bool $getCount Optional. Allow get the number of rows from the result
4329
     * @param int  $urlId
4330
     *
4331
     * @return array|int A list with an user list. If $getCount is true then return a the count of registers
4332
     */
4333
    public static function get_users_by_session(
4334
        $id,
4335
        $status = null,
4336
        $getCount = false,
4337
        $urlId = 0
4338
    ) {
4339
        if (empty($id)) {
4340
            return [];
4341
        }
4342
        $id = (int) $id;
4343
        $urlId = empty($urlId) ? api_get_current_access_url_id() : (int) $urlId;
4344
4345
        $tbl_user = Database::get_main_table(TABLE_MAIN_USER);
4346
        $tbl_session_rel_user = Database::get_main_table(TABLE_MAIN_SESSION_USER);
4347
        $table_access_url_user = Database::get_main_table(TABLE_MAIN_ACCESS_URL_REL_USER);
4348
4349
        $selectedField = '
4350
            u.id as user_id, u.lastname, u.firstname, u.username, su.relation_type, au.access_url_id,
4351
            su.moved_to, su.moved_status, su.moved_at, su.registered_at
4352
        ';
4353
4354
        if ($getCount) {
4355
            $selectedField = 'count(1) AS count';
4356
        }
4357
4358
        $sql = "SELECT $selectedField
4359
                FROM $tbl_user u
4360
                INNER JOIN $tbl_session_rel_user su
4361
                ON u.user_id = su.user_id AND
4362
                su.session_id = $id
4363
                LEFT OUTER JOIN $table_access_url_user au
4364
                ON (au.user_id = u.user_id)
4365
                ";
4366
4367
        if (is_numeric($status)) {
4368
            $status = (int) $status;
4369
            $sql .= " WHERE su.relation_type = $status AND (au.access_url_id = $urlId OR au.access_url_id is null)";
4370
        } else {
4371
            $sql .= " WHERE (au.access_url_id = $urlId OR au.access_url_id is null )";
4372
        }
4373
4374
        $sql .= ' ORDER BY su.relation_type, ';
4375
        $sql .= api_sort_by_first_name() ? ' u.firstname, u.lastname' : '  u.lastname, u.firstname';
4376
4377
        $result = Database::query($sql);
4378
        if ($getCount) {
4379
            $count = Database::fetch_assoc($result);
4380
            if ($count) {
4381
                return (int) $count['count'];
4382
            }
4383
4384
            return 0;
4385
        }
4386
4387
        $return = [];
4388
        while ($row = Database::fetch_array($result, 'ASSOC')) {
4389
            $return[] = $row;
4390
        }
4391
4392
        return $return;
4393
    }
4394
4395
    /**
4396
     * The general coach (field: session.id_coach).
4397
     *
4398
     * @param int  $user_id         user id
4399
     * @param bool $asPlatformAdmin The user is platform admin, return everything
4400
     *
4401
     * @return array
4402
     */
4403
    public static function get_sessions_by_general_coach($user_id, $asPlatformAdmin = false)
4404
    {
4405
        $session_table = Database::get_main_table(TABLE_MAIN_SESSION);
4406
        $user_id = (int) $user_id;
4407
4408
        // Session where we are general coach
4409
        $sql = "SELECT DISTINCT *
4410
                FROM $session_table";
4411
4412
        if (!$asPlatformAdmin) {
4413
            $sql .= " WHERE id_coach = $user_id";
4414
        }
4415
4416
        if (api_is_multiple_url_enabled()) {
4417
            $tbl_session_rel_access_url = Database::get_main_table(TABLE_MAIN_ACCESS_URL_REL_SESSION);
4418
            $access_url_id = api_get_current_access_url_id();
4419
4420
            $sqlCoach = '';
4421
            if (!$asPlatformAdmin) {
4422
                $sqlCoach = " id_coach = $user_id AND ";
4423
            }
4424
4425
            if ($access_url_id != -1) {
4426
                $sql = 'SELECT DISTINCT session.*
4427
                    FROM '.$session_table.' session INNER JOIN '.$tbl_session_rel_access_url.' session_rel_url
4428
                    ON (session.id = session_rel_url.session_id)
4429
                    WHERE '.$sqlCoach.' access_url_id = '.$access_url_id;
4430
            }
4431
        }
4432
        $sql .= ' ORDER by name';
4433
        $result = Database::query($sql);
4434
4435
        return Database::store_result($result, 'ASSOC');
4436
    }
4437
4438
    /**
4439
     * @param int $user_id
4440
     *
4441
     * @return array
4442
     *
4443
     * @deprecated use get_sessions_by_general_coach()
4444
     */
4445
    public static function get_sessions_by_coach($user_id)
4446
    {
4447
        $session_table = Database::get_main_table(TABLE_MAIN_SESSION);
4448
4449
        return Database::select(
4450
            '*',
4451
            $session_table,
4452
            ['where' => ['id_coach = ?' => $user_id]]
4453
        );
4454
    }
4455
4456
    /**
4457
     * @param int $user_id
4458
     * @param int $courseId
4459
     * @param int $session_id
4460
     *
4461
     * @return array|bool
4462
     */
4463
    public static function get_user_status_in_course_session($user_id, $courseId, $session_id)
4464
    {
4465
        $table = Database::get_main_table(TABLE_MAIN_SESSION_COURSE_USER);
4466
        $tbl_user = Database::get_main_table(TABLE_MAIN_USER);
4467
        $sql = "SELECT session_rcru.status
4468
                FROM $table session_rcru
4469
                INNER JOIN $tbl_user user
4470
                ON (session_rcru.user_id = user.user_id)
4471
                WHERE
4472
                    session_rcru.session_id = '".intval($session_id)."' AND
4473
                    session_rcru.c_id ='".intval($courseId)."' AND
4474
                    user.user_id = ".intval($user_id);
4475
4476
        $result = Database::query($sql);
4477
        $status = false;
4478
        if (Database::num_rows($result)) {
4479
            $status = Database::fetch_row($result);
4480
            $status = $status['0'];
4481
        }
4482
4483
        return $status;
4484
    }
4485
4486
    /**
4487
     * Gets user status within a session.
4488
     *
4489
     * @param int $userId
4490
     * @param int $sessionId
4491
     *
4492
     * @return SessionRelUser
4493
     */
4494
    public static function getUserStatusInSession($userId, $sessionId)
4495
    {
4496
        $em = Database::getManager();
4497
        $subscriptions = $em
4498
            ->getRepository('ChamiloCoreBundle:SessionRelUser')
4499
            ->findBy(['session' => $sessionId, 'user' => $userId]);
4500
4501
        /** @var SessionRelUser $subscription */
4502
        $subscription = current($subscriptions);
4503
4504
        return $subscription;
4505
    }
4506
4507
    /**
4508
     * @param int $id
4509
     *
4510
     * @return array
4511
     */
4512
    public static function get_all_sessions_by_promotion($id)
4513
    {
4514
        $table = Database::get_main_table(TABLE_MAIN_SESSION);
4515
4516
        return Database::select(
4517
            '*',
4518
            $table,
4519
            ['where' => ['promotion_id = ?' => $id]]
4520
        );
4521
    }
4522
4523
    /**
4524
     * @param int   $promotion_id
4525
     * @param array $list
4526
     */
4527
    public static function subscribe_sessions_to_promotion($promotion_id, $list)
4528
    {
4529
        $table = Database::get_main_table(TABLE_MAIN_SESSION);
4530
        $params = [];
4531
        $params['promotion_id'] = 0;
4532
        Database::update(
4533
            $table,
4534
            $params,
4535
            ['promotion_id = ?' => $promotion_id]
4536
        );
4537
4538
        $params['promotion_id'] = $promotion_id;
4539
        if (!empty($list)) {
4540
            foreach ($list as $session_id) {
4541
                $session_id = (int) $session_id;
4542
                Database::update($table, $params, ['id = ?' => $session_id]);
4543
            }
4544
        }
4545
    }
4546
4547
    /**
4548
     * Updates a session status.
4549
     *
4550
     * @param int session id
4551
     * @param int status
4552
     */
4553
    public static function set_session_status($session_id, $status)
4554
    {
4555
        $t = Database::get_main_table(TABLE_MAIN_SESSION);
4556
        $params['visibility'] = $status;
4557
        Database::update($t, $params, ['id = ?' => $session_id]);
4558
    }
4559
4560
    /**
4561
     * Copies a session with the same data to a new session.
4562
     * The new copy is not assigned to the same promotion.
4563
     *
4564
     * @param int  $id                         Session ID
4565
     * @param bool $copy_courses               Whether to copy the relationship with courses
4566
     * @param bool $copyTeachersAndDrh
4567
     * @param bool $create_new_courses         New courses will be created
4568
     * @param bool $set_exercises_lp_invisible Set exercises and LPs in the new session to invisible by default
4569
     * @param bool $copyWithSessionContent     Copy course session content into the courses
4570
     *
4571
     * @return int The new session ID on success, 0 otherwise
4572
     *
4573
     * @see subscribe_sessions_to_promotions() for that.
4574
     *
4575
     * @todo make sure the extra session fields are copied too
4576
     */
4577
    public static function copy(
4578
        $id,
4579
        $copy_courses = true,
4580
        $copyTeachersAndDrh = true,
4581
        $create_new_courses = false,
4582
        $set_exercises_lp_invisible = false,
4583
        $copyWithSessionContent = false
4584
    ) {
4585
        $id = (int) $id;
4586
        $s = self::fetch($id);
4587
4588
        if (empty($s)) {
4589
            return false;
4590
        }
4591
4592
        // Check all dates before copying
4593
        // Get timestamp for now in UTC - see http://php.net/manual/es/function.time.php#117251
4594
        $now = time() - date('Z');
4595
        // Timestamp in one month
4596
        $inOneMonth = $now + (30 * 24 * 3600);
4597
        $inOneMonth = api_get_local_time($inOneMonth);
4598
        if (api_strtotime($s['access_start_date']) < $now) {
4599
            $s['access_start_date'] = api_get_local_time($now);
4600
        } else {
4601
            $s['access_start_date'] = api_get_local_time($s['access_start_date']);
4602
        }
4603
        if (api_strtotime($s['display_start_date']) < $now) {
4604
            $s['display_start_date'] = api_get_local_time($now);
4605
        } else {
4606
            $s['display_start_date'] = api_get_local_time($s['display_start_date']);
4607
        }
4608
        if (api_strtotime($s['coach_access_start_date']) < $now) {
4609
            $s['coach_access_start_date'] = api_get_local_time($now);
4610
        } else {
4611
            $s['coach_access_start_date'] = api_get_local_time($s['coach_access_start_date']);
4612
        }
4613
        if (api_strtotime($s['access_end_date']) < $now) {
4614
            $s['access_end_date'] = $inOneMonth;
4615
        } else {
4616
            $s['access_end_date'] = api_get_local_time($s['access_end_date']);
4617
        }
4618
        if (api_strtotime($s['display_end_date']) < $now) {
4619
            $s['display_end_date'] = $inOneMonth;
4620
        } else {
4621
            $s['display_end_date'] = api_get_local_time($s['display_end_date']);
4622
        }
4623
        if (api_strtotime($s['coach_access_end_date']) < $now) {
4624
            $s['coach_access_end_date'] = $inOneMonth;
4625
        } else {
4626
            $s['coach_access_end_date'] = api_get_local_time($s['coach_access_end_date']);
4627
        }
4628
4629
        $extraFieldValue = new ExtraFieldValue('session');
4630
        $extraFieldsValues = $extraFieldValue->getAllValuesByItem($id);
4631
        $extraFieldsValuesToCopy = [];
4632
        if (!empty($extraFieldsValues)) {
4633
            foreach ($extraFieldsValues as $extraFieldValue) {
4634
                $extraFieldsValuesToCopy['extra_'.$extraFieldValue['variable']]['extra_'.$extraFieldValue['variable']] = $extraFieldValue['value'];
4635
            }
4636
        }
4637
4638
        if (isset($extraFieldsValuesToCopy['extra_image']) && isset($extraFieldsValuesToCopy['extra_image']['extra_image'])) {
4639
            $extraFieldsValuesToCopy['extra_image'] = [
4640
                'tmp_name' => api_get_path(SYS_UPLOAD_PATH).$extraFieldsValuesToCopy['extra_image']['extra_image'],
4641
                'error' => 0,
4642
            ];
4643
        }
4644
4645
        // Now try to create the session
4646
        $sid = self::create_session(
4647
            $s['name'].' '.get_lang('CopyLabelSuffix'),
4648
            $s['access_start_date'],
4649
            $s['access_end_date'],
4650
            $s['display_start_date'],
4651
            $s['display_end_date'],
4652
            $s['coach_access_start_date'],
4653
            $s['coach_access_end_date'],
4654
            (int) $s['id_coach'],
4655
            $s['session_category_id'],
4656
            (int) $s['visibility'],
4657
            true,
4658
            $s['duration'],
4659
            $s['description'],
4660
            $s['show_description'],
4661
            $extraFieldsValuesToCopy,
4662
            0,
4663
            $s['send_subscription_notification']
4664
        );
4665
4666
        if (!is_numeric($sid) || empty($sid)) {
4667
            return false;
4668
        }
4669
4670
        if ($copy_courses) {
4671
            // Register courses from the original session to the new session
4672
            $courses = self::get_course_list_by_session_id($id);
4673
            $short_courses = $new_short_courses = [];
4674
            if (is_array($courses) && count($courses) > 0) {
4675
                foreach ($courses as $course) {
4676
                    $short_courses[] = $course;
4677
                }
4678
            }
4679
4680
            // We will copy the current courses of the session to new courses
4681
            if (!empty($short_courses)) {
4682
                if ($create_new_courses) {
4683
                    api_set_more_memory_and_time_limits();
4684
                    $params = [];
4685
                    $params['skip_lp_dates'] = true;
4686
4687
                    foreach ($short_courses as $course_data) {
4688
                        $course_info = CourseManager::copy_course_simple(
4689
                            $course_data['title'].' '.get_lang('CopyLabelSuffix'),
4690
                            $course_data['course_code'],
4691
                            $id,
4692
                            $sid,
4693
                            $params
4694
                        );
4695
4696
                        if ($course_info) {
4697
                            //By default new elements are invisible
4698
                            if ($set_exercises_lp_invisible) {
4699
                                $list = new LearnpathList('', $course_info, $sid);
4700
                                $flat_list = $list->get_flat_list();
4701
                                if (!empty($flat_list)) {
4702
                                    foreach ($flat_list as $lp_id => $data) {
4703
                                        api_item_property_update(
4704
                                            $course_info,
4705
                                            TOOL_LEARNPATH,
4706
                                            $lp_id,
4707
                                            'invisible',
4708
                                            api_get_user_id(),
4709
                                            0,
4710
                                            0,
4711
                                            0,
4712
                                            0,
4713
                                            $sid
4714
                                        );
4715
                                    }
4716
                                }
4717
                                $quiz_table = Database::get_course_table(TABLE_QUIZ_TEST);
4718
                                $course_id = $course_info['real_id'];
4719
                                //@todo check this query
4720
                                $sql = "UPDATE $quiz_table SET active = 0
4721
                                        WHERE c_id = $course_id AND session_id = $sid";
4722
                                Database::query($sql);
4723
                            }
4724
                            $new_short_courses[] = $course_info['real_id'];
4725
                        }
4726
                    }
4727
                } else {
4728
                    foreach ($short_courses as $course_data) {
4729
                        $new_short_courses[] = $course_data['id'];
4730
                    }
4731
                }
4732
4733
                $short_courses = $new_short_courses;
4734
                self::add_courses_to_session($sid, $short_courses, true);
4735
4736
                if ($copyWithSessionContent) {
4737
                    foreach ($courses as $course) {
4738
                        CourseManager::copy_course(
4739
                            $course['code'],
4740
                            $id,
4741
                            $course['code'],
4742
                            $sid,
4743
                            [],
4744
                            false,
4745
                            true
4746
                        );
4747
                    }
4748
                }
4749
4750
                if ($create_new_courses === false && $copyTeachersAndDrh) {
4751
                    foreach ($short_courses as $courseItemId) {
4752
                        $coachList = self::getCoachesByCourseSession($id, $courseItemId);
4753
                        foreach ($coachList as $userId) {
4754
                            self::set_coach_to_course_session($userId, $sid, $courseItemId);
4755
                        }
4756
                    }
4757
                }
4758
            }
4759
        }
4760
4761
        if ($copyTeachersAndDrh) {
4762
            // Register users from the original session to the new session
4763
            $users = self::get_users_by_session($id);
4764
            if (!empty($users)) {
4765
                $userListByStatus = [];
4766
                foreach ($users as $userData) {
4767
                    $userData['relation_type'] = (int) $userData['relation_type'];
4768
                    $userListByStatus[$userData['relation_type']][] = $userData;
4769
                }
4770
4771
                foreach ($userListByStatus as $status => $userList) {
4772
                    $userList = array_column($userList, 'user_id');
4773
                    switch ($status) {
4774
                        case 0:
4775
                            /*self::subscribeUsersToSession(
4776
                                $sid,
4777
                                $userList,
4778
                                SESSION_VISIBLE_READ_ONLY,
4779
                                false,
4780
                                true
4781
                            );*/
4782
                            break;
4783
                        case 1:
4784
                            // drh users
4785
                            foreach ($userList as $drhId) {
4786
                                $userInfo = api_get_user_info($drhId);
4787
                                self::subscribeSessionsToDrh($userInfo, [$sid], false, false);
4788
                            }
4789
                            break;
4790
                    }
4791
                }
4792
            }
4793
        }
4794
4795
        return $sid;
4796
    }
4797
4798
    /**
4799
     * @param int $user_id
4800
     * @param int $session_id
4801
     *
4802
     * @return bool
4803
     */
4804
    public static function user_is_general_coach($user_id, $session_id)
4805
    {
4806
        $session_id = (int) $session_id;
4807
        $user_id = (int) $user_id;
4808
        $table = Database::get_main_table(TABLE_MAIN_SESSION);
4809
        $sql = "SELECT DISTINCT id
4810
	         	FROM $table
4811
	         	WHERE session.id_coach = '".$user_id."' AND id = '$session_id'";
4812
        $result = Database::query($sql);
4813
        if ($result && Database::num_rows($result)) {
4814
            return true;
4815
        }
4816
4817
        return false;
4818
    }
4819
4820
    /**
4821
     * Get the number of sessions.
4822
     *
4823
     * @param int $access_url_id ID of the URL we want to filter on (optional)
4824
     *
4825
     * @return int Number of sessions
4826
     */
4827
    public static function count_sessions($access_url_id = 0)
4828
    {
4829
        $session_table = Database::get_main_table(TABLE_MAIN_SESSION);
4830
        $access_url_rel_session_table = Database::get_main_table(TABLE_MAIN_ACCESS_URL_REL_SESSION);
4831
        $access_url_id = (int) $access_url_id;
4832
        $sql = "SELECT count(s.id) FROM $session_table s";
4833
        if (!empty($access_url_id)) {
4834
            $sql .= ", $access_url_rel_session_table u ".
4835
                " WHERE s.id = u.session_id AND u.access_url_id = $access_url_id";
4836
        }
4837
        $res = Database::query($sql);
4838
        $row = Database::fetch_row($res);
4839
4840
        return $row[0];
4841
    }
4842
4843
    /**
4844
     * @param int  $id
4845
     * @param bool $checkSession
4846
     *
4847
     * @return bool
4848
     */
4849
    public static function cantEditSession($id, $checkSession = true)
4850
    {
4851
        if (!self::allowToManageSessions()) {
4852
            return false;
4853
        }
4854
4855
        if (api_is_platform_admin() && self::allowed($id)) {
4856
            return true;
4857
        }
4858
4859
        if ($checkSession) {
4860
            if (self::allowed($id)) {
4861
                return true;
4862
            }
4863
4864
            return false;
4865
        }
4866
4867
        return true;
4868
    }
4869
4870
    /**
4871
     * Protect a session to be edited.
4872
     *
4873
     * @param int  $id
4874
     * @param bool $checkSession
4875
     *
4876
     * @return mixed|bool true if pass the check, api_not_allowed otherwise
4877
     */
4878
    public static function protectSession($id, $checkSession = true)
4879
    {
4880
        if (!self::cantEditSession($id, $checkSession)) {
4881
            api_not_allowed(true);
4882
        }
4883
    }
4884
4885
    /**
4886
     * @return bool
4887
     */
4888
    public static function allowToManageSessions()
4889
    {
4890
        if (self::allowManageAllSessions()) {
4891
            return true;
4892
        }
4893
4894
        $setting = api_get_setting('allow_teachers_to_create_sessions');
4895
4896
        if (api_is_teacher() && $setting == 'true') {
4897
            return true;
4898
        }
4899
4900
        return false;
4901
    }
4902
4903
    /**
4904
     * @return bool
4905
     */
4906
    public static function allowOnlyMySessions()
4907
    {
4908
        if (self::allowToManageSessions() &&
4909
            !api_is_platform_admin() &&
4910
            api_is_teacher()
4911
        ) {
4912
            return true;
4913
        }
4914
4915
        return false;
4916
    }
4917
4918
    /**
4919
     * @return bool
4920
     */
4921
    public static function allowManageAllSessions()
4922
    {
4923
        if (api_is_platform_admin() || api_is_session_admin()) {
4924
            return true;
4925
        }
4926
4927
        return false;
4928
    }
4929
4930
    /**
4931
     * @param $id
4932
     *
4933
     * @return bool
4934
     */
4935
    public static function protect_teacher_session_edit($id)
4936
    {
4937
        if (!api_is_coach($id) && !api_is_platform_admin()) {
4938
            api_not_allowed(true);
4939
        } else {
4940
            return true;
4941
        }
4942
    }
4943
4944
    /**
4945
     * @todo Add param to get only active sessions (not expires ones)
4946
     */
4947
    public static function get_session_by_course(int $courseId, ?string $startDate = null, ?string $endDate = null): array
4948
    {
4949
        $table_session_course = Database::get_main_table(TABLE_MAIN_SESSION_COURSE);
4950
        $table_session = Database::get_main_table(TABLE_MAIN_SESSION);
4951
        $url = Database::get_main_table(TABLE_MAIN_ACCESS_URL_REL_SESSION);
4952
        $courseId = (int) $courseId;
4953
        $urlId = api_get_current_access_url_id();
4954
4955
        if (empty($courseId)) {
4956
            return [];
4957
        }
4958
4959
        $dateCondition = '';
4960
        if ($startDate && $endDate) {
4961
            $dateCondition .= "AND (s.display_start_date BETWEEN '$startDate' AND '$endDate' OR s.display_end_date BETWEEN '$startDate' AND '$endDate') ";
4962
        } elseif ($startDate) {
4963
            $dateCondition .= "AND s.display_start_date >= '$startDate' ";
4964
        } elseif ($endDate) {
4965
            $dateCondition .= "AND s.display_end_date <= '$endDate' ";
4966
        }
4967
4968
        $sql = "SELECT name, s.id
4969
            FROM $table_session_course sc
4970
            INNER JOIN $table_session s
4971
            ON (sc.session_id = s.id)
4972
            INNER JOIN $url u
4973
            ON (u.session_id = s.id)
4974
            WHERE
4975
                u.access_url_id = $urlId AND
4976
                sc.c_id = '$courseId'
4977
                $dateCondition";
4978
        $result = Database::query($sql);
4979
4980
        return Database::store_result($result);
4981
    }
4982
4983
    /**
4984
     * @param int  $userId
4985
     * @param bool $ignoreVisibilityForAdmins
4986
     * @param bool $ignoreTimeLimit
4987
     *
4988
     * @return array
4989
     */
4990
    public static function get_sessions_by_user(
4991
        $userId,
4992
        $ignoreVisibilityForAdmins = false,
4993
        $ignoreTimeLimit = false
4994
    ) {
4995
        $sessionCategories = UserManager::get_sessions_by_category(
4996
            $userId,
4997
            false,
4998
            $ignoreVisibilityForAdmins,
4999
            $ignoreTimeLimit
5000
        );
5001
5002
        $sessionArray = [];
5003
        if (!empty($sessionCategories)) {
5004
            foreach ($sessionCategories as $category) {
5005
                if (isset($category['sessions'])) {
5006
                    foreach ($category['sessions'] as $session) {
5007
                        $sessionArray[] = $session;
5008
                    }
5009
                }
5010
            }
5011
        }
5012
5013
        return $sessionArray;
5014
    }
5015
5016
    /**
5017
     * @param string $file
5018
     * @param bool   $updateSession                                   true: if the session exists it will be updated.
5019
     *                                                                false: if session exists a new session will be
5020
     *                                                                created adding a counter session1, session2, etc
5021
     * @param int    $defaultUserId
5022
     * @param Logger $logger
5023
     * @param array  $extraFields                                     convert a file row to an extra field. Example in
5024
     *                                                                CSV file there's a SessionID then it will
5025
     *                                                                converted to extra_external_session_id if you
5026
     *                                                                set: array('SessionId' =>
5027
     *                                                                'extra_external_session_id')
5028
     * @param string $extraFieldId
5029
     * @param int    $daysCoachAccessBeforeBeginning
5030
     * @param int    $daysCoachAccessAfterBeginning
5031
     * @param int    $sessionVisibility
5032
     * @param array  $fieldsToAvoidUpdate
5033
     * @param bool   $deleteUsersNotInList
5034
     * @param bool   $updateCourseCoaches
5035
     * @param bool   $sessionWithCoursesModifier
5036
     * @param bool   $addOriginalCourseTeachersAsCourseSessionCoaches
5037
     * @param bool   $removeAllTeachersFromCourse
5038
     * @param int    $showDescription
5039
     * @param array  $teacherBackupList
5040
     * @param array  $groupBackup
5041
     *
5042
     * @return array
5043
     */
5044
    public static function importCSV(
5045
        $file,
5046
        $updateSession,
5047
        $defaultUserId = null,
5048
        $logger = null,
5049
        $extraFields = [],
5050
        $extraFieldId = null,
5051
        $daysCoachAccessBeforeBeginning = null,
5052
        $daysCoachAccessAfterBeginning = null,
5053
        $sessionVisibility = 1,
5054
        $fieldsToAvoidUpdate = [],
5055
        $deleteUsersNotInList = false,
5056
        $updateCourseCoaches = false,
5057
        $sessionWithCoursesModifier = false,
5058
        $addOriginalCourseTeachersAsCourseSessionCoaches = true,
5059
        $removeAllTeachersFromCourse = true,
5060
        $showDescription = null,
5061
        &$teacherBackupList = [],
5062
        &$groupBackup = []
5063
    ) {
5064
        $content = file($file);
5065
        $error_message = null;
5066
        $session_counter = 0;
5067
        $defaultUserId = empty($defaultUserId) ? api_get_user_id() : (int) $defaultUserId;
5068
5069
        $eol = PHP_EOL;
5070
        if (PHP_SAPI != 'cli') {
5071
            $eol = '<br />';
5072
        }
5073
5074
        $debug = false;
5075
        if (isset($logger)) {
5076
            $debug = true;
5077
        }
5078
5079
        $tbl_session = Database::get_main_table(TABLE_MAIN_SESSION);
5080
        $tbl_session_user = Database::get_main_table(TABLE_MAIN_SESSION_USER);
5081
        $tbl_session_course = Database::get_main_table(TABLE_MAIN_SESSION_COURSE);
5082
        $tbl_session_course_user = Database::get_main_table(TABLE_MAIN_SESSION_COURSE_USER);
5083
        $sessions = [];
5084
        if (!api_strstr($content[0], ';')) {
5085
            $error_message = get_lang('NotCSV');
5086
        } else {
5087
            $tag_names = [];
5088
            foreach ($content as $key => $enreg) {
5089
                $enreg = explode(';', trim($enreg));
5090
                if ($key) {
5091
                    foreach ($tag_names as $tag_key => $tag_name) {
5092
                        if (isset($enreg[$tag_key])) {
5093
                            $sessions[$key - 1][$tag_name] = $enreg[$tag_key];
5094
                        }
5095
                    }
5096
                } else {
5097
                    foreach ($enreg as $tag_name) {
5098
                        $tag_names[] = api_preg_replace('/[^a-zA-Z0-9_\-]/', '', $tag_name);
5099
                    }
5100
                    if (!in_array('SessionName', $tag_names) ||
5101
                        !in_array('DateStart', $tag_names) ||
5102
                        !in_array('DateEnd', $tag_names)
5103
                    ) {
5104
                        $error_message = get_lang('NoNeededData');
5105
                        break;
5106
                    }
5107
                }
5108
            }
5109
5110
            $sessionList = [];
5111
            $report = [];
5112
5113
            // Looping the sessions.
5114
            foreach ($sessions as $enreg) {
5115
                $user_counter = 0;
5116
                $course_counter = 0;
5117
5118
                if (isset($extraFields) && !empty($extraFields)) {
5119
                    foreach ($extraFields as $original => $to) {
5120
                        $enreg[$to] = isset($enreg[$original]) ? $enreg[$original] : null;
5121
                    }
5122
                }
5123
5124
                $session_name = trim(trim(api_utf8_decode($enreg['SessionName']), '"'));
5125
5126
                if ($debug) {
5127
                    $logger->addInfo('---------------------------------------');
5128
                    $logger->addInfo("Sessions - Start process of session: $session_name");
5129
                    $logger->addInfo('---------------------------------------');
5130
                }
5131
5132
                // Default visibility
5133
                $visibilityAfterExpirationPerSession = $sessionVisibility;
5134
5135
                if (isset($enreg['VisibilityAfterExpiration'])) {
5136
                    $visibility = $enreg['VisibilityAfterExpiration'];
5137
                    switch ($visibility) {
5138
                        case 'read_only':
5139
                            $visibilityAfterExpirationPerSession = SESSION_VISIBLE_READ_ONLY;
5140
                            break;
5141
                        case 'accessible':
5142
                            $visibilityAfterExpirationPerSession = SESSION_VISIBLE;
5143
                            break;
5144
                        case 'not_accessible':
5145
                            $visibilityAfterExpirationPerSession = SESSION_INVISIBLE;
5146
                            break;
5147
                    }
5148
                }
5149
5150
                if (empty($session_name)) {
5151
                    continue;
5152
                }
5153
5154
                $displayAccessStartDate = $enreg['DisplayStartDate'] ?? $enreg['DateStart'];
5155
                $displayAccessEndDate = $enreg['DisplayEndDate'] ?? $enreg['DateEnd'];
5156
                $coachAccessStartDate = $enreg['CoachStartDate'] ?? $enreg['DateStart'];
5157
                $coachAccessEndDate = $enreg['CoachEndDate'] ?? $enreg['DateEnd'];
5158
                // We assume the dates are already in UTC
5159
                $dateStart = explode('/', $enreg['DateStart']);
5160
                $dateEnd = explode('/', $enreg['DateEnd']);
5161
                $dateStart = $dateStart[0].'-'.$dateStart[1].'-'.$dateStart[2].' 00:00:00';
5162
                $dateEnd = $dateEnd[0].'-'.$dateEnd[1].'-'.$dateEnd[2].' 23:59:59';
5163
                $displayAccessStartDate = explode('/', $displayAccessStartDate);
5164
                $displayAccessStartDate = implode('-', $displayAccessStartDate).' 00:00:00';
5165
                $displayAccessEndDate = explode('/', $displayAccessEndDate);
5166
                $displayAccessEndDate = implode('-', $displayAccessEndDate).' 23:59:59';
5167
                $coachAccessStartDate = explode('/', $coachAccessStartDate);
5168
                $coachAccessStartDate = implode('-', $coachAccessStartDate).' 00:00:00';
5169
                $coachAccessEndDate = explode('/', $coachAccessEndDate);
5170
                $coachAccessEndDate = implode('-', $coachAccessEndDate).' 23:59:59';
5171
                $session_category_id = $enreg['SessionCategory'] ?? null;
5172
                $sessionDescription = $enreg['SessionDescription'] ?? null;
5173
                $classes = isset($enreg['Classes']) ? explode('|', $enreg['Classes']) : [];
5174
                $extraParams = [];
5175
                if (!is_null($showDescription)) {
5176
                    $extraParams['show_description'] = intval($showDescription);
5177
                }
5178
5179
                $coachBefore = '';
5180
                $coachAfter = '';
5181
                if (!empty($daysCoachAccessBeforeBeginning) && !empty($daysCoachAccessAfterBeginning)) {
5182
                    $date = new DateTime($dateStart);
5183
                    $interval = new DateInterval('P'.$daysCoachAccessBeforeBeginning.'D');
5184
                    $date->sub($interval);
5185
                    $coachBefore = $date->format('Y-m-d h:i');
5186
                    $coachAccessStartDate = $coachBefore;
5187
                    $coachBefore = api_get_utc_datetime($coachBefore);
5188
5189
                    $date = new DateTime($dateEnd);
5190
                    $interval = new DateInterval('P'.$daysCoachAccessAfterBeginning.'D');
5191
                    $date->add($interval);
5192
                    $coachAfter = $date->format('Y-m-d h:i');
5193
                    $coachAccessEndDate = $coachAfter;
5194
                    $coachAfter = api_get_utc_datetime($coachAfter);
5195
                }
5196
5197
                $dateStart = api_get_utc_datetime($dateStart);
5198
                $dateEnd = api_get_utc_datetime($dateEnd);
5199
                $displayAccessStartDate = api_get_utc_datetime($displayAccessStartDate);
5200
                $displayAccessEndDate = api_get_utc_datetime($displayAccessEndDate);
5201
                $coachAccessStartDate = api_get_utc_datetime($coachAccessStartDate);
5202
                $coachAccessEndDate = api_get_utc_datetime($coachAccessEndDate);
5203
5204
                if (!empty($sessionDescription)) {
5205
                    $extraParams['description'] = $sessionDescription;
5206
                }
5207
5208
                if (!empty($session_category_id)) {
5209
                    $extraParams['session_category_id'] = $session_category_id;
5210
                }
5211
5212
                // Searching a general coach.
5213
                if (!empty($enreg['Coach'])) {
5214
                    $coach_id = UserManager::get_user_id_from_username($enreg['Coach']);
5215
                    if ($coach_id === false) {
5216
                        // If the coach-user does not exist - I'm the coach.
5217
                        $coach_id = $defaultUserId;
5218
                    }
5219
                } else {
5220
                    $coach_id = $defaultUserId;
5221
                }
5222
5223
                $users = explode('|', $enreg['Users']);
5224
                $courses = explode('|', $enreg['Courses']);
5225
5226
                $deleteOnlyCourseCoaches = false;
5227
                if (count($courses) == 1) {
5228
                    if ($logger) {
5229
                        $logger->addInfo('Only one course delete old coach list');
5230
                    }
5231
                    $deleteOnlyCourseCoaches = true;
5232
                }
5233
5234
                if (!$updateSession) {
5235
                    // Create a session.
5236
                    $unique_name = false;
5237
                    $i = 0;
5238
                    // Change session name, verify that session doesn't exist.
5239
                    $suffix = null;
5240
                    while (!$unique_name) {
5241
                        if ($i > 1) {
5242
                            $suffix = ' - '.$i;
5243
                        }
5244
                        $sql = 'SELECT id FROM '.$tbl_session.'
5245
                                WHERE name="'.Database::escape_string($session_name).$suffix.'"';
5246
                        $rs = Database::query($sql);
5247
                        if (Database::result($rs, 0, 0)) {
5248
                            $i++;
5249
                        } else {
5250
                            $unique_name = true;
5251
                            $session_name .= $suffix;
5252
                        }
5253
                    }
5254
5255
                    $sessionParams = [
5256
                        'name' => $session_name,
5257
                        'id_coach' => $coach_id,
5258
                        'access_start_date' => $dateStart,
5259
                        'access_end_date' => $dateEnd,
5260
                        'display_start_date' => $displayAccessStartDate,
5261
                        'display_end_date' => $displayAccessEndDate,
5262
                        'coach_access_start_date' => $coachAccessStartDate,
5263
                        'coach_access_end_date' => $coachAccessEndDate,
5264
                        'visibility' => $visibilityAfterExpirationPerSession,
5265
                        'session_admin_id' => $defaultUserId,
5266
                    ];
5267
5268
                    if (!empty($extraParams)) {
5269
                        $sessionParams = array_merge($sessionParams, $extraParams);
5270
                    }
5271
                    // Creating the session.
5272
                    $session_id = Database::insert($tbl_session, $sessionParams);
5273
                    if ($debug) {
5274
                        if ($session_id) {
5275
                            foreach ($enreg as $key => $value) {
5276
                                if (substr($key, 0, 6) == 'extra_') { //an extra field
5277
                                    self::update_session_extra_field_value($session_id, substr($key, 6), $value);
5278
                                }
5279
                            }
5280
                            $logger->addInfo("Session created: #$session_id - $session_name");
5281
                        } else {
5282
                            $message = "Sessions - Session NOT created: $session_name";
5283
                            $logger->addError($message);
5284
                            $report[] = $message;
5285
                        }
5286
                    }
5287
                    $session_counter++;
5288
                } else {
5289
                    $sessionId = null;
5290
                    if (isset($extraFields) && !empty($extraFields) && !empty($enreg['extra_'.$extraFieldId])) {
5291
                        $sessionId = self::getSessionIdFromOriginalId($enreg['extra_'.$extraFieldId], $extraFieldId);
5292
                        if (empty($sessionId)) {
5293
                            $my_session_result = false;
5294
                        } else {
5295
                            $my_session_result = true;
5296
                        }
5297
                    } else {
5298
                        $my_session_result = self::get_session_by_name($enreg['SessionName']);
5299
                    }
5300
5301
                    if ($my_session_result === false) {
5302
                        // One more check
5303
                        $sessionExistsWithName = self::get_session_by_name($session_name);
5304
                        if ($sessionExistsWithName) {
5305
                            if ($debug) {
5306
                                $message = "Skip Session - Trying to update a session, but name already exists: $session_name";
5307
                                $logger->addError($message);
5308
                                $report[] = $message;
5309
                            }
5310
                            continue;
5311
                        }
5312
5313
                        $sessionParams = [
5314
                            'name' => $session_name,
5315
                            'id_coach' => $coach_id,
5316
                            'access_start_date' => $dateStart,
5317
                            'access_end_date' => $dateEnd,
5318
                            'display_start_date' => $displayAccessStartDate,
5319
                            'display_end_date' => $displayAccessEndDate,
5320
                            'coach_access_start_date' => $coachAccessStartDate,
5321
                            'coach_access_end_date' => $coachAccessEndDate,
5322
                            'visibility' => $visibilityAfterExpirationPerSession,
5323
                            'session_admin_id' => $defaultUserId,
5324
                        ];
5325
5326
                        if (!empty($extraParams)) {
5327
                            $sessionParams = array_merge($sessionParams, $extraParams);
5328
                        }
5329
                        Database::insert($tbl_session, $sessionParams);
5330
5331
                        // We get the last insert id.
5332
                        $my_session_result = self::get_session_by_name($session_name);
5333
                        $session_id = $my_session_result['id'];
5334
5335
                        if ($session_id) {
5336
                            foreach ($enreg as $key => $value) {
5337
                                if (substr($key, 0, 6) == 'extra_') { //an extra field
5338
                                    self::update_session_extra_field_value($session_id, substr($key, 6), $value);
5339
                                }
5340
                            }
5341
                            if ($debug) {
5342
                                $logger->addInfo("Sessions - #$session_id created: $session_name");
5343
                            }
5344
5345
                            // Delete session-user relation only for students
5346
                            $sql = "DELETE FROM $tbl_session_user
5347
                                    WHERE session_id = '$session_id' AND relation_type <> ".SESSION_RELATION_TYPE_RRHH;
5348
                            Database::query($sql);
5349
5350
                            $sql = "DELETE FROM $tbl_session_course WHERE session_id = '$session_id'";
5351
                            Database::query($sql);
5352
5353
                            // Delete session-course-user relationships students and coaches.
5354
                            if ($updateCourseCoaches) {
5355
                                $sql = "DELETE FROM $tbl_session_course_user
5356
                                        WHERE session_id = '$session_id' AND status in ('0', '2')";
5357
                                Database::query($sql);
5358
                            } else {
5359
                                // Delete session-course-user relation ships *only* for students.
5360
                                $sql = "DELETE FROM $tbl_session_course_user
5361
                                        WHERE session_id = '$session_id' AND status <> 2";
5362
                                Database::query($sql);
5363
                            }
5364
                            if ($deleteOnlyCourseCoaches) {
5365
                                $sql = "DELETE FROM $tbl_session_course_user
5366
                                        WHERE session_id = '$session_id' AND status in ('2')";
5367
                                Database::query($sql);
5368
                            }
5369
                        }
5370
                    } else {
5371
                        // Updating the session.
5372
                        $params = [
5373
                            'id_coach' => $coach_id,
5374
                            'access_start_date' => $dateStart,
5375
                            'access_end_date' => $dateEnd,
5376
                            'display_start_date' => $displayAccessStartDate,
5377
                            'display_end_date' => $displayAccessEndDate,
5378
                            'coach_access_start_date' => $coachAccessStartDate,
5379
                            'coach_access_end_date' => $coachAccessEndDate,
5380
                            'visibility' => $visibilityAfterExpirationPerSession,
5381
                            'session_category_id' => $session_category_id,
5382
                        ];
5383
5384
                        if (!empty($sessionDescription)) {
5385
                            $params['description'] = $sessionDescription;
5386
                        }
5387
5388
                        if (!empty($fieldsToAvoidUpdate)) {
5389
                            foreach ($fieldsToAvoidUpdate as $field) {
5390
                                unset($params[$field]);
5391
                            }
5392
                        }
5393
5394
                        if (isset($sessionId) && !empty($sessionId)) {
5395
                            $session_id = $sessionId;
5396
                            if (!empty($enreg['SessionName'])) {
5397
                                $sessionExistsWithName = self::get_session_by_name($session_name);
5398
                                if ($sessionExistsWithName === false) {
5399
                                    $sessionName = Database::escape_string($enreg['SessionName']);
5400
                                    $sql = "UPDATE $tbl_session SET name = '$sessionName' WHERE id = $session_id";
5401
                                    Database::query($sql);
5402
                                    $logger->addInfo(
5403
                                        "Session #$session_id name IS updated with: '$session_name' External id: ".$enreg['extra_'.$extraFieldId]
5404
                                    );
5405
                                } else {
5406
                                    $sessionExistsBesidesMe = self::sessionNameExistBesidesMySession(
5407
                                        $session_id,
5408
                                        $session_name
5409
                                    );
5410
                                    if ($sessionExistsBesidesMe === true) {
5411
                                        if ($debug) {
5412
                                            $message = "Skip Session. Error when update session Session #$session_id Name: '$session_name'. Other session has the same name. External id: ".$enreg['extra_'.$extraFieldId];
5413
                                            $logger->addError($message);
5414
                                            $report[] = $message;
5415
                                        }
5416
                                        continue;
5417
                                    } else {
5418
                                        if ($debug) {
5419
                                            $logger->addInfo(
5420
                                                "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]
5421
                                            );
5422
                                        }
5423
                                    }
5424
                                }
5425
                            }
5426
                        } else {
5427
                            $my_session_result = self::get_session_by_name($session_name);
5428
                            $session_id = $my_session_result['id'];
5429
                        }
5430
5431
                        if ($debug) {
5432
                            $logger->addInfo("Session #$session_id to be updated: '$session_name'");
5433
                        }
5434
5435
                        if ($session_id) {
5436
                            $sessionInfo = api_get_session_info($session_id);
5437
                            $params['show_description'] = isset($sessionInfo['show_description']) ? $sessionInfo['show_description'] : intval($showDescription);
5438
5439
                            if (!empty($daysCoachAccessBeforeBeginning) && !empty($daysCoachAccessAfterBeginning)) {
5440
                                if (empty($sessionInfo['nb_days_access_before_beginning']) ||
5441
                                    (!empty($sessionInfo['nb_days_access_before_beginning']) &&
5442
                                        $sessionInfo['nb_days_access_before_beginning'] < $daysCoachAccessBeforeBeginning)
5443
                                ) {
5444
                                    $params['coach_access_start_date'] = $coachBefore;
5445
                                }
5446
5447
                                if (empty($sessionInfo['nb_days_access_after_end']) ||
5448
                                    (!empty($sessionInfo['nb_days_access_after_end']) &&
5449
                                        $sessionInfo['nb_days_access_after_end'] < $daysCoachAccessAfterBeginning)
5450
                                ) {
5451
                                    $params['coach_access_end_date'] = $coachAfter;
5452
                                }
5453
                            }
5454
5455
                            Database::update($tbl_session, $params, ['id = ?' => $session_id]);
5456
                            foreach ($enreg as $key => $value) {
5457
                                if (substr($key, 0, 6) == 'extra_') { //an extra field
5458
                                    self::update_session_extra_field_value($session_id, substr($key, 6), $value);
5459
                                }
5460
                            }
5461
5462
                            if ($debug) {
5463
                                $logger->addInfo("Session updated #$session_id");
5464
                            }
5465
5466
                            // Delete session-user relation only for students
5467
                            $sql = "DELETE FROM $tbl_session_user
5468
                                    WHERE session_id = '$session_id' AND relation_type <> ".SESSION_RELATION_TYPE_RRHH;
5469
                            Database::query($sql);
5470
5471
                            $sql = "DELETE FROM $tbl_session_course WHERE session_id = '$session_id'";
5472
                            Database::query($sql);
5473
5474
                            // Delete session-course-user relationships students and coaches.
5475
                            if ($updateCourseCoaches) {
5476
                                $sql = "DELETE FROM $tbl_session_course_user
5477
                                        WHERE session_id = '$session_id' AND status in ('0', '2')";
5478
                                Database::query($sql);
5479
                            } else {
5480
                                // Delete session-course-user relation ships *only* for students.
5481
                                $sql = "DELETE FROM $tbl_session_course_user
5482
                                        WHERE session_id = '$session_id' AND status <> 2";
5483
                                Database::query($sql);
5484
                            }
5485
5486
                            if ($deleteOnlyCourseCoaches) {
5487
                                $sql = "DELETE FROM $tbl_session_course_user
5488
                                        WHERE session_id = '$session_id' AND status in ('2')";
5489
                                Database::query($sql);
5490
                            }
5491
                        } else {
5492
                            if ($debug) {
5493
                                $logger->addError(
5494
                                    "Sessions - Session not found"
5495
                                );
5496
                            }
5497
                        }
5498
                    }
5499
                    $session_counter++;
5500
                }
5501
5502
                $sessionList[] = $session_id;
5503
5504
                // Adding the relationship "Session - User" for students
5505
                $userList = [];
5506
                if (is_array($users)) {
5507
                    $extraFieldValueCareer = new ExtraFieldValue('career');
5508
                    $careerList = isset($enreg['extra_careerid']) && !empty($enreg['extra_careerid']) ? $enreg['extra_careerid'] : [];
5509
                    $careerList = str_replace(['[', ']'], '', $careerList);
5510
                    $finalCareerIdList = [];
5511
                    if (!empty($careerList)) {
5512
                        $careerList = explode(',', $careerList);
5513
                        foreach ($careerList as $careerId) {
5514
                            $realCareerIdList = $extraFieldValueCareer->get_item_id_from_field_variable_and_field_value(
5515
                                'external_career_id',
5516
                                $careerId
5517
                            );
5518
                            if (isset($realCareerIdList['item_id'])) {
5519
                                $finalCareerIdList[] = $realCareerIdList['item_id'];
5520
                            }
5521
                        }
5522
                    }
5523
                    foreach ($users as $user) {
5524
                        $user_id = UserManager::get_user_id_from_username($user);
5525
                        if ($user_id !== false) {
5526
                            if (!empty($finalCareerIdList)) {
5527
                                foreach ($finalCareerIdList as $careerId) {
5528
                                    UserManager::addUserCareer($user_id, $careerId);
5529
                                }
5530
                            }
5531
5532
                            $userList[] = $user_id;
5533
                            // Insert new users.
5534
                            $sql = "INSERT IGNORE INTO $tbl_session_user SET
5535
                                    user_id = '$user_id',
5536
                                    session_id = '$session_id',
5537
                                    registered_at = '".api_get_utc_datetime()."'";
5538
                            Database::query($sql);
5539
                            if ($debug) {
5540
                                $logger->addInfo("Adding User #$user_id ($user) to session #$session_id");
5541
                            }
5542
                            $user_counter++;
5543
                        }
5544
                    }
5545
                }
5546
5547
                if ($deleteUsersNotInList) {
5548
                    // Getting user in DB in order to compare to the new list.
5549
                    $usersListInDatabase = self::get_users_by_session($session_id, 0);
5550
                    if (!empty($usersListInDatabase)) {
5551
                        if (empty($userList)) {
5552
                            foreach ($usersListInDatabase as $userInfo) {
5553
                                self::unsubscribe_user_from_session($session_id, $userInfo['user_id']);
5554
                            }
5555
                        } else {
5556
                            foreach ($usersListInDatabase as $userInfo) {
5557
                                if (!in_array($userInfo['user_id'], $userList)) {
5558
                                    self::unsubscribe_user_from_session($session_id, $userInfo['user_id']);
5559
                                }
5560
                            }
5561
                        }
5562
                    }
5563
                }
5564
5565
                // See BT#6449
5566
                $onlyAddFirstCoachOrTeacher = false;
5567
                if ($sessionWithCoursesModifier) {
5568
                    if (count($courses) >= 2) {
5569
                        // Only first teacher in course session;
5570
                        $onlyAddFirstCoachOrTeacher = true;
5571
                        // Remove all teachers from course.
5572
                        $removeAllTeachersFromCourse = false;
5573
                    }
5574
                }
5575
5576
                $position = 0;
5577
                foreach ($courses as $course) {
5578
                    $courseArray = bracketsToArray($course);
5579
                    $course_code = $courseArray[0];
5580
5581
                    if (CourseManager::course_exists($course_code)) {
5582
                        $courseInfo = api_get_course_info($course_code);
5583
                        $courseId = $courseInfo['real_id'];
5584
5585
                        // Adding the course to a session.
5586
                        $sql = "INSERT IGNORE INTO $tbl_session_course
5587
                                SET c_id = '$courseId', session_id='$session_id', position = '$position'";
5588
                        Database::query($sql);
5589
5590
                        self::installCourse($session_id, $courseInfo['real_id']);
5591
5592
                        if ($debug) {
5593
                            $logger->addInfo("Adding course '$course_code' to session #$session_id");
5594
                        }
5595
5596
                        $course_counter++;
5597
                        $course_coaches = isset($courseArray[1]) ? $courseArray[1] : null;
5598
                        $course_users = isset($courseArray[2]) ? $courseArray[2] : null;
5599
                        $course_users = explode(',', $course_users);
5600
                        $course_coaches = explode(',', $course_coaches);
5601
5602
                        // Checking if the flag is set TeachersWillBeAddedAsCoachInAllCourseSessions (course_edit.php)
5603
                        $addTeachersToSession = true;
5604
5605
                        if (array_key_exists('add_teachers_to_sessions_courses', $courseInfo)) {
5606
                            $addTeachersToSession = $courseInfo['add_teachers_to_sessions_courses'];
5607
                        }
5608
5609
                        // If any user provided for a course, use the users array.
5610
                        if (empty($course_users)) {
5611
                            if (!empty($userList)) {
5612
                                self::subscribe_users_to_session_course(
5613
                                    $userList,
5614
                                    $session_id,
5615
                                    $course_code
5616
                                );
5617
                                if ($debug) {
5618
                                    $msg = "Adding student list ".implode(', #', $userList)." to course: '$course_code' and session #$session_id";
5619
                                    $logger->addInfo($msg);
5620
                                }
5621
                            }
5622
                        }
5623
5624
                        // Adding coaches to session course user.
5625
                        if (!empty($course_coaches)) {
5626
                            $savedCoaches = [];
5627
                            // only edit if add_teachers_to_sessions_courses is set.
5628
                            if ($addTeachersToSession) {
5629
                                if ($addOriginalCourseTeachersAsCourseSessionCoaches) {
5630
                                    // Adding course teachers as course session teachers.
5631
                                    $alreadyAddedTeachers = CourseManager::get_teacher_list_from_course_code(
5632
                                        $course_code
5633
                                    );
5634
5635
                                    if (!empty($alreadyAddedTeachers)) {
5636
                                        $teachersToAdd = [];
5637
                                        foreach ($alreadyAddedTeachers as $user) {
5638
                                            $teachersToAdd[] = $user['username'];
5639
                                        }
5640
                                        $course_coaches = array_merge(
5641
                                            $course_coaches,
5642
                                            $teachersToAdd
5643
                                        );
5644
                                    }
5645
                                }
5646
5647
                                foreach ($course_coaches as $course_coach) {
5648
                                    $coach_id = UserManager::get_user_id_from_username($course_coach);
5649
                                    if ($coach_id !== false) {
5650
                                        // Just insert new coaches
5651
                                        self::updateCoaches(
5652
                                            $session_id,
5653
                                            $courseId,
5654
                                            [$coach_id],
5655
                                            false
5656
                                        );
5657
5658
                                        if ($debug) {
5659
                                            $logger->addInfo("Adding course coach: user #$coach_id ($course_coach) to course: '$course_code' and session #$session_id");
5660
                                        }
5661
                                        $savedCoaches[] = $coach_id;
5662
                                    } else {
5663
                                        $error_message .= get_lang('UserDoesNotExist').' : '.$course_coach.$eol;
5664
                                    }
5665
                                }
5666
                            }
5667
5668
                            // Custom courses/session coaches
5669
                            $teacherToAdd = null;
5670
                            // Only one coach is added.
5671
                            if ($onlyAddFirstCoachOrTeacher == true) {
5672
                                if ($debug) {
5673
                                    $logger->addInfo("onlyAddFirstCoachOrTeacher : true");
5674
                                }
5675
5676
                                foreach ($course_coaches as $course_coach) {
5677
                                    $coach_id = UserManager::get_user_id_from_username($course_coach);
5678
                                    if ($coach_id !== false) {
5679
                                        $teacherToAdd = $coach_id;
5680
                                        break;
5681
                                    }
5682
                                }
5683
5684
                                // Un subscribe everyone that's not in the list.
5685
                                $teacherList = CourseManager::get_teacher_list_from_course_code($course_code);
5686
                                if (!empty($teacherList)) {
5687
                                    foreach ($teacherList as $teacher) {
5688
                                        if ($teacherToAdd != $teacher['user_id']) {
5689
                                            $sql = "SELECT * FROM ".Database::get_main_table(TABLE_MAIN_COURSE_USER)."
5690
                                                    WHERE
5691
                                                        user_id = ".$teacher['user_id']." AND
5692
                                                        c_id = '".$courseId."'
5693
                                                    ";
5694
5695
                                            $result = Database::query($sql);
5696
                                            $rows = Database::num_rows($result);
5697
                                            if ($rows > 0) {
5698
                                                $userCourseData = Database::fetch_array($result, 'ASSOC');
5699
                                                if (!empty($userCourseData)) {
5700
                                                    $teacherBackupList[$teacher['user_id']][$course_code] = $userCourseData;
5701
                                                }
5702
                                            }
5703
5704
                                            $sql = "SELECT * FROM ".Database::get_course_table(TABLE_GROUP_USER)."
5705
                                                    WHERE
5706
                                                        user_id = ".$teacher['user_id']." AND
5707
                                                        c_id = '".$courseInfo['real_id']."'
5708
                                                    ";
5709
5710
                                            $result = Database::query($sql);
5711
                                            while ($groupData = Database::fetch_array($result, 'ASSOC')) {
5712
                                                $groupBackup['user'][$teacher['user_id']][$course_code][$groupData['group_id']] = $groupData;
5713
                                            }
5714
5715
                                            $sql = "SELECT * FROM ".Database::get_course_table(TABLE_GROUP_TUTOR)."
5716
                                                    WHERE
5717
                                                        user_id = ".$teacher['user_id']." AND
5718
                                                        c_id = '".$courseInfo['real_id']."'
5719
                                                    ";
5720
5721
                                            $result = Database::query($sql);
5722
                                            while ($groupData = Database::fetch_array($result, 'ASSOC')) {
5723
                                                $groupBackup['tutor'][$teacher['user_id']][$course_code][$groupData['group_id']] = $groupData;
5724
                                            }
5725
5726
                                            CourseManager::unsubscribe_user(
5727
                                                $teacher['user_id'],
5728
                                                $course_code
5729
                                            );
5730
5731
                                            if ($debug) {
5732
                                                $logger->addInfo("Delete user #".$teacher['user_id']." from base course: $course_code");
5733
                                            }
5734
                                        }
5735
                                    }
5736
                                }
5737
5738
                                if (!empty($teacherToAdd)) {
5739
                                    self::updateCoaches(
5740
                                        $session_id,
5741
                                        $courseId,
5742
                                        [$teacherToAdd],
5743
                                        true
5744
                                    );
5745
5746
                                    if ($debug) {
5747
                                        $logger->addInfo("Add coach #$teacherToAdd to course $courseId and session $session_id");
5748
                                    }
5749
5750
                                    $userCourseCategory = '';
5751
                                    if (isset($teacherBackupList[$teacherToAdd]) &&
5752
                                        isset($teacherBackupList[$teacherToAdd][$course_code])
5753
                                    ) {
5754
                                        $courseUserData = $teacherBackupList[$teacherToAdd][$course_code];
5755
                                        $userCourseCategory = $courseUserData['user_course_cat'];
5756
                                    }
5757
5758
                                    CourseManager::subscribeUser(
5759
                                        $teacherToAdd,
5760
                                        $course_code,
5761
                                        COURSEMANAGER,
5762
                                        0,
5763
                                        $userCourseCategory
5764
                                    );
5765
5766
                                    if ($debug) {
5767
                                        $logger->addInfo("Subscribe user #$teacherToAdd as teacher in course $course_code with user userCourseCategory $userCourseCategory");
5768
                                    }
5769
5770
                                    if (isset($groupBackup['user'][$teacherToAdd]) &&
5771
                                        isset($groupBackup['user'][$teacherToAdd][$course_code]) &&
5772
                                        !empty($groupBackup['user'][$teacherToAdd][$course_code])
5773
                                    ) {
5774
                                        foreach ($groupBackup['user'][$teacherToAdd][$course_code] as $data) {
5775
                                            $groupInfo = GroupManager::get_group_properties($data['group_id']);
5776
                                            GroupManager::subscribe_users(
5777
                                                $teacherToAdd,
5778
                                                $groupInfo,
5779
                                                $data['c_id']
5780
                                            );
5781
                                        }
5782
                                    }
5783
5784
                                    if (isset($groupBackup['tutor'][$teacherToAdd]) &&
5785
                                        isset($groupBackup['tutor'][$teacherToAdd][$course_code]) &&
5786
                                        !empty($groupBackup['tutor'][$teacherToAdd][$course_code])
5787
                                    ) {
5788
                                        foreach ($groupBackup['tutor'][$teacherToAdd][$course_code] as $data) {
5789
                                            $groupInfo = GroupManager::get_group_properties($data['group_id']);
5790
                                            GroupManager::subscribe_tutors(
5791
                                                $teacherToAdd,
5792
                                                $groupInfo,
5793
                                                $data['c_id']
5794
                                            );
5795
                                        }
5796
                                    }
5797
                                }
5798
                            }
5799
5800
                            // See BT#6449#note-195
5801
                            // All coaches are added.
5802
                            if ($removeAllTeachersFromCourse) {
5803
                                if ($debug) {
5804
                                    $logger->addInfo("removeAllTeachersFromCourse true");
5805
                                }
5806
                                $teacherToAdd = null;
5807
                                foreach ($course_coaches as $course_coach) {
5808
                                    $coach_id = UserManager::get_user_id_from_username(
5809
                                        $course_coach
5810
                                    );
5811
                                    if ($coach_id !== false) {
5812
                                        $teacherToAdd[] = $coach_id;
5813
                                    }
5814
                                }
5815
5816
                                if (!empty($teacherToAdd)) {
5817
                                    // Deleting all course teachers and adding the only coach as teacher.
5818
                                    $teacherList = CourseManager::get_teacher_list_from_course_code($course_code);
5819
5820
                                    if (!empty($teacherList)) {
5821
                                        foreach ($teacherList as $teacher) {
5822
                                            if (!in_array($teacher['user_id'], $teacherToAdd)) {
5823
                                                $sql = "SELECT * FROM ".Database::get_main_table(TABLE_MAIN_COURSE_USER)."
5824
                                                        WHERE
5825
                                                            user_id = ".$teacher['user_id']." AND
5826
                                                            c_id = '".$courseId."'
5827
                                                        ";
5828
5829
                                                $result = Database::query($sql);
5830
                                                $rows = Database::num_rows($result);
5831
                                                if ($rows > 0) {
5832
                                                    $userCourseData = Database::fetch_array($result, 'ASSOC');
5833
                                                    if (!empty($userCourseData)) {
5834
                                                        $teacherBackupList[$teacher['user_id']][$course_code] = $userCourseData;
5835
                                                    }
5836
                                                }
5837
5838
                                                $sql = "SELECT * FROM ".Database::get_course_table(TABLE_GROUP_USER)."
5839
                                                        WHERE
5840
                                                            user_id = ".$teacher['user_id']." AND
5841
                                                            c_id = '".$courseInfo['real_id']."'
5842
                                                        ";
5843
5844
                                                $result = Database::query($sql);
5845
                                                while ($groupData = Database::fetch_array($result, 'ASSOC')) {
5846
                                                    $groupBackup['user'][$teacher['user_id']][$course_code][$groupData['group_id']] = $groupData;
5847
                                                }
5848
5849
                                                $sql = "SELECT * FROM ".Database::get_course_table(TABLE_GROUP_TUTOR)."
5850
                                                        WHERE
5851
                                                            user_id = ".$teacher['user_id']." AND
5852
                                                            c_id = '".$courseInfo['real_id']."'
5853
                                                        ";
5854
5855
                                                $result = Database::query($sql);
5856
                                                while ($groupData = Database::fetch_array($result, 'ASSOC')) {
5857
                                                    $groupBackup['tutor'][$teacher['user_id']][$course_code][$groupData['group_id']] = $groupData;
5858
                                                }
5859
5860
                                                CourseManager::unsubscribe_user(
5861
                                                    $teacher['user_id'],
5862
                                                    $course_code
5863
                                                );
5864
5865
                                                if ($debug) {
5866
                                                    $logger->addInfo("Delete user #".$teacher['user_id']." from base course: $course_code");
5867
                                                }
5868
                                            }
5869
                                        }
5870
                                    }
5871
5872
                                    foreach ($teacherToAdd as $teacherId) {
5873
                                        $userCourseCategory = '';
5874
                                        if (isset($teacherBackupList[$teacherId]) &&
5875
                                            isset($teacherBackupList[$teacherId][$course_code])
5876
                                        ) {
5877
                                            $courseUserData = $teacherBackupList[$teacherId][$course_code];
5878
                                            $userCourseCategory = $courseUserData['user_course_cat'];
5879
                                        }
5880
5881
                                        CourseManager::subscribeUser(
5882
                                            $teacherId,
5883
                                            $course_code,
5884
                                            COURSEMANAGER,
5885
                                            0,
5886
                                            $userCourseCategory
5887
                                        );
5888
5889
                                        if ($debug) {
5890
                                            $logger->addInfo("Add user as teacher #".$teacherId." in base course: $course_code with userCourseCategory: $userCourseCategory");
5891
                                        }
5892
5893
                                        if (isset($groupBackup['user'][$teacherId]) &&
5894
                                            isset($groupBackup['user'][$teacherId][$course_code]) &&
5895
                                            !empty($groupBackup['user'][$teacherId][$course_code])
5896
                                        ) {
5897
                                            foreach ($groupBackup['user'][$teacherId][$course_code] as $data) {
5898
                                                $groupInfo = GroupManager::get_group_properties($data['group_id']);
5899
                                                GroupManager::subscribe_users(
5900
                                                    $teacherId,
5901
                                                    $groupInfo,
5902
                                                    $data['c_id']
5903
                                                );
5904
                                            }
5905
                                        }
5906
5907
                                        if (isset($groupBackup['tutor'][$teacherId]) &&
5908
                                            isset($groupBackup['tutor'][$teacherId][$course_code]) &&
5909
                                            !empty($groupBackup['tutor'][$teacherId][$course_code])
5910
                                        ) {
5911
                                            foreach ($groupBackup['tutor'][$teacherId][$course_code] as $data) {
5912
                                                $groupInfo = GroupManager::get_group_properties($data['group_id']);
5913
                                                GroupManager::subscribe_tutors(
5914
                                                    $teacherId,
5915
                                                    $groupInfo,
5916
                                                    $data['c_id']
5917
                                                );
5918
                                            }
5919
                                        }
5920
                                    }
5921
                                }
5922
                            }
5923
5924
                            // Continue default behaviour.
5925
                            if ($onlyAddFirstCoachOrTeacher == false) {
5926
                                // Checking one more time see BT#6449#note-149
5927
                                $coaches = self::getCoachesByCourseSession($session_id, $courseId);
5928
                                // Update coaches if only there's 1 course see BT#6449#note-189
5929
                                if (empty($coaches) || count($courses) == 1) {
5930
                                    foreach ($course_coaches as $course_coach) {
5931
                                        $course_coach = trim($course_coach);
5932
                                        $coach_id = UserManager::get_user_id_from_username($course_coach);
5933
                                        if ($coach_id !== false) {
5934
                                            // Just insert new coaches
5935
                                            self::updateCoaches(
5936
                                                $session_id,
5937
                                                $courseId,
5938
                                                [$coach_id],
5939
                                                false
5940
                                            );
5941
5942
                                            if ($debug) {
5943
                                                $logger->addInfo("Sessions - Adding course coach: user #$coach_id ($course_coach) to course: '$course_code' and session #$session_id");
5944
                                            }
5945
                                            $savedCoaches[] = $coach_id;
5946
                                        } else {
5947
                                            $error_message .= get_lang('UserDoesNotExist').' : '.$course_coach.$eol;
5948
                                        }
5949
                                    }
5950
                                }
5951
                            }
5952
                        }
5953
5954
                        // Adding Students, updating relationship "Session - Course - User".
5955
                        $course_users = array_filter($course_users);
5956
                        if (!empty($course_users)) {
5957
                            foreach ($course_users as $user) {
5958
                                $user_id = UserManager::get_user_id_from_username($user);
5959
5960
                                if ($user_id !== false) {
5961
                                    self::subscribe_users_to_session_course(
5962
                                        [$user_id],
5963
                                        $session_id,
5964
                                        $course_code
5965
                                    );
5966
                                    if ($debug) {
5967
                                        $logger->addInfo("Adding student: user #$user_id ($user) to course: '$course_code' and session #$session_id");
5968
                                    }
5969
                                } else {
5970
                                    $error_message .= get_lang('UserDoesNotExist').': '.$user.$eol;
5971
                                }
5972
                            }
5973
                        }
5974
                        $inserted_in_course[$course_code] = $courseInfo['title'];
5975
                        $position++;
5976
                    }
5977
                }
5978
                $access_url_id = api_get_current_access_url_id();
5979
                UrlManager::add_session_to_url($session_id, $access_url_id);
5980
                $sql = "UPDATE $tbl_session SET nbr_users = '$user_counter', nbr_courses = '$course_counter'
5981
                        WHERE id = '$session_id'";
5982
                Database::query($sql);
5983
5984
                self::addClassesByName($session_id, $classes, false, $error_message);
5985
5986
                if ($debug) {
5987
                    $logger->addInfo("End process session #$session_id -------------------- ");
5988
                }
5989
            }
5990
5991
            if (!empty($report)) {
5992
                if ($debug) {
5993
                    $logger->addInfo("--Summary--");
5994
                    foreach ($report as $line) {
5995
                        $logger->addInfo($line);
5996
                    }
5997
                }
5998
            }
5999
        }
6000
6001
        return [
6002
            'error_message' => $error_message,
6003
            'session_counter' => $session_counter,
6004
            'session_list' => $sessionList,
6005
        ];
6006
    }
6007
6008
    /**
6009
     * @param int $sessionId
6010
     * @param int $courseId
6011
     *
6012
     * @return array
6013
     */
6014
    public static function getCoachesByCourseSession($sessionId, $courseId)
6015
    {
6016
        $table = Database::get_main_table(TABLE_MAIN_SESSION_COURSE_USER);
6017
        $sessionId = (int) $sessionId;
6018
        $courseId = (int) $courseId;
6019
6020
        $sql = "SELECT user_id FROM $table
6021
                WHERE
6022
                    session_id = '$sessionId' AND
6023
                    c_id = '$courseId' AND
6024
                    status = 2";
6025
        $result = Database::query($sql);
6026
6027
        $coaches = [];
6028
        if (Database::num_rows($result) > 0) {
6029
            while ($row = Database::fetch_array($result)) {
6030
                $coaches[] = $row['user_id'];
6031
            }
6032
        }
6033
6034
        return $coaches;
6035
    }
6036
6037
    /**
6038
     * @param int    $sessionId
6039
     * @param int    $courseId
6040
     * @param string $separator
6041
     *
6042
     * @return string
6043
     */
6044
    public static function getCoachesByCourseSessionToString(
6045
        $sessionId,
6046
        $courseId,
6047
        $separator = ''
6048
    ) {
6049
        $coaches = self::getCoachesByCourseSession($sessionId, $courseId);
6050
        $list = [];
6051
        if (!empty($coaches)) {
6052
            foreach ($coaches as $coachId) {
6053
                $userInfo = api_get_user_info($coachId);
6054
                if ($userInfo) {
6055
                    $list[] = $userInfo['complete_name'];
6056
                }
6057
            }
6058
        }
6059
6060
        $separator = empty($separator) ? CourseManager::USER_SEPARATOR : $separator;
6061
6062
        return array_to_string($list, $separator);
6063
    }
6064
6065
    /**
6066
     * Get all coaches added in the session - course relationship.
6067
     *
6068
     * @param int $sessionId
6069
     *
6070
     * @return array
6071
     */
6072
    public static function getCoachesBySession($sessionId)
6073
    {
6074
        $table = Database::get_main_table(TABLE_MAIN_SESSION_COURSE_USER);
6075
        $sessionId = intval($sessionId);
6076
6077
        $sql = "SELECT DISTINCT user_id
6078
                FROM $table
6079
                WHERE session_id = '$sessionId' AND status = 2";
6080
        $result = Database::query($sql);
6081
6082
        $coaches = [];
6083
        if (Database::num_rows($result) > 0) {
6084
            while ($row = Database::fetch_array($result)) {
6085
                $coaches[] = $row['user_id'];
6086
            }
6087
        }
6088
6089
        return $coaches;
6090
    }
6091
6092
    /**
6093
     * @param int $userId
6094
     *
6095
     * @return array
6096
     */
6097
    public static function getAllCoursesFromAllSessionFromDrh($userId)
6098
    {
6099
        $sessions = self::get_sessions_followed_by_drh($userId);
6100
        $coursesFromSession = [];
6101
        if (!empty($sessions)) {
6102
            foreach ($sessions as $session) {
6103
                $courseList = self::get_course_list_by_session_id($session['id']);
6104
                foreach ($courseList as $course) {
6105
                    $coursesFromSession[] = $course['code'];
6106
                }
6107
            }
6108
        }
6109
6110
        return $coursesFromSession;
6111
    }
6112
6113
    /**
6114
     * getAllCoursesFromAllSessions.
6115
     *
6116
     * @return array
6117
     */
6118
    public static function getAllCoursesFromAllSessions()
6119
    {
6120
        $sessions = self::get_sessions_list();
6121
        $coursesFromSession = [];
6122
        if (!empty($sessions)) {
6123
            foreach ($sessions as $session) {
6124
                $courseList = self::get_course_list_by_session_id($session['id']);
6125
                foreach ($courseList as $course) {
6126
                    $coursesFromSession[$course['code'].':'.$session['id']] = $course['visual_code'].' - '.$course['title'].' ('.$session['name'].')';
6127
                }
6128
            }
6129
        }
6130
6131
        return $coursesFromSession;
6132
    }
6133
6134
    /**
6135
     * Return user id list or count of users depending of the $getCount parameter.
6136
     *
6137
     * @param string $status
6138
     * @param int    $userId
6139
     * @param bool   $getCount
6140
     * @param int    $from
6141
     * @param int    $numberItems
6142
     * @param int    $column
6143
     * @param string $direction
6144
     * @param string $keyword
6145
     * @param string $active
6146
     * @param string $lastConnectionDate
6147
     * @param array  $sessionIdList
6148
     * @param array  $studentIdList
6149
     * @param int    $filterByStatus
6150
     *
6151
     * @return array|int
6152
     */
6153
    public static function getAllUsersFromCoursesFromAllSessionFromStatus(
6154
        $status,
6155
        $userId,
6156
        $getCount = false,
6157
        $from = null,
6158
        $numberItems = null,
6159
        $column = '',
6160
        $direction = 'asc',
6161
        $keyword = null,
6162
        $active = null,
6163
        $lastConnectionDate = null,
6164
        $sessionIdList = [],
6165
        $studentIdList = [],
6166
        $filterByStatus = null,
6167
        $filterUsers = null
6168
    ) {
6169
        $filterByStatus = (int) $filterByStatus;
6170
        $userId = (int) $userId;
6171
6172
        if (empty($column)) {
6173
            $column = 'u.lastname';
6174
            if (api_is_western_name_order()) {
6175
                $column = 'u.firstname';
6176
            }
6177
        }
6178
6179
        $tbl_user = Database::get_main_table(TABLE_MAIN_USER);
6180
        $tbl_session = Database::get_main_table(TABLE_MAIN_SESSION);
6181
        $tbl_course = Database::get_main_table(TABLE_MAIN_COURSE);
6182
        $tbl_course_user = Database::get_main_table(TABLE_MAIN_COURSE_USER);
6183
        $tbl_user_rel_access_url = Database::get_main_table(TABLE_MAIN_ACCESS_URL_REL_USER);
6184
        $tbl_course_rel_access_url = Database::get_main_table(TABLE_MAIN_ACCESS_URL_REL_COURSE);
6185
        $tbl_session_rel_course_rel_user = Database::get_main_table(TABLE_MAIN_SESSION_COURSE_USER);
6186
        $tbl_session_rel_access_url = Database::get_main_table(TABLE_MAIN_ACCESS_URL_REL_SESSION);
6187
6188
        $direction = in_array(strtolower($direction), ['asc', 'desc']) ? $direction : 'asc';
6189
        $column = Database::escape_string($column);
6190
6191
        $urlId = api_get_current_access_url_id();
6192
6193
        $sessionConditions = '';
6194
        $courseConditions = '';
6195
        $userConditions = '';
6196
6197
        if (isset($active)) {
6198
            $active = (int) $active;
6199
            $userConditions .= " AND active = $active";
6200
        }
6201
6202
        $courseList = CourseManager::get_courses_followed_by_drh($userId, DRH);
6203
        if (!empty($courseList)) {
6204
            $courseIdList = array_column($courseList, 'id');
6205
            $courseConditions = ' AND c.id IN ("'.implode('","', $courseIdList).'")';
6206
        }
6207
6208
        $userConditionsFromDrh = '';
6209
6210
        // Classic DRH
6211
        if (empty($studentIdList)) {
6212
            $studentListSql = UserManager::get_users_followed_by_drh(
6213
                $userId,
6214
                $filterByStatus,
6215
                true,
6216
                false
6217
            );
6218
            if (!empty($studentListSql)) {
6219
                $studentIdList = array_keys($studentListSql);
6220
                $studentListSql = "'".implode("','", $studentIdList)."'";
6221
            }
6222
        } else {
6223
            $studentIdList = array_map('intval', $studentIdList);
6224
            $studentListSql = "'".implode("','", $studentIdList)."'";
6225
        }
6226
        if (!empty($studentListSql)) {
6227
            $userConditionsFromDrh = " AND u.user_id IN ($studentListSql) ";
6228
        }
6229
6230
        switch ($status) {
6231
            case 'admin':
6232
            case 'drh':
6233
                break;
6234
            case 'drh_all':
6235
                // Show all by DRH
6236
                if (empty($sessionIdList)) {
6237
                    $sessionListFollowed = self::get_sessions_followed_by_drh(
6238
                        $userId,
6239
                        null,
6240
                        null,
6241
                        false,
6242
                        true
6243
                    );
6244
6245
                    if (!empty($sessionListFollowed)) {
6246
                        $sessionIdList = array_column($sessionListFollowed, 'id');
6247
                    }
6248
                }
6249
6250
                if (!empty($sessionIdList)) {
6251
                    $sessionIdList = array_map('intval', $sessionIdList);
6252
                    $sessionsListSql = "'".implode("','", $sessionIdList)."'";
6253
                    $sessionConditions = " AND s.id IN ($sessionsListSql) ";
6254
                }
6255
6256
                break;
6257
            case 'teacher':
6258
            case 'session_admin':
6259
                $sessionConditions = " AND s.id_coach = $userId ";
6260
                $userConditionsFromDrh = '';
6261
                break;
6262
        }
6263
6264
        $select = 'SELECT DISTINCT u.* ';
6265
        $masterSelect = 'SELECT DISTINCT user_id FROM ';
6266
6267
        if ($getCount) {
6268
            $select = 'SELECT DISTINCT u.user_id ';
6269
            $masterSelect = 'SELECT COUNT(DISTINCT(user_id)) as count FROM ';
6270
        }
6271
6272
        if (!empty($filterByStatus)) {
6273
            $userConditions .= " AND u.status = $filterByStatus";
6274
        }
6275
6276
        if (!empty($lastConnectionDate)) {
6277
            $lastConnectionDate = Database::escape_string($lastConnectionDate);
6278
            $userConditions .= " AND u.last_login <= '$lastConnectionDate' ";
6279
        }
6280
6281
        if (!empty($filterUsers)) {
6282
            $userConditions .= " AND u.id IN(".implode(',', $filterUsers).")";
6283
        }
6284
6285
        if (!empty($keyword)) {
6286
            $keyword = trim(Database::escape_string($keyword));
6287
            $keywordParts = array_filter(explode(' ', $keyword));
6288
            $extraKeyword = '';
6289
            if (!empty($keywordParts)) {
6290
                $keywordPartsFixed = Database::escape_string(implode('%', $keywordParts));
6291
                if (!empty($keywordPartsFixed)) {
6292
                    $extraKeyword .= " OR
6293
                        CONCAT(u.firstname, ' ', u.lastname) LIKE '%$keywordPartsFixed%' OR
6294
                        CONCAT(u.lastname, ' ', u.firstname) LIKE '%$keywordPartsFixed%' ";
6295
                }
6296
            }
6297
6298
            $userConditions .= " AND (
6299
                u.username LIKE '%$keyword%' OR
6300
                u.firstname LIKE '%$keyword%' OR
6301
                u.lastname LIKE '%$keyword%' OR
6302
                u.official_code LIKE '%$keyword%' OR
6303
                u.email LIKE '%$keyword%' OR
6304
                CONCAT(u.firstname, ' ', u.lastname) LIKE '%$keyword%' OR
6305
                CONCAT(u.lastname, ' ', u.firstname) LIKE '%$keyword%'
6306
                $extraKeyword
6307
            )";
6308
        }
6309
6310
        $where = " WHERE
6311
                   access_url_id = $urlId
6312
                   $userConditions
6313
        ";
6314
6315
        $userUnion = '';
6316
        if (!empty($userConditionsFromDrh)) {
6317
            $userUnion = "
6318
            UNION (
6319
                $select
6320
                FROM $tbl_user u
6321
                INNER JOIN $tbl_user_rel_access_url url ON (url.user_id = u.id)
6322
                $where
6323
                $userConditionsFromDrh
6324
            )";
6325
        }
6326
6327
        $sql = "$masterSelect (
6328
                ($select
6329
                    FROM $tbl_session s
6330
                    INNER JOIN $tbl_session_rel_access_url url ON (url.session_id = s.id)
6331
                    INNER JOIN $tbl_session_rel_course_rel_user su ON (s.id = su.session_id)
6332
                    INNER JOIN $tbl_user u ON (u.user_id = su.user_id)
6333
                    $where
6334
                    $sessionConditions
6335
                    $userConditionsFromDrh
6336
                ) UNION (
6337
                    $select
6338
                    FROM $tbl_course c
6339
                    INNER JOIN $tbl_course_rel_access_url url ON (url.c_id = c.id)
6340
                    INNER JOIN $tbl_course_user cu ON (cu.c_id = c.id)
6341
                    INNER JOIN $tbl_user u ON (u.user_id = cu.user_id)
6342
                    $where
6343
                    $courseConditions
6344
                    $userConditionsFromDrh
6345
                ) $userUnion
6346
                ) as t1
6347
                ";
6348
6349
        if ($getCount) {
6350
            $result = Database::query($sql);
6351
6352
            $count = 0;
6353
            if (Database::num_rows($result)) {
6354
                $rows = Database::fetch_array($result);
6355
                $count = $rows['count'];
6356
            }
6357
6358
            return $count;
6359
        }
6360
6361
        if (!empty($column) && !empty($direction)) {
6362
            $column = str_replace('u.', '', $column);
6363
            $sql .= " ORDER BY `$column` $direction ";
6364
        }
6365
6366
        $limitCondition = '';
6367
        if (isset($from) && isset($numberItems)) {
6368
            $from = (int) $from;
6369
            $numberItems = (int) $numberItems;
6370
            $limitCondition = "LIMIT $from, $numberItems";
6371
        }
6372
6373
        $sql .= $limitCondition;
6374
6375
        $result = Database::query($sql);
6376
6377
        return Database::store_result($result);
6378
    }
6379
6380
    /**
6381
     * @param int   $sessionId
6382
     * @param int   $courseId
6383
     * @param array $coachList
6384
     * @param bool  $deleteCoachesNotInList
6385
     */
6386
    public static function updateCoaches(
6387
        $sessionId,
6388
        $courseId,
6389
        $coachList,
6390
        $deleteCoachesNotInList = false
6391
    ) {
6392
        $currentCoaches = self::getCoachesByCourseSession($sessionId, $courseId);
6393
6394
        if (!empty($coachList)) {
6395
            foreach ($coachList as $userId) {
6396
                self::set_coach_to_course_session($userId, $sessionId, $courseId);
6397
            }
6398
        }
6399
6400
        if ($deleteCoachesNotInList) {
6401
            if (!empty($coachList)) {
6402
                $coachesToDelete = array_diff($currentCoaches, $coachList);
6403
            } else {
6404
                $coachesToDelete = $currentCoaches;
6405
            }
6406
6407
            if (!empty($coachesToDelete)) {
6408
                foreach ($coachesToDelete as $userId) {
6409
                    self::set_coach_to_course_session(
6410
                        $userId,
6411
                        $sessionId,
6412
                        $courseId,
6413
                        true
6414
                    );
6415
                }
6416
            }
6417
        }
6418
    }
6419
6420
    /**
6421
     * @param array $sessions
6422
     * @param array $sessionsDestination
6423
     *
6424
     * @return array
6425
     */
6426
    public static function copyStudentsFromSession($sessions, $sessionsDestination)
6427
    {
6428
        $messages = [];
6429
        if (!empty($sessions)) {
6430
            foreach ($sessions as $sessionId) {
6431
                $sessionInfo = self::fetch($sessionId);
6432
                $userList = self::get_users_by_session($sessionId, 0);
6433
                if (!empty($userList)) {
6434
                    $newUserList = [];
6435
                    $userToString = null;
6436
                    foreach ($userList as $userInfo) {
6437
                        $newUserList[] = $userInfo['user_id'];
6438
                        $userToString .= $userInfo['firstname'].' '.$userInfo['lastname'].'<br />';
6439
                    }
6440
6441
                    if (!empty($sessionsDestination)) {
6442
                        foreach ($sessionsDestination as $sessionDestinationId) {
6443
                            $sessionDestinationInfo = self::fetch($sessionDestinationId);
6444
                            $messages[] = Display::return_message(
6445
                                sprintf(
6446
                                    get_lang(
6447
                                        'AddingStudentsFromSessionXToSessionY'
6448
                                    ),
6449
                                    $sessionInfo['name'],
6450
                                    $sessionDestinationInfo['name']
6451
                                ),
6452
                                'info',
6453
                                false
6454
                            );
6455
                            if ($sessionId == $sessionDestinationId) {
6456
                                $messages[] = Display::return_message(
6457
                                    sprintf(
6458
                                        get_lang('SessionXSkipped'),
6459
                                        $sessionDestinationId
6460
                                    ),
6461
                                    'warning',
6462
                                    false
6463
                                );
6464
                                continue;
6465
                            }
6466
                            $messages[] = Display::return_message(get_lang('StudentList').'<br />'.$userToString, 'info', false);
6467
                            self::subscribeUsersToSession(
6468
                                $sessionDestinationId,
6469
                                $newUserList,
6470
                                SESSION_VISIBLE_READ_ONLY,
6471
                                false
6472
                            );
6473
                        }
6474
                    } else {
6475
                        $messages[] = Display::return_message(get_lang('NoDestinationSessionProvided'), 'warning');
6476
                    }
6477
                } else {
6478
                    $messages[] = Display::return_message(
6479
                        get_lang('NoStudentsFoundForSession').' #'.$sessionInfo['name'],
6480
                        'warning'
6481
                    );
6482
                }
6483
            }
6484
        } else {
6485
            $messages[] = Display::return_message(get_lang('NoData'), 'warning');
6486
        }
6487
6488
        return $messages;
6489
    }
6490
6491
    /**
6492
     * Assign coaches of a session(s) as teachers to a given course (or courses).
6493
     *
6494
     * @param array A list of session IDs
6495
     * @param array A list of course IDs
6496
     *
6497
     * @return string
6498
     */
6499
    public static function copyCoachesFromSessionToCourse($sessions, $courses)
6500
    {
6501
        $coachesPerSession = [];
6502
        foreach ($sessions as $sessionId) {
6503
            $coaches = self::getCoachesBySession($sessionId);
6504
            $coachesPerSession[$sessionId] = $coaches;
6505
        }
6506
6507
        $result = [];
6508
6509
        if (!empty($courses)) {
6510
            foreach ($courses as $courseId) {
6511
                $courseInfo = api_get_course_info_by_id($courseId);
6512
                foreach ($coachesPerSession as $sessionId => $coachList) {
6513
                    CourseManager::updateTeachers(
6514
                        $courseInfo,
6515
                        $coachList,
6516
                        false,
6517
                        false,
6518
                        false
6519
                    );
6520
                    $result[$courseInfo['code']][$sessionId] = $coachList;
6521
                }
6522
            }
6523
        }
6524
        $sessionUrl = api_get_path(WEB_CODE_PATH).'session/resume_session.php?id_session=';
6525
        $htmlResult = null;
6526
6527
        if (!empty($result)) {
6528
            foreach ($result as $courseCode => $data) {
6529
                $url = api_get_course_url($courseCode);
6530
                $htmlResult .= sprintf(
6531
                    get_lang('CoachesSubscribedAsATeacherInCourseX'),
6532
                    Display::url($courseCode, $url, ['target' => '_blank'])
6533
                );
6534
                foreach ($data as $sessionId => $coachList) {
6535
                    $sessionInfo = self::fetch($sessionId);
6536
                    $htmlResult .= '<br />';
6537
                    $htmlResult .= Display::url(
6538
                        get_lang('Session').': '.$sessionInfo['name'].' <br />',
6539
                        $sessionUrl.$sessionId,
6540
                        ['target' => '_blank']
6541
                    );
6542
                    $teacherList = [];
6543
                    foreach ($coachList as $coachId) {
6544
                        $userInfo = api_get_user_info($coachId);
6545
                        $teacherList[] = $userInfo['complete_name'];
6546
                    }
6547
                    if (!empty($teacherList)) {
6548
                        $htmlResult .= implode(', ', $teacherList);
6549
                    } else {
6550
                        $htmlResult .= get_lang('NothingToAdd');
6551
                    }
6552
                }
6553
                $htmlResult .= '<br />';
6554
            }
6555
            $htmlResult = Display::return_message($htmlResult, 'normal', false);
6556
        }
6557
6558
        return $htmlResult;
6559
    }
6560
6561
    /**
6562
     * @param string $keyword
6563
     * @param string $active
6564
     * @param string $lastConnectionDate
6565
     * @param array  $sessionIdList
6566
     * @param array  $studentIdList
6567
     * @param int    $filterUserStatus   STUDENT|COURSEMANAGER constants
6568
     *
6569
     * @return array|int
6570
     */
6571
    public static function getCountUserTracking(
6572
        $keyword = null,
6573
        $active = null,
6574
        $lastConnectionDate = null,
6575
        $sessionIdList = [],
6576
        $studentIdList = [],
6577
        $filterUserStatus = null
6578
    ) {
6579
        $userId = api_get_user_id();
6580
        $drhLoaded = false;
6581
        if (api_is_drh()) {
6582
            if (api_drh_can_access_all_session_content()) {
6583
                $count = self::getAllUsersFromCoursesFromAllSessionFromStatus(
6584
                    'drh_all',
6585
                    $userId,
6586
                    true,
6587
                    null,
6588
                    null,
6589
                    null,
6590
                    null,
6591
                    $keyword,
6592
                    $active,
6593
                    $lastConnectionDate,
6594
                    $sessionIdList,
6595
                    $studentIdList,
6596
                    $filterUserStatus
6597
                );
6598
                $drhLoaded = true;
6599
            }
6600
            $allowDhrAccessToAllStudents = api_get_configuration_value('drh_allow_access_to_all_students');
6601
            if ($allowDhrAccessToAllStudents) {
6602
                $conditions = ['status' => STUDENT];
6603
                if (isset($active)) {
6604
                    $conditions['active'] = (int) $active;
6605
                }
6606
                $students = UserManager::get_user_list(
6607
                    $conditions,
6608
                    [],
6609
                    false,
6610
                    false,
6611
                    null,
6612
                    $keyword,
6613
                    $lastConnectionDate
6614
                );
6615
                $count = count($students);
6616
                $drhLoaded = true;
6617
            }
6618
        }
6619
6620
        $checkSessionVisibility = api_get_configuration_value('show_users_in_active_sessions_in_tracking');
6621
6622
        if (false === $drhLoaded) {
6623
            $count = UserManager::getUsersFollowedByUser(
6624
                $userId,
6625
                $filterUserStatus,
6626
                false,
6627
                false,
6628
                true,
6629
                null,
6630
                null,
6631
                null,
6632
                null,
6633
                $active,
6634
                $lastConnectionDate,
6635
                api_is_student_boss() ? STUDENT_BOSS : COURSEMANAGER,
6636
                $keyword,
6637
                $checkSessionVisibility
6638
            );
6639
        }
6640
6641
        return $count;
6642
    }
6643
6644
    /**
6645
     * Get teachers followed by a user.
6646
     *
6647
     * @param int    $userId
6648
     * @param int    $active
6649
     * @param string $lastConnectionDate
6650
     * @param bool   $getCount
6651
     * @param array  $sessionIdList
6652
     *
6653
     * @return array|int
6654
     */
6655
    public static function getTeacherTracking(
6656
        $userId,
6657
        $active = 1,
6658
        $lastConnectionDate = null,
6659
        $getCount = false,
6660
        $sessionIdList = []
6661
    ) {
6662
        $teacherListId = [];
6663
        if (api_is_drh() || api_is_platform_admin()) {
6664
            // Followed teachers by drh
6665
            if (api_drh_can_access_all_session_content()) {
6666
                if (empty($sessionIdList)) {
6667
                    $sessions = self::get_sessions_followed_by_drh($userId);
6668
                    $sessionIdList = [];
6669
                    foreach ($sessions as $session) {
6670
                        $sessionIdList[] = $session['id'];
6671
                    }
6672
                }
6673
6674
                $sessionIdList = array_map('intval', $sessionIdList);
6675
                $sessionToString = implode("', '", $sessionIdList);
6676
6677
                $course = Database::get_main_table(TABLE_MAIN_COURSE);
6678
                $sessionCourse = Database::get_main_table(TABLE_MAIN_SESSION_COURSE);
6679
                $courseUser = Database::get_main_table(TABLE_MAIN_COURSE_USER);
6680
6681
                // Select the teachers.
6682
                $sql = "SELECT DISTINCT(cu.user_id)
6683
                        FROM $course c
6684
                        INNER JOIN $sessionCourse src
6685
                        ON c.id = src.c_id
6686
                        INNER JOIN $courseUser cu
6687
                        ON (cu.c_id = c.id)
6688
		                WHERE src.session_id IN ('$sessionToString') AND cu.status = 1";
6689
                $result = Database::query($sql);
6690
                while ($row = Database::fetch_array($result, 'ASSOC')) {
6691
                    $teacherListId[$row['user_id']] = $row['user_id'];
6692
                }
6693
            } else {
6694
                $teacherResult = UserManager::get_users_followed_by_drh($userId, COURSEMANAGER);
6695
                foreach ($teacherResult as $userInfo) {
6696
                    $teacherListId[] = $userInfo['user_id'];
6697
                }
6698
            }
6699
        }
6700
6701
        if (!empty($teacherListId)) {
6702
            $tableUser = Database::get_main_table(TABLE_MAIN_USER);
6703
6704
            $select = "SELECT DISTINCT u.* ";
6705
            if ($getCount) {
6706
                $select = "SELECT count(DISTINCT(u.user_id)) as count";
6707
            }
6708
6709
            $sql = "$select FROM $tableUser u";
6710
6711
            if (!empty($lastConnectionDate)) {
6712
                $tableLogin = Database::get_main_table(TABLE_STATISTIC_TRACK_E_LOGIN);
6713
                //$sql .= " INNER JOIN $tableLogin l ON (l.login_user_id = u.user_id) ";
6714
            }
6715
            $active = intval($active);
6716
            $teacherListId = implode("','", $teacherListId);
6717
            $where = " WHERE u.active = $active AND u.user_id IN ('$teacherListId') ";
6718
6719
            if (!empty($lastConnectionDate)) {
6720
                $lastConnectionDate = Database::escape_string($lastConnectionDate);
6721
                //$where .= " AND l.login_date <= '$lastConnectionDate' ";
6722
            }
6723
6724
            $sql .= $where;
6725
            $result = Database::query($sql);
6726
            if (Database::num_rows($result)) {
6727
                if ($getCount) {
6728
                    $row = Database::fetch_array($result);
6729
6730
                    return $row['count'];
6731
                } else {
6732
                    return Database::store_result($result, 'ASSOC');
6733
                }
6734
            }
6735
        }
6736
6737
        return 0;
6738
    }
6739
6740
    /**
6741
     * Get the list of course tools that have to be dealt with in case of
6742
     * registering any course to a session.
6743
     *
6744
     * @return array The list of tools to be dealt with (literal names)
6745
     */
6746
    public static function getCourseToolToBeManaged()
6747
    {
6748
        return [
6749
            'courseDescription',
6750
            'courseIntroduction',
6751
        ];
6752
    }
6753
6754
    /**
6755
     * Calls the methods bound to each tool when a course is registered into a session.
6756
     *
6757
     * @param int $sessionId
6758
     * @param int $courseId
6759
     *
6760
     * @return bool
6761
     *
6762
     * @deprecated
6763
     */
6764
    public static function installCourse($sessionId, $courseId)
6765
    {
6766
        return true;
6767
        $toolList = self::getCourseToolToBeManaged();
0 ignored issues
show
Unused Code introduced by
$toolList = self::getCourseToolToBeManaged() is not reachable.

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

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

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

    return false;
}

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

Loading history...
6768
6769
        foreach ($toolList as $tool) {
6770
            $method = 'add'.$tool;
6771
            if (method_exists(get_class(), $method)) {
6772
                self::$method($sessionId, $courseId);
6773
            }
6774
        }
6775
    }
6776
6777
    /**
6778
     * Calls the methods bound to each tool when a course is unregistered from
6779
     * a session.
6780
     *
6781
     * @param int $sessionId
6782
     * @param int $courseId
6783
     */
6784
    public static function unInstallCourse($sessionId, $courseId)
6785
    {
6786
        return true;
6787
        $toolList = self::getCourseToolToBeManaged();
0 ignored issues
show
Unused Code introduced by
$toolList = self::getCourseToolToBeManaged() is not reachable.

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

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

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

    return false;
}

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

Loading history...
6788
6789
        foreach ($toolList as $tool) {
6790
            $method = 'remove'.$tool;
6791
            if (method_exists(get_class(), $method)) {
6792
                self::$method($sessionId, $courseId);
6793
            }
6794
        }
6795
    }
6796
6797
    /**
6798
     * @param array $userSessionList        format see self::importSessionDrhCSV()
6799
     * @param bool  $sendEmail
6800
     * @param bool  $removeOldRelationShips
6801
     */
6802
    public static function subscribeDrhToSessionList(
6803
        $userSessionList,
6804
        $sendEmail,
6805
        $removeOldRelationShips
6806
    ) {
6807
        if (!empty($userSessionList)) {
6808
            foreach ($userSessionList as $userId => $data) {
6809
                $sessionList = [];
6810
                foreach ($data['session_list'] as $sessionInfo) {
6811
                    $sessionList[] = $sessionInfo['session_id'];
6812
                }
6813
                $userInfo = $data['user_info'];
6814
                self::subscribeSessionsToDrh(
6815
                    $userInfo,
6816
                    $sessionList,
6817
                    $sendEmail,
6818
                    $removeOldRelationShips
6819
                );
6820
            }
6821
        }
6822
    }
6823
6824
    /**
6825
     * @param array $userSessionList format see self::importSessionDrhCSV()
6826
     *
6827
     * @return string
6828
     */
6829
    public static function checkSubscribeDrhToSessionList($userSessionList)
6830
    {
6831
        $message = null;
6832
        if (!empty($userSessionList)) {
6833
            if (!empty($userSessionList)) {
6834
                foreach ($userSessionList as $userId => $data) {
6835
                    $userInfo = $data['user_info'];
6836
6837
                    $sessionListSubscribed = self::get_sessions_followed_by_drh($userId);
6838
                    if (!empty($sessionListSubscribed)) {
6839
                        $sessionListSubscribed = array_keys($sessionListSubscribed);
6840
                    }
6841
6842
                    $sessionList = [];
6843
                    if (!empty($data['session_list'])) {
6844
                        foreach ($data['session_list'] as $sessionInfo) {
6845
                            if (in_array($sessionInfo['session_id'], $sessionListSubscribed)) {
6846
                                $sessionList[] = $sessionInfo['session_info']['name'];
6847
                            }
6848
                        }
6849
                    }
6850
6851
                    $message .= '<strong>'.get_lang('User').'</strong>: ';
6852
                    $message .= $userInfo['complete_name_with_username'].' <br />';
6853
6854
                    if (!in_array($userInfo['status'], [DRH]) && !api_is_platform_admin_by_id($userInfo['user_id'])) {
6855
                        $message .= get_lang('UserMustHaveTheDrhRole').'<br />';
6856
                        continue;
6857
                    }
6858
6859
                    if (!empty($sessionList)) {
6860
                        $message .= '<strong>'.get_lang('Sessions').':</strong> <br />';
6861
                        $message .= implode(', ', $sessionList).'<br /><br />';
6862
                    } else {
6863
                        $message .= get_lang('NoSessionProvided').' <br /><br />';
6864
                    }
6865
                }
6866
            }
6867
        }
6868
6869
        return $message;
6870
    }
6871
6872
    /**
6873
     * @param string $file
6874
     * @param bool   $sendEmail
6875
     * @param bool   $removeOldRelationShips
6876
     *
6877
     * @return string
6878
     */
6879
    public static function importSessionDrhCSV($file, $sendEmail, $removeOldRelationShips)
6880
    {
6881
        $list = Import::csv_reader($file);
6882
6883
        if (!empty($list)) {
6884
            $userSessionList = [];
6885
            foreach ($list as $data) {
6886
                $sessionInfo = [];
6887
                if (isset($data['SessionId'])) {
6888
                    $sessionInfo = api_get_session_info($data['SessionId']);
6889
                }
6890
6891
                if (isset($data['SessionName']) && empty($sessionInfo)) {
6892
                    $sessionInfo = self::get_session_by_name($data['SessionName']);
6893
                }
6894
6895
                if (empty($sessionInfo)) {
6896
                    $sessionData = isset($data['SessionName']) ? $data['SessionName'] : $data['SessionId'];
6897
                    Display::addFlash(
6898
                        Display::return_message(get_lang('SessionNotFound').' - '.$sessionData, 'warning')
6899
                    );
6900
                    continue;
6901
                }
6902
6903
                $userList = explode(',', $data['Username']);
6904
6905
                foreach ($userList as $username) {
6906
                    $userInfo = api_get_user_info_from_username($username);
6907
6908
                    if (empty($userInfo)) {
6909
                        Display::addFlash(
6910
                            Display::return_message(get_lang('UserDoesNotExist').' - '.$username, 'warning')
6911
                        );
6912
                        continue;
6913
                    }
6914
6915
                    if (!empty($userInfo) && !empty($sessionInfo)) {
6916
                        $userSessionList[$userInfo['user_id']]['session_list'][] = [
6917
                            'session_id' => $sessionInfo['id'],
6918
                            'session_info' => $sessionInfo,
6919
                        ];
6920
                        $userSessionList[$userInfo['user_id']]['user_info'] = $userInfo;
6921
                    }
6922
                }
6923
            }
6924
6925
            self::subscribeDrhToSessionList($userSessionList, $sendEmail, $removeOldRelationShips);
6926
6927
            return self::checkSubscribeDrhToSessionList($userSessionList);
6928
        }
6929
    }
6930
6931
    /**
6932
     * Courses re-ordering in resume_session.php flag see BT#8316.
6933
     */
6934
    public static function orderCourseIsEnabled()
6935
    {
6936
        $sessionCourseOrder = api_get_setting('session_course_ordering');
6937
        if ($sessionCourseOrder === 'true') {
6938
            return true;
6939
        }
6940
6941
        return false;
6942
    }
6943
6944
    /**
6945
     * @param string $direction (up/down)
6946
     * @param int    $sessionId
6947
     * @param int    $courseId
6948
     *
6949
     * @return bool
6950
     */
6951
    public static function move($direction, $sessionId, $courseId)
6952
    {
6953
        if (!self::orderCourseIsEnabled()) {
6954
            return false;
6955
        }
6956
6957
        $sessionId = intval($sessionId);
6958
        $courseId = intval($courseId);
6959
6960
        $table = Database::get_main_table(TABLE_MAIN_SESSION_COURSE);
6961
        $courseList = self::get_course_list_by_session_id($sessionId, null, 'position');
6962
6963
        $position = [];
6964
        $count = 0;
6965
        foreach ($courseList as $course) {
6966
            if ($course['position'] == '') {
6967
                $course['position'] = $count;
6968
            }
6969
            $position[$course['code']] = $course['position'];
6970
            // Saving current order.
6971
            $sql = "UPDATE $table SET position = $count
6972
                    WHERE session_id = $sessionId AND c_id = '".$course['real_id']."'";
6973
            Database::query($sql);
6974
            $count++;
6975
        }
6976
6977
        // Loading new positions.
6978
        $courseList = self::get_course_list_by_session_id($sessionId, null, 'position');
6979
6980
        $found = false;
6981
6982
        switch ($direction) {
6983
            case 'up':
6984
                $courseList = array_reverse($courseList);
6985
                break;
6986
            case 'down':
6987
                break;
6988
        }
6989
6990
        foreach ($courseList as $course) {
6991
            if ($found) {
6992
                $nextId = $course['real_id'];
6993
                $nextOrder = $course['position'];
6994
                break;
6995
            }
6996
6997
            if ($courseId == $course['real_id']) {
6998
                $thisCourseCode = $course['real_id'];
6999
                $thisOrder = $course['position'];
7000
                $found = true;
7001
            }
7002
        }
7003
7004
        $sql1 = "UPDATE $table SET position = '".intval($nextOrder)."'
7005
                 WHERE session_id = $sessionId AND c_id =  $thisCourseCode";
7006
        Database::query($sql1);
7007
7008
        $sql2 = "UPDATE $table SET position = '".intval($thisOrder)."'
7009
                 WHERE session_id = $sessionId AND c_id = $nextId";
7010
        Database::query($sql2);
7011
7012
        return true;
7013
    }
7014
7015
    /**
7016
     * @param int $sessionId
7017
     * @param int $courseId
7018
     *
7019
     * @return bool
7020
     */
7021
    public static function moveUp($sessionId, $courseId)
7022
    {
7023
        return self::move('up', $sessionId, $courseId);
7024
    }
7025
7026
    /**
7027
     * @param int    $sessionId
7028
     * @param string $courseCode
7029
     *
7030
     * @return bool
7031
     */
7032
    public static function moveDown($sessionId, $courseCode)
7033
    {
7034
        return self::move('down', $sessionId, $courseCode);
7035
    }
7036
7037
    /**
7038
     * Use the session duration to allow/block user access see BT#8317
7039
     * Needs these DB changes
7040
     * ALTER TABLE session ADD COLUMN duration int;
7041
     * ALTER TABLE session_rel_user ADD COLUMN duration int;.
7042
     */
7043
    public static function durationPerUserIsEnabled()
7044
    {
7045
        return api_get_configuration_value('session_duration_feature');
7046
    }
7047
7048
    /**
7049
     * Returns the number of days the student has left in a session when using
7050
     * sessions durations.
7051
     *
7052
     * @param int $userId
7053
     *
7054
     * @return int
7055
     */
7056
    public static function getDayLeftInSession(array $sessionInfo, $userId)
7057
    {
7058
        $sessionId = $sessionInfo['id'];
7059
        $subscription = self::getUserSession($userId, $sessionId);
7060
        $duration = empty($subscription['duration'])
7061
            ? $sessionInfo['duration']
7062
            : $sessionInfo['duration'] + $subscription['duration'];
7063
7064
        // Get an array with the details of the first access of the student to
7065
        // this session
7066
        $courseAccess = CourseManager::getFirstCourseAccessPerSessionAndUser(
7067
            $sessionId,
7068
            $userId
7069
        );
7070
7071
        $currentTime = time();
7072
7073
        // If no previous access, return false
7074
        if (count($courseAccess) == 0) {
7075
            return $duration;
7076
        }
7077
7078
        $firstAccess = api_strtotime($courseAccess['login_course_date'], 'UTC');
7079
        $endDateInSeconds = $firstAccess + $duration * 24 * 60 * 60;
7080
        $leftDays = round(($endDateInSeconds - $currentTime) / 60 / 60 / 24);
7081
7082
        return $leftDays;
7083
    }
7084
7085
    /**
7086
     * @param int $duration
7087
     * @param int $userId
7088
     * @param int $sessionId
7089
     *
7090
     * @return bool
7091
     */
7092
    public static function editUserSessionDuration($duration, $userId, $sessionId)
7093
    {
7094
        $duration = (int) $duration;
7095
        $userId = (int) $userId;
7096
        $sessionId = (int) $sessionId;
7097
7098
        if (empty($userId) || empty($sessionId)) {
7099
            return false;
7100
        }
7101
7102
        $table = Database::get_main_table(TABLE_MAIN_SESSION_USER);
7103
        $parameters = ['duration' => $duration];
7104
        $where = ['session_id = ? AND user_id = ? ' => [$sessionId, $userId]];
7105
        Database::update($table, $parameters, $where);
7106
7107
        return true;
7108
    }
7109
7110
    /**
7111
     * Gets one row from the session_rel_user table.
7112
     *
7113
     * @param int $userId
7114
     * @param int $sessionId
7115
     *
7116
     * @return array
7117
     */
7118
    public static function getUserSession($userId, $sessionId)
7119
    {
7120
        $userId = (int) $userId;
7121
        $sessionId = (int) $sessionId;
7122
7123
        if (empty($userId) || empty($sessionId)) {
7124
            return false;
7125
        }
7126
7127
        $table = Database::get_main_table(TABLE_MAIN_SESSION_USER);
7128
        $sql = "SELECT * FROM $table
7129
                WHERE session_id = $sessionId AND user_id = $userId";
7130
        $result = Database::query($sql);
7131
        $values = [];
7132
        if (Database::num_rows($result)) {
7133
            $values = Database::fetch_array($result, 'ASSOC');
7134
        }
7135
7136
        return $values;
7137
    }
7138
7139
    /**
7140
     * Check if user is subscribed inside a session as student.
7141
     *
7142
     * @param int $sessionId The session id
7143
     * @param int $userId    The user id
7144
     *
7145
     * @return bool Whether is subscribed
7146
     */
7147
    public static function isUserSubscribedAsStudent($sessionId, $userId)
7148
    {
7149
        $sessionRelUserTable = Database::get_main_table(TABLE_MAIN_SESSION_USER);
7150
        $sessionId = (int) $sessionId;
7151
        $userId = (int) $userId;
7152
7153
        // COUNT(1) actually returns the number of rows from the table (as if
7154
        // counting the results from the first column)
7155
        $sql = "SELECT COUNT(1) AS qty FROM $sessionRelUserTable
7156
                WHERE
7157
                    session_id = $sessionId AND
7158
                    user_id = $userId AND
7159
                    relation_type = 0";
7160
7161
        $result = Database::fetch_assoc(Database::query($sql));
7162
7163
        if (!empty($result) && $result['qty'] > 0) {
7164
            return true;
7165
        }
7166
7167
        return false;
7168
    }
7169
7170
    /**
7171
     * Check if user is subscribed inside a session as a HRM.
7172
     *
7173
     * @param int $sessionId The session id
7174
     * @param int $userId    The user id
7175
     *
7176
     * @return bool Whether is subscribed
7177
     */
7178
    public static function isUserSubscribedAsHRM($sessionId, $userId)
7179
    {
7180
        $sessionRelUserTable = Database::get_main_table(TABLE_MAIN_SESSION_USER);
7181
7182
        $sessionId = (int) $sessionId;
7183
        $userId = (int) $userId;
7184
7185
        // COUNT(1) actually returns the number of rows from the table (as if
7186
        // counting the results from the first column)
7187
        $sql = "SELECT COUNT(1) AS qty FROM $sessionRelUserTable
7188
                WHERE
7189
                    session_id = $sessionId AND
7190
                    user_id = $userId AND
7191
                    relation_type = ".SESSION_RELATION_TYPE_RRHH;
7192
7193
        $result = Database::fetch_assoc(Database::query($sql));
7194
7195
        if (!empty($result) && $result['qty'] > 0) {
7196
            return true;
7197
        }
7198
7199
        return false;
7200
    }
7201
7202
    /**
7203
     * Get the session coached by a user (general coach and course-session coach).
7204
     *
7205
     * @param int  $coachId                       The coach id
7206
     * @param bool $checkSessionRelUserVisibility Check the session visibility
7207
     * @param bool $asPlatformAdmin               The user is a platform admin and we want all sessions
7208
     *
7209
     * @return array The session list
7210
     */
7211
    public static function getSessionsCoachedByUser(
7212
        $coachId,
7213
        $checkSessionRelUserVisibility = false,
7214
        $asPlatformAdmin = false
7215
    ) {
7216
        // Get all sessions where $coachId is the general coach
7217
        $sessions = self::get_sessions_by_general_coach($coachId, $asPlatformAdmin);
7218
        // Get all sessions where $coachId is the course - session coach
7219
        $courseSessionList = self::getCoursesListByCourseCoach($coachId);
7220
        $sessionsByCoach = [];
7221
        if (!empty($courseSessionList)) {
7222
            foreach ($courseSessionList as $userCourseSubscription) {
7223
                $session = $userCourseSubscription->getSession();
7224
                $sessionsByCoach[$session->getId()] = api_get_session_info(
7225
                    $session->getId()
7226
                );
7227
            }
7228
        }
7229
7230
        if (!empty($sessionsByCoach)) {
7231
            $sessions = array_merge($sessions, $sessionsByCoach);
7232
        }
7233
7234
        // Remove repeated sessions
7235
        if (!empty($sessions)) {
7236
            $cleanSessions = [];
7237
            foreach ($sessions as $session) {
7238
                $cleanSessions[$session['id']] = $session;
7239
            }
7240
            $sessions = $cleanSessions;
7241
        }
7242
7243
        if ($checkSessionRelUserVisibility) {
7244
            if (!empty($sessions)) {
7245
                $newSessions = [];
7246
                foreach ($sessions as $session) {
7247
                    $visibility = api_get_session_visibility($session['id']);
7248
                    if ($visibility == SESSION_INVISIBLE) {
7249
                        continue;
7250
                    }
7251
                    $newSessions[] = $session;
7252
                }
7253
                $sessions = $newSessions;
7254
            }
7255
        }
7256
7257
        return $sessions;
7258
    }
7259
7260
    /**
7261
     * Check if the course belongs to the session.
7262
     *
7263
     * @param int    $sessionId  The session id
7264
     * @param string $courseCode The course code
7265
     *
7266
     * @return bool
7267
     */
7268
    public static function sessionHasCourse($sessionId, $courseCode)
7269
    {
7270
        $sessionId = (int) $sessionId;
7271
        $courseCode = Database::escape_string($courseCode);
7272
        $courseTable = Database::get_main_table(TABLE_MAIN_COURSE);
7273
        $sessionRelCourseTable = Database::get_main_table(TABLE_MAIN_SESSION_COURSE);
7274
7275
        $sql = "SELECT COUNT(1) AS qty
7276
                FROM $courseTable c
7277
                INNER JOIN $sessionRelCourseTable src
7278
                ON c.id = src.c_id
7279
                WHERE src.session_id = $sessionId
7280
                AND c.code = '$courseCode'  ";
7281
7282
        $result = Database::query($sql);
7283
7284
        if (false !== $result) {
7285
            $data = Database::fetch_assoc($result);
7286
7287
            if ($data['qty'] > 0) {
7288
                return true;
7289
            }
7290
        }
7291
7292
        return false;
7293
    }
7294
7295
    /**
7296
     * Calculate the total user time in the platform.
7297
     *
7298
     * @param int    $userId The user id
7299
     * @param string $from   Optional. From date
7300
     * @param string $until  Optional. Until date
7301
     *
7302
     * @return string The time (hh:mm:ss)
7303
     */
7304
    public static function getTotalUserTimeInPlatform($userId, $from = '', $until = '')
7305
    {
7306
        $userId = (int) $userId;
7307
        $trackLoginTable = Database::get_main_table(TABLE_STATISTIC_TRACK_E_LOGIN);
7308
        $whereConditions = [
7309
            'login_user_id = ? ' => $userId,
7310
        ];
7311
7312
        if (!empty($from) && !empty($until)) {
7313
            $whereConditions["AND (login_date >= '?' "] = $from;
7314
            $whereConditions["AND logout_date <= DATE_ADD('?', INTERVAL 1 DAY)) "] = $until;
7315
        }
7316
7317
        $trackResult = Database::select(
7318
            'SEC_TO_TIME(SUM(UNIX_TIMESTAMP(logout_date) - UNIX_TIMESTAMP(login_date))) as total_time',
7319
            $trackLoginTable,
7320
            [
7321
                'where' => $whereConditions,
7322
            ],
7323
            'first'
7324
        );
7325
7326
        if (false != $trackResult) {
7327
            return $trackResult['total_time'] ? $trackResult['total_time'] : '00:00:00';
7328
        }
7329
7330
        return '00:00:00';
7331
    }
7332
7333
    /**
7334
     * Get the courses list by a course coach.
7335
     *
7336
     * @param int $coachId The coach id
7337
     *
7338
     * @return array (id, user_id, session_id, c_id, visibility, status, legal_agreement)
7339
     */
7340
    public static function getCoursesListByCourseCoach($coachId)
7341
    {
7342
        $entityManager = Database::getManager();
7343
        $scuRepo = $entityManager->getRepository(
7344
            'ChamiloCoreBundle:SessionRelCourseRelUser'
7345
        );
7346
7347
        return $scuRepo->findBy([
7348
            'user' => $coachId,
7349
            'status' => SessionRelCourseRelUser::STATUS_COURSE_COACH,
7350
        ]);
7351
    }
7352
7353
    /**
7354
     * Get the count of user courses in session.
7355
     *
7356
     * @param int $sessionId
7357
     * @param int $courseId
7358
     *
7359
     * @return array
7360
     */
7361
    public static function getTotalUserCoursesInSession($sessionId, $courseId = 0)
7362
    {
7363
        $tableUser = Database::get_main_table(TABLE_MAIN_USER);
7364
        $table = Database::get_main_table(TABLE_MAIN_SESSION_COURSE_USER);
7365
7366
        $sessionId = (int) $sessionId;
7367
7368
        if (empty($sessionId)) {
7369
            return [];
7370
        }
7371
7372
        $courseCondition = '';
7373
        if (!empty($courseId)) {
7374
            $courseId = (int) $courseId;
7375
            $courseCondition = "  c_id = $courseId AND ";
7376
        }
7377
7378
        $sql = "SELECT
7379
                    COUNT(u.id) as count,
7380
                    u.id,
7381
                    scu.status status_in_session,
7382
                    u.status user_status
7383
                FROM $table scu
7384
                INNER JOIN $tableUser u
7385
                ON scu.user_id = u.id
7386
                WHERE
7387
                  $courseCondition
7388
                  scu.session_id = ".$sessionId."
7389
                GROUP BY u.id";
7390
7391
        $result = Database::query($sql);
7392
7393
        $list = [];
7394
        while ($data = Database::fetch_assoc($result)) {
7395
            $list[] = $data;
7396
        }
7397
7398
        return $list;
7399
    }
7400
7401
    /**
7402
     * Returns list of a few data from session (name, short description, start
7403
     * date, end date) and the given extra fields if defined based on a
7404
     * session category Id.
7405
     *
7406
     * @param int    $categoryId  The internal ID of the session category
7407
     * @param string $target      Value to search for in the session field values
7408
     * @param array  $extraFields A list of fields to be scanned and returned
7409
     *
7410
     * @return mixed
7411
     */
7412
    public static function getShortSessionListAndExtraByCategory(
7413
        $categoryId,
7414
        $target,
7415
        $extraFields = null,
7416
        $publicationDate = null
7417
    ) {
7418
        $categoryId = (int) $categoryId;
7419
        $sessionList = [];
7420
        // Check if categoryId is valid
7421
        if ($categoryId > 0) {
7422
            $target = Database::escape_string($target);
7423
            $sTable = Database::get_main_table(TABLE_MAIN_SESSION);
7424
            $sfTable = Database::get_main_table(TABLE_EXTRA_FIELD);
7425
            $sfvTable = Database::get_main_table(TABLE_EXTRA_FIELD_VALUES);
7426
            // Join session field and session field values tables
7427
            $joinTable = $sfTable.' sf INNER JOIN '.$sfvTable.' sfv ON sf.id = sfv.field_id';
7428
            $fieldsArray = [];
7429
            foreach ($extraFields as $field) {
7430
                $fieldsArray[] = Database::escape_string($field);
7431
            }
7432
            $extraFieldType = ExtraField::SESSION_FIELD_TYPE;
7433
            if (isset($publicationDate)) {
7434
                $publicationDateString = $publicationDate->format('Y-m-d H:i:s');
7435
                $wherePublication = " AND id NOT IN (
7436
                    SELECT sfv.item_id FROM $joinTable
7437
                    WHERE
7438
                        sf.extra_field_type = $extraFieldType AND
7439
                        ((sf.variable = 'publication_start_date' AND sfv.value > '$publicationDateString' and sfv.value != '') OR
7440
                        (sf.variable = 'publication_end_date' AND sfv.value < '$publicationDateString' and sfv.value != ''))
7441
                )";
7442
            }
7443
            // Get the session list from session category and target
7444
            $sessionList = Database::select(
7445
                'id, name, access_start_date, access_end_date',
7446
                $sTable,
7447
                [
7448
                    'where' => [
7449
                        "session_category_id = ? AND id IN (
7450
                            SELECT sfv.item_id FROM $joinTable
7451
                            WHERE
7452
                                sf.extra_field_type = $extraFieldType AND
7453
                                sfv.item_id = session.id AND
7454
                                sf.variable = 'target' AND
7455
                                sfv.value = ?
7456
                        ) $wherePublication" => [$categoryId, $target],
7457
                    ],
7458
                ]
7459
            );
7460
            $whereFieldVariables = [];
7461
            $whereFieldIds = [];
7462
            if (
7463
                is_array($fieldsArray) &&
7464
                count($fieldsArray) > 0
7465
            ) {
7466
                $whereParams = '?';
7467
                for ($i = 1; $i < count($fieldsArray); $i++) {
0 ignored issues
show
Performance Best Practice introduced by
It seems like you are calling the size function count() as part of the test condition. You might want to compute the size beforehand, and not on each iteration.

If the size of the collection does not change during the iteration, it is generally a good practice to compute it beforehand, and not on each iteration:

for ($i=0; $i<count($array); $i++) { // calls count() on each iteration
}

// Better
for ($i=0, $c=count($array); $i<$c; $i++) { // calls count() just once
}
Loading history...
7468
                    $whereParams .= ', ?';
7469
                }
7470
                $whereFieldVariables = ' variable IN ( '.$whereParams.' )';
7471
                $whereFieldIds = 'field_id IN ( '.$whereParams.' )';
7472
            }
7473
            // Get session fields
7474
            $extraField = new ExtraFieldModel('session');
7475
            $questionMarks = substr(str_repeat('?, ', count($fieldsArray)), 0, -2);
7476
            $fieldsList = $extraField->get_all([
7477
                ' variable IN ( '.$questionMarks.' )' => $fieldsArray,
7478
            ]);
7479
            // Index session fields
7480
            foreach ($fieldsList as $field) {
7481
                $fields[$field['id']] = $field['variable'];
7482
            }
7483
            // Get session field values
7484
            $extra = new ExtraFieldValue('session');
7485
            $questionMarksFields = substr(str_repeat('?, ', count($fields)), 0, -2);
7486
            $sessionFieldValueList = $extra->get_all(['where' => ['field_id IN ( '.$questionMarksFields.' )' => array_keys($fields)]]);
7487
            // Add session fields values to session list
7488
            foreach ($sessionList as $id => &$session) {
7489
                foreach ($sessionFieldValueList as $sessionFieldValue) {
7490
                    // Match session field values to session
7491
                    if ($sessionFieldValue['item_id'] == $id) {
7492
                        // Check if session field value is set in session field list
7493
                        if (isset($fields[$sessionFieldValue['field_id']])) {
7494
                            // Avoid overwriting the session's ID field
7495
                            if ($fields[$sessionFieldValue['field_id']] != 'id') {
7496
                                $var = $fields[$sessionFieldValue['field_id']];
7497
                                $val = $sessionFieldValue['value'];
7498
                                // Assign session field value to session
7499
                                $session[$var] = $val;
7500
                            }
7501
                        }
7502
                    }
7503
                }
7504
            }
7505
        }
7506
7507
        return $sessionList;
7508
    }
7509
7510
    /**
7511
     * Return the Session Category id searched by name.
7512
     *
7513
     * @param string $categoryName Name attribute of session category used for search query
7514
     * @param bool   $force        boolean used to get even if something is wrong (e.g not unique name)
7515
     *
7516
     * @return int|array If success, return category id (int), else it will return an array
7517
     *                   with the next structure:
7518
     *                   array('error' => true, 'errorMessage' => ERROR_MESSAGE)
7519
     */
7520
    public static function getSessionCategoryIdByName($categoryName, $force = false)
7521
    {
7522
        // Start error result
7523
        $errorResult = ['error' => true, 'errorMessage' => get_lang('ThereWasAnError')];
7524
        $categoryName = Database::escape_string($categoryName);
7525
        // Check if is not empty category name
7526
        if (!empty($categoryName)) {
7527
            $sessionCategoryTable = Database::get_main_table(TABLE_MAIN_SESSION_CATEGORY);
7528
            // Get all session category with same name
7529
            $result = Database::select(
7530
                'id',
7531
                $sessionCategoryTable,
7532
                [
7533
                    'where' => [
7534
                        'name = ?' => $categoryName,
7535
                    ],
7536
                ]
7537
            );
7538
            // Check the result
7539
            if ($result < 1) {
7540
                // If not found any result, update error message
7541
                $errorResult['errorMessage'] = 'Not found any session category name '.$categoryName;
7542
            } elseif (count($result) > 1 && !$force) {
7543
                // If found more than one result and force is disabled, update error message
7544
                $errorResult['errorMessage'] = 'Found many session categories';
7545
            } elseif (count($result) == 1 || $force) {
7546
                // If found just one session category or force option is enabled
7547
7548
                return key($result);
7549
            }
7550
        } else {
7551
            // category name is empty, update error message
7552
            $errorResult['errorMessage'] = 'Not valid category name';
7553
        }
7554
7555
        return $errorResult;
7556
    }
7557
7558
    /**
7559
     * Return all data from sessions (plus extra field, course and coach data) by category id.
7560
     *
7561
     * @param int $sessionCategoryId session category id used to search sessions
7562
     *
7563
     * @return array If success, return session list and more session related data, else it will return an array
7564
     *               with the next structure:
7565
     *               array('error' => true, 'errorMessage' => ERROR_MESSAGE)
7566
     */
7567
    public static function getSessionListAndExtraByCategoryId($sessionCategoryId)
7568
    {
7569
        // Start error result
7570
        $errorResult = [
7571
            'error' => true,
7572
            'errorMessage' => get_lang('ThereWasAnError'),
7573
        ];
7574
7575
        $sessionCategoryId = intval($sessionCategoryId);
7576
        // Check if session category id is valid
7577
        if ($sessionCategoryId > 0) {
7578
            // Get table names
7579
            $sessionTable = Database::get_main_table(TABLE_MAIN_SESSION);
7580
            $sessionFieldTable = Database::get_main_table(TABLE_EXTRA_FIELD);
7581
            $sessionFieldValueTable = Database::get_main_table(TABLE_EXTRA_FIELD_VALUES);
7582
            $sessionCourseUserTable = Database::get_main_table(TABLE_MAIN_SESSION_COURSE_USER);
7583
            $userTable = Database::get_main_table(TABLE_MAIN_USER);
7584
            $courseTable = Database::get_main_table(TABLE_MAIN_COURSE);
7585
7586
            // Get all data from all sessions whit the session category specified
7587
            $sessionList = Database::select(
7588
                '*',
7589
                $sessionTable,
7590
                [
7591
                    'where' => [
7592
                        'session_category_id = ?' => $sessionCategoryId,
7593
                    ],
7594
                ]
7595
            );
7596
7597
            $extraFieldType = ExtraField::SESSION_FIELD_TYPE;
7598
7599
            // Check if session list query had result
7600
            if (!empty($sessionList)) {
7601
                // implode all session id
7602
                $sessionIdsString = '('.implode(', ', array_keys($sessionList)).')';
7603
                // Get all field variables
7604
                $sessionFieldList = Database::select(
7605
                    'id, variable',
7606
                    $sessionFieldTable,
7607
                    ['extra_field_type = ? ' => [$extraFieldType]]
7608
                );
7609
7610
                // Get all field values
7611
                $sql = "SELECT item_id, field_id, value FROM
7612
                        $sessionFieldValueTable v INNER JOIN $sessionFieldTable f
7613
                        ON (f.id = v.field_id)
7614
                        WHERE
7615
                            item_id IN $sessionIdsString AND
7616
                            extra_field_type = $extraFieldType
7617
                ";
7618
                $result = Database::query($sql);
7619
                $sessionFieldValueList = Database::store_result($result, 'ASSOC');
7620
7621
                // Check if session field values had result
7622
                if (!empty($sessionFieldValueList)) {
7623
                    $sessionFieldValueListBySession = [];
7624
                    foreach ($sessionFieldValueList as $key => $sessionFieldValue) {
7625
                        // Create an array to index ids to session id
7626
                        $sessionFieldValueListBySession[$sessionFieldValue['item_id']][] = $key;
7627
                    }
7628
                }
7629
                // Query used to find course-coaches from sessions
7630
                $sql = "SELECT
7631
                            scu.session_id,
7632
                            c.id AS course_id,
7633
                            c.code AS course_code,
7634
                            c.title AS course_title,
7635
                            u.username AS coach_username,
7636
                            u.firstname AS coach_firstname,
7637
                            u.lastname AS coach_lastname
7638
                        FROM $courseTable c
7639
                        INNER JOIN $sessionCourseUserTable scu ON c.id = scu.c_id
7640
                        INNER JOIN $userTable u ON scu.user_id = u.user_id
7641
                        WHERE scu.status = 2 AND scu.session_id IN $sessionIdsString
7642
                        ORDER BY scu.session_id ASC ";
7643
                $res = Database::query($sql);
7644
                $sessionCourseList = Database::store_result($res, 'ASSOC');
7645
                // Check if course list had result
7646
                if (!empty($sessionCourseList)) {
7647
                    foreach ($sessionCourseList as $key => $sessionCourse) {
7648
                        // Create an array to index ids to session_id
7649
                        $sessionCourseListBySession[$sessionCourse['session_id']][] = $key;
7650
                    }
7651
                }
7652
                // Join lists
7653
                if (is_array($sessionList)) {
7654
                    foreach ($sessionList as $id => &$row) {
7655
                        if (
7656
                            !empty($sessionFieldValueListBySession) &&
7657
                            is_array($sessionFieldValueListBySession[$id])
7658
                        ) {
7659
                            // If have an index array for session extra fields, use it to join arrays
7660
                            foreach ($sessionFieldValueListBySession[$id] as $key) {
7661
                                $row['extra'][$key] = [
7662
                                    'field_name' => $sessionFieldList[$sessionFieldValueList[$key]['field_id']]['variable'],
7663
                                    'value' => $sessionFieldValueList[$key]['value'],
7664
                                ];
7665
                            }
7666
                        }
7667
                        if (
7668
                            !empty($sessionCourseListBySession) &&
7669
                            is_array($sessionCourseListBySession[$id])
7670
                        ) {
7671
                            // If have an index array for session course coach, use it to join arrays
7672
                            foreach ($sessionCourseListBySession[$id] as $key) {
7673
                                $row['course'][$key] = [
7674
                                    'course_id' => $sessionCourseList[$key]['course_id'],
7675
                                    'course_code' => $sessionCourseList[$key]['course_code'],
7676
                                    'course_title' => $sessionCourseList[$key]['course_title'],
7677
                                    'coach_username' => $sessionCourseList[$key]['coach_username'],
7678
                                    'coach_firstname' => $sessionCourseList[$key]['coach_firstname'],
7679
                                    'coach_lastname' => $sessionCourseList[$key]['coach_lastname'],
7680
                                ];
7681
                            }
7682
                        }
7683
                    }
7684
                }
7685
7686
                return $sessionList;
7687
            } else {
7688
                // Not found result, update error message
7689
                $errorResult['errorMessage'] = 'Not found any session for session category id '.$sessionCategoryId;
7690
            }
7691
        }
7692
7693
        return $errorResult;
7694
    }
7695
7696
    /**
7697
     * Return session description from session id.
7698
     *
7699
     * @param int $sessionId
7700
     *
7701
     * @return string
7702
     */
7703
    public static function getDescriptionFromSessionId($sessionId)
7704
    {
7705
        // Init variables
7706
        $sessionId = (int) $sessionId;
7707
        $description = '';
7708
        // Check if session id is valid
7709
        if ($sessionId > 0) {
7710
            // Select query from session id
7711
            $rows = Database::select(
7712
                'description',
7713
                Database::get_main_table(TABLE_MAIN_SESSION),
7714
                [
7715
                    'where' => [
7716
                        'id = ?' => $sessionId,
7717
                    ],
7718
                ]
7719
            );
7720
7721
            // Check if select query result is not empty
7722
            if (!empty($rows)) {
7723
                // Get session description
7724
                $description = $rows[0]['description'];
7725
            }
7726
        }
7727
7728
        return $description;
7729
    }
7730
7731
    /**
7732
     * Get a session list filtered by name, description or any of the given extra fields.
7733
     *
7734
     * @param string $term                 The term to search
7735
     * @param array  $extraFieldsToInclude Extra fields to include in the session data
7736
     *
7737
     * @return array The list
7738
     */
7739
    public static function searchSession($term, $extraFieldsToInclude = [])
7740
    {
7741
        $sTable = Database::get_main_table(TABLE_MAIN_SESSION);
7742
        $extraFieldTable = Database::get_main_table(TABLE_EXTRA_FIELD);
7743
        $sfvTable = Database::get_main_table(TABLE_EXTRA_FIELD_VALUES);
7744
        $term = Database::escape_string($term);
7745
        $extraFieldType = ExtraField::SESSION_FIELD_TYPE;
7746
        if (is_array($extraFieldsToInclude) && count($extraFieldsToInclude) > 0) {
7747
            $resultData = Database::select('*', $sTable, [
7748
                'where' => [
7749
                    "name LIKE %?% " => $term,
7750
                    " OR description LIKE %?% " => $term,
7751
                    " OR id IN (
7752
                    SELECT item_id
7753
                    FROM $sfvTable v INNER JOIN $extraFieldTable e
7754
                    ON (v.field_id = e.id)
7755
                    WHERE value LIKE %?% AND extra_field_type = $extraFieldType
7756
                ) " => $term,
7757
                ],
7758
            ]);
7759
        } else {
7760
            $resultData = Database::select('*', $sTable, [
7761
                'where' => [
7762
                    "name LIKE %?% " => $term,
7763
                    "OR description LIKE %?% " => $term,
7764
                ],
7765
            ]);
7766
7767
            return $resultData;
7768
        }
7769
7770
        foreach ($resultData as $id => &$session) {
7771
            $session['extra'] = self::getFilteredExtraFields($id, $extraFieldsToInclude);
7772
        }
7773
7774
        return $resultData;
7775
    }
7776
7777
    /**
7778
     * @param int   $sessionId
7779
     * @param array $extraFieldsToInclude (empty means all)
7780
     *
7781
     * @return array
7782
     */
7783
    public static function getFilteredExtraFields($sessionId, $extraFieldsToInclude = [])
7784
    {
7785
        $extraData = [];
7786
        $variables = [];
7787
        $variablePlaceHolders = [];
7788
7789
        foreach ($extraFieldsToInclude as $sessionExtraField) {
7790
            $variablePlaceHolders[] = "?";
7791
            $variables[] = Database::escape_string($sessionExtraField);
7792
        }
7793
7794
        $sessionExtraField = new ExtraFieldModel('session');
7795
        $fieldList = $sessionExtraField->get_all(empty($extraFieldsToInclude) ? [] : [
7796
            "variable IN ( ".implode(", ", $variablePlaceHolders)." ) " => $variables,
7797
        ]);
7798
7799
        if (empty($fieldList)) {
7800
            return [];
7801
        }
7802
7803
        $fields = [];
7804
7805
        // Index session fields
7806
        foreach ($fieldList as $field) {
7807
            $fields[$field['id']] = $field['variable'];
7808
        }
7809
7810
        // Get session field values
7811
        $extra = new ExtraFieldValue('session');
7812
        $sessionFieldValueList = [];
7813
        foreach (array_keys($fields) as $fieldId) {
7814
            $sessionFieldValue = $extra->get_values_by_handler_and_field_id($sessionId, $fieldId);
7815
            if ($sessionFieldValue != false) {
7816
                $sessionFieldValueList[$fieldId] = $sessionFieldValue;
7817
            }
7818
        }
7819
7820
        foreach ($sessionFieldValueList as $sessionFieldValue) {
7821
            $extrafieldVariable = $fields[$sessionFieldValue['field_id']];
7822
            $extrafieldValue = $sessionFieldValue['value'];
7823
7824
            $extraData[] = [
7825
                'variable' => $extrafieldVariable,
7826
                'value' => $extrafieldValue,
7827
            ];
7828
        }
7829
7830
        return $extraData;
7831
    }
7832
7833
    /**
7834
     * @param int $sessionId
7835
     *
7836
     * @return bool
7837
     */
7838
    public static function isValidId($sessionId)
7839
    {
7840
        $sessionId = (int) $sessionId;
7841
        if ($sessionId > 0) {
7842
            $rows = Database::select(
7843
                'id',
7844
                Database::get_main_table(TABLE_MAIN_SESSION),
7845
                ['where' => ['id = ?' => $sessionId]]
7846
            );
7847
            if (!empty($rows)) {
7848
                return true;
7849
            }
7850
        }
7851
7852
        return false;
7853
    }
7854
7855
    /**
7856
     * Get list of sessions based on users of a group for a group admin.
7857
     *
7858
     * @param int $userId The user id
7859
     *
7860
     * @return array
7861
     */
7862
    public static function getSessionsFollowedForGroupAdmin($userId)
7863
    {
7864
        $sessionList = [];
7865
        $sessionTable = Database::get_main_table(TABLE_MAIN_SESSION);
7866
        $sessionUserTable = Database::get_main_table(TABLE_MAIN_SESSION_USER);
7867
        $userGroup = new UserGroup();
7868
        $userIdList = $userGroup->getGroupUsersByUser($userId);
7869
7870
        if (empty($userIdList)) {
7871
            return [];
7872
        }
7873
7874
        $sql = "SELECT DISTINCT s.*
7875
                FROM $sessionTable s
7876
                INNER JOIN $sessionUserTable sru
7877
                ON s.id = sru.id_session
7878
                WHERE
7879
                    (sru.id_user IN (".implode(', ', $userIdList).")
7880
                    AND sru.relation_type = 0
7881
                )";
7882
7883
        if (api_is_multiple_url_enabled()) {
7884
            $sessionAccessUrlTable = Database::get_main_table(TABLE_MAIN_ACCESS_URL_REL_SESSION);
7885
            $accessUrlId = api_get_current_access_url_id();
7886
7887
            if (-1 != $accessUrlId) {
7888
                $sql = "SELECT DISTINCT s.*
7889
                        FROM $sessionTable s
7890
                        INNER JOIN $sessionUserTable sru ON s.id = sru.id_session
7891
                        INNER JOIN $sessionAccessUrlTable srau ON s.id = srau.session_id
7892
                        WHERE
7893
                            srau.access_url_id = $accessUrlId
7894
                            AND (
7895
                                sru.id_user IN (".implode(', ', $userIdList).")
7896
                                AND sru.relation_type = 0
7897
                            )";
7898
            }
7899
        }
7900
7901
        $result = Database::query($sql);
7902
        while ($row = Database::fetch_assoc($result)) {
7903
            $sessionList[] = $row;
7904
        }
7905
7906
        return $sessionList;
7907
    }
7908
7909
    /**
7910
     * @param array $sessionInfo
7911
     *
7912
     * @return string
7913
     */
7914
    public static function getSessionVisibility($sessionInfo)
7915
    {
7916
        switch ($sessionInfo['visibility']) {
7917
            case 1:
7918
                return get_lang('ReadOnly');
7919
            case 2:
7920
                return get_lang('Visible');
7921
            case 3:
7922
                return api_ucfirst(get_lang('Invisible'));
7923
        }
7924
    }
7925
7926
    /**
7927
     * Returns a human readable string.
7928
     *
7929
     * @param array $sessionInfo An array with all the session dates
7930
     * @param bool  $showTime
7931
     *
7932
     * @return array
7933
     */
7934
    public static function parseSessionDates($sessionInfo, $showTime = false)
7935
    {
7936
        $displayDates = self::convertSessionDateToString(
7937
            $sessionInfo['display_start_date'],
7938
            $sessionInfo['display_end_date'],
7939
            $showTime,
7940
            true
7941
        );
7942
        $accessDates = self::convertSessionDateToString(
7943
            $sessionInfo['access_start_date'],
7944
            $sessionInfo['access_end_date'],
7945
            $showTime,
7946
            true
7947
        );
7948
7949
        $coachDates = self::convertSessionDateToString(
7950
            $sessionInfo['coach_access_start_date'],
7951
            $sessionInfo['coach_access_end_date'],
7952
            $showTime,
7953
            true
7954
        );
7955
7956
        $result = [
7957
            'access' => $accessDates,
7958
            'display' => $displayDates,
7959
            'coach' => $coachDates,
7960
        ];
7961
7962
        return $result;
7963
    }
7964
7965
    /**
7966
     * @param array $sessionInfo Optional
7967
     *
7968
     * @return array
7969
     */
7970
    public static function setForm(FormValidator $form, array $sessionInfo = [])
7971
    {
7972
        $sessionId = 0;
7973
        $coachInfo = [];
7974
7975
        if (!empty($sessionInfo)) {
7976
            $sessionId = (int) $sessionInfo['id'];
7977
            $coachInfo = api_get_user_info($sessionInfo['id_coach']);
7978
        }
7979
7980
        $categoriesList = self::get_all_session_category();
7981
        $userInfo = api_get_user_info();
7982
7983
        $categoriesOptions = [
7984
            '0' => get_lang('None'),
7985
        ];
7986
7987
        if ($categoriesList != false) {
7988
            foreach ($categoriesList as $categoryItem) {
7989
                $categoriesOptions[$categoryItem['id']] = $categoryItem['name'];
7990
            }
7991
        }
7992
7993
        // Database Table Definitions
7994
        $tbl_user = Database::get_main_table(TABLE_MAIN_USER);
7995
7996
        $form->addText(
7997
            'name',
7998
            get_lang('SessionName'),
7999
            true,
8000
            ['maxlength' => 150, 'aria-label' => get_lang('SessionName')]
8001
        );
8002
        $form->addRule('name', get_lang('SessionNameAlreadyExists'), 'callback', 'check_session_name');
8003
8004
        if (!api_is_platform_admin() && api_is_teacher()) {
8005
            $form->addElement(
8006
                'select',
8007
                'coach_username',
8008
                get_lang('CoachName'),
8009
                [api_get_user_id() => $userInfo['complete_name']],
8010
                [
8011
                    'id' => 'coach_username',
8012
                    'style' => 'width:370px;',
8013
                ]
8014
            );
8015
        } else {
8016
            $sql = "SELECT COUNT(1) FROM $tbl_user WHERE status = 1";
8017
            $rs = Database::query($sql);
8018
            $countUsers = (int) Database::result($rs, 0, 0);
8019
8020
            if ($countUsers < 50) {
8021
                $orderClause = 'ORDER BY ';
8022
                $orderClause .= api_sort_by_first_name() ? 'firstname, lastname, username' : 'lastname, firstname, username';
8023
8024
                $sql = "SELECT user_id, lastname, firstname, username
8025
                        FROM $tbl_user
8026
                        WHERE status = '1' ".
8027
                        $orderClause;
8028
8029
                if (api_is_multiple_url_enabled()) {
8030
                    $userRelAccessUrlTable = Database::get_main_table(
8031
                        TABLE_MAIN_ACCESS_URL_REL_USER
8032
                    );
8033
                    $accessUrlId = api_get_current_access_url_id();
8034
                    if ($accessUrlId != -1) {
8035
                        $sql = "SELECT user.user_id, username, lastname, firstname
8036
                        FROM $tbl_user user
8037
                        INNER JOIN $userRelAccessUrlTable url_user
8038
                        ON (url_user.user_id = user.user_id)
8039
                        WHERE
8040
                            access_url_id = $accessUrlId AND
8041
                            status = 1 "
8042
                            .$orderClause;
8043
                    }
8044
                }
8045
8046
                $result = Database::query($sql);
8047
                $coachesList = Database::store_result($result);
8048
                $coachesOptions = [];
8049
                foreach ($coachesList as $coachItem) {
8050
                    $coachesOptions[$coachItem['user_id']] =
8051
                        api_get_person_name($coachItem['firstname'], $coachItem['lastname']).' ('.$coachItem['username'].')';
8052
                }
8053
8054
                $form->addElement(
8055
                    'select',
8056
                    'coach_username',
8057
                    get_lang('CoachName'),
8058
                    $coachesOptions,
8059
                    [
8060
                        'id' => 'coach_username',
8061
                        'style' => 'width:370px;',
8062
                    ]
8063
                );
8064
            } else {
8065
                $form->addElement(
8066
                    'select_ajax',
8067
                    'coach_username',
8068
                    get_lang('CoachName'),
8069
                    $coachInfo ? [$coachInfo['id'] => $coachInfo['complete_name_with_username']] : [],
8070
                    [
8071
                        'url' => api_get_path(WEB_AJAX_PATH).'session.ajax.php?a=search_general_coach',
8072
                        'width' => '100%',
8073
                        'id' => 'coach_username',
8074
                    ]
8075
                );
8076
            }
8077
        }
8078
8079
        $form->addRule('coach_username', get_lang('ThisFieldIsRequired'), 'required');
8080
        $form->addHtml('<div id="ajax_list_coachs"></div>');
8081
8082
        $form->addButtonAdvancedSettings('advanced_params');
8083
        $form->addElement('html', '<div id="advanced_params_options" style="display:none">');
8084
8085
        if (empty($sessionId)) {
8086
            $form->addSelectAjax(
8087
                'session_template',
8088
                get_lang('SessionTemplate'),
8089
                [],
8090
                ['url' => api_get_path(WEB_AJAX_PATH).'session.ajax.php?a=search_template_session', 'id' => 'system_template']
8091
            );
8092
        }
8093
8094
        $form->addSelect(
8095
            'session_category',
8096
            get_lang('SessionCategory'),
8097
            $categoriesOptions,
8098
            [
8099
                'id' => 'session_category',
8100
            ]
8101
        );
8102
8103
        if (api_get_configuration_value('allow_session_status')) {
8104
            $statusList = self::getStatusList();
8105
            $form->addSelect(
8106
                'status',
8107
                get_lang('SessionStatus'),
8108
                $statusList,
8109
                [
8110
                    'id' => 'status',
8111
                ]
8112
            );
8113
        }
8114
8115
        $form->addHtmlEditor(
8116
            'description',
8117
            get_lang('Description'),
8118
            false,
8119
            false,
8120
            [
8121
                'ToolbarSet' => 'Minimal',
8122
            ]
8123
        );
8124
8125
        $form->addElement('checkbox', 'show_description', null, get_lang('ShowDescription'));
8126
8127
        $visibilityOptions = [
8128
            SESSION_VISIBLE_READ_ONLY => get_lang('SessionReadOnly'),
8129
            SESSION_VISIBLE => get_lang('SessionAccessible'),
8130
            SESSION_INVISIBLE => api_ucfirst(get_lang('SessionNotAccessible')),
8131
        ];
8132
8133
        $visibilityOptionsConfiguration = api_get_configuration_value('session_visibility_after_end_date_options_configuration');
8134
        if (!empty($visibilityOptionsConfiguration)) {
8135
            foreach ($visibilityOptionsConfiguration['visibility_options_to_hide'] as $option) {
8136
                $option = trim($option);
8137
                if (defined($option)) {
8138
                    $constantValue = constant($option);
8139
                    if (isset($visibilityOptions[$constantValue])) {
8140
                        unset($visibilityOptions[$constantValue]);
8141
                    }
8142
                }
8143
            }
8144
        }
8145
8146
        $visibilityGroup = [];
8147
        $visibilityGroup[] = $form->createElement(
8148
            'select',
8149
            'session_visibility',
8150
            null,
8151
            $visibilityOptions
8152
        );
8153
        $form->addGroup(
8154
            $visibilityGroup,
8155
            'visibility_group',
8156
            get_lang('SessionVisibility'),
8157
            null,
8158
            false
8159
        );
8160
8161
        $options = [
8162
            0 => get_lang('ByDuration'),
8163
            1 => get_lang('ByDates'),
8164
        ];
8165
8166
        $form->addSelect('access', get_lang('Access'), $options, [
8167
            'onchange' => 'accessSwitcher()',
8168
            'id' => 'access',
8169
        ]);
8170
8171
        $form->addHtml('<div id="duration_div" style="display:none">');
8172
        $form->addElement(
8173
            'number',
8174
            'duration',
8175
            [
8176
                get_lang('SessionDurationTitle'),
8177
                get_lang('SessionDurationDescription'),
8178
            ],
8179
            [
8180
                'maxlength' => 50,
8181
            ]
8182
        );
8183
8184
        $form->addHtml('</div>');
8185
        $form->addHtml('<div id="date_fields" style="display:none">');
8186
8187
        // Dates
8188
        $form->addDateTimePicker(
8189
            'access_start_date',
8190
            [get_lang('SessionStartDate'), get_lang('SessionStartDateComment')],
8191
            ['id' => 'access_start_date']
8192
        );
8193
8194
        $form->addDateTimePicker(
8195
            'access_end_date',
8196
            [get_lang('SessionEndDate'), get_lang('SessionEndDateComment')],
8197
            ['id' => 'access_end_date']
8198
        );
8199
8200
        $form->addRule(
8201
            ['access_start_date', 'access_end_date'],
8202
            get_lang('StartDateMustBeBeforeTheEndDate'),
8203
            'compare_datetime_text',
8204
            '< allow_empty'
8205
        );
8206
8207
        $form->addDateTimePicker(
8208
            'display_start_date',
8209
            [
8210
                get_lang('SessionDisplayStartDate'),
8211
                get_lang('SessionDisplayStartDateComment'),
8212
            ],
8213
            ['id' => 'display_start_date']
8214
        );
8215
8216
        $form->addDateTimePicker(
8217
            'display_end_date',
8218
            [
8219
                get_lang('SessionDisplayEndDate'),
8220
                get_lang('SessionDisplayEndDateComment'),
8221
            ],
8222
            ['id' => 'display_end_date']
8223
        );
8224
8225
        $form->addRule(
8226
            ['display_start_date', 'display_end_date'],
8227
            get_lang('StartDateMustBeBeforeTheEndDate'),
8228
            'compare_datetime_text',
8229
            '< allow_empty'
8230
        );
8231
8232
        $form->addDateTimePicker(
8233
            'coach_access_start_date',
8234
            [
8235
                get_lang('SessionCoachStartDate'),
8236
                get_lang('SessionCoachStartDateComment'),
8237
            ],
8238
            ['id' => 'coach_access_start_date']
8239
        );
8240
8241
        $form->addDateTimePicker(
8242
            'coach_access_end_date',
8243
            [
8244
                get_lang('SessionCoachEndDate'),
8245
                get_lang('SessionCoachEndDateComment'),
8246
            ],
8247
            ['id' => 'coach_access_end_date']
8248
        );
8249
8250
        $form->addRule(
8251
            ['coach_access_start_date', 'coach_access_end_date'],
8252
            get_lang('StartDateMustBeBeforeTheEndDate'),
8253
            'compare_datetime_text',
8254
            '< allow_empty'
8255
        );
8256
8257
        $form->addElement('html', '</div>');
8258
8259
        $form->addCheckBox(
8260
            'send_subscription_notification',
8261
            [
8262
                get_lang('SendSubscriptionNotification'),
8263
                get_lang('SendAnEmailWhenAUserBeingSubscribed'),
8264
            ]
8265
        );
8266
8267
        // Extra fields
8268
        $setExtraFieldsMandatory = api_get_configuration_value('session_creation_form_set_extra_fields_mandatory');
8269
        $fieldsRequired = [];
8270
        if (false !== $setExtraFieldsMandatory && !empty($setExtraFieldsMandatory['fields'])) {
8271
            $fieldsRequired = $setExtraFieldsMandatory['fields'];
8272
        }
8273
        $extra_field = new ExtraFieldModel('session');
8274
        $extra = $extra_field->addElements(
8275
            $form,
8276
            $sessionId,
8277
            [],
8278
            false,
8279
            false,
8280
            [],
8281
            [],
8282
            [],
8283
            false,
8284
            false,
8285
            [],
8286
            [],
8287
            false,
8288
            [],
8289
            $fieldsRequired
8290
        );
8291
8292
        $form->addElement('html', '</div>');
8293
8294
        $js = $extra['jquery_ready_content'];
8295
8296
        return ['js' => $js];
8297
    }
8298
8299
    /**
8300
     * Gets the number of rows in the session table filtered through the given
8301
     * array of parameters.
8302
     *
8303
     * @param array Array of options/filters/keys
8304
     *
8305
     * @return int The number of rows, or false on wrong param
8306
     * @assert ('a') === false
8307
     */
8308
    public static function get_count_admin_complete($options = [])
8309
    {
8310
        if (!is_array($options)) {
8311
            return false;
8312
        }
8313
        $tbl_session = Database::get_main_table(TABLE_MAIN_SESSION);
8314
        $tbl_session_category = Database::get_main_table(TABLE_MAIN_SESSION_CATEGORY);
8315
        $tbl_user = Database::get_main_table(TABLE_MAIN_USER);
8316
        $sessionCourseUserTable = Database::get_main_table(TABLE_MAIN_SESSION_COURSE_USER);
8317
        $courseTable = Database::get_main_table(TABLE_MAIN_COURSE);
8318
        $tbl_session_field_values = Database::get_main_table(TABLE_EXTRA_FIELD_VALUES);
8319
        $tbl_session_field_options = Database::get_main_table(TABLE_EXTRA_FIELD_OPTIONS);
8320
8321
        $where = 'WHERE 1 = 1 ';
8322
        $user_id = api_get_user_id();
8323
8324
        if (api_is_session_admin() &&
8325
            'false' == api_get_setting('allow_session_admins_to_see_all_sessions')
8326
        ) {
8327
            $where .= " WHERE s.session_admin_id = $user_id ";
8328
        }
8329
8330
        $extraFieldTables = '';
8331
        if (!empty($options['where'])) {
8332
            $options['where'] = str_replace('course_title', 'c.title', $options['where']);
8333
            $options['where'] = str_replace("( session_active = '0' )", '1=1', $options['where']);
8334
8335
            $options['where'] = str_replace(
8336
                ["AND session_active = '1'  )", " AND (  session_active = '1'  )"],
8337
                [') GROUP BY s.name HAVING session_active = 1 ', " GROUP BY s.name HAVING session_active = 1 "],
8338
                $options['where']
8339
            );
8340
8341
            $options['where'] = str_replace(
8342
                ["AND session_active = '0'  )", " AND (  session_active = '0'  )"],
8343
                [') GROUP BY s.name HAVING session_active = 0 ', " GROUP BY s.name HAVING session_active = '0' "],
8344
                $options['where']
8345
            );
8346
8347
            if (!empty($options['extra'])) {
8348
                $options['where'] = str_replace(' 1 = 1  AND', '', $options['where']);
8349
                $options['where'] = str_replace('AND', 'OR', $options['where']);
8350
8351
                foreach ($options['extra'] as $extra) {
8352
                    $options['where'] = str_replace(
8353
                        $extra['field'],
8354
                        'fv.field_id = '.$extra['id'].' AND fvo.option_value',
8355
                        $options['where']
8356
                    );
8357
                    $extraFieldTables = "$tbl_session_field_values fv, $tbl_session_field_options fvo, ";
8358
                }
8359
            }
8360
            $where .= ' AND '.$options['where'];
8361
        }
8362
8363
        $today = api_get_utc_datetime();
8364
        $query_rows = "SELECT count(*) as total_rows, c.title as course_title, s.name,
8365
                        IF (
8366
                            (s.access_start_date <= '$today' AND '$today' < s.access_end_date) OR
8367
                            (s.access_start_date = '0000-00-00 00:00:00' AND s.access_end_date = '0000-00-00 00:00:00' ) OR
8368
                            (s.access_start_date IS NULL AND s.access_end_date IS NULL) OR
8369
                            (s.access_start_date <= '$today' AND ('0000-00-00 00:00:00' = s.access_end_date OR s.access_end_date IS NULL )) OR
8370
                            ('$today' < s.access_end_date AND ('0000-00-00 00:00:00' = s.access_start_date OR s.access_start_date IS NULL) )
8371
                        , 1, 0) as session_active
8372
                       FROM $extraFieldTables $tbl_session s
8373
                       LEFT JOIN  $tbl_session_category sc
8374
                       ON s.session_category_id = sc.id
8375
                       INNER JOIN $tbl_user u
8376
                       ON s.id_coach = u.id
8377
                       INNER JOIN $sessionCourseUserTable scu
8378
                       ON s.id = scu.session_id
8379
                       INNER JOIN $courseTable c
8380
                       ON c.id = scu.c_id
8381
                       $where ";
8382
8383
        if (api_is_multiple_url_enabled()) {
8384
            $table_access_url_rel_session = Database::get_main_table(TABLE_MAIN_ACCESS_URL_REL_SESSION);
8385
            $access_url_id = api_get_current_access_url_id();
8386
            if (-1 != $access_url_id) {
8387
                $where .= " AND ar.access_url_id = $access_url_id ";
8388
                $query_rows = "SELECT count(*) as total_rows
8389
                               FROM $tbl_session s
8390
                               LEFT JOIN  $tbl_session_category sc
8391
                               ON s.session_category_id = sc.id
8392
                               INNER JOIN $tbl_user u
8393
                               ON s.id_coach = u.id
8394
                               INNER JOIN $table_access_url_rel_session ar
8395
                               ON ar.session_id = s.id $where ";
8396
            }
8397
        }
8398
8399
        $result = Database::query($query_rows);
8400
        $num = 0;
8401
        if (Database::num_rows($result)) {
8402
            $rows = Database::fetch_array($result);
8403
            $num = $rows['total_rows'];
8404
        }
8405
8406
        return $num;
8407
    }
8408
8409
    /**
8410
     * @param string $listType
8411
     * @param array  $extraFields
8412
     *
8413
     * @return array
8414
     */
8415
    public static function getGridColumns(
8416
        $listType = 'all',
8417
        $extraFields = [],
8418
        $addExtraFields = true
8419
    ) {
8420
        $showCount = api_get_configuration_value('session_list_show_count_users');
8421
        // Column config
8422
        $operators = ['cn', 'nc'];
8423
        $date_operators = ['gt', 'ge', 'lt', 'le'];
8424
8425
        $columnModel = [];
8426
8427
        switch ($listType) {
8428
            case 'my_space':
8429
                $columns = [
8430
                    get_lang('Title'),
8431
                    get_lang('Date'),
8432
                    get_lang('NbCoursesPerSession'),
8433
                    get_lang('NbStudentPerSession'),
8434
                    get_lang('Details'),
8435
                ];
8436
8437
                $columnModel = [
8438
                    ['name' => 'name', 'index' => 'name', 'width' => '255', 'align' => 'left'],
8439
                    ['name' => 'date', 'index' => 'access_start_date', 'width' => '150', 'align' => 'left'],
8440
                    [
8441
                        'name' => 'course_per_session',
8442
                        'index' => 'course_per_session',
8443
                        'width' => '150',
8444
                        'sortable' => 'false',
8445
                        'search' => 'false',
8446
                    ],
8447
                    [
8448
                        'name' => 'student_per_session',
8449
                        'index' => 'student_per_session',
8450
                        'width' => '100',
8451
                        'sortable' => 'false',
8452
                        'search' => 'false',
8453
                    ],
8454
                    [
8455
                        'name' => 'actions',
8456
                        'index' => 'actions',
8457
                        'width' => '100',
8458
                        'sortable' => 'false',
8459
                        'search' => 'false',
8460
                    ],
8461
                ];
8462
                break;
8463
            case 'all':
8464
            case 'active':
8465
            case 'close':
8466
                $columns = [
8467
                    '#',
8468
                    get_lang('Name'),
8469
                    get_lang('Category'),
8470
                    get_lang('SessionDisplayStartDate'),
8471
                    get_lang('SessionDisplayEndDate'),
8472
                    get_lang('Visibility'),
8473
                ];
8474
8475
                $columnModel = [
8476
                    [
8477
                        'name' => 'id',
8478
                        'index' => 's.id',
8479
                        'width' => '160',
8480
                        'hidden' => 'true',
8481
                    ],
8482
                    [
8483
                        'name' => 'name',
8484
                        'index' => 's.name',
8485
                        'width' => '160',
8486
                        'align' => 'left',
8487
                        'search' => 'true',
8488
                        'searchoptions' => ['sopt' => $operators],
8489
                    ],
8490
                    [
8491
                        'name' => 'category_name',
8492
                        'index' => 'category_name',
8493
                        'width' => '40',
8494
                        'align' => 'left',
8495
                        'search' => 'true',
8496
                        'searchoptions' => ['sopt' => $operators],
8497
                    ],
8498
                    [
8499
                        'name' => 'display_start_date',
8500
                        'index' => 'display_start_date',
8501
                        'width' => '50',
8502
                        'align' => 'left',
8503
                        'search' => 'true',
8504
                        'searchoptions' => [
8505
                            'dataInit' => 'date_pick_today',
8506
                            'sopt' => $date_operators,
8507
                        ],
8508
                    ],
8509
                    [
8510
                        'name' => 'display_end_date',
8511
                        'index' => 'display_end_date',
8512
                        'width' => '50',
8513
                        'align' => 'left',
8514
                        'search' => 'true',
8515
                        'searchoptions' => [
8516
                            'dataInit' => 'date_pick_one_month',
8517
                            'sopt' => $date_operators,
8518
                        ],
8519
                    ],
8520
                    [
8521
                        'name' => 'visibility',
8522
                        'index' => 'visibility',
8523
                        'width' => '40',
8524
                        'align' => 'left',
8525
                        'search' => 'false',
8526
                    ],
8527
                ];
8528
8529
                if ($showCount) {
8530
                    $columns[] = get_lang('Users');
8531
                    $columnModel[] = [
8532
                        'name' => 'users',
8533
                        'index' => 'users',
8534
                        'width' => '20',
8535
                        'align' => 'left',
8536
                        'search' => 'false',
8537
                    ];
8538
8539
                    // ofaj
8540
                    $columns[] = get_lang('Teachers');
8541
                    $columnModel[] = [
8542
                        'name' => 'teachers',
8543
                        'index' => 'teachers',
8544
                        'width' => '20',
8545
                        'align' => 'left',
8546
                        'search' => 'false',
8547
                    ];
8548
                }
8549
8550
                if (api_get_configuration_value('allow_session_status')) {
8551
                    $columns[] = get_lang('SessionStatus');
8552
                    $list = self::getStatusList();
8553
                    $listToString = '';
8554
                    foreach ($list as $statusId => $status) {
8555
                        $listToString .= $statusId.':'.$status.';';
8556
                    }
8557
8558
                    $columnModel[] = [
8559
                        'name' => 'status',
8560
                        'index' => 'status',
8561
                        'width' => '25',
8562
                        'align' => 'left',
8563
                        'search' => 'true',
8564
                        'stype' => 'select',
8565
                        // for the bottom bar
8566
                        'searchoptions' => [
8567
                            'defaultValue' => '1',
8568
                            'value' => $listToString,
8569
                        ],
8570
                    ];
8571
                }
8572
                break;
8573
            case 'complete':
8574
                $columns = [
8575
                    get_lang('Name'),
8576
                    get_lang('SessionDisplayStartDate'),
8577
                    get_lang('SessionDisplayEndDate'),
8578
                    get_lang('Coach'),
8579
                    get_lang('Status'),
8580
                    get_lang('Visibility'),
8581
                    get_lang('CourseTitle'),
8582
                ];
8583
                $columnModel = [
8584
                    [
8585
                        'name' => 'name',
8586
                        'index' => 's.name',
8587
                        'width' => '200',
8588
                        'align' => 'left',
8589
                        'search' => 'true',
8590
                        'searchoptions' => ['sopt' => $operators],
8591
                    ],
8592
                    [
8593
                        'name' => 'display_start_date',
8594
                        'index' => 'display_start_date',
8595
                        'width' => '70',
8596
                        'align' => 'left',
8597
                        'search' => 'true',
8598
                        'searchoptions' => ['dataInit' => 'date_pick_today', 'sopt' => $date_operators],
8599
                    ],
8600
                    [
8601
                        'name' => 'display_end_date',
8602
                        'index' => 'display_end_date',
8603
                        'width' => '70',
8604
                        'align' => 'left',
8605
                        'search' => 'true',
8606
                        'searchoptions' => ['dataInit' => 'date_pick_one_month', 'sopt' => $date_operators],
8607
                    ],
8608
                    [
8609
                        'name' => 'coach_name',
8610
                        'index' => 'coach_name',
8611
                        'width' => '70',
8612
                        'align' => 'left',
8613
                        'search' => 'false',
8614
                        'searchoptions' => ['sopt' => $operators],
8615
                    ],
8616
                    [
8617
                        'name' => 'session_active',
8618
                        'index' => 'session_active',
8619
                        'width' => '25',
8620
                        'align' => 'left',
8621
                        'search' => 'true',
8622
                        'stype' => 'select',
8623
                        // for the bottom bar
8624
                        'searchoptions' => [
8625
                            'defaultValue' => '1',
8626
                            'value' => '1:'.get_lang('Active').';0:'.get_lang('Inactive'),
8627
                        ],
8628
                        // for the top bar
8629
                        'editoptions' => [
8630
                            'value' => '" ":'.get_lang('All').';1:'.get_lang('Active').';0:'.get_lang(
8631
                                    'Inactive'
8632
                                ),
8633
                        ],
8634
                    ],
8635
                    [
8636
                        'name' => 'visibility',
8637
                        'index' => 'visibility',
8638
                        'width' => '40',
8639
                        'align' => 'left',
8640
                        'search' => 'false',
8641
                    ],
8642
                    [
8643
                        'name' => 'course_title',
8644
                        'index' => 'course_title',
8645
                        'width' => '50',
8646
                        'hidden' => 'true',
8647
                        'search' => 'true',
8648
                        'searchoptions' => ['searchhidden' => 'true', 'sopt' => $operators],
8649
                    ],
8650
                ];
8651
8652
                break;
8653
8654
            case 'custom':
8655
                $columns = [
8656
                    '#',
8657
                    get_lang('Name'),
8658
                    get_lang('Category'),
8659
                    get_lang('SessionDisplayStartDate'),
8660
                    get_lang('SessionDisplayEndDate'),
8661
                    get_lang('Visibility'),
8662
                ];
8663
                $columnModel = [
8664
                    [
8665
                        'name' => 'id',
8666
                        'index' => 's.id',
8667
                        'width' => '160',
8668
                        'hidden' => 'true',
8669
                    ],
8670
                    [
8671
                        'name' => 'name',
8672
                        'index' => 's.name',
8673
                        'width' => '160',
8674
                        'align' => 'left',
8675
                        'search' => 'true',
8676
                        'searchoptions' => ['sopt' => $operators],
8677
                    ],
8678
                    [
8679
                        'name' => 'category_name',
8680
                        'index' => 'category_name',
8681
                        'width' => '40',
8682
                        'align' => 'left',
8683
                        'search' => 'true',
8684
                        'searchoptions' => ['sopt' => $operators],
8685
                    ],
8686
                    [
8687
                        'name' => 'display_start_date',
8688
                        'index' => 'display_start_date',
8689
                        'width' => '50',
8690
                        'align' => 'left',
8691
                        'search' => 'true',
8692
                        'searchoptions' => [
8693
                            'dataInit' => 'date_pick_today',
8694
                            'sopt' => $date_operators,
8695
                        ],
8696
                    ],
8697
                    [
8698
                        'name' => 'display_end_date',
8699
                        'index' => 'display_end_date',
8700
                        'width' => '50',
8701
                        'align' => 'left',
8702
                        'search' => 'true',
8703
                        'searchoptions' => [
8704
                            'dataInit' => 'date_pick_one_month',
8705
                            'sopt' => $date_operators,
8706
                        ],
8707
                    ],
8708
                    [
8709
                        'name' => 'visibility',
8710
                        'index' => 'visibility',
8711
                        'width' => '40',
8712
                        'align' => 'left',
8713
                        'search' => 'false',
8714
                    ],
8715
                ];
8716
8717
                if ($showCount) {
8718
                    $columns[] = get_lang('Users');
8719
                    $columnModel[] = [
8720
                        'name' => 'users',
8721
                        'index' => 'users',
8722
                        'width' => '20',
8723
                        'align' => 'left',
8724
                        'search' => 'false',
8725
                    ];
8726
8727
                    // ofaj
8728
                    $columns[] = get_lang('Teachers');
8729
                    $columnModel[] = [
8730
                        'name' => 'teachers',
8731
                        'index' => 'teachers',
8732
                        'width' => '20',
8733
                        'align' => 'left',
8734
                        'search' => 'false',
8735
                    ];
8736
                }
8737
8738
                if (api_get_configuration_value('allow_session_status')) {
8739
                    $columns[] = get_lang('SessionStatus');
8740
                    $list = self::getStatusList();
8741
                    $listToString = '';
8742
                    foreach ($list as $statusId => $status) {
8743
                        $listToString .= $statusId.':'.$status.';';
8744
                    }
8745
8746
                    $columnModel[] = [
8747
                        'name' => 'status',
8748
                        'index' => 'status',
8749
                        'width' => '25',
8750
                        'align' => 'left',
8751
                        'search' => 'true',
8752
                        'stype' => 'select',
8753
                        // for the bottom bar
8754
                        'searchoptions' => [
8755
                            'defaultValue' => '1',
8756
                            'value' => $listToString,
8757
                        ],
8758
                    ];
8759
                }
8760
8761
                break;
8762
        }
8763
8764
        if (!empty($extraFields)) {
8765
            foreach ($extraFields as $field) {
8766
                $columns[] = $field['display_text'];
8767
                $columnModel[] = [
8768
                    'name' => $field['variable'],
8769
                    'index' => $field['variable'],
8770
                    'width' => '80',
8771
                    'align' => 'center',
8772
                    'search' => 'false',
8773
                ];
8774
            }
8775
        }
8776
8777
        // Inject extra session fields
8778
        $rules = [];
8779
        if ($addExtraFields) {
8780
            $sessionField = new ExtraFieldModel('session');
8781
            $rules = $sessionField->getRules($columns, $columnModel);
8782
        }
8783
8784
        if (!in_array('actions', array_column($columnModel, 'name'))) {
8785
            $columnModel[] = [
8786
                'name' => 'actions',
8787
                'index' => 'actions',
8788
                'width' => '80',
8789
                'align' => 'left',
8790
                'formatter' => 'action_formatter',
8791
                'sortable' => 'false',
8792
                'search' => 'false',
8793
            ];
8794
            $columns[] = get_lang('Actions');
8795
        }
8796
8797
        $columnName = [];
8798
        foreach ($columnModel as $col) {
8799
            $columnName[] = $col['name'];
8800
        }
8801
8802
        $return = [
8803
            'columns' => $columns,
8804
            'column_model' => $columnModel,
8805
            'rules' => $rules,
8806
            'simple_column_name' => $columnName,
8807
        ];
8808
8809
        return $return;
8810
    }
8811
8812
    /**
8813
     * Converts all dates sent through the param array (given form) to correct dates with timezones.
8814
     *
8815
     * @param array The dates The same array, with times converted
8816
     * @param bool $applyFormat Whether apply the DATE_TIME_FORMAT_SHORT format for sessions
8817
     *
8818
     * @return array The same array, with times converted
8819
     */
8820
    public static function convert_dates_to_local($params, $applyFormat = false)
8821
    {
8822
        if (!is_array($params)) {
8823
            return false;
8824
        }
8825
        $params['display_start_date'] = api_get_local_time($params['display_start_date'], null, null, true);
8826
        $params['display_end_date'] = api_get_local_time($params['display_end_date'], null, null, true);
8827
8828
        $params['access_start_date'] = api_get_local_time($params['access_start_date'], null, null, true);
8829
        $params['access_end_date'] = api_get_local_time($params['access_end_date'], null, null, true);
8830
8831
        $params['coach_access_start_date'] = isset($params['coach_access_start_date']) ? api_get_local_time($params['coach_access_start_date'], null, null, true) : null;
8832
        $params['coach_access_end_date'] = isset($params['coach_access_end_date']) ? api_get_local_time($params['coach_access_end_date'], null, null, true) : null;
8833
8834
        if ($applyFormat) {
8835
            if (isset($params['display_start_date'])) {
8836
                $params['display_start_date'] = api_format_date($params['display_start_date'], DATE_TIME_FORMAT_SHORT);
8837
            }
8838
8839
            if (isset($params['display_end_date'])) {
8840
                $params['display_end_date'] = api_format_date($params['display_end_date'], DATE_TIME_FORMAT_SHORT);
8841
            }
8842
8843
            if (isset($params['access_start_date'])) {
8844
                $params['access_start_date'] = api_format_date($params['access_start_date'], DATE_TIME_FORMAT_SHORT);
8845
            }
8846
8847
            if (isset($params['access_end_date'])) {
8848
                $params['access_end_date'] = api_format_date($params['access_end_date'], DATE_TIME_FORMAT_SHORT);
8849
            }
8850
8851
            if (isset($params['coach_access_start_date'])) {
8852
                $params['coach_access_start_date'] = api_format_date($params['coach_access_start_date'], DATE_TIME_FORMAT_SHORT);
8853
            }
8854
8855
            if (isset($params['coach_access_end_date'])) {
8856
                $params['coach_access_end_date'] = api_format_date($params['coach_access_end_date'], DATE_TIME_FORMAT_SHORT);
8857
            }
8858
        }
8859
8860
        return $params;
8861
    }
8862
8863
    /**
8864
     * Gets the admin session list callback of the session/session_list.php
8865
     * page with all user/details in the right fomat.
8866
     *
8867
     * @param array $options
8868
     *
8869
     * @return array Array of rows results
8870
     * @asset ('a') === false
8871
     */
8872
    public static function get_sessions_admin_complete($options = [])
8873
    {
8874
        if (!is_array($options)) {
8875
            return false;
8876
        }
8877
8878
        $tbl_session = Database::get_main_table(TABLE_MAIN_SESSION);
8879
        $tbl_session_category = Database::get_main_table(TABLE_MAIN_SESSION_CATEGORY);
8880
        $tbl_user = Database::get_main_table(TABLE_MAIN_USER);
8881
        $tbl_session_rel_course = Database::get_main_table(TABLE_MAIN_SESSION_COURSE);
8882
        $tbl_course = Database::get_main_table(TABLE_MAIN_COURSE);
8883
8884
        $extraFieldTable = Database::get_main_table(TABLE_EXTRA_FIELD);
8885
        $tbl_session_field_values = Database::get_main_table(TABLE_EXTRA_FIELD_VALUES);
8886
        $tbl_session_field_options = Database::get_main_table(TABLE_EXTRA_FIELD_OPTIONS);
8887
8888
        $where = 'WHERE 1 = 1 ';
8889
        $user_id = api_get_user_id();
8890
8891
        if (!api_is_platform_admin()) {
8892
            if (api_is_session_admin() &&
8893
                'false' == api_get_setting('allow_session_admins_to_manage_all_sessions')
8894
            ) {
8895
                $where .= " AND s.session_admin_id = $user_id ";
8896
            }
8897
        }
8898
8899
        $coach_name = " CONCAT(u.lastname , ' ', u.firstname) as coach_name ";
8900
        if (api_is_western_name_order()) {
8901
            $coach_name = " CONCAT(u.firstname, ' ', u.lastname) as coach_name ";
8902
        }
8903
8904
        $today = api_get_utc_datetime();
8905
        $injectExtraFields = null;
8906
        $extra_fields_info = [];
8907
8908
        //for now only sessions
8909
        $extra_field = new ExtraFieldModel('session');
8910
        $double_fields = [];
8911
        $extra_field_option = new ExtraFieldOption('session');
8912
8913
        if (isset($options['extra'])) {
8914
            $extra_fields = $options['extra'];
8915
            if (!empty($extra_fields)) {
8916
                foreach ($extra_fields as $extra) {
8917
                    $injectExtraFields .= " IF (fv.field_id = {$extra['id']}, fvo.option_display_text, NULL ) as {$extra['field']} , ";
8918
                    if (isset($extra_fields_info[$extra['id']])) {
8919
                        $info = $extra_fields_info[$extra['id']];
8920
                    } else {
8921
                        $info = $extra_field->get($extra['id']);
8922
                        $extra_fields_info[$extra['id']] = $info;
8923
                    }
8924
8925
                    if (ExtraFieldModel::FIELD_TYPE_DOUBLE_SELECT == $info['field_type']) {
8926
                        $double_fields[$info['id']] = $info;
8927
                    }
8928
                }
8929
            }
8930
        }
8931
8932
        $options_by_double = [];
8933
        foreach ($double_fields as $double) {
8934
            $my_options = $extra_field_option->get_field_options_by_field(
8935
                $double['id'],
8936
                true
8937
            );
8938
            $options_by_double['extra_'.$double['field_variable']] = $my_options;
8939
        }
8940
8941
        //sc.name as category_name,
8942
        $select = "
8943
                SELECT * FROM (
8944
                    SELECT DISTINCT
8945
                        IF (
8946
                            (s.access_start_date <= '$today' AND '$today' < s.access_end_date) OR
8947
                            (s.access_start_date = '0000-00-00 00:00:00' AND s.access_end_date = '0000-00-00 00:00:00' ) OR
8948
                            (s.access_start_date IS NULL AND s.access_end_date IS NULL) OR
8949
                            (s.access_start_date <= '$today' AND ('0000-00-00 00:00:00' = s.access_end_date OR s.access_end_date IS NULL )) OR
8950
                            ('$today' < s.access_end_date AND ('0000-00-00 00:00:00' = s.access_start_date OR s.access_start_date IS NULL) )
8951
                        , 1, 0) as session_active,
8952
                s.name,
8953
                s.nbr_courses,
8954
                s.nbr_users,
8955
                s.display_start_date,
8956
                s.display_end_date,
8957
                $coach_name,
8958
                access_start_date,
8959
                access_end_date,
8960
                s.visibility,
8961
                u.id as user_id,
8962
                $injectExtraFields
8963
                c.title as course_title,
8964
                s.id ";
8965
8966
        if (!empty($options['where'])) {
8967
            if (!empty($options['extra'])) {
8968
                $options['where'] = str_replace(' 1 = 1  AND', '', $options['where']);
8969
                $options['where'] = str_replace('AND', 'OR', $options['where']);
8970
                foreach ($options['extra'] as $extra) {
8971
                    $options['where'] = str_replace($extra['field'], 'fv.field_id = '.$extra['id'].' AND fvo.option_value', $options['where']);
8972
                }
8973
            }
8974
            $options['where'] = str_replace('course_title', 'c.title', $options['where']);
8975
            $options['where'] = str_replace("( session_active = '0' )", '1=1', $options['where']);
8976
            $options['where'] = str_replace(
8977
                ["AND session_active = '1'  )", " AND (  session_active = '1'  )"],
8978
                [') GROUP BY s.name HAVING session_active = 1 ', " GROUP BY s.name HAVING session_active = 1 "],
8979
                $options['where']
8980
            );
8981
8982
            $options['where'] = str_replace(
8983
                ["AND session_active = '0'  )", " AND (  session_active = '0'  )"],
8984
                [') GROUP BY s.name HAVING session_active = 0 ', " GROUP BY s.name HAVING session_active = '0' "],
8985
                $options['where']
8986
            );
8987
8988
            $where .= ' AND '.$options['where'];
8989
        }
8990
8991
        $limit = '';
8992
        if (!empty($options['limit'])) {
8993
            $limit = ' LIMIT '.$options['limit'];
8994
        }
8995
8996
        $query = "$select FROM $tbl_session s
8997
                    LEFT JOIN $tbl_session_field_values fv
8998
                    ON (fv.item_id = s.id)
8999
                    LEFT JOIN $extraFieldTable f
9000
                    ON f.id = fv.field_id
9001
                    LEFT JOIN $tbl_session_field_options fvo
9002
                    ON (fv.field_id = fvo.field_id)
9003
                    LEFT JOIN $tbl_session_rel_course src
9004
                    ON (src.session_id = s.id)
9005
                    LEFT JOIN $tbl_course c
9006
                    ON (src.c_id = c.id)
9007
                    LEFT JOIN $tbl_session_category sc
9008
                    ON (s.session_category_id = sc.id)
9009
                    INNER JOIN $tbl_user u
9010
                    ON (s.id_coach = u.id)
9011
                    $where
9012
                    $limit
9013
        ";
9014
9015
        if (api_is_multiple_url_enabled()) {
9016
            $table_access_url_rel_session = Database::get_main_table(TABLE_MAIN_ACCESS_URL_REL_SESSION);
9017
            $access_url_id = api_get_current_access_url_id();
9018
            if (-1 != $access_url_id) {
9019
                $query = "$select
9020
                    FROM $tbl_session s
9021
                    LEFT JOIN $tbl_session_field_values fv
9022
                    ON (fv.item_id = s.id)
9023
                    LEFT JOIN $tbl_session_field_options fvo
9024
                    ON (fv.field_id = fvo.field_id)
9025
                    LEFT JOIN $tbl_session_rel_course src
9026
                    ON (src.session_id = s.id)
9027
                    LEFT JOIN $tbl_course c
9028
                    ON (src.c_id = c.id)
9029
                    LEFT JOIN $tbl_session_category sc
9030
                    ON (s.session_category_id = sc.id)
9031
                    INNER JOIN $tbl_user u
9032
                    ON (s.id_coach = u.id)
9033
                    INNER JOIN $table_access_url_rel_session ar
9034
                    ON (ar.session_id = s.id AND ar.access_url_id = $access_url_id)
9035
                    $where
9036
                    $limit
9037
                ";
9038
            }
9039
        }
9040
9041
        $query .= ') AS s';
9042
9043
        if (!empty($options['order'])) {
9044
            $query .= ' ORDER BY '.$options['order'];
9045
        }
9046
9047
        $result = Database::query($query);
9048
9049
        $acceptIcon = Display::return_icon(
9050
            'accept.png',
9051
            get_lang('Active'),
9052
            [],
9053
            ICON_SIZE_SMALL
9054
        );
9055
9056
        $errorIcon = Display::return_icon(
9057
            'error.png',
9058
            get_lang('Inactive'),
9059
            [],
9060
            ICON_SIZE_SMALL
9061
        );
9062
9063
        $formatted_sessions = [];
9064
        if (Database::num_rows($result)) {
9065
            $sessions = Database::store_result($result, 'ASSOC');
9066
            foreach ($sessions as $session) {
9067
                $session_id = $session['id'];
9068
                $session['name'] = Display::url($session['name'], "resume_session.php?id_session=".$session['id']);
9069
                $session['coach_name'] = Display::url($session['coach_name'], "user_information.php?user_id=".$session['user_id']);
9070
                if (1 == $session['session_active']) {
9071
                    $session['session_active'] = $acceptIcon;
9072
                } else {
9073
                    $session['session_active'] = $errorIcon;
9074
                }
9075
9076
                $session = self::convert_dates_to_local($session);
9077
9078
                switch ($session['visibility']) {
9079
                    case SESSION_VISIBLE_READ_ONLY: //1
9080
                        $session['visibility'] = get_lang('ReadOnly');
9081
                        break;
9082
                    case SESSION_VISIBLE:           //2
9083
                    case SESSION_AVAILABLE:         //4
9084
                        $session['visibility'] = get_lang('Visible');
9085
                        break;
9086
                    case SESSION_INVISIBLE:         //3
9087
                        $session['visibility'] = api_ucfirst(get_lang('Invisible'));
9088
                        break;
9089
                }
9090
9091
                // Cleaning double selects
9092
                foreach ($session as $key => &$value) {
9093
                    if (isset($options_by_double[$key]) || isset($options_by_double[$key.'_second'])) {
9094
                        $options = explode('::', $value);
9095
                    }
9096
                    $original_key = $key;
9097
9098
                    if (strpos($key, '_second') === false) {
9099
                    } else {
9100
                        $key = str_replace('_second', '', $key);
9101
                    }
9102
9103
                    if (isset($options_by_double[$key])) {
9104
                        if (isset($options[0])) {
9105
                            if (isset($options_by_double[$key][$options[0]])) {
9106
                                if (strpos($original_key, '_second') === false) {
9107
                                    $value = $options_by_double[$key][$options[0]]['option_display_text'];
9108
                                } else {
9109
                                    $value = $options_by_double[$key][$options[1]]['option_display_text'];
9110
                                }
9111
                            }
9112
                        }
9113
                    }
9114
                }
9115
9116
                // Magic filter
9117
                if (isset($formatted_sessions[$session_id])) {
9118
                    $formatted_sessions[$session_id] = self::compareArraysToMerge(
9119
                        $formatted_sessions[$session_id],
9120
                        $session
9121
                    );
9122
                } else {
9123
                    $formatted_sessions[$session_id] = $session;
9124
                }
9125
            }
9126
        }
9127
9128
        return $formatted_sessions;
9129
    }
9130
9131
    /**
9132
     * Compare two arrays.
9133
     *
9134
     * @param array $array1
9135
     * @param array $array2
9136
     *
9137
     * @return array
9138
     */
9139
    public static function compareArraysToMerge($array1, $array2)
9140
    {
9141
        if (empty($array2)) {
9142
            return $array1;
9143
        }
9144
        foreach ($array1 as $key => $item) {
9145
            if (!isset($array1[$key])) {
9146
                //My string is empty try the other one
9147
                if (isset($array2[$key]) && !empty($array2[$key])) {
9148
                    $array1[$key] = $array2[$key];
9149
                }
9150
            }
9151
        }
9152
9153
        return $array1;
9154
    }
9155
9156
    /**
9157
     * Get link to the admin page for this session.
9158
     *
9159
     * @param int $id Session ID
9160
     *
9161
     * @return mixed URL to the admin page to manage the session, or false on error
9162
     */
9163
    public static function getAdminPath($id)
9164
    {
9165
        $id = (int) $id;
9166
        $session = self::fetch($id);
9167
        if (empty($session)) {
9168
            return false;
9169
        }
9170
9171
        return api_get_path(WEB_CODE_PATH).'session/resume_session.php?id_session='.$id;
9172
    }
9173
9174
    /**
9175
     * Get link to the user page for this session.
9176
     * If a course is provided, build the link to the course.
9177
     *
9178
     * @param int $id       Session ID
9179
     * @param int $courseId Course ID (optional) in case the link has to send straight to the course
9180
     *
9181
     * @return mixed URL to the page to use the session, or false on error
9182
     */
9183
    public static function getPath($id, $courseId = 0)
9184
    {
9185
        $id = (int) $id;
9186
        $session = self::fetch($id);
9187
        if (empty($session)) {
9188
            return false;
9189
        }
9190
        if (empty($courseId)) {
9191
            return api_get_path(WEB_CODE_PATH).'session/index.php?session_id='.$id;
9192
        } else {
9193
            $courseInfo = api_get_course_info_by_id($courseId);
9194
            if ($courseInfo) {
9195
                return $courseInfo['course_public_url'].'?id_session='.$id;
9196
            }
9197
        }
9198
9199
        return false;
9200
    }
9201
9202
    /**
9203
     * Return an associative array 'id_course' => [id_session1, id_session2...]
9204
     * where course id_course is in sessions id_session1, id_session2
9205
     * for course where user is coach
9206
     * i.e. coach for the course or
9207
     * main coach for a session the course is in
9208
     * for a session category (or woth no session category if empty).
9209
     *
9210
     * @param int $userId
9211
     *
9212
     * @return array
9213
     */
9214
    public static function getSessionCourseForUser($userId)
9215
    {
9216
        // list of COURSES where user is COURSE session coach
9217
        $listCourseCourseCoachSession = self::getCoursesForCourseSessionCoach($userId);
9218
        // list of courses where user is MAIN session coach
9219
        $listCourseMainCoachSession = self::getCoursesForMainSessionCoach($userId);
9220
        // merge these 2 array
9221
        $listResCourseSession = $listCourseCourseCoachSession;
9222
        foreach ($listCourseMainCoachSession as $courseId2 => $listSessionId2) {
9223
            if (isset($listResCourseSession[$courseId2])) {
9224
                // if sessionId array exists for this course
9225
                // same courseId, merge the list of session
9226
                foreach ($listCourseMainCoachSession[$courseId2] as $i => $sessionId2) {
9227
                    if (!in_array($sessionId2, $listResCourseSession[$courseId2])) {
9228
                        $listResCourseSession[$courseId2][] = $sessionId2;
9229
                    }
9230
                }
9231
            } else {
9232
                $listResCourseSession[$courseId2] = $listSessionId2;
9233
            }
9234
        }
9235
9236
        return $listResCourseSession;
9237
    }
9238
9239
    /**
9240
     * Return an associative array 'id_course' => [id_session1, id_session2...]
9241
     * where course id_course is in sessions id_session1, id_session2.
9242
     *
9243
     * @param int $userId
9244
     *
9245
     * @return array
9246
     */
9247
    public static function getCoursesForCourseSessionCoach($userId)
9248
    {
9249
        $userId = (int) $userId;
9250
        $listResCourseSession = [];
9251
        $tblCourse = Database::get_main_table(TABLE_MAIN_COURSE);
9252
        $tblSessionRelCourseRelUser = Database::get_main_table(TABLE_MAIN_SESSION_COURSE_USER);
9253
9254
        $sql = "SELECT session_id, c_id, c.id
9255
                FROM $tblSessionRelCourseRelUser srcru
9256
                LEFT JOIN $tblCourse c
9257
                ON c.id = srcru.c_id
9258
                WHERE
9259
                    srcru.user_id = $userId AND
9260
                    srcru.status = 2";
9261
9262
        $res = Database::query($sql);
9263
9264
        while ($data = Database::fetch_assoc($res)) {
9265
            if (api_get_session_visibility($data['session_id'])) {
9266
                if (!isset($listResCourseSession[$data['id']])) {
9267
                    $listResCourseSession[$data['id']] = [];
9268
                }
9269
                $listResCourseSession[$data['id']][] = $data['session_id'];
9270
            }
9271
        }
9272
9273
        return $listResCourseSession;
9274
    }
9275
9276
    /**
9277
     * Return an associative array 'id_course' => [id_session1, id_session2...]
9278
     * where course id_course is in sessions id_session1, id_session2.
9279
     *
9280
     * @param $userId
9281
     *
9282
     * @return array
9283
     */
9284
    public static function getCoursesForMainSessionCoach($userId)
9285
    {
9286
        $userId = (int) $userId;
9287
        $listResCourseSession = [];
9288
        $tblSession = Database::get_main_table(TABLE_MAIN_SESSION);
9289
9290
        // list of SESSION where user is session coach
9291
        $sql = "SELECT id FROM $tblSession
9292
                WHERE id_coach = ".$userId;
9293
        $res = Database::query($sql);
9294
9295
        while ($data = Database::fetch_assoc($res)) {
9296
            $sessionId = $data['id'];
9297
            $listCoursesInSession = self::getCoursesInSession($sessionId);
9298
            foreach ($listCoursesInSession as $i => $courseId) {
9299
                if (api_get_session_visibility($sessionId)) {
9300
                    if (!isset($listResCourseSession[$courseId])) {
9301
                        $listResCourseSession[$courseId] = [];
9302
                    }
9303
                    $listResCourseSession[$courseId][] = $sessionId;
9304
                }
9305
            }
9306
        }
9307
9308
        return $listResCourseSession;
9309
    }
9310
9311
    /**
9312
     * Return an array of course_id used in session $sessionId.
9313
     *
9314
     * @param $sessionId
9315
     *
9316
     * @return array
9317
     */
9318
    public static function getCoursesInSession($sessionId)
9319
    {
9320
        if (empty($sessionId)) {
9321
            return [];
9322
        }
9323
9324
        $tblSessionRelCourse = Database::get_main_table(TABLE_MAIN_SESSION_COURSE);
9325
        $tblCourse = Database::get_main_table(TABLE_MAIN_COURSE);
9326
9327
        // list of course in this session
9328
        $sql = "SELECT session_id, c.id
9329
                FROM $tblSessionRelCourse src
9330
                LEFT JOIN $tblCourse c
9331
                ON c.id = src.c_id
9332
                WHERE session_id = ".intval($sessionId);
9333
        $res = Database::query($sql);
9334
9335
        $listResultsCourseId = [];
9336
        while ($data = Database::fetch_assoc($res)) {
9337
            $listResultsCourseId[] = $data['id'];
9338
        }
9339
9340
        return $listResultsCourseId;
9341
    }
9342
9343
    /**
9344
     * Return an array of courses in session for user
9345
     * and for each courses the list of session that use this course for user.
9346
     *
9347
     * [0] => array
9348
     *      userCatId
9349
     *      userCatTitle
9350
     *      courseInUserCatList
9351
     *          [0] => array
9352
     *              courseId
9353
     *              title
9354
     *              courseCode
9355
     *              sessionCatList
9356
     *                  [0] => array
9357
     *                      catSessionId
9358
     *                      catSessionName
9359
     *                      sessionList
9360
     *                          [0] => array
9361
     *                              sessionId
9362
     *                              sessionName
9363
     *
9364
     * @param int $userId
9365
     *
9366
     * @return array
9367
     */
9368
    public static function getNamedSessionCourseForCoach($userId)
9369
    {
9370
        $listResults = [];
9371
        $listCourseSession = self::getSessionCourseForUser($userId);
9372
        foreach ($listCourseSession as $courseId => $listSessionId) {
9373
            // Course info
9374
            $courseInfo = api_get_course_info_by_id($courseId);
9375
            $listOneCourse = [];
9376
            $listOneCourse['courseId'] = $courseId;
9377
            $listOneCourse['title'] = $courseInfo['title'];
9378
            //$listOneCourse['courseCode'] = $courseInfo['code'];
9379
            $listOneCourse['course'] = $courseInfo;
9380
            $listOneCourse['sessionCatList'] = [];
9381
            $listCat = [];
9382
            foreach ($listSessionId as $i => $sessionId) {
9383
                // here we got all session for this course
9384
                // lets check there session categories
9385
                $sessionInfo = self::fetch($sessionId);
9386
                $catId = $sessionInfo['session_category_id'];
9387
                if (!isset($listCat[$catId])) {
9388
                    $listCatInfo = self::get_session_category($catId);
9389
                    if ($listCatInfo) {
9390
                        $listCat[$catId] = [];
9391
                        $listCat[$catId]['catSessionId'] = $catId;
9392
                        $listCat[$catId]['catSessionName'] = $listCatInfo['name'];
9393
                        $listCat[$catId]['sessionList'] = [];
9394
                    }
9395
                }
9396
                $listSessionInfo = self::fetch($sessionId);
9397
                $listSessionIdName = [
9398
                    'sessionId' => $sessionId,
9399
                    'sessionName' => $listSessionInfo['name'],
9400
                ];
9401
                $listCat[$catId]['sessionList'][] = $listSessionIdName;
9402
            }
9403
            // sort $listCat by catSessionName
9404
            usort($listCat, 'self::compareBySessionName');
9405
            // in each catSession sort sessionList by sessionName
9406
            foreach ($listCat as $i => $listCatSessionInfo) {
9407
                $listSessionList = $listCatSessionInfo['sessionList'];
9408
                usort($listSessionList, 'self::compareCatSessionInfo');
9409
                $listCat[$i]['sessionList'] = $listSessionList;
9410
            }
9411
9412
            $listOneCourse['sessionCatList'] = $listCat;
9413
9414
            // user course category
9415
            $courseCategory = CourseManager::getUserCourseCategoryForCourse(
9416
                $userId,
9417
                $courseId
9418
            );
9419
9420
            $userCatTitle = '';
9421
            $userCatId = 0;
9422
            if ($courseCategory) {
9423
                $userCatId = $courseCategory['user_course_cat'];
9424
                $userCatTitle = $courseCategory['title'];
9425
            }
9426
9427
            $listResults[$userCatId]['courseInUserCategoryId'] = $userCatId;
9428
            $listResults[$userCatId]['courseInUserCategoryTitle'] = $userCatTitle;
9429
            $listResults[$userCatId]['courseInUserCatList'][] = $listOneCourse;
9430
        }
9431
9432
        // sort by user course cat
9433
        uasort($listResults, 'self::compareByUserCourseCat');
9434
9435
        // sort by course title
9436
        foreach ($listResults as $userCourseCatId => $tabCoursesInCat) {
9437
            $courseInUserCatList = $tabCoursesInCat['courseInUserCatList'];
9438
            uasort($courseInUserCatList, 'self::compareByCourse');
9439
            $listResults[$userCourseCatId]['courseInUserCatList'] = $courseInUserCatList;
9440
        }
9441
9442
        return $listResults;
9443
    }
9444
9445
    /**
9446
     * @param int $userId
9447
     * @param int $courseId
9448
     *
9449
     * @return array
9450
     */
9451
    public static function searchCourseInSessionsFromUser($userId, $courseId)
9452
    {
9453
        $table = Database::get_main_table(TABLE_MAIN_SESSION_COURSE_USER);
9454
        $userId = (int) $userId;
9455
        $courseId = (int) $courseId;
9456
        if (empty($userId) || empty($courseId)) {
9457
            return [];
9458
        }
9459
9460
        $sql = "SELECT * FROM $table
9461
                WHERE c_id = $courseId AND user_id = $userId";
9462
        $result = Database::query($sql);
9463
9464
        return Database::store_result($result, 'ASSOC');
9465
    }
9466
9467
    /**
9468
     * Subscribe and redirect to session after inscription.
9469
     */
9470
    public static function redirectToSession()
9471
    {
9472
        $sessionId = (int) ChamiloSession::read('session_redirect');
9473
        $onlyOneCourseSessionToRedirect = ChamiloSession::read('only_one_course_session_redirect');
9474
        if ($sessionId) {
9475
            $sessionInfo = api_get_session_info($sessionId);
9476
            if (!empty($sessionInfo)) {
9477
                $userId = api_get_user_id();
9478
                $response = self::isUserSubscribedAsStudent($sessionId, $userId);
9479
                if ($response) {
9480
                    $urlToRedirect = api_get_path(WEB_CODE_PATH).'session/index.php?session_id='.$sessionId;
9481
                    if (!empty($onlyOneCourseSessionToRedirect)) {
9482
                        $urlToRedirect = api_get_path(WEB_PATH).
9483
                            'courses/'.$onlyOneCourseSessionToRedirect.'/index.php?id_session='.$sessionId;
9484
                    }
9485
9486
                    header('Location: '.$urlToRedirect);
9487
                    exit;
9488
                }
9489
            }
9490
        }
9491
    }
9492
9493
    /**
9494
     * @return int
9495
     */
9496
    public static function getCountUsersInCourseSession(Course $course, Session $session)
9497
    {
9498
        $urlId = api_get_current_access_url_id();
9499
9500
        return Database::getManager()
9501
            ->createQuery("
9502
                SELECT COUNT(scu)
9503
                FROM ChamiloCoreBundle:SessionRelCourseRelUser scu
9504
                INNER JOIN ChamiloCoreBundle:SessionRelUser su
9505
                    WITH scu.user = su.user
9506
                    AND scu.session = su.session
9507
                INNER JOIN ChamiloCoreBundle:AccessUrlRelUser a
9508
                    WITH a.user = su.user
9509
                WHERE
9510
                    scu.course = :course AND
9511
                    su.relationType <> :relationType AND
9512
                    scu.session = :session AND
9513
                    a.portal = :url
9514
            ")
9515
            ->setParameters([
9516
                'course' => $course->getId(),
9517
                'relationType' => SESSION_RELATION_TYPE_RRHH,
9518
                'session' => $session->getId(),
9519
                'url' => $urlId,
9520
            ])
9521
            ->getSingleScalarResult();
9522
    }
9523
9524
    /**
9525
     * Get course IDs where user in not subscribed in session.
9526
     *
9527
     * @return array
9528
     */
9529
    public static function getAvoidedCoursesInSession(User $user, Session $session)
9530
    {
9531
        $courseIds = [];
9532
9533
        /** @var SessionRelCourse $sessionCourse */
9534
        foreach ($session->getCourses() as $sessionCourse) {
9535
            /** @var Course $course */
9536
            $course = $sessionCourse->getCourse();
9537
9538
            if ($session->getUserInCourse($user, $course)->count()) {
9539
                continue;
9540
            }
9541
9542
            $courseIds[] = $course->getId();
9543
        }
9544
9545
        return $courseIds;
9546
    }
9547
9548
    /**
9549
     * @param int             $userId
9550
     * @param int             $sessionId
9551
     * @param ExtraFieldValue $extraFieldValue
9552
     * @param string          $collapsableLink
9553
     *
9554
     * @return array
9555
     */
9556
    public static function getCollapsableData($userId, $sessionId, $extraFieldValue, $collapsableLink)
9557
    {
9558
        $collapsed = 0;
9559
9560
        // Get default collapsed value in extra field
9561
        $value = $extraFieldValue->get_values_by_handler_and_field_variable($sessionId, 'collapsed');
9562
        if (!empty($value) && isset($value['value'])) {
9563
            $collapsed = $value['value'];
9564
        }
9565
9566
        $userRelSession = self::getUserSession($userId, $sessionId);
9567
9568
        if ($userRelSession) {
9569
            if (isset($userRelSession['collapsed']) && '' != $userRelSession['collapsed']) {
9570
                $collapsed = $userRelSession['collapsed'];
9571
            }
9572
        } else {
9573
            return ['collapsed' => $collapsed, 'collapsable_link' => '&nbsp;'];
9574
        }
9575
9576
        $link = $collapsableLink.'&session_id='.$sessionId.'&value=1';
9577
        $image = '<i class="fa fa-folder-open"></i>';
9578
        if (1 == $collapsed) {
9579
            $link = $collapsableLink.'&session_id='.$sessionId.'&value=0';
9580
            $image = '<i class="fa fa-folder"></i>';
9581
        }
9582
9583
        $link = Display::url(
9584
            $image,
9585
            $link
9586
        );
9587
9588
        return ['collapsed' => $collapsed, 'collapsable_link' => $link];
9589
    }
9590
9591
    /**
9592
     * Converts "start date" and "end date" to "From start date to end date" string.
9593
     *
9594
     * @param string $startDate
9595
     * @param string $endDate
9596
     * @param bool   $showTime
9597
     * @param bool   $dateHuman
9598
     *
9599
     * @return string
9600
     */
9601
    public static function convertSessionDateToString($startDate, $endDate, $showTime, $dateHuman)
9602
    {
9603
        // api_get_local_time returns empty if date is invalid like 0000-00-00 00:00:00
9604
        $startDateToLocal = api_get_local_time(
9605
            $startDate,
9606
            null,
9607
            null,
9608
            true,
9609
            $showTime,
9610
            $dateHuman
9611
        );
9612
        $endDateToLocal = api_get_local_time(
9613
            $endDate,
9614
            null,
9615
            null,
9616
            true,
9617
            $showTime,
9618
            $dateHuman
9619
        );
9620
9621
        $format = $showTime ? DATE_TIME_FORMAT_LONG_24H : DATE_FORMAT_LONG_NO_DAY;
9622
9623
        $result = '';
9624
        if (!empty($startDateToLocal) && !empty($endDateToLocal)) {
9625
            $result = sprintf(
9626
                get_lang('FromDateXToDateY'),
9627
                api_format_date($startDateToLocal, $format),
9628
                api_format_date($endDateToLocal, $format)
9629
            );
9630
        } else {
9631
            if (!empty($startDateToLocal)) {
9632
                $result = get_lang('From').' '.api_format_date($startDateToLocal, $format);
9633
            }
9634
            if (!empty($endDateToLocal)) {
9635
                $result = get_lang('Until').' '.api_format_date($endDateToLocal, $format);
9636
            }
9637
        }
9638
        if (empty($result)) {
9639
            $result = get_lang('NoTimeLimits');
9640
        }
9641
9642
        return $result;
9643
    }
9644
9645
    public static function getStatusList()
9646
    {
9647
        return [
9648
            self::STATUS_PLANNED => get_lang('Planned'),
9649
            self::STATUS_PROGRESS => get_lang('InProgress'),
9650
            self::STATUS_FINISHED => get_lang('Finished'),
9651
            self::STATUS_CANCELLED => get_lang('Cancelled'),
9652
        ];
9653
    }
9654
9655
    public static function getStatusLabel($status)
9656
    {
9657
        $list = self::getStatusList();
9658
9659
        if (!isset($list[$status])) {
9660
            return get_lang('NoStatus');
9661
        }
9662
9663
        return $list[$status];
9664
    }
9665
9666
    public static function getDefaultSessionTab()
9667
    {
9668
        $default = 'all';
9669
        $view = api_get_configuration_value('default_session_list_view');
9670
9671
        if (!empty($view)) {
9672
            $default = $view;
9673
        }
9674
9675
        return $default;
9676
    }
9677
9678
    /**
9679
     * @return string
9680
     */
9681
    public static function getSessionListTabs($listType)
9682
    {
9683
        $tabs = [
9684
            [
9685
                'content' => get_lang('AllSessionsShort'),
9686
                'url' => api_get_path(WEB_CODE_PATH).'session/session_list.php?list_type=all',
9687
            ],
9688
            [
9689
                'content' => get_lang('ActiveSessionsShort'),
9690
                'url' => api_get_path(WEB_CODE_PATH).'session/session_list.php?list_type=active',
9691
            ],
9692
            [
9693
                'content' => get_lang('ClosedSessionsShort'),
9694
                'url' => api_get_path(WEB_CODE_PATH).'session/session_list.php?list_type=close',
9695
            ],
9696
            [
9697
                'content' => get_lang('SessionListCustom'),
9698
                'url' => api_get_path(WEB_CODE_PATH).'session/session_list.php?list_type=custom',
9699
            ],
9700
            /*[
9701
                'content' => get_lang('Complete'),
9702
                'url' => api_get_path(WEB_CODE_PATH).'session/session_list_simple.php?list_type=complete',
9703
            ],*/
9704
        ];
9705
9706
        switch ($listType) {
9707
            case 'all':
9708
                $default = 1;
9709
                break;
9710
            case 'active':
9711
                $default = 2;
9712
                break;
9713
            case 'close':
9714
                $default = 3;
9715
                break;
9716
            case 'custom':
9717
                $default = 4;
9718
                break;
9719
        }
9720
9721
        return Display::tabsOnlyLink($tabs, $default);
9722
    }
9723
9724
    /**
9725
     * Check if a session is followed by human resources manager.
9726
     *
9727
     * @param int $sessionId
9728
     * @param int $userId
9729
     *
9730
     * @return bool
9731
     */
9732
    public static function isSessionFollowedByDrh($sessionId, $userId)
9733
    {
9734
        $userId = (int) $userId;
9735
        $sessionId = (int) $sessionId;
9736
9737
        $tblSession = Database::get_main_table(TABLE_MAIN_SESSION);
9738
        $tblSessionRelUser = Database::get_main_table(TABLE_MAIN_SESSION_USER);
9739
9740
        if (api_is_multiple_url_enabled()) {
9741
            $tblSessionRelAccessUrl = Database::get_main_table(TABLE_MAIN_ACCESS_URL_REL_SESSION);
9742
9743
            $sql = "SELECT s.id FROM $tblSession s
9744
                INNER JOIN $tblSessionRelUser sru ON (sru.session_id = s.id)
9745
                LEFT JOIN $tblSessionRelAccessUrl a ON (s.id = a.session_id)
9746
                WHERE
9747
                    sru.user_id = '$userId' AND
9748
                    sru.session_id = '$sessionId' AND
9749
                    sru.relation_type = '".SESSION_RELATION_TYPE_RRHH."' AND
9750
                    access_url_id = ".api_get_current_access_url_id();
9751
        } else {
9752
            $sql = "SELECT s.id FROM $tblSession s
9753
                INNER JOIN $tblSessionRelUser sru ON sru.session_id = s.id
9754
                WHERE
9755
                    sru.user_id = '$userId' AND
9756
                    sru.session_id = '$sessionId' AND
9757
                    sru.relation_type = '".SESSION_RELATION_TYPE_RRHH."'";
9758
        }
9759
9760
        $result = Database::query($sql);
9761
9762
        return Database::num_rows($result) > 0;
9763
    }
9764
9765
    /**
9766
     * Add a warning message when session is read-only mode.
9767
     */
9768
    public static function addFlashSessionReadOnly()
9769
    {
9770
        if (api_get_session_id() && !api_is_allowed_to_session_edit()) {
9771
            Display::addFlash(
9772
                Display::return_message(get_lang('SessionIsReadOnly'), 'warning')
9773
            );
9774
        }
9775
    }
9776
9777
    public static function insertUsersInCourses(array $studentIds, array $courseIds, int $sessionId)
9778
    {
9779
        $tblSessionUser = Database::get_main_table(TABLE_MAIN_SESSION_USER);
9780
        $tblSession = Database::get_main_table(TABLE_MAIN_SESSION);
9781
9782
        foreach ($courseIds as $courseId) {
9783
            self::insertUsersInCourse($studentIds, $courseId, $sessionId, [], false);
9784
        }
9785
9786
        foreach ($studentIds as $studentId) {
9787
            Database::query(
9788
                "INSERT IGNORE INTO $tblSessionUser (session_id, user_id, registered_at)
9789
                VALUES ($sessionId, $studentId, '".api_get_utc_datetime()."')"
9790
            );
9791
        }
9792
9793
        Database::query(
9794
            "UPDATE $tblSession s
9795
            SET s.nbr_users = (
9796
                SELECT COUNT(1) FROM session_rel_user sru
9797
                WHERE sru.session_id = $sessionId AND sru.relation_type <> ".Session::DRH."
9798
            )
9799
            WHERE s.id = $sessionId"
9800
        );
9801
    }
9802
9803
    public static function insertUsersInCourse(
9804
        array $studentIds,
9805
        int $courseId,
9806
        int $sessionId,
9807
        array $relationInfo = [],
9808
        bool $updateSession = true
9809
    ) {
9810
        $tblSessionCourseUser = Database::get_main_table(TABLE_MAIN_SESSION_COURSE_USER);
9811
        $tblSessionCourse = Database::get_main_table(TABLE_MAIN_SESSION_COURSE);
9812
        $tblSessionUser = Database::get_main_table(TABLE_MAIN_SESSION_USER);
9813
        $tblSession = Database::get_main_table(TABLE_MAIN_SESSION);
9814
9815
        $relationInfo = array_merge(['visibility' => 0, 'status' => Session::STUDENT], $relationInfo);
9816
        $courseInfo = api_get_course_info_by_id($courseId);
9817
        $courseCode = $courseInfo['code'];
9818
        $subscribeToForums = (int) api_get_course_setting('subscribe_users_to_forum_notifications', $courseInfo);
9819
        if ($subscribeToForums) {
9820
            $forums = [];
9821
            $forumsBaseCourse = [];
9822
            require_once api_get_path(SYS_CODE_PATH).'forum/forumfunction.inc.php';
9823
            $forums = get_forums(0, $courseCode, true, $sessionId);
9824
            if (api_get_configuration_value('subscribe_users_to_forum_notifications_also_in_base_course')) {
9825
                $forumsBaseCourse = get_forums(0, $courseCode, true, 0);
9826
            }
9827
        }
9828
9829
        $sessionCourseUser = [
9830
            'session_id' => $sessionId,
9831
            'c_id' => $courseId,
9832
            'visibility' => $relationInfo['visibility'],
9833
            'status' => $relationInfo['status'],
9834
        ];
9835
        $sessionUser = [
9836
            'session_id' => $sessionId,
9837
            'registered_at' => api_get_utc_datetime(),
9838
        ];
9839
9840
        foreach ($studentIds as $studentId) {
9841
            $sessionCourseUser['user_id'] = $studentId;
9842
9843
            $count = Database::select(
9844
                'COUNT(1) as nbr',
9845
                $tblSessionCourseUser,
9846
                ['where' => ['session_id = ? AND c_id = ? AND user_id = ?' => [$sessionId, $courseId, $studentId]]],
9847
                'first'
9848
            );
9849
9850
            if (empty($count['nbr'])) {
9851
                Database::insert($tblSessionCourseUser, $sessionCourseUser);
9852
9853
                Event::logUserSubscribedInCourseSession($studentId, $courseId, $sessionId);
9854
                if ($subscribeToForums) {
9855
                    $userInfo = api_get_user_info($studentId);
9856
                    if (!empty($forums)) {
9857
                        foreach ($forums as $forum) {
9858
                            $forumId = $forum['iid'];
9859
                            set_notification('forum', $forumId, false, $userInfo, $courseInfo);
9860
                        }
9861
                    }
9862
                    if (!empty($forumsBaseCourse)) {
9863
                        foreach ($forumsBaseCourse as $forum) {
9864
                            $forumId = $forum['iid'];
9865
                            set_notification('forum', $forumId, false, $userInfo, $courseInfo);
9866
                        }
9867
                    }
9868
                }
9869
            }
9870
9871
            if ($updateSession) {
9872
                $sessionUser['user_id'] = $studentId;
9873
9874
                $count = Database::select(
9875
                    'COUNT(1) as nbr',
9876
                    $tblSessionUser,
9877
                    ['where' => ['session_id = ? AND user_id = ?' => [$sessionId, $studentId]]],
9878
                    'first'
9879
                );
9880
9881
                if (empty($count['nbr'])) {
9882
                    Database::insert($tblSessionUser, $sessionUser);
9883
                }
9884
            }
9885
        }
9886
9887
        Database::query(
9888
            "UPDATE $tblSessionCourse src
9889
            SET src.nbr_users = (
9890
                SELECT COUNT(1) FROM $tblSessionCourseUser srcru
9891
                WHERE
9892
                    srcru.session_id = $sessionId AND srcru.c_id = $courseId AND srcru.status <> ".Session::COACH."
9893
            )
9894
            WHERE src.session_id = $sessionId AND src.c_id = $courseId"
9895
        );
9896
9897
        if ($updateSession) {
9898
            Database::query(
9899
                "UPDATE $tblSession s
9900
                SET s.nbr_users = (
9901
                    SELECT COUNT(1) FROM session_rel_user sru
9902
                    WHERE sru.session_id = $sessionId AND sru.relation_type <> ".Session::DRH."
9903
                )
9904
                WHERE s.id = $sessionId"
9905
            );
9906
        }
9907
    }
9908
9909
    public static function getCareersFromSession(int $sessionId): array
9910
    {
9911
        $extraFieldValueSession = new ExtraFieldValue('session');
9912
        $extraFieldValueCareer = new ExtraFieldValue('career');
9913
9914
        $value = $extraFieldValueSession->get_values_by_handler_and_field_variable($sessionId, 'careerid');
9915
        $careers = [];
9916
        if (isset($value['value']) && !empty($value['value'])) {
9917
            $careerList = str_replace(['[', ']'], '', $value['value']);
9918
            $careerList = explode(',', $careerList);
9919
            $careerManager = new Career();
9920
            foreach ($careerList as $career) {
9921
                $careerIdValue = $extraFieldValueCareer->get_item_id_from_field_variable_and_field_value(
9922
                    'external_career_id',
9923
                    $career
9924
                );
9925
                if (isset($careerIdValue['item_id']) && !empty($careerIdValue['item_id'])) {
9926
                    $finalCareerId = $careerIdValue['item_id'];
9927
                    $careerInfo = $careerManager->get($finalCareerId);
9928
                    if (!empty($careerInfo)) {
9929
                        $careers[] = $careerInfo;
9930
                    }
9931
                }
9932
            }
9933
        }
9934
9935
        return $careers;
9936
    }
9937
9938
    public static function getCareerDiagramPerSessionList($sessionList, $userId)
9939
    {
9940
        if (empty($sessionList) || empty($userId)) {
9941
            return '';
9942
        }
9943
9944
        $userId = (int) $userId;
9945
        $careersAdded = [];
9946
        $careerModel = new Career();
9947
        $frames = '';
9948
        foreach ($sessionList as $sessionId) {
9949
            $visibility = api_get_session_visibility($sessionId, null, false, $userId);
9950
            if (SESSION_AVAILABLE === $visibility) {
9951
                $careerList = self::getCareersFromSession($sessionId);
9952
                if (empty($careerList)) {
9953
                    continue;
9954
                }
9955
                foreach ($careerList as $career) {
9956
                    $careerId = $careerIdToShow = $career['id'];
9957
                    if (api_get_configuration_value('use_career_external_id_as_identifier_in_diagrams')) {
9958
                        $careerIdToShow = $careerModel->getCareerIdFromInternalToExternal($careerId);
9959
                    }
9960
9961
                    if (!in_array($careerId, $careersAdded)) {
9962
                        $careersAdded[] = $careerId;
9963
                        $careerUrl = api_get_path(WEB_CODE_PATH).'user/career_diagram.php?iframe=1&career_id='.$careerIdToShow.'&user_id='.$userId;
9964
                        $frames .= '
9965
                            <iframe
9966
                                onload="resizeIframe(this)"
9967
                                style="width:100%;"
9968
                                border="0"
9969
                                frameborder="0"
9970
                                scrolling="no"
9971
                                src="'.$careerUrl.'"
9972
                            ></iframe>';
9973
                    }
9974
                }
9975
            }
9976
        }
9977
9978
        $content = '';
9979
        if (!empty($frames)) {
9980
            $content = Display::page_subheader(get_lang('OngoingTraining'));
9981
            $content .= '
9982
               <script>
9983
                resizeIframe = function(iFrame) {
9984
                    iFrame.height = iFrame.contentWindow.document.body.scrollHeight + 20;
9985
                }
9986
                </script>
9987
            ';
9988
            $content .= $frames;
9989
            $content .= Career::renderDiagramFooter();
9990
        }
9991
9992
        return $content;
9993
    }
9994
9995
    public static function importAgendaFromSessionModel(int $modelSessionId, int $sessionId, int $courseId)
9996
    {
9997
        $em = Database::getManager();
9998
        $repo = $em->getRepository('ChamiloCourseBundle:CCalendarEvent');
9999
10000
        $courseInfo = api_get_course_info_by_id($courseId);
10001
        $session = api_get_session_entity($sessionId);
10002
        $modelSession = api_get_session_entity($modelSessionId);
10003
10004
        $sessionDateDiff = $modelSession->getAccessStartDate()->diff($session->getAccessStartDate());
10005
10006
        $events = $repo->findBy(
10007
            ['cId' => $courseId, 'sessionId' => $modelSessionId]
10008
        );
10009
10010
        $agenda = new Agenda('course');
10011
        $agenda->set_course($courseInfo);
10012
        $agenda->setSessionId($sessionId);
10013
10014
        foreach ($events as $event) {
10015
            $startDate = $event->getStartDate()->add($sessionDateDiff);
10016
            $endDate = $event->getEndDate()->add($sessionDateDiff);
10017
10018
            $agenda->addEvent(
10019
                $startDate->format('Y-m-d H:i:s'),
10020
                $endDate->format('Y-m-d H:i:s'),
10021
                'false',
10022
                $event->getTitle(),
10023
                $event->getContent(),
10024
                ['GROUP:0'],
10025
                false,
10026
                null,
10027
                [],
10028
                [],
10029
                $event->getComment(),
10030
                $event->getColor()
10031
            );
10032
        }
10033
    }
10034
10035
    /**
10036
     * Export an Excel report for a specific course within a session.
10037
     *
10038
     * The report includes session details and a list of certified users
10039
     * with their extra field values.
10040
     *
10041
     * @param int    $sessionId  ID of the session
10042
     * @param string $courseCode Course code of the course in the session
10043
     */
10044
    public static function exportCourseSessionReport(int $sessionId, string $courseCode): void
10045
    {
10046
        $courseInfo = api_get_course_info($courseCode);
10047
        $sessionInfo = api_get_session_info($sessionId);
10048
10049
        if (empty($courseInfo) || empty($sessionInfo)) {
10050
            exit('Invalid course or session.');
0 ignored issues
show
Best Practice introduced by
Using exit here is not recommended.

In general, usage of exit should be done with care and only when running in a scripting context like a CLI script.

Loading history...
10051
        }
10052
10053
        $config = api_get_configuration_value('session_course_excel_export');
10054
        if (empty($config)) {
10055
            exit('Configuration not set.');
0 ignored issues
show
Best Practice introduced by
Using exit here is not recommended.

In general, usage of exit should be done with care and only when running in a scripting context like a CLI script.

Loading history...
10056
        }
10057
10058
        $sessionFields = $config['session_fields'] ?? [];
10059
        $userFieldsBefore = $config['user_fields_before'] ?? [];
10060
        $userFieldsAfter = $config['user_fields_after'] ?? [];
10061
10062
        // 1. SESSION HEADER
10063
        $header1 = [''];
10064
        $header1[] = $config['session_start_date_header'] ?? get_lang('StartDate');
10065
        $header1[] = $config['session_end_date_header'] ?? get_lang('EndDate');
10066
10067
        foreach ($sessionFields as $entry) {
10068
            $header1[] = $entry['header'] ?? '';
10069
        }
10070
10071
        // 2. SESSION DATA
10072
        $row2 = $config['course_field_value'] ? [$config['course_field_value']] : [$courseInfo['title']];
10073
        $row2[] = (new DateTime($sessionInfo['access_start_date']))->format('d/m/Y');
10074
        $row2[] = (new DateTime($sessionInfo['access_end_date']))->format('d/m/Y');
10075
10076
        $extraValuesObj = new ExtraFieldValue('session');
10077
        $sessionExtra = $extraValuesObj->getAllValuesByItem($sessionId);
10078
        $sessionExtraMap = array_column($sessionExtra, 'value', 'variable');
10079
10080
        foreach ($sessionFields as $entry) {
10081
            if (!empty($entry['field'])) {
10082
                $value = $sessionExtraMap[$entry['field']] ?? '';
10083
                if (!empty($entry['numberOfLetter']) && $entry['numberOfLetter'] > 0) {
10084
                    $value = mb_substr($value, 0, $entry['numberOfLetter']);
10085
                }
10086
            } else {
10087
                $value = '';
10088
            }
10089
            $row2[] = $value;
10090
        }
10091
10092
        // 3. USER HEADER
10093
        $header3 = [''];
10094
10095
        foreach ($userFieldsBefore as $entry) {
10096
            $header3[] = $entry['header'] ?? '';
10097
        }
10098
10099
        $header3[] = $config['user_firstname_header'] ?? get_lang('FirstName');
10100
        $header3[] = $config['user_lastname_header'] ?? get_lang('LastName');
10101
10102
        foreach ($userFieldsAfter as $entry) {
10103
            $header3[] = $entry['header'] ?? '';
10104
        }
10105
10106
        // 4. USERS WITH CERTIFICATE
10107
        $dataRows = [];
10108
10109
        $tblCat = Database::get_main_table(TABLE_MAIN_GRADEBOOK_CATEGORY);
10110
        $sql = "
10111
            SELECT id FROM $tblCat
10112
            WHERE course_code = '".Database::escape_string($courseCode)."'
10113
            AND session_id = ".intval($sessionId)."
10114
            AND generate_certificates = 1
10115
            LIMIT 1
10116
        ";
10117
        $res = Database::query($sql);
10118
        $row = Database::fetch_array($res);
10119
        $catId = $row ? (int) $row['id'] : 0;
10120
10121
        if ($catId > 0) {
10122
            $tableCertificate = Database::get_main_table(TABLE_MAIN_GRADEBOOK_CERTIFICATE);
10123
            $sql = "SELECT DISTINCT user_id FROM $tableCertificate WHERE cat_id = $catId";
10124
            $res = Database::query($sql);
10125
10126
            $rowIndex = 0;
10127
            while ($cert = Database::fetch_array($res)) {
10128
                $userId = $cert['user_id'];
10129
                $userInfo = api_get_user_info($userId);
10130
10131
                $row = [];
10132
                $row[] = get_lang('Learners');
10133
10134
                $userExtraObj = new ExtraFieldValue('user');
10135
                $userExtra = $userExtraObj->getAllValuesByItem($userId);
10136
                $userExtraMap = array_column($userExtra, 'value', 'variable');
10137
10138
                foreach ($userFieldsBefore as $entry) {
10139
                    if (!empty($entry['field'])) {
10140
                        $value = $userExtraMap[$entry['field']] ?? '';
10141
                    } else {
10142
                        $value = '';
10143
                    }
10144
                    $row[] = $value;
10145
                }
10146
10147
                $row[] = $userInfo['firstname'];
10148
                $row[] = $userInfo['lastname'];
10149
10150
                foreach ($userFieldsAfter as $entry) {
10151
                    if (!empty($entry['field'])) {
10152
                        $value = $userExtraMap[$entry['field']] ?? '';
10153
                    } else {
10154
                        $value = '';
10155
                    }
10156
                    $row[] = $value;
10157
                }
10158
10159
                $dataRows[] = $row;
10160
                $rowIndex++;
10161
            }
10162
        }
10163
10164
        // 5. EXPORT FINAL
10165
        $rows = [];
10166
        $rows[] = $header1;
10167
        $rows[] = $row2;
10168
        $rows[] = $header3;
10169
        $rows = array_merge($rows, $dataRows);
10170
10171
        $filename = 'session_'.$sessionId.'_course_'.$courseCode;
10172
        Export::arrayToXls($rows, $filename);
10173
    }
10174
10175
    /**
10176
     * @param int $id
10177
     *
10178
     * @return bool
10179
     */
10180
    private static function allowed($id)
10181
    {
10182
        $sessionInfo = self::fetch($id);
10183
10184
        if (empty($sessionInfo)) {
10185
            return false;
10186
        }
10187
10188
        if (api_is_platform_admin()) {
10189
            return true;
10190
        }
10191
10192
        $userId = api_get_user_id();
10193
10194
        if (api_is_session_admin() &&
10195
            api_get_setting('allow_session_admins_to_manage_all_sessions') != 'true'
10196
        ) {
10197
            if ($sessionInfo['session_admin_id'] != $userId) {
10198
                return false;
10199
            }
10200
        }
10201
10202
        if (api_is_teacher() &&
10203
            api_get_setting('allow_teachers_to_create_sessions') == 'true'
10204
        ) {
10205
            if ($sessionInfo['id_coach'] != $userId) {
10206
                return false;
10207
            }
10208
        }
10209
10210
        return true;
10211
    }
10212
10213
    /**
10214
     * Add classes (by their names) to a session.
10215
     *
10216
     * @param int   $sessionId
10217
     * @param array $classesNames
10218
     * @param bool  $deleteClassSessions Optional. Empty the session list for the usergroup (class)
10219
     */
10220
    private static function addClassesByName($sessionId, $classesNames, $deleteClassSessions = true, ?string &$error_message = '')
10221
    {
10222
        if (!$classesNames) {
10223
            return;
10224
        }
10225
10226
        $usergroup = new UserGroup();
10227
10228
        foreach ($classesNames as $className) {
10229
            if (empty($className)) {
10230
                continue;
10231
            }
10232
10233
            $classIdByName = $usergroup->getIdByName($className);
10234
10235
            if (empty($classIdByName)) {
10236
                $error_message .= sprintf(get_lang('ClassNameXDoesntExists'), $className).'<br>';
10237
                continue;
10238
            }
10239
10240
            $usergroup->subscribe_sessions_to_usergroup(
10241
                $usergroup->getIdByName($className),
10242
                [$sessionId],
10243
                $deleteClassSessions
10244
            );
10245
        }
10246
    }
10247
10248
    /**
10249
     * @param array $listA
10250
     * @param array $listB
10251
     *
10252
     * @return int
10253
     */
10254
    private static function compareCatSessionInfo($listA, $listB)
10255
    {
10256
        if ($listA['sessionName'] == $listB['sessionName']) {
10257
            return 0;
10258
        } elseif ($listA['sessionName'] > $listB['sessionName']) {
10259
            return 1;
10260
        } else {
10261
            return -1;
10262
        }
10263
    }
10264
10265
    /**
10266
     * @param array $listA
10267
     * @param array $listB
10268
     *
10269
     * @return int
10270
     */
10271
    private static function compareBySessionName($listA, $listB)
10272
    {
10273
        if ('' == $listB['catSessionName']) {
10274
            return -1;
10275
        } elseif ('' == $listA['catSessionName']) {
10276
            return 1;
10277
        } elseif ($listA['catSessionName'] == $listB['catSessionName']) {
10278
            return 0;
10279
        } elseif ($listA['catSessionName'] > $listB['catSessionName']) {
10280
            return 1;
10281
        } else {
10282
            return -1;
10283
        }
10284
    }
10285
10286
    /**
10287
     * @param array $listA
10288
     * @param array $listB
10289
     *
10290
     * @return int
10291
     */
10292
    private static function compareByUserCourseCat($listA, $listB)
10293
    {
10294
        if ($listA['courseInUserCategoryTitle'] == $listB['courseInUserCategoryTitle']) {
10295
            return 0;
10296
        } elseif ($listA['courseInUserCategoryTitle'] > $listB['courseInUserCategoryTitle']) {
10297
            return 1;
10298
        } else {
10299
            return -1;
10300
        }
10301
    }
10302
10303
    /**
10304
     * @param array $listA
10305
     * @param array $listB
10306
     *
10307
     * @return int
10308
     */
10309
    private static function compareByCourse($listA, $listB)
10310
    {
10311
        if ($listA['title'] == $listB['title']) {
10312
            return 0;
10313
        } elseif ($listA['title'] > $listB['title']) {
10314
            return 1;
10315
        } else {
10316
            return -1;
10317
        }
10318
    }
10319
}
10320