Passed
Push — master ( e0f7b0...a8affd )
by Julito
10:09
created

subscribe_users_to_session_course()   D

Complexity

Conditions 13
Paths 251

Size

Total Lines 118
Code Lines 71

Duplication

Lines 0
Ratio 0 %

Importance

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