Passed
Push — 1.11.x ( 5b3cc8...a5e65d )
by Yannick
08:50
created

SessionManager::getCountUserTracking()   B

Complexity

Conditions 7

Size

Total Lines 71
Code Lines 51

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 51
c 0
b 0
f 0
dl 0
loc 71
rs 8.1357
cc 7
nop 6

How to fix   Long Method   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

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