Passed
Push — master ( 271415...ff556a )
by Julito
09:26
created

SessionManager::generateNextSessionName()   A

Complexity

Conditions 4
Paths 4

Size

Total Lines 23
Code Lines 16

Duplication

Lines 0
Ratio 0 %

Importance

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