Passed
Push — master ( 846ef0...bcba07 )
by Julito
10:18
created

SessionManager::get_session_by_course()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 24
Code Lines 15

Duplication

Lines 0
Ratio 0 %

Importance

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