Passed
Push — master ( 6d3a7a...482b77 )
by Julito
12:08 queued 02:23
created

SessionManager::getGridColumns()   F

Complexity

Conditions 16
Paths 176

Size

Total Lines 339
Code Lines 240

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 16
eloc 240
nc 176
nop 3
dl 0
loc 339
rs 3.9466
c 0
b 0
f 0

How to fix   Long Method    Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

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