Passed
Push — master ( 6f8cb0...cccadf )
by Julito
09:47
created

SessionManager::getDayLeftInSession()   A

Complexity

Conditions 3
Paths 4

Size

Total Lines 27
Code Lines 15

Duplication

Lines 0
Ratio 0 %

Importance

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