SessionManager::isUserSubscribedAsStudent()   A
last analyzed

Complexity

Conditions 3
Paths 2

Size

Total Lines 21
Code Lines 10

Duplication

Lines 0
Ratio 0 %

Importance

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

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

Loading history...
10045
        }
10046
10047
        $config = api_get_configuration_value('session_course_excel_export');
10048
        if (empty($config)) {
10049
            exit('Configuration not set.');
0 ignored issues
show
Best Practice introduced by
Using exit here is not recommended.

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

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