Passed
Push — master ( ade321...56ef38 )
by Julito
07:36
created

SessionManager::getCoachesBySession()   A

Complexity

Conditions 3
Paths 2

Size

Total Lines 18
Code Lines 11

Duplication

Lines 0
Ratio 0 %

Importance

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