Passed
Pull Request — master (#5678)
by Angel Fernando Quiroz
07:40
created

SessionManager::getSessionsCoachedByUser()   B

Complexity

Conditions 10
Paths 24

Size

Total Lines 47
Code Lines 25

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 10
eloc 25
nc 24
nop 3
dl 0
loc 47
rs 7.6666
c 0
b 0
f 0

How to fix   Complexity   

Long Method

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

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

Commonly applied refactorings include:

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