Passed
Push — 1.11.x ( 14e699...c8748f )
by Yannick
08:32
created

SessionManager::getCoachesByCourseSession()   A

Complexity

Conditions 3

Size

Total Lines 21
Code Lines 12

Duplication

Lines 0
Ratio 0 %

Importance

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