Passed
Pull Request — master (#5828)
by
unknown
07:02
created

SessionManager::notifyBossOfInscription()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 33
Code Lines 21

Duplication

Lines 0
Ratio 0 %

Importance

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