Completed
Push — 1.11.x ( 0adea3...e968b6 )
by Angel Fernando Quiroz
01:23 queued 37s
created

subscribe_users_to_session_course()   B

Complexity

Conditions 10
Paths 41

Size

Total Lines 56
Code Lines 35

Duplication

Lines 0
Ratio 0 %

Importance

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