Passed
Push — 1.11.x ( e282bd...b5efff )
by Julito
12:38
created

SessionManager::getDrhUsersInSession()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Importance

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