Passed
Push — master ( a1bcc9...8213a1 )
by Julito
08:44 queued 10s
created

SessionManager::importSessionDrhCSV()   B

Complexity

Conditions 7
Paths 10

Size

Total Lines 30
Code Lines 17

Duplication

Lines 0
Ratio 0 %

Importance

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