Passed
Push — 1.11.x ( 1417ae...7f8c05 )
by Julito
14:05 queued 10s
created

SessionManager::allowOnlyMySessions()   A

Complexity

Conditions 4
Paths 2

Size

Total Lines 10
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Importance

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