Passed
Pull Request — master (#5831)
by
unknown
07:40
created

SessionManager::getSessionListTabs()   B

Complexity

Conditions 6

Size

Total Lines 44
Code Lines 29

Duplication

Lines 0
Ratio 0 %

Importance

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