Passed
Push — master ( 3ef090...0b35a3 )
by Julito
12:21
created

SessionManager::get_sessions_by_coach()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 8
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Importance

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